diff --git a/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/agents/generic.py b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/agents/generic.py new file mode 100644 index 00000000..a19d6461 --- /dev/null +++ b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/agents/generic.py @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Generic agent installer for Agent Skills-compatible folders.""" + +from pathlib import Path + +import yaml +from nemo_platform_ext.cli.commands.skills.base import Scope, Skill +from nemo_platform_ext.cli.commands.skills.installer import BaseAgentInstaller + + +class GenericInstaller(BaseAgentInstaller): + name = "generic" + display_name = "Generic (.agents/skills)" + supported_scopes = [Scope.PROJECT, Scope.USER] + + def get_install_path(self, scope: Scope, project_root: Path, skill_name: str) -> Path: + if scope == Scope.PROJECT: + return project_root / ".agents" / "skills" / f"nemo-{skill_name}" / "SKILL.md" + return Path.home() / ".agents" / "skills" / f"nemo-{skill_name}" / "SKILL.md" + + def format_content(self, skill: Skill) -> str: + front_matter = yaml.safe_dump( + {"name": f"nemo-{skill.name}", "description": skill.description}, + sort_keys=False, + allow_unicode=True, + ) + return f"---\n{front_matter}---\n\n{skill.content}" diff --git a/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/cli.py b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/cli.py index 57114188..f17b9be6 100644 --- a/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/cli.py +++ b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/cli.py @@ -268,6 +268,20 @@ def install( bool, typer.Option("--user", help="Install to user scope (default: project scope)"), ] = False, + project_root: Annotated[ + Path | None, + typer.Option( + "--project-root", + help=( + "Override the project root for project-scope installs. Defaults to " + "the nearest ancestor containing a .git directory, or the current " + "working directory if no Git root is found." + ), + file_okay=False, + dir_okay=True, + exists=True, + ), + ] = None, ) -> None: """Install Nemo skill files for an AI coding agent. @@ -278,6 +292,7 @@ def install( nemo skills install --agent claude nemo skills install --agent claude --user nemo skills install --agent claude --skill inference + nemo skills install --agent generic --project-root path/to/agent """ try: installer = get_installer(agent) @@ -295,9 +310,16 @@ def install( ) raise typer.Exit(code=1) + if project_root is not None and scope is not Scope.PROJECT: + typer.echo( + "Error: --project-root only applies to project-scope installs (omit --user).", + err=True, + ) + raise typer.Exit(code=1) + skills = _resolve_skills(skill) - project_root = _find_project_root() - result_paths = installer.install(scope, project_root, skills) + resolved_root = project_root.resolve() if project_root is not None else _find_project_root() + result_paths = installer.install(scope, resolved_root, skills) typer.echo(f"Installed {len(skills)} skill(s) for {installer.display_name}:") for path in result_paths: typer.echo(f" {path}") diff --git a/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/registry.py b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/registry.py index ffa17c62..f78646a7 100644 --- a/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/registry.py +++ b/packages/nemo_platform_ext/src/nemo_platform_ext/cli/commands/skills/registry.py @@ -21,6 +21,7 @@ from nemo_platform_ext.cli.commands.skills.agents.claude import ClaudeInstaller from nemo_platform_ext.cli.commands.skills.agents.codex import CodexInstaller from nemo_platform_ext.cli.commands.skills.agents.cursor import CursorInstaller +from nemo_platform_ext.cli.commands.skills.agents.generic import GenericInstaller from nemo_platform_ext.cli.commands.skills.agents.opencode import OpenCodeInstaller from nemo_platform_ext.cli.commands.skills.base import Skill from nemo_platform_ext.cli.commands.skills.installer import BaseAgentInstaller @@ -42,6 +43,7 @@ "claude": ClaudeInstaller(), "cursor": CursorInstaller(), "codex": CodexInstaller(), + "generic": GenericInstaller(), "opencode": OpenCodeInstaller(), } diff --git a/plugins/nemo-agents/examples/nemo-cli-agent/AGENTS.md b/plugins/nemo-agents/examples/nemo-cli-agent/AGENTS.md new file mode 100644 index 00000000..95f9f945 --- /dev/null +++ b/plugins/nemo-agents/examples/nemo-cli-agent/AGENTS.md @@ -0,0 +1,10 @@ +# NeMo CLI Agent + +You are a NeMo Platform CLI assistant. + +Help the user understand and operate NeMo Platform through natural language. + +## Skills + +If you do not see any NeMo-related skills, install them with +`nemo skills install --agent generic` from this folder. \ No newline at end of file diff --git a/plugins/nemo-agents/examples/nemo-cli-agent/DEEP_AGENTS.md b/plugins/nemo-agents/examples/nemo-cli-agent/DEEP_AGENTS.md new file mode 100644 index 00000000..cd90c5f1 --- /dev/null +++ b/plugins/nemo-agents/examples/nemo-cli-agent/DEEP_AGENTS.md @@ -0,0 +1,29 @@ +# DeepAgents Runtime + +These instructions apply when this folder is run through the bundled +LangChain DeepAgents graph. + +## Skills + +The runtime loads `.agents/skills/` with DeepAgents `SkillsMiddleware`. It +injects every skill's name, description, and path into this prompt in an +**Available Skills** section. + +For every user request, scan **Available Skills** first. If a skill matches the +intent, even loosely, call `read_file` on that skill's `SKILL.md` path before +running any `nemo` command. + +## Tools + +Use `nemo_cli` only for a single command whose first token is `nemo`. It cannot +run shell pipelines, redirection, `echo`, `cat`, `&&`, or local file creation. +When an instruction shows unsupported shell syntax, adapt it to an equivalent +single `nemo` command. + +Do not claim tools are insufficient until you have attempted reasonable +equivalent operations with valid `nemo_cli` commands. + +The `write_file` tool defaults to an in-memory scratchpad that subprocess tools, +including `nemo_cli`, cannot read. When a file you create needs to be read by a +subprocess, write it under `/tmp/` and reference that same `/tmp/...` path from +the subprocess. diff --git a/plugins/nemo-agents/examples/nemo-cli-agent/README.md b/plugins/nemo-agents/examples/nemo-cli-agent/README.md new file mode 100644 index 00000000..82c6cc73 --- /dev/null +++ b/plugins/nemo-agents/examples/nemo-cli-agent/README.md @@ -0,0 +1,45 @@ +# NeMo CLI Agent + +`nemo-cli-agent` is a proof-of-concept NeMo Platform reference agent. It uses a NAT wrapper around a DeepAgents graph to help users operate NeMo Platform through natural language and the `nemo` CLI. + +## Invoke + +```bash +export NEMO_DEFAULT_INFERENCE_BASE_URL=https://inference-api.nvidia.com/v1 +export NEMO_DEFAULT_INFERENCE_API_KEY=nvapi-... +export NEMO_DEFAULT_MODEL=nvidia/nvidia/nemotron-3-super-v3 +``` + +The workflow reads these variables from `nemo-cli-agent.yml` and passes them to +NAT's OpenAI-compatible LLM provider. + +The fastest path is the bundled `nemo ask` shortcut: + +```bash +nemo ask "load the nemo cli skills" +nemo ask "list all my workspaces" +``` + +`nemo ask` is registered as a top-level command via the `nemo.cli` plugin hook and dispatches to this example agent. + +Or run via the standard agent invocation from the repository root: + +```bash +nemo agents invoke \ + --agent-config plugins/nemo-agents/examples/nemo-cli-agent/nemo-cli-agent.yml \ + --input "list all my workspaces" +``` + +On first run, the DeepAgents runtime installs the NeMo CLI skills into `.agents/skills/`. `AGENTS.md` stays portable for Cursor and other harnesses; `DEEP_AGENTS.md` adds the runtime-specific instructions for the bundled LangChain DeepAgents graph. + +Or register it as a platform-managed agent: + +```bash +nemo agents create \ + --name nemo-cli-agent \ + --agent-config plugins/nemo-agents/examples/nemo-cli-agent/nemo-cli-agent.yml +nemo agents deploy --agent nemo-cli-agent +nemo agents invoke --agent nemo-cli-agent --input "show me what is running" +``` + +Operations that call the Platform API still require the local platform to be running and inference to be configured. diff --git a/plugins/nemo-agents/examples/nemo-cli-agent/nemo-cli-agent.yml b/plugins/nemo-agents/examples/nemo-cli-agent/nemo-cli-agent.yml new file mode 100644 index 00000000..fed65510 --- /dev/null +++ b/plugins/nemo-agents/examples/nemo-cli-agent/nemo-cli-agent.yml @@ -0,0 +1,30 @@ +# NeMo CLI Agent +# +# A DeepAgents workflow for operating NeMo Platform through the `nemo` CLI. +# +# Try it locally: +# nemo agents invoke \ +# --agent-config plugins/nemo-agents/examples/nemo-cli-agent/nemo-cli-agent.yml \ +# --input "load the nemo cli skills" +# nemo agents invoke \ +# --agent-config plugins/nemo-agents/examples/nemo-cli-agent/nemo-cli-agent.yml \ +# --input "list all my workspaces" +# +# Or deploy it: +# nemo agents create --name nemo-cli-agent \ +# --agent-config plugins/nemo-agents/examples/nemo-cli-agent/nemo-cli-agent.yml +# nemo agents deploy --agent nemo-cli-agent +# nemo agents invoke --agent nemo-cli-agent --input "Create a workspace called demo" + +llms: + agent: + _type: openai + base_url: ${NEMO_DEFAULT_INFERENCE_BASE_URL} + api_key: ${NEMO_DEFAULT_INFERENCE_API_KEY} + model_name: ${NEMO_DEFAULT_MODEL} + +workflow: + # Generic wrapper for current NAT/LangGraph compatibility gaps. + _type: nat_compatible_langgraph_wrapper + graph: nemo_cli_agent.agent:create_nemo_cli_agent + description: NeMo Platform CLI assistant using LangChain Deep Agents diff --git a/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/agent.py b/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/agent.py new file mode 100644 index 00000000..a9198bf5 --- /dev/null +++ b/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/agent.py @@ -0,0 +1,212 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +import logging +import os +import shlex +import shutil +import subprocess +import sys +import warnings +from pathlib import Path + +# TODO: Replace this blunt local-run suppression with a cleaner NAT/local invoke +# output mode once the POC behavior is stable. +warnings.filterwarnings("ignore") + +from deepagents import create_deep_agent # noqa: E402 +from deepagents.backends.filesystem import FilesystemBackend # noqa: E402 +from langchain_core.tools import tool # noqa: E402 +from nemo_cli_agent.utils import print_loaded_skills # noqa: E402 + +logger = logging.getLogger(__name__) + +AGENT_ROOT = Path(__file__).resolve().parents[2] +AGENTS_MD = AGENT_ROOT / "AGENTS.md" +DEEP_AGENTS_MD = AGENT_ROOT / "DEEP_AGENTS.md" +SKILLS_DIR = AGENT_ROOT / ".agents" / "skills" + +VERBOSE_ENV_VAR = "NEMO_CLI_AGENT_VERBOSE" + +os.environ.setdefault("NAT_TELEMETRY_ENABLED", "false") + +_NEMO_BIN: str | None = shutil.which("nemo") or (str(p) if (p := Path(sys.prefix) / "bin" / "nemo").exists() else None) + + +def _load_prompt_file(path: Path, fallback: str) -> str: + try: + return path.read_text(encoding="utf-8") + except OSError: + logger.warning("%s not found; using fallback prompt fragment", path.name) + return fallback + + +def _load_system_prompt() -> str: + base_prompt = _load_prompt_file( + AGENTS_MD, + "You are a NeMo Platform CLI assistant. Print the nemo commands you run, then execute them.", + ) + deepagents_prompt = _load_prompt_file( + DEEP_AGENTS_MD, + "Use the available skills first. Use nemo_cli only for single nemo commands.", + ) + return f"{base_prompt.rstrip()}\n\n{deepagents_prompt.strip()}" + + +def _run_command(args: list[str], *, cwd: Path | None = None, timeout: int = 60) -> str: + result = subprocess.run( + args, + capture_output=True, + text=True, + timeout=timeout, + cwd=cwd, + ) + if result.returncode == 0: + return result.stdout or "(no output)" + return f"Error (exit code {result.returncode}): {result.stderr or result.stdout}" + + +@tool +def nemo_cli(command: str) -> str: + """Run one `nemo ...` CLI command and return the output. + + The command must be one `nemo ...` invocation. Shell syntax is not + supported. + + Args: + command: The full CLI command to run, for example `nemo workspaces list` + or `nemo skills install --agent generic`. + + Returns: + The printed command and its stdout, or an error message if it fails. + """ + try: + args = shlex.split(command) + except ValueError as e: + return f"Error: invalid command syntax: {e}" + if not args or Path(args[0]).name != "nemo": + return "Error: only 'nemo' commands are allowed." + resolved = _NEMO_BIN or shutil.which(args[0]) + if resolved is None: + venv_path = Path(sys.prefix) / "bin" / args[0] + if venv_path.exists(): + resolved = str(venv_path) + else: + return f"Error: '{args[0]}' not found on PATH or in venv ({sys.prefix}/bin/)" + args[0] = resolved + + # Generic skill installs are project-scoped. Pin the project root to this + # example folder so the installer writes to `/.agents/skills/` + # regardless of where the user invoked the agent from. + is_generic_skill_install = ( + args[1:4] == ["skills", "install", "--agent"] and "generic" in args[4:] and "--project-root" not in args + ) + if is_generic_skill_install: + args.extend(["--project-root", str(AGENT_ROOT)]) + + try: + return _run_command(args, timeout=120 if is_generic_skill_install else 60) + except Exception as e: + return f"Error: {type(e).__name__}: {e}" + + +def _get_model(): + """Get the LLM from NAT's builder context (YAML llms: section).""" + from nat.builder.framework_enum import LLMFrameworkEnum + from nat.builder.sync_builder import SyncBuilder + + return SyncBuilder.current().get_llm("agent", wrapper_type=LLMFrameworkEnum.LANGCHAIN) + + +def _has_installed_skills() -> bool: + """Return True if ``SKILLS_DIR`` already contains at least one skill entry.""" + return SKILLS_DIR.is_dir() and any(SKILLS_DIR.iterdir()) + + +def _ensure_skills_installed() -> None: + """Install the NeMo CLI skills into the agent folder on first run. + + No-op once ``.agents/skills/`` is populated. Failures are reported but + don't block the agent from starting — the agent can always re-run the + install through its ``nemo_cli`` tool. + """ + if _has_installed_skills(): + return + nemo_bin = _NEMO_BIN or shutil.which("nemo") + if nemo_bin is None: + print( + f"Skipping initial skill install: 'nemo' not found on PATH or in {sys.prefix}/bin/", + flush=True, + ) + return + print(f"Installing NeMo CLI skills into {SKILLS_DIR} (first run)...", flush=True) + try: + result = subprocess.run( + [nemo_bin, "skills", "install", "--agent", "generic", "--project-root", str(AGENT_ROOT)], + capture_output=True, + text=True, + timeout=120, + ) + except Exception as exc: + print(f"Initial skill install failed: {type(exc).__name__}: {exc}", flush=True) + return + if result.returncode == 0: + print("Skills installed.", flush=True) + else: + print( + f"Initial skill install failed (exit {result.returncode}): {(result.stderr or result.stdout).strip()}", + flush=True, + ) + + +def create_nemo_cli_agent(config=None): + """Create the NeMo Platform CLI Deep Agent. + + Wires the DeepAgents ``SkillsMiddleware`` against a real filesystem + backend rooted at this example folder so the agent can see the + ``.agents/skills/`` directory we populate via ``nemo skills install``. + The middleware injects every ``SKILL.md``'s name + description into + the system prompt; the agent then reads the full skill file via the + built-in ``read_file`` tool when one matches the user's request. + + TODO: For cloud-bundled deployments where the agent has no writeable + filesystem, swap ``FilesystemBackend`` for a read-only backend that + wraps an in-memory ``{path: bytes}`` map loaded from the wheel at + import time. The ``SkillsMiddleware`` only consumes the backend's + ``ls`` and ``download_files`` APIs, so a tiny custom backend is + enough — we don't need ``StateBackend`` plumbing through every + ``invoke()``. + """ + _ensure_skills_installed() + model = _get_model() + # ``virtual_mode=False`` is the historical default and matches our + # assumption that ``SKILLS_DIR`` is referenced via its absolute path. + # Spelling it out silences the ``virtual_mode default will change in + # deepagents==0.6.0`` deprecation warning. + backend = FilesystemBackend(root_dir=AGENT_ROOT, virtual_mode=False) + # Verbose mode prints the loaded-skill catalog and the post-middleware + # system prompt. Lazy-import the verbose middleware so the default + # (non-verbose) path never pulls in ``langchain.agents.middleware.types`` + # — that import chain transitively loads ``langgraph`` and triggers a + # ``LangChainPendingDeprecationWarning`` before any warning filter we + # set can run. + extra_middleware: list = [] + if os.environ.get(VERBOSE_ENV_VAR) == "1": + print_loaded_skills(SKILLS_DIR) + from nemo_cli_agent.verbose import SystemPromptDumpMiddleware + + extra_middleware.append(SystemPromptDumpMiddleware()) + return create_deep_agent( + model=model, + tools=[nemo_cli], + system_prompt=_load_system_prompt(), + backend=backend, + skills=[str(SKILLS_DIR)], + middleware=extra_middleware, + ) + + +# Module-level graph factory used by ``nat_compatible_langgraph_wrapper`` in +# ``nemo-cli-agent.yml``. The ``agent`` alias is kept for ad-hoc debugging with +# other graph-loading paths. +agent = create_nemo_cli_agent diff --git a/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/cli.py b/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/cli.py new file mode 100644 index 00000000..33b1808d --- /dev/null +++ b/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/cli.py @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""``nemo ask`` shortcut for the nemo-cli-agent example. + +Plugins cannot directly add root-level commands to the NeMo CLI; the +platform always mounts plugin contributions as top-level groups under +``nemo ``. Registering this class under +``nemo.cli -> ask`` therefore creates the group ``nemo ask``, and we use +``invoke_without_command=True`` plus a callback positional argument so the +group behaves like a one-shot command from the user's perspective — +``nemo ask "list my workspaces"``. + +The shortcut just dispatches to ``_local_invoke`` from the agents plugin +against the bundled ``nemo-cli-agent.yml``. +""" + +from __future__ import annotations + +import os +from pathlib import Path +from typing import ClassVar + +import typer +from nemo_platform_plugin.cli import NemoCLI + +# Heavy imports (``nemo_cli_agent.agent``, ``nemo_agents_plugin.cli``, +# and transitively langgraph/langchain) are deferred to the ``ask`` +# callback so the ``nemo`` CLI's entry-point discovery — which imports +# *this* module just to learn the command name — doesn't pull in the +# whole agent stack on every ``nemo`` invocation. + + +def _agent_config_path() -> Path: + """Locate the bundled nemo-cli-agent NAT config.""" + # Resolves to ``examples/nemo-cli-agent`` from the source tree (and the + # equivalent location in installed wheels via the hatch package layout). + package_dir = Path(__file__).resolve().parent + candidates = ( + package_dir / "nemo-cli-agent.yml", + package_dir.parent.parent / "nemo-cli-agent.yml", + ) + for path in candidates: + if path.is_file(): + return path + raise FileNotFoundError("nemo-cli-agent.yml not found. Tried: " + ", ".join(str(c) for c in candidates)) + + +class AskCLI(NemoCLI): + """``nemo ask ""`` — shortcut for the nemo-cli-agent example.""" + + name: ClassVar[str] = "ask" + description: ClassVar[str] = "Ask the NeMo CLI agent (shortcut for the nemo-cli-agent example)." + + def get_cli(self) -> typer.Typer: + app = typer.Typer( + name=self.name, + help=self.description, + invoke_without_command=True, + no_args_is_help=False, + add_completion=False, + ) + + @app.callback(invoke_without_command=True) + def ask( + ctx: typer.Context, + question: str = typer.Argument(..., help="Question for the NeMo CLI agent."), + verbose: bool = typer.Option( + False, + "--verbose", + "-v", + help="Print the rendered system prompt (including the loaded skills catalog) before answering.", + ), + ) -> None: + """Ask the NeMo CLI agent a question.""" + if ctx.invoked_subcommand is not None: + return + + # Toggle the agent-side debug middleware via env var so the + # flag flows through ``_local_invoke`` / NAT without needing + # to widen its public signature. + if verbose: + from nemo_cli_agent.agent import VERBOSE_ENV_VAR + + os.environ[VERBOSE_ENV_VAR] = "1" + + from nemo_agents_plugin.cli import _local_invoke + + _local_invoke(_agent_config_path(), input=question, input_file=None) + + return app diff --git a/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/utils.py b/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/utils.py new file mode 100644 index 00000000..e32b8bbd --- /dev/null +++ b/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/utils.py @@ -0,0 +1,851 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Generic NAT-compatible LangGraph wrapper. + +Why this exists +--------------- +``nvidia-nat-langchain``'s built-in ``langgraph_wrapper`` is a generic adapter +that wraps any compiled LangGraph as a NAT ``Function``. In NAT 1.6.0 it has +two limitations that block our use case end-to-end: + +1. **Input schema is too narrow.** ``LanggraphWrapperInput`` declares + ``messages: list[...] | PromptValue`` as required. ``nvidia-nat-eval``'s + remote workflow client (used when ``nemo agents evaluate run`` is invoked + with ``--agent ``) POSTs ``{"input_message": "..."}`` to the + ``/generate/full`` route. FastAPI builds a ``TypeAdapter`` from + ``LanggraphWrapperInput`` per route, validates the body against it, and + rejects with **422 Unprocessable Entity** before the agent ever runs. + +2. **Stream output schema is too narrow.** ``LanggraphWrapperOutput.messages`` + is required, and the wrapper validates *every* per-node state delta that + ``LangGraph.astream()`` yields against it. Deep-agent graphs (and any graph + whose state schema is wider than ``{messages: [...]}``) emit deltas like + ``{"skills_metadata": []}`` that don't carry ``messages``; the resulting + ``ValidationError`` aborts the whole stream before the final, + ``messages``-bearing chunk arrives, surfacing as a 500 to the caller. + +We can't fix (1) by monkey-patching ``cls.__pydantic_validator__`` because +FastAPI uses ``TypeAdapter`` per param, which builds its own validator from +the model's frozen core schema and bypasses ``cls.__pydantic_validator__`` +entirely. The only reliable in-process fix is to register a *different* +NAT workflow type with permissive schemas. That's this module. + +How it works +------------ +* ``NatCompatibleLangGraphWrapperConfig`` registers + ``_type: nat_compatible_langgraph_wrapper`` with NAT via ``register_function`` + at import time. +* ``NatCompatibleLangGraphWrapperInput`` accepts **either** ``messages`` (native LangGraph + state shape) **or** ``input_message`` (the eval client's shape) and + normalizes the latter to a single ``user`` message via a + ``model_validator(mode="after")`` that participates in the Pydantic core + schema (so it survives FastAPI's TypeAdapter path). +* ``NatCompatibleLangGraphWrapperOutput.messages`` defaults to an empty list, so streaming + chunks without ``messages`` validate cleanly. +* ``NatCompatibleLangGraphWrapperFunction`` is a ``Function`` parametrized over those + schemas. ``_ainvoke`` and ``_astream`` build a ``{"messages": [...]}`` state + for the graph, run it, and coerce each output (or chunk) into + ``NatCompatibleLangGraphWrapperOutput`` via ``_parse``. +* ``_parse`` extracts ``messages`` from the outer dict, from a single-keyed + node-update wrapper, or — if neither shape applies — yields an empty + placeholder. This is the key behavioral difference from + ``LanggraphWrapperFunction._parse_stream_output``: we never raise on a + state delta that lacks ``messages``. +* The graph itself comes from the ``graph`` factory path configured in YAML. + +Use it via ``_type: nat_compatible_langgraph_wrapper`` and a ``graph`` field in +workflow YAML. Once the upstream NAT limitations are fixed, users should be +able to revert to NAT's stock ``langgraph_wrapper``. +""" + +from __future__ import annotations + +import json +import logging +import os +from collections.abc import AsyncGenerator +from contextlib import contextmanager +from importlib import import_module +from pathlib import Path +from typing import Any, cast + +from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, MessageLikeRepresentation, ToolMessage +from langchain_core.messages.utils import convert_to_messages +from langchain_core.prompt_values import PromptValue +from langchain_core.runnables import RunnableConfig +from nat.builder.builder import Builder +from nat.builder.framework_enum import LLMFrameworkEnum +from nat.builder.function import Function +from nat.cli.register_workflow import register_function +from nat.data_models.api_server import ChatRequest, ChatResponse, ChatResponseChunk, Usage +from nat.data_models.function import FunctionBaseConfig +from pydantic import BaseModel, ConfigDict, Field, computed_field, model_validator +from rich.console import Console +from rich.panel import Panel +from rich.text import Text + +logger = logging.getLogger(__name__) +console = Console() + +os.environ.setdefault("NAT_TELEMETRY_ENABLED", "false") +# TODO: This is a hard local-PoC unblocker. Replace it with a scoped, supported +# NAT/local invoke quiet mode once the wrapper behavior is proven. +logging.disable(logging.CRITICAL) + +_QUIET_LOGGERS = ( + "httpx", + "nat.builder.intermediate_step_manager", + "nat.observability", + "nat.runtime.session", +) + +_EMPTY_FINAL_CONTINUATION_PROMPT = """Your previous assistant response was empty, so the task is not complete. + +Continue from the current tool history and finish every remaining requirement in the original user instruction. Do not stop after partial progress. Before returning, verify the requested final state with tools when possible. If every requirement is already complete, respond with a concise completion summary.""" + + +@contextmanager +def _quiet_local_run_logs(): + previous = {name: logging.getLogger(name).level for name in _QUIET_LOGGERS} + try: + for name in _QUIET_LOGGERS: + logging.getLogger(name).setLevel(logging.ERROR) + yield + finally: + for name, level in previous.items(): + logging.getLogger(name).setLevel(level) + + +def _final_message_text(output: Any) -> str: + if not isinstance(output, dict): + return "" + messages = output.get("messages") + if not isinstance(messages, list) or not messages: + return "" + last = messages[-1] + if isinstance(last, BaseMessage): + return last.text + if isinstance(last, dict): + content = last.get("content", "") + return content if isinstance(content, str) else "" + return "" + + +def _extract_messages(output: Any) -> list[Any]: + if not isinstance(output, dict): + return [] + messages = output.get("messages") + if isinstance(messages, list): + return messages + for inner in output.values(): + if isinstance(inner, dict) and isinstance(inner.get("messages"), list): + return inner["messages"] + return [] + + +def _message_id(message: Any, fallback: str) -> str: + if isinstance(message, BaseMessage) and message.id: + return message.id + if isinstance(message, dict) and isinstance(message.get("id"), str): + return message["id"] + return fallback + + +def _message_text(message: Any) -> str: + if isinstance(message, BaseMessage): + return message.text + if isinstance(message, dict): + content = message.get("content", "") + return content if isinstance(content, str) else "" + return "" + + +def _tool_calls(message: Any) -> list[dict[str, Any]]: + if isinstance(message, AIMessage): + return list(message.tool_calls or []) + if not isinstance(message, dict): + return [] + raw_calls = message.get("tool_calls") or message.get("additional_kwargs", {}).get("tool_calls") + return raw_calls if isinstance(raw_calls, list) else [] + + +def _parse_tool_args(call: dict[str, Any]) -> Any: + args = call.get("args") or call.get("function", {}).get("arguments") or "" + if isinstance(args, str): + try: + return json.loads(args) + except json.JSONDecodeError: + return args + return args + + +def _skill_read_target(call: dict[str, Any]) -> tuple[str, str] | None: + """Return ``(skill_name, path)`` when a tool call reads a ``SKILL.md`` file. + + The DeepAgents ``SkillsMiddleware`` injects skill paths into the system + prompt and the agent picks them up through the built-in ``read_file`` + tool; matching here lets us render those reads as proof the agent is + actually consulting the installed skills. + """ + name = call.get("name") or call.get("function", {}).get("name") + if name not in {"read_file", "read"}: + return None + parsed = _parse_tool_args(call) + if not isinstance(parsed, dict): + return None + path = parsed.get("path") or parsed.get("file_path") + if not isinstance(path, str) or not path.endswith("SKILL.md"): + return None + parent = path.rsplit("/", 2) + skill_name = parent[-2] if len(parent) >= 2 else path + return skill_name, path + + +def _file_read_target(call: dict[str, Any]) -> str | None: + """Return the target path when a tool call reads a local file.""" + name = call.get("name") or call.get("function", {}).get("name") + if name not in {"read_file", "read"}: + return None + parsed = _parse_tool_args(call) + if not isinstance(parsed, dict): + return None + path = parsed.get("path") or parsed.get("file_path") + return path if isinstance(path, str) else None + + +def _tool_call_display(call: dict[str, Any]) -> str: + name = call.get("name") or call.get("function", {}).get("name") or "tool" + args = call.get("args") or call.get("function", {}).get("arguments") or "" + if name == "nemo_cli": + parsed_args = _parse_tool_args(call) + if isinstance(parsed_args, dict) and isinstance(parsed_args.get("command"), str): + return parsed_args["command"] + return f"{name} {args}".strip() + + +def _tool_result(message: Any) -> tuple[str, str] | None: + if isinstance(message, ToolMessage): + return message.tool_call_id or _message_id(message, "tool"), message.text + if not isinstance(message, dict): + return None + role = message.get("role") or message.get("type") + if role != "tool": + return None + tool_call_id = message.get("tool_call_id") or message.get("id") or "tool" + content = message.get("content", "") + return str(tool_call_id), content if isinstance(content, str) else str(content) + + +def _print_line(text: str) -> None: + if text: + console.print(text) + + +def _print_tool_call(command: str) -> None: + console.print() + console.print(Text(f"$ {command}", style="bold cyan")) + + +def _print_skill_read(skill_name: str, path: str) -> None: + # The full path is intentionally elided; it's noisy and the skill + # name alone is enough to verify the agent consulted the right one. + del path + console.print() + console.print(Text(f"read skill: {skill_name}", style="bold magenta")) + + +def _print_file_read(path: str) -> None: + console.print() + console.print(Text(f"read file: {path}", style="bold magenta")) + + +def _print_tool_output(output: str) -> None: + console.print(Panel(output or "(no output)", title="output", border_style="cyan", expand=False)) + + +def _print_final_answer(text: str) -> None: + console.print() + console.print(text) + + +def list_installed_skills(skills_dir: Path) -> list[str]: + """Return sorted skill folder names found under ``skills_dir``. + + The folders are the units the DeepAgents ``SkillsMiddleware`` + enumerates, so listing them gives a reliable preview of what will + be exposed to the model without having to parse every ``SKILL.md`` + ourselves. + """ + if not skills_dir.is_dir(): + return [] + return sorted(p.name for p in skills_dir.iterdir() if (p / "SKILL.md").is_file()) + + +def print_loaded_skills(skills_dir: Path) -> None: + """Print a one-line summary of the skills installed in ``skills_dir``.""" + skills = list_installed_skills(skills_dir) + if not skills: + print(f"No skills found under {skills_dir}.", flush=True) + return + preview = ", ".join(skills[:6]) + suffix = f", ... (+{len(skills) - 6} more)" if len(skills) > 6 else "" + print(f"Loaded {len(skills)} skills from {skills_dir}: {preview}{suffix}", flush=True) + + +class _StreamSafeGraph: + """Wrap a compiled graph so ``astream()`` yields final state for NAT parsing. + + Some graph implementations emit intermediate stream chunks that do not carry + ``messages``. This adapter delegates streaming to ``ainvoke`` so the wrapper + sees the single fully resolved state. + """ + + def __init__(self, graph: Any) -> None: + self._graph = graph + self._printed_calls: set[str] = set() + self._printed_results: set[str] = set() + self._printed_result_texts: set[str] = set() + self._printed_messages: set[str] = set() + self._suppressed_output_call_ids: set[str] = set() + + def __getattr__(self, name: str) -> Any: + return getattr(self._graph, name) + + def _print_chunk_activity(self, chunk: Any) -> None: + for index, message in enumerate(_extract_messages(chunk)): + if isinstance(message, HumanMessage) or (isinstance(message, dict) and message.get("role") == "user"): + continue + message_key = _message_id(message, f"message-{index}") + for call_index, call in enumerate(_tool_calls(message)): + call_id = str(call.get("id") or f"{message_key}-tool-{call_index}") + if call_id in self._printed_calls: + continue + self._printed_calls.add(call_id) + skill_target = _skill_read_target(call) + if skill_target is not None: + self._suppressed_output_call_ids.add(call_id) + _print_skill_read(*skill_target) + else: + file_read_target = _file_read_target(call) + if file_read_target is not None: + self._suppressed_output_call_ids.add(call_id) + _print_file_read(file_read_target) + else: + _print_tool_call(_tool_call_display(call)) + + tool_result = _tool_result(message) + if tool_result is not None: + result_id, content = tool_result + stripped_content = content.strip() + if result_id not in self._printed_results: + self._printed_results.add(result_id) + if stripped_content: + self._printed_result_texts.add(stripped_content) + # File reads can return thousands of lines; the concise + # ``read ...`` line above is the verifiable evidence that + # the agent fetched the file, so skip the content panel. + if result_id not in self._suppressed_output_call_ids: + _print_tool_output(stripped_content) + continue + + text = _message_text(message).strip() + if ( + text + and text not in self._printed_result_texts + and not _tool_calls(message) + and message_key not in self._printed_messages + ): + self._printed_messages.add(message_key) + _print_final_answer(text) + + async def ainvoke(self, input_data: Any, config: RunnableConfig | None = None, **kwargs: Any) -> Any: + latest: Any = None + stream_kwargs = dict(kwargs) + stream_kwargs.setdefault("stream_mode", "values") + with _quiet_local_run_logs(): + async for chunk in self._graph.astream(input_data, config=config, **stream_kwargs): + latest = chunk + self._print_chunk_activity(chunk) + if latest is not None: + return latest + with _quiet_local_run_logs(): + result = await self._graph.ainvoke(input_data, config=config, **kwargs) + self._print_chunk_activity(result) + return result + + async def astream(self, input_data: Any, config: RunnableConfig | None = None, **kwargs: Any): + stream_kwargs = dict(kwargs) + stream_kwargs.setdefault("stream_mode", "values") + with _quiet_local_run_logs(): + async for chunk in self._graph.astream(input_data, config=config, **stream_kwargs): + self._print_chunk_activity(chunk) + yield chunk + + async def astream_events(self, *args: Any, **kwargs: Any): + with _quiet_local_run_logs(): + async for event in self._graph.astream_events(*args, **kwargs): + yield event + + +def _attach_langchain_profiler(graph: Any) -> Any: + """Attach NAT's LangChain callback handler to graph invocations.""" + from nat.plugins.langchain.callback_handler import LangchainProfilerHandler + + original_ainvoke = graph.ainvoke + original_astream = graph.astream + + def _merge(config: RunnableConfig | None) -> RunnableConfig: + cfg: dict[str, Any] = {} + if config is not None: + for key, value in config.items(): + cfg[key] = value + raw_callbacks = cfg.get("callbacks") + callbacks = list(raw_callbacks) if isinstance(raw_callbacks, list) else [] + if raw_callbacks is not None and not isinstance(raw_callbacks, list): + callbacks.append(raw_callbacks) + callbacks.append(LangchainProfilerHandler()) + cfg["callbacks"] = callbacks + return cast(RunnableConfig, cfg) + + async def ainvoke(input_data: Any, config: RunnableConfig | None = None, **kwargs: Any): + return await original_ainvoke(input_data, config=_merge(config), **kwargs) + + async def astream(input_data: Any, config: RunnableConfig | None = None, **kwargs: Any): + async for chunk in original_astream(input_data, config=_merge(config), **kwargs): + yield chunk + + graph.ainvoke = ainvoke + graph.astream = astream + return graph + + +def _prepare_graph_for_nat(graph: Any) -> Any: + return _StreamSafeGraph(_attach_langchain_profiler(graph)) + + +class NatCompatibleLangGraphWrapperConfig(FunctionBaseConfig, name="nat_compatible_langgraph_wrapper"): + """Configuration for a NAT-compatible LangGraph workflow. + + The ``graph`` field points to a callable that returns the compiled graph. + The callable is invoked with ``RunnableConfig()`` for compatibility with + existing graph factories. + + workflow: + _type: nat_compatible_langgraph_wrapper + graph: package.module:create_graph + description: Agent description + """ + + model_config = ConfigDict(extra="forbid") + + graph: str + description: str = "" + + +class NatCompatibleLangGraphWrapperInput(BaseModel): + """Input schema accepted by the wrapper's ``/generate*`` routes. + + Accepts either: + + * ``{"messages": [...]}`` — native LangGraph state shape, used by chat + clients (``nemo agents invoke``, the Studio UI, direct ``curl``). + * ``{"input_message": "..."}`` — the shape that ``nvidia-nat-eval``'s + ``remote_workflow.py`` POSTs to ``/generate/full`` when running an + eval with ``--endpoint`` (i.e. ``nemo agents evaluate run --agent``). + + The ``model_validator`` below normalizes the second form to the first + so the rest of the pipeline only ever sees ``messages``. Because the + validator is declared on the class, it's part of the Pydantic core + schema and survives FastAPI's per-route ``TypeAdapter`` path — + something a runtime monkey-patch on ``__pydantic_validator__`` would + not achieve. + + ``extra="allow"`` so callers (or NAT itself) can attach unrelated + metadata fields without rejection. + """ + + model_config = ConfigDict(extra="allow") + + messages: list[MessageLikeRepresentation] | PromptValue | None = None + input_message: str | None = None + + @model_validator(mode="after") + def _ensure_messages(self) -> "NatCompatibleLangGraphWrapperInput": + if self.messages is not None: + return self + if self.input_message is not None: + self.messages = [{"role": "user", "content": self.input_message}] + return self + raise ValueError("Either 'messages' or 'input_message' is required") + + +class NatCompatibleLangGraphWrapperOutput(BaseModel): + """Output schema for chunks and final results. + + ``messages`` defaults to an empty list (vs. required in + ``LanggraphWrapperOutput``) because LangGraph's per-node state deltas + aren't guaranteed to include it — deep agents emit chunks like + ``{"skills_metadata": []}`` that contain no messages at all, and we + don't want those to crash the stream. Consumers that need the final + answer keep accumulating from the last non-empty chunk; the chunk + that emits the assistant's reply will populate ``messages`` + naturally. + + The ``value`` computed field exposes the last message's text directly + so ``nvidia-nat-eval``'s ``remote_workflow.py`` can consume it. That + client extracts the answer via ``chunk_data.get("value")`` from each + streamed ``data:`` line; without this field every line would parse as + ``{"messages": [...]}`` only and the eval would record an empty answer + (and therefore a 0 score) regardless of the agent's actual reply. + Empty / non-list ``messages`` produce ``value == ""``, which is falsy + on the eval client side so it won't clobber a previously captured + non-empty answer. + + ``extra="allow"`` lets the rest of the deep-agent state ride along + in the response without being silently dropped. + """ + + model_config = ConfigDict(extra="allow") + + messages: list[BaseMessage] = Field(default_factory=list) + + @computed_field + @property + def value(self) -> str: + # We use ``model_construct`` in ``_parse`` to skip validation on + # streaming chunks (so graph state deltas don't error out), + # which means ``self.messages`` may be a ``list[dict]`` (raw graph + # output) or even a non-list (e.g. a langgraph add-messages + # operator wrapper like ``{"value": [...]}``) instead of the + # declared ``list[BaseMessage]``. Handle each shape explicitly. + msgs = self.messages + if not isinstance(msgs, list) or not msgs: + return "" + last = msgs[-1] + if isinstance(last, BaseMessage): + return last.text + if isinstance(last, dict): + content = last.get("content", "") + return content if isinstance(content, str) else "" + return "" + + +class NatCompatibleLangGraphWrapperFunction( + Function[ + NatCompatibleLangGraphWrapperInput, + NatCompatibleLangGraphWrapperOutput, + NatCompatibleLangGraphWrapperOutput, + ] +): + """NAT ``Function`` wrapping a compiled LangGraph. + + Behavior mirrors ``LanggraphWrapperFunction`` (so the same converters + work for both the chat-completions route and the raw generate routes), + with two differences: + + * **Input normalization** happens via ``NatCompatibleLangGraphWrapperInput``'s + validator, before this class is reached. + * **Stream chunks** that lack ``messages`` are coerced to an empty + output instead of raising — see :meth:`_parse`. + """ + + def __init__(self, *, config: NatCompatibleLangGraphWrapperConfig, graph: Any) -> None: + super().__init__( + config=config, + description=config.description, + converters=[ + NatCompatibleLangGraphWrapperFunction.convert_to_str, + NatCompatibleLangGraphWrapperFunction.convert_chat_request, + NatCompatibleLangGraphWrapperFunction.convert_str, + NatCompatibleLangGraphWrapperFunction.convert_to_chat_response, + NatCompatibleLangGraphWrapperFunction.convert_to_chat_response_chunk, + ], + ) + self._graph = graph + + @staticmethod + def _build_state(value: NatCompatibleLangGraphWrapperInput) -> dict[str, Any]: + """Project the validated input down to the LangGraph state shape. + + We deliberately forward only ``messages`` — that's all the deep + agent's state schema accepts as a top-level input. ``input_message`` + is a synthetic field for HTTP callers and would not be a valid + LangGraph state key. + """ + messages = value.messages if value.messages is not None else [] + return {"messages": convert_to_messages(messages)} + + @staticmethod + def _has_tool_calls(message: AIMessage | dict[str, Any]) -> bool: + if isinstance(message, AIMessage): + if message.tool_calls: + return True + tool_calls = message.additional_kwargs.get("tool_calls") + return isinstance(tool_calls, list) and bool(tool_calls) + + tool_calls = message.get("tool_calls") + if isinstance(tool_calls, list) and tool_calls: + return True + additional_kwargs = message.get("additional_kwargs") + if isinstance(additional_kwargs, dict): + nested_tool_calls = additional_kwargs.get("tool_calls") + return isinstance(nested_tool_calls, list) and bool(nested_tool_calls) + return False + + @staticmethod + def _is_empty_assistant_message(message: Any) -> bool: + if isinstance(message, AIMessage): + return not message.text.strip() and not NatCompatibleLangGraphWrapperFunction._has_tool_calls(message) + if not isinstance(message, dict): + return False + role = message.get("role") or message.get("type") + if role not in {"assistant", "ai"}: + return False + content = message.get("content", "") + if isinstance(content, str): + return not content.strip() and not NatCompatibleLangGraphWrapperFunction._has_tool_calls(message) + if content in (None, []): + return not NatCompatibleLangGraphWrapperFunction._has_tool_calls(message) + return False + + @staticmethod + def _drop_trailing_empty_assistant_messages(messages: list[Any]) -> list[Any]: + sanitized = list(messages) + while sanitized and NatCompatibleLangGraphWrapperFunction._is_empty_assistant_message(sanitized[-1]): + sanitized.pop() + return sanitized + + async def _ainvoke_with_empty_response_retry(self, state: dict[str, Any]) -> NatCompatibleLangGraphWrapperOutput: + """Retry once when the graph silently stops with an empty final answer. + + Random-routed weaker models can occasionally emit an empty ``stop`` + response after successful tool calls. LangGraph treats that as a valid + final state, but user requests can still have remaining requirements. A + short continuation prompt preserves the prior tool history and gives the + agent a chance to complete the task instead of ending silently. + """ + output = await self._graph.ainvoke(state) + parsed = self._parse(output) + if parsed.value.strip(): + return parsed + + logger.warning("nat_compatible_langgraph_wrapper received empty final response; prompting graph to continue") + messages = parsed.messages if parsed.messages else state.get("messages", []) + messages = self._drop_trailing_empty_assistant_messages(messages) + if not messages: + messages = list(state.get("messages", [])) + # _parse preserves dict-backed messages as-is, so normalize before + # handing back to the graph — otherwise we can mix BaseMessage and + # raw dicts in the retry state, which some graphs reject. + retry_messages = convert_to_messages([*messages, HumanMessage(content=_EMPTY_FINAL_CONTINUATION_PROMPT)]) + retry_state = { + **state, + "messages": retry_messages, + } + return self._parse(await self._graph.ainvoke(retry_state)) + + async def _ainvoke(self, value: NatCompatibleLangGraphWrapperInput) -> NatCompatibleLangGraphWrapperOutput: + try: + return await self._ainvoke_with_empty_response_retry(self._build_state(value)) + except Exception as e: + logger.exception("nat_compatible_langgraph_wrapper _ainvoke failed") + raise RuntimeError(f"Error in nat_compatible_langgraph_wrapper workflow: {e}") from e + + async def _astream( + self, value: NatCompatibleLangGraphWrapperInput + ) -> AsyncGenerator[NatCompatibleLangGraphWrapperOutput, None]: + # Streaming consumers receive graph chunks as they arrive; the + # empty-final-response retry lives only on the non-streaming + # ``_ainvoke`` path because it requires having the full final state. + try: + async for chunk in self._graph.astream(self._build_state(value)): + yield self._parse(chunk) + except Exception as e: + logger.exception("nat_compatible_langgraph_wrapper _astream failed") + raise RuntimeError(f"Error in nat_compatible_langgraph_wrapper workflow: {e}") from e + + @staticmethod + def _parse(output: Any) -> NatCompatibleLangGraphWrapperOutput: + """Coerce any LangGraph output (final state OR stream chunk) into our output type. + + ``LangGraph.astream()`` yields different shapes depending on stream + mode and node fan-out: + + * ``{"messages": [...]}`` — full-state shape (``stream_mode="values"``) + or a node update that happens to write ``messages``. + * ``{: {}}`` — the default + ``stream_mode="updates"`` shape, where ```` is just + the keys that node modified. May or may not contain ``messages``. + * Anything else (e.g. ``{"skills_metadata": []}`` from a deep-agent + subagent state node) — neither carries messages. + + We extract ``messages`` if it appears at either nesting level, and + otherwise emit an empty ``NatCompatibleLangGraphWrapperOutput``. ``model_construct`` + bypasses validation since we've already chosen the data ourselves. + """ + if isinstance(output, dict): + if "messages" in output: + payload = {"messages": output["messages"], **{k: v for k, v in output.items() if k != "messages"}} + return NatCompatibleLangGraphWrapperOutput.model_construct(**payload) + # Scan all node deltas (not just the single-key shape): under + # ``stream_mode="updates"`` LangGraph can fan out and emit a chunk + # like ``{"agent": {"messages": [...]}, "tools": {...}}``. We pick + # the first node delta that carries ``messages``; if multiple do, + # the one that wrote the most recent assistant message will be + # surfaced again in a later chunk anyway. + for inner in output.values(): + if isinstance(inner, dict) and "messages" in inner: + payload = {"messages": inner["messages"], **{k: v for k, v in inner.items() if k != "messages"}} + return NatCompatibleLangGraphWrapperOutput.model_construct(**payload) + return NatCompatibleLangGraphWrapperOutput.model_construct(messages=[]) + + # Converters — called by NAT to translate between this Function's + # native types and the chat-completions / string shapes that NAT's + # route handlers expose. Behavior matches ``LanggraphWrapperFunction``; + # the only delta is the output type they return is our wider one. + + @staticmethod + def convert_to_str(value: NatCompatibleLangGraphWrapperOutput) -> str: + if not value.messages: + return "" + return value.messages[-1].text + + @staticmethod + def _extract_usage(value: NatCompatibleLangGraphWrapperOutput) -> Usage: + """Best-effort token usage extraction from the final assistant message.""" + candidates: list[dict[str, Any]] = [] + extras = getattr(value, "__pydantic_extra__", None) + if isinstance(extras, dict): + for key in ("usage", "usage_metadata", "response_metadata"): + extra_val = extras.get(key) + if isinstance(extra_val, dict): + candidates.append(extra_val) + + if value.messages: + last = value.messages[-1] + if isinstance(last, BaseMessage): + usage_metadata = getattr(last, "usage_metadata", None) + response_metadata = getattr(last, "response_metadata", None) + if isinstance(usage_metadata, dict): + candidates.append(usage_metadata) + if isinstance(response_metadata, dict): + candidates.append(response_metadata) + elif isinstance(last, dict): + usage_metadata = last.get("usage_metadata") + response_metadata = last.get("response_metadata") + usage = last.get("usage") + if isinstance(usage_metadata, dict): + candidates.append(usage_metadata) + if isinstance(response_metadata, dict): + candidates.append(response_metadata) + if isinstance(usage, dict): + candidates.append(usage) + + prompt_tokens: int | None = None + completion_tokens: int | None = None + total_tokens: int | None = None + + # BFS over candidate dicts so a nested ``token_usage`` can contribute + # without mutating the list we're iterating. + queue: list[dict[str, Any]] = list(candidates) + seen: set[int] = set() + while queue: + candidate = queue.pop(0) + ident = id(candidate) + if ident in seen: + continue + seen.add(ident) + + token_usage = candidate.get("token_usage") + if isinstance(token_usage, dict): + queue.append(token_usage) + + if prompt_tokens is None: + raw_prompt = candidate.get("prompt_tokens", candidate.get("input_tokens")) + if isinstance(raw_prompt, int): + prompt_tokens = raw_prompt + if completion_tokens is None: + raw_completion = candidate.get("completion_tokens", candidate.get("output_tokens")) + if isinstance(raw_completion, int): + completion_tokens = raw_completion + if total_tokens is None: + raw_total = candidate.get("total_tokens") + if isinstance(raw_total, int): + total_tokens = raw_total + + if total_tokens is None and isinstance(prompt_tokens, int) and isinstance(completion_tokens, int): + total_tokens = prompt_tokens + completion_tokens + return Usage( + prompt_tokens=prompt_tokens, + completion_tokens=completion_tokens, + total_tokens=total_tokens, + ) + + @staticmethod + def convert_chat_request(value: ChatRequest) -> NatCompatibleLangGraphWrapperInput: + """Translate NAT's ``ChatRequest`` (chat-completions route body) to our input. + + NAT's chat-completions handler hands us a ``ChatRequest`` per call; + converting it to ``NatCompatibleLangGraphWrapperInput.messages`` is what lets the + ``/chat/completions`` and ``/generate/full`` routes share a single + downstream graph invocation. We unpack the role enum and any + ``model_dump``-able content parts so the LangGraph state ends up with + plain JSON-able dicts. + """ + message_dicts: list[MessageLikeRepresentation] = [] + for message in value.messages: + role = message.role.value if hasattr(message.role, "value") else str(message.role) + content: Any = message.content + if isinstance(content, list): + content = [part.model_dump() if hasattr(part, "model_dump") else part for part in content] + message_dicts.append({"role": role, "content": content}) + return NatCompatibleLangGraphWrapperInput(messages=message_dicts) + + @staticmethod + def convert_str(value: str) -> NatCompatibleLangGraphWrapperInput: + """Translate the ``/generate`` route body (a bare string) to our input. + + NAT's ``/generate`` route accepts a plain string and asks each + registered ``str`` converter to lift it into the workflow's input + type. We populate ``input_message`` (rather than ``messages``) so the + ``model_validator`` on :class:`NatCompatibleLangGraphWrapperInput` can take the + canonical eval-client path that ``nvidia-nat-eval``'s + ``remote_workflow.py`` uses against ``/generate/full`` — see the + module docstring for the FastAPI/TypeAdapter rationale. + """ + return NatCompatibleLangGraphWrapperInput(input_message=value) + + @staticmethod + def convert_to_chat_response(value: NatCompatibleLangGraphWrapperOutput) -> ChatResponse: + # ``value.value`` already handles dict-backed messages from + # ``model_construct`` (see NatCompatibleLangGraphWrapperOutput.value), so we don't + # have to reach into ``messages[-1].text`` here and risk + # ``AttributeError`` when streaming chunks contain raw graph dicts. + return ChatResponse.from_string(value.value, usage=NatCompatibleLangGraphWrapperFunction._extract_usage(value)) + + @staticmethod + def convert_to_chat_response_chunk(value: NatCompatibleLangGraphWrapperOutput) -> ChatResponseChunk: + return ChatResponseChunk.from_string(value.value) + + +def _load_graph_factory(path: str): + module_name, sep, attr_name = path.partition(":") + if not sep or not module_name or not attr_name: + raise ValueError("graph must be in 'module:callable' format") + module = import_module(module_name) + factory = getattr(module, attr_name) + if not callable(factory): + raise TypeError(f"Configured graph factory is not callable: {path}") + return factory + + +@register_function(config_type=NatCompatibleLangGraphWrapperConfig, framework_wrappers=[LLMFrameworkEnum.LANGCHAIN]) +async def register(config: NatCompatibleLangGraphWrapperConfig, b: Builder): + """Build the configured graph and yield a NAT-callable wrapper. + + NAT calls this once per workflow build and yields the function + instance to the runtime; ``_ainvoke`` / ``_astream`` are then driven + per request by the FastAPI route handlers. + """ + graph = _prepare_graph_for_nat(_load_graph_factory(config.graph)(RunnableConfig())) + yield NatCompatibleLangGraphWrapperFunction(config=config, graph=graph) diff --git a/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/verbose.py b/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/verbose.py new file mode 100644 index 00000000..5bc691fd --- /dev/null +++ b/plugins/nemo-agents/examples/nemo-cli-agent/src/nemo_cli_agent/verbose.py @@ -0,0 +1,84 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Opt-in middleware that dumps the rendered system prompt. + +Isolated from :mod:`nemo_cli_agent.utils` so the ``from +langchain.agents.middleware.types import AgentMiddleware`` import stays out +of the entry-point load path. ``utils`` is imported by NAT at startup +(it registers the workflow type), and pulling ``langchain.agents`` in +there transitively imports ``langgraph`` *before* any of our warning +filters run, which is what re-introduced the +``LangChainPendingDeprecationWarning`` chatter on every ``nemo ask``. + +This module is imported only when ``--verbose`` is set, so the default +``nemo ask`` path never touches ``langchain.agents``. +""" + +from __future__ import annotations + +from typing import Any + +# Importing ``langchain.agents.middleware.types`` here pulls in +# ``langgraph.checkpoint.serde.encrypted`` for the first time on the +# ``--verbose`` path, which emits a one-shot +# ``LangChainPendingDeprecationWarning``. We deliberately don't try to +# silence it: ``langchain_core``'s import-time +# ``surface_langchain_deprecation_warnings`` re-enables the category +# *after* any filter we set here, so suppression would require ugly +# stderr/fd workarounds. ``--verbose`` is a debug mode and the single +# benign warning is an acceptable trade-off for keeping the default +# (non-verbose) ``nemo ask`` path warning-free. +from langchain.agents.middleware.types import AgentMiddleware +from rich.console import Console +from rich.panel import Panel + +_console = Console() + + +def _print_system_prompt(system_message: Any) -> None: + """Render the final system prompt (post-middleware) to the local console. + + Used by :class:`SystemPromptDumpMiddleware` so the operator can + confirm that skills (and any other middleware-injected context) + actually reached the model. + """ + if system_message is None: + text = "(no system message)" + elif isinstance(system_message, str): + text = system_message + else: + # Cover both ``SystemMessage`` and any other LangChain message + # shape that exposes ``.text`` or string-coercible ``.content``. + text = getattr(system_message, "text", None) + if not text: + content = getattr(system_message, "content", system_message) + text = content if isinstance(content, str) else str(content) + _console.print() + _console.print(Panel(text, title="system prompt", border_style="magenta", expand=False)) + + +class SystemPromptDumpMiddleware(AgentMiddleware): + """Print the post-middleware system prompt once per agent run. + + DeepAgents' ``SkillsMiddleware`` injects the skill catalog into the + system message via ``modify_request`` / ``wrap_model_call``; + inserting this middleware *after* the SkillsMiddleware in the stack + therefore lets us see the exact string the model receives, including + the ``Available Skills:`` block, before the first model call. + """ + + def __init__(self) -> None: + super().__init__() + self._dumped = False + + def wrap_model_call(self, request: Any, handler: Any) -> Any: + if not self._dumped: + self._dumped = True + _print_system_prompt(getattr(request, "system_message", None)) + return handler(request) + + async def awrap_model_call(self, request: Any, handler: Any) -> Any: + if not self._dumped: + self._dumped = True + _print_system_prompt(getattr(request, "system_message", None)) + return await handler(request) diff --git a/plugins/nemo-agents/pyproject.toml b/plugins/nemo-agents/pyproject.toml index d54f73fe..a598ba09 100644 --- a/plugins/nemo-agents/pyproject.toml +++ b/plugins/nemo-agents/pyproject.toml @@ -26,6 +26,7 @@ agents = "nemo_agents_plugin.service:AgentsService" [project.entry-points."nemo.cli"] agents = "nemo_agents_plugin.cli:AgentsCLI" +ask = "nemo_cli_agent.cli:AskCLI" [project.entry-points."nemo.sdk"] agents = "nemo_agents_plugin.sdk:agents_sdk_resources" @@ -48,6 +49,10 @@ agents = "nemo_agents_plugin.skills:skills_dir" [project.entry-points."nat.plugins"] nemo_agents_files_telemetry = "nemo_agents_plugin.telemetry.files_service_exporter" +[project.entry-points."nat.components"] +nemo_agents_nemo_cli_agent = "nemo_cli_agent.agent" +nemo_agents_nat_compatible_langgraph_wrapper = "nemo_cli_agent.utils" + [project.optional-dependencies] test = [ "pytest>=8.0", @@ -56,12 +61,19 @@ test = [ "fastapi>=0.115", ] +# Extras for the bundled examples. Pulling deepagents only when the example is +# actually used keeps the base plugin install lean. +cli-agent = [ + "deepagents>=0.5.9,<0.6", + "langchain-core", +] + [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] -packages = ["src/nemo_agents_plugin"] +packages = ["src/nemo_agents_plugin", "examples/nemo-cli-agent/src/nemo_cli_agent"] [tool.uv.sources] nemo-platform = { workspace = true } diff --git a/pyproject.toml b/pyproject.toml index 754fd978..981179e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -177,7 +177,7 @@ enabled-plugins = [ "nemo-guardrails-plugin", "nemo-auditor-plugin", "nemo-switchyard", - "nemo-agents-plugin", + "nemo-agents-plugin[cli-agent]", ] # Legacy runtime needed specifically for task images that still invoke diff --git a/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/agents/generic.py b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/agents/generic.py new file mode 100644 index 00000000..b3774a69 --- /dev/null +++ b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/agents/generic.py @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +"""Generic agent installer for Agent Skills-compatible folders.""" + +from pathlib import Path + +import yaml +from nemo_platform.cli.commands.skills.base import Scope, Skill +from nemo_platform.cli.commands.skills.installer import BaseAgentInstaller + + +class GenericInstaller(BaseAgentInstaller): + name = "generic" + display_name = "Generic (.agents/skills)" + supported_scopes = [Scope.PROJECT, Scope.USER] + + def get_install_path(self, scope: Scope, project_root: Path, skill_name: str) -> Path: + if scope == Scope.PROJECT: + return project_root / ".agents" / "skills" / f"nemo-{skill_name}" / "SKILL.md" + return Path.home() / ".agents" / "skills" / f"nemo-{skill_name}" / "SKILL.md" + + def format_content(self, skill: Skill) -> str: + front_matter = yaml.safe_dump( + {"name": f"nemo-{skill.name}", "description": skill.description}, + sort_keys=False, + allow_unicode=True, + ) + return f"---\n{front_matter}---\n\n{skill.content}" diff --git a/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/cli.py b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/cli.py index c4a76417..1db5453b 100644 --- a/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/cli.py +++ b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/cli.py @@ -268,6 +268,20 @@ def install( bool, typer.Option("--user", help="Install to user scope (default: project scope)"), ] = False, + project_root: Annotated[ + Path | None, + typer.Option( + "--project-root", + help=( + "Override the project root for project-scope installs. Defaults to " + "the nearest ancestor containing a .git directory, or the current " + "working directory if no Git root is found." + ), + file_okay=False, + dir_okay=True, + exists=True, + ), + ] = None, ) -> None: """Install Nemo skill files for an AI coding agent. @@ -278,6 +292,7 @@ def install( nemo skills install --agent claude nemo skills install --agent claude --user nemo skills install --agent claude --skill inference + nemo skills install --agent generic --project-root path/to/agent """ try: installer = get_installer(agent) @@ -295,9 +310,16 @@ def install( ) raise typer.Exit(code=1) + if project_root is not None and scope is not Scope.PROJECT: + typer.echo( + "Error: --project-root only applies to project-scope installs (omit --user).", + err=True, + ) + raise typer.Exit(code=1) + skills = _resolve_skills(skill) - project_root = _find_project_root() - result_paths = installer.install(scope, project_root, skills) + resolved_root = project_root.resolve() if project_root is not None else _find_project_root() + result_paths = installer.install(scope, resolved_root, skills) typer.echo(f"Installed {len(skills)} skill(s) for {installer.display_name}:") for path in result_paths: typer.echo(f" {path}") diff --git a/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/registry.py b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/registry.py index c303568f..6a8220e8 100644 --- a/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/registry.py +++ b/sdk/python/nemo-platform/src/nemo_platform/cli/commands/skills/registry.py @@ -21,6 +21,7 @@ from nemo_platform.cli.commands.skills.agents.claude import ClaudeInstaller from nemo_platform.cli.commands.skills.agents.codex import CodexInstaller from nemo_platform.cli.commands.skills.agents.cursor import CursorInstaller +from nemo_platform.cli.commands.skills.agents.generic import GenericInstaller from nemo_platform.cli.commands.skills.agents.opencode import OpenCodeInstaller from nemo_platform.cli.commands.skills.base import Skill from nemo_platform.cli.commands.skills.installer import BaseAgentInstaller @@ -42,6 +43,7 @@ "claude": ClaudeInstaller(), "cursor": CursorInstaller(), "codex": CodexInstaller(), + "generic": GenericInstaller(), "opencode": OpenCodeInstaller(), } diff --git a/uv.lock b/uv.lock index 1e2fb2b4..d07c3b8d 100644 --- a/uv.lock +++ b/uv.lock @@ -782,6 +782,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/76/cab7af7f16c0b09347f2ebe7ffda7101132f786acb767666dce43055faab/botocore_stubs-1.42.41-py3-none-any.whl", hash = "sha256:9423110fb0e391834bd2ed44ae5f879d8cb370a444703d966d30842ce2bcb5f0", size = 66759, upload-time = "2026-02-03T20:46:13.02Z" }, ] +[[package]] +name = "bracex" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/63/9a/fec38644694abfaaeca2798b58e276a8e61de49e2e37494ace423395febc/bracex-2.6.tar.gz", hash = "sha256:98f1347cd77e22ee8d967a30ad4e310b233f7754dbf31ff3fceb76145ba47dc7", size = 26642, upload-time = "2025-06-22T19:12:31.254Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/2a/9186535ce58db529927f6cf5990a849aa9e052eea3e2cfefe20b9e1802da/bracex-2.6-py3-none-any.whl", hash = "sha256:0b0049264e7340b3ec782b5cb99beb325f36c3782a32e36e876452fd49a09952", size = 11508, upload-time = "2025-06-22T19:12:29.781Z" }, +] + [[package]] name = "cached-property" version = "2.0.1" @@ -1598,6 +1607,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, ] +[[package]] +name = "deepagents" +version = "0.5.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "langchain-anthropic", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "langchain-core", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "langchain-google-genai", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "langsmith", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "wcmatch", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/74/776e606f0508a4d7d4c9d061c797dcde43eed2452fea546ae29047aeaaa6/deepagents-0.5.9.tar.gz", hash = "sha256:74fe0f998641b20bda8adac662a018051c623a3c8e5ed4b6ff9ad53fc493a783", size = 165651, upload-time = "2026-05-10T22:31:17.095Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/f6/9698f98da72dfa8dc8e1d0f0542f2407a40a50cfdccf522fdb5cb43e39e2/deepagents-0.5.9-py3-none-any.whl", hash = "sha256:ce24a41763b2793bd21217411e9fb9f187a9128da6789f5a81654da1de9e4c7c", size = 188118, upload-time = "2026-05-10T22:31:15.974Z" }, +] + [[package]] name = "defusedxml" version = "0.7.1" @@ -2411,6 +2437,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/eb/c6c2478d8a8d633460be40e2a8a6f8f429171997a35a96f81d3b680dec83/google_auth-2.49.1-py3-none-any.whl", hash = "sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7", size = 240737, upload-time = "2026-03-12T19:30:53.159Z" }, ] +[package.optional-dependencies] +requests = [ + { name = "requests", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, +] + +[[package]] +name = "google-genai" +version = "1.75.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "distro", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "google-auth", extra = ["requests"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "httpx", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "pydantic", extra = ["email"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "requests", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "sniffio", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "tenacity", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "typing-extensions", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "websockets", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/59/3ed61240ef20b3ae6ed54e82c6f8b6d1f194947bc6679679dd6cdb037594/google_genai-1.75.0.tar.gz", hash = "sha256:56bac3991b311c93f980c0a2abcd287b672146905df1fbd71c92ed633d5a07cf", size = 539039, upload-time = "2026-05-04T22:48:54.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/b6/552d40e96da22921eb1fead7c14b00b5b5473a20e45959488660fab35ee2/google_genai-1.75.0-py3-none-any.whl", hash = "sha256:8dc4c096e7d6288c3087f6893f582fe52468932464781edb8193bd92b9fefb2c", size = 793726, upload-time = "2026-05-04T22:48:53.033Z" }, +] + [[package]] name = "googleapis-common-protos" version = "1.73.1" @@ -3523,6 +3575,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4c/87/324ae5fd9993f024339a452fc89e3fd808bccde87ef95c8dafab3de023c0/langchain-1.2.14-py3-none-any.whl", hash = "sha256:96da6d7338d5a6fc41eb4ec0db83f7ef5d03bb5efd17bb269f34ba4378ebdb4d", size = 112715, upload-time = "2026-03-31T13:50:35.997Z" }, ] +[[package]] +name = "langchain-anthropic" +version = "1.4.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anthropic", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "langchain-core", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "pydantic", extra = ["email"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/e3/d2f9dec95602524b1cfb4be2747ba5bc38d32501b2a56cb4bcb76e80bb45/langchain_anthropic-1.4.3.tar.gz", hash = "sha256:f8a2442463c0629b1b3110eaeaa56fdbdc87df2a802f8c7f5ecf611eb4874ec8", size = 685219, upload-time = "2026-05-03T17:33:27.118Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/55/482a1968c95275e8be6d8c1e53b54f0f7be0b8b155ce1608c947a95cf543/langchain_anthropic-1.4.3-py3-none-any.whl", hash = "sha256:65466e0f2f95909a009708f2958e917dfdbfab79c612b4484a30866a85e1f291", size = 50389, upload-time = "2026-05-03T17:33:25.671Z" }, +] + [[package]] name = "langchain-aws" version = "1.1.0" @@ -3612,6 +3678,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/d0/cfce61b53b79974a4883ff7675fe516192ae715e0f925e063e5869b6a929/langchain_exa-1.1.0-py3-none-any.whl", hash = "sha256:7eb4e1b6004f74fe278467470a4e76ba3b74a17df13f64e64745f0780f63d845", size = 7972, upload-time = "2026-03-26T17:00:09.239Z" }, ] +[[package]] +name = "langchain-google-genai" +version = "4.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filetype", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "google-genai", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "langchain-core", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "pydantic", extra = ["email"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/78/dfe068937338727b0dee637d971d59fe2fa275f9d0f0edee3fa80e811846/langchain_google_genai-4.2.2.tar.gz", hash = "sha256:5fc774bf41d1dc1c1a5ba8d7b9f2017dfa77e30653c9b44d2dfbaf0e877e7388", size = 267457, upload-time = "2026-04-15T15:08:32.18Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/5c/adf81d68ab89b4cf505e690f8c1956d11b5969c831c951c7b4b1b1818080/langchain_google_genai-4.2.2-py3-none-any.whl", hash = "sha256:c8d09aac0304d26f1c2483e41a350f15587af1fbe034c39a304e1e17a3b743f3", size = 67605, upload-time = "2026-04-15T15:08:31.346Z" }, +] + [[package]] name = "langchain-huggingface" version = "1.2.2" @@ -4644,6 +4725,10 @@ dependencies = [ ] [package.optional-dependencies] +cli-agent = [ + { name = "deepagents", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "langchain-core", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, +] test = [ { name = "fastapi", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "httpx", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, @@ -4654,9 +4739,11 @@ test = [ [package.metadata] requires-dist = [ { name = "anthropic", specifier = ">=0.88.0" }, + { name = "deepagents", marker = "extra == 'cli-agent'", specifier = ">=0.5.9,<0.6" }, { name = "fastapi", marker = "extra == 'test'", specifier = ">=0.115" }, { name = "httpx", specifier = ">=0.27" }, { name = "httpx", marker = "extra == 'test'", specifier = ">=0.27" }, + { name = "langchain-core", marker = "extra == 'cli-agent'" }, { name = "nemo-agents-example-calculator", editable = "plugins/nemo-agents/examples/calculator-agent" }, { name = "nemo-platform", editable = "packages/nemo_platform" }, { name = "nemo-platform-plugin", editable = "packages/nemo_platform_plugin" }, @@ -4672,7 +4759,7 @@ requires-dist = [ { name = "pyyaml", specifier = ">=6.0" }, { name = "rich", specifier = ">=13.7.1" }, ] -provides-extras = ["test"] +provides-extras = ["test", "cli-agent"] [[package]] name = "nemo-anonymizer" @@ -6520,7 +6607,7 @@ cpu = [ [package.dev-dependencies] core-services = [ - { name = "nemo-agents-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "nemo-agents-plugin", extra = ["cli-agent"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "nemo-anonymizer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "nemo-auditor-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "nemo-data-designer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, @@ -6618,7 +6705,7 @@ dev = [ { name = "types-colorama", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, ] enabled-plugins = [ - { name = "nemo-agents-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "nemo-agents-plugin", extra = ["cli-agent"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "nemo-anonymizer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "nemo-auditor-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "nemo-data-designer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, @@ -6627,7 +6714,7 @@ enabled-plugins = [ { name = "nemo-switchyard", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, ] functional-services = [ - { name = "nemo-agents-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, + { name = "nemo-agents-plugin", extra = ["cli-agent"], marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "nemo-anonymizer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "nemo-auditor-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, { name = "nemo-data-designer-plugin", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, @@ -6722,7 +6809,7 @@ provides-extras = ["cpu", "cu128"] [package.metadata.requires-dev] core-services = [ - { name = "nemo-agents-plugin", editable = "plugins/nemo-agents" }, + { name = "nemo-agents-plugin", extras = ["cli-agent"], editable = "plugins/nemo-agents" }, { name = "nemo-anonymizer-plugin", editable = "plugins/nemo-anonymizer" }, { name = "nemo-auditor-plugin", editable = "plugins/nemo-auditor" }, { name = "nemo-data-designer-plugin", editable = "plugins/nemo-data-designer" }, @@ -6823,7 +6910,7 @@ dev = [ { name = "types-colorama", specifier = ">=0.4.6" }, ] enabled-plugins = [ - { name = "nemo-agents-plugin", editable = "plugins/nemo-agents" }, + { name = "nemo-agents-plugin", extras = ["cli-agent"], editable = "plugins/nemo-agents" }, { name = "nemo-anonymizer-plugin", editable = "plugins/nemo-anonymizer" }, { name = "nemo-auditor-plugin", editable = "plugins/nemo-auditor" }, { name = "nemo-data-designer-plugin", editable = "plugins/nemo-data-designer" }, @@ -6832,7 +6919,7 @@ enabled-plugins = [ { name = "nemo-switchyard", editable = "plugins/nemo-switchyard" }, ] functional-services = [ - { name = "nemo-agents-plugin", editable = "plugins/nemo-agents" }, + { name = "nemo-agents-plugin", extras = ["cli-agent"], editable = "plugins/nemo-agents" }, { name = "nemo-anonymizer-plugin", editable = "plugins/nemo-anonymizer" }, { name = "nemo-auditor-plugin", editable = "plugins/nemo-auditor" }, { name = "nemo-data-designer-plugin", editable = "plugins/nemo-data-designer" }, @@ -12183,6 +12270,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6e/d4/ed38dd3b1767193de971e694aa544356e63353c33a85d948166b5ff58b9e/watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49", size = 457546, upload-time = "2025-10-14T15:06:13.372Z" }, ] +[[package]] +name = "wcmatch" +version = "10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "bracex", marker = "(platform_machine == 'arm64' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform != 'darwin' and sys_platform != 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'darwin' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'darwin' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-12-nemoplatform-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128') or (sys_platform == 'linux' and extra == 'extra-12-nemoplatform-cu128' and extra == 'extra-20-nmp-safe-synthesizer-cpu') or (sys_platform == 'linux' and extra == 'extra-20-nmp-safe-synthesizer-cpu' and extra == 'extra-20-nmp-safe-synthesizer-cu128')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/79/3e/c0bdc27cf06f4e47680bd5803a07cb3dfd17de84cde92dd217dcb9e05253/wcmatch-10.1.tar.gz", hash = "sha256:f11f94208c8c8484a16f4f48638a85d771d9513f4ab3f37595978801cb9465af", size = 117421, upload-time = "2025-06-22T19:14:02.49Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/d8/0d1d2e9d3fabcf5d6840362adcf05f8cf3cd06a73358140c3a97189238ae/wcmatch-10.1-py3-none-any.whl", hash = "sha256:5848ace7dbb0476e5e55ab63c6bbd529745089343427caa5537f230cc01beb8a", size = 39854, upload-time = "2025-06-22T19:14:00.978Z" }, +] + [[package]] name = "wcwidth" version = "0.6.0"