Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 52 additions & 16 deletions services/studio/src/nmp/studio/coding_agent_mcp_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
"name": SELECT_AGENT_TOOL_NAME,
"description": (
"Ask the Studio user to choose an agent from a visual dropdown. "
"Use this instead of plain text prompting when a Studio workflow needs a concrete agent name."
"This is the required way to get an agent name in Studio: call it whenever a workflow needs the "
"user to name, pick, confirm, or disambiguate an agent (including choosing among deployed agents). "
"Always prefer this over plain-text prompting and over Claude Code's AskUserQuestion tool for agent choices. "
"Returns the chosen agent name, or status=skipped / status=error if the user dismisses the dropdown."
),
"inputSchema": {
"type": "object",
Expand Down Expand Up @@ -75,8 +78,14 @@
"name": SELECT_DATASET_FILE_TOOL_NAME,
"description": (
"Ask the Studio user to choose a dataset file from a visual fileset file picker. "
"Use this instead of plain text prompting when a workflow needs source data, "
"for example while helping create an evaluation config. Returns dataset_fileset and dataset_path."
"This is the required way to get a fileset, fileset reference, dataset, or input/source data file "
"in Studio (for example an anonymizer or evaluation input, or a CSV/Parquet file). Call it whenever "
"a workflow needs the user to pick a fileset or a file inside one, instead of asking for a fileset "
"reference, path, or '<workspace>/<fileset>#<file>' string in plain text. "
"Always prefer this over plain-text prompting and over AskUserQuestion for file/fileset choices. "
"Pass accepted_file_types (for example ['.csv', '.parquet']) to constrain the picker. "
"Returns dataset_fileset and dataset_path, which you can combine as '<fileset>#<path>' when a tool "
"needs a fileset reference. Returns status=skipped / status=error if the user dismisses the picker."
),
"inputSchema": {
"type": "object",
Expand Down Expand Up @@ -120,7 +129,10 @@
"name": JOB_PROGRESS_TOOL_NAME,
"description": (
"Show a compact Studio progress card for a long-running job. "
"Call this only after a real Studio job has been started and you know its job_name. "
"This is the required way to surface a launched job in Studio: after you start, submit, or kick off "
"any platform job and know its job_name, you must call this before your final response, once for "
"every job you launch. Do not substitute a plain-text job summary or a manual status command. "
"Call it only after a real job has been started and you know its job_name. "
"Pass job_type or source when known so Studio can link to the best detail page."
),
"inputSchema": {
Expand Down Expand Up @@ -168,22 +180,40 @@
STUDIO_CODING_AGENT_CONTEXT = "\n".join(
[
"You are running inside NeMo Studio's Code Agent chat.",
"NeMo Studio and the NeMo Platform API are already running for this workspace.",
"Do not spend time starting the platform or checking whether Studio is up unless the user asks.",
"Your local shell and file tools may be sandboxed; use the normal Studio approval flow when needed.",
(
"NeMo Studio and the NeMo Platform API are already installed, set up, and running for this "
"workspace. Treat the platform as healthy and available."
),
(
"Do not run setup, bootstrap, install, start, or health-check steps for the platform: skip "
"'nemo setup', 'make bootstrap', 'nemo services run', service restarts, port probes, and "
"'health/ready' checks unless the user explicitly asks you to. Assume services are up and "
"go straight to the actual task."
),
("Prefer NeMo Studio MCP tools and the nemo CLI over ad-hoc shell or filesystem commands. "),
(
"When you need to prompt the user for input, use a Studio UI tool instead of writing a "
"plain-text question whenever a suitable tool exists."
),
(
"Use mcp__nemo_studio__select_agent for agent names, "
"mcp__nemo_studio__select_model for model names, "
"mcp__nemo_studio__select_dataset_file for dataset or source files, and "
"mcp__nemo_studio__select_eval_config for evaluation config files."
"These needs are mandatory tool calls, not plain-text questions and not AskUserQuestion: "
"use mcp__nemo_studio__select_agent whenever you need the user to name, pick, confirm, or "
"disambiguate an agent (including among deployed agents); "
"mcp__nemo_studio__select_model for model names; "
"mcp__nemo_studio__select_dataset_file whenever you need a fileset, fileset reference, dataset, "
"or input/source data file (for example an anonymizer or evaluation input, or a CSV/Parquet "
"file) instead of asking for a fileset reference or '<workspace>/<fileset>#<file>' path in text; "
"and mcp__nemo_studio__select_eval_config for evaluation config files."
),
(
"For broader clarification, multiple-choice, yes/no, or freeform questions, use Claude "
"Code's AskUserQuestion tool rather than writing a questionnaire in markdown."
"Never use AskUserQuestion or a plain-text question to choose an agent, model, fileset, "
"dataset or input file, or eval config; those each have a dedicated select_* tool you must "
"call instead."
),
(
"For clarification, multiple-choice, yes/no, or freeform questions that do NOT map to one of "
"the select_* tools, use Claude Code's AskUserQuestion tool rather than writing a "
"questionnaire in markdown."
),
(
"Only fall back to plain chat questions when no suitable UI tool is available, the user "
Expand All @@ -194,9 +224,15 @@
"current workflow while keeping the tools reusable."
),
(
"When you start a long-running Studio job and a matching progress/status MCP tool is "
"available, call it after job creation with the job id or name so Studio can render "
"progress inline. Use mcp__nemo_studio__job_progress for Studio jobs."
"Whenever you start, submit, or kick off any platform job (for example an anonymizer run, "
"customization, data designer, safe synthesizer, or evaluation job) and you know its job name, "
"you MUST call mcp__nemo_studio__job_progress with that job name before your final response so "
"Studio renders the progress card inline. Do this for every job you launch, not only the first, "
"and pass job_type or source when known so the card links to the right detail page."
),
(
"Never replace the job_progress card with a plain-text job summary or by telling the user to "
"run a status command; call job_progress in addition to any Studio link you include."
),
]
)
Expand Down
14 changes: 11 additions & 3 deletions services/studio/src/nmp/studio/coding_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,11 +270,16 @@ def _build_studio_system_prompt(
"If studio_link is unavailable and you must construct a Studio UI link manually, use only a known enabled Studio route and prefer a relative Markdown link that starts with /workspaces/ or /models/.",
"Evaluation pages use /workspaces/{workspace}/evaluation/... with singular evaluation; never nest evaluation links under /dashboard/evaluations/.",
"Interactive Studio choice behavior:",
"When you need the user to choose from a finite set of agents, deployments, models, jobs, filesets, resources, or next actions, do not ask them to type the choice in plain text.",
"Use Claude Code's AskUserQuestion tool so Studio can render the choices as clickable options.",
"Studio ships dedicated visual picker tools. When a picker fits, you MUST use it instead of plain text and instead of AskUserQuestion.",
"Whenever you need the user to name, pick, confirm, or disambiguate an agent (including choosing among deployed agents), you MUST call mcp__nemo_studio__select_agent to render the agent dropdown. Never ask for an agent in plain text and never use AskUserQuestion for an agent choice.",
"Whenever you need the user to choose a model, you MUST call mcp__nemo_studio__select_model. Never use AskUserQuestion or plain text for a model choice.",
"Whenever you need a fileset, fileset reference, dataset, or input/source data file (including an anonymizer or evaluation input, or a CSV/Parquet file), you MUST call mcp__nemo_studio__select_dataset_file instead of asking for a fileset reference or '<workspace>/<fileset>#<file>' path in plain text; for an evaluation config file, you MUST call mcp__nemo_studio__select_eval_config.",
"Treat 'which agent', 'pick an agent', 'choose a model', 'which fileset', and 'what is your fileset reference' as mandatory tool-use requests for the matching select_* tool, exactly like Studio link requests are mandatory studio_link requests.",
"Set the picker title and description to match the current workflow, for example title='Select agent to audit'.",
"Only skip a picker when the user already gave the value, the value is already unambiguous from the conversation, or a previous picker call returned skipped or error.",
"For finite choices that have no dedicated Studio picker (for example deployments, jobs, or next actions) and for yes/no or multiple-choice clarifications, use Claude Code's AskUserQuestion tool so Studio can render clickable options instead of asking the user to type.",
"For AskUserQuestion, provide input shaped as {'questions': [{'header': '<short title>', 'question': '<what should the user choose?>', 'options': [{'label': '<option>', 'description': '<short impact/details>'}]}]}.",
"If you need both a finite choice and free-form text, ask multiple AskUserQuestion questions: first the finite options, then a text question without options.",
"For a list of deployed agents, make each option label the agent name and put status/model/tool details in the description.",
"Required Studio-link behavior:",
"Default to trying to include a Studio link in Studio-related responses.",
"When your answer mentions or depends on a Studio resource, page, workflow, or result, first choose the nearest studio_link destination and include that link unless no relevant Studio page exists.",
Expand All @@ -285,6 +290,9 @@ def _build_studio_system_prompt(
"After any successful Studio action, you must include a Studio link in the response even if the user did not ask for one.",
"Before your final response for any successful create, start, deploy, evaluate, inspect, or modify action, call mcp__nemo_studio__studio_link and include the returned markdown exactly.",
"Never finish a successful Studio action without a visible Markdown link to the most relevant Studio page.",
"Required job-progress behavior:",
"Whenever you start, submit, or kick off any platform job and you know its job name, you MUST call mcp__nemo_studio__job_progress with that job name before your final response, once for every job you launch.",
"Do not replace the job_progress card with a plain-text job summary or by telling the user to run a status command; call job_progress in addition to any Studio link.",
"Use the returned markdown from studio_link exactly; do not replace it with localhost, the API host, or the MCP server host.",
"If the user asks for an agent link and an agent name is known from the conversation, use destination='agent' with that name; otherwise use destination='agents'.",
"If the user asks for an agent chat or playground link and an agent name is known from the conversation, use destination='agent_chat' with that name; otherwise use destination='agents'.",
Expand Down
10 changes: 7 additions & 3 deletions services/studio/tests/unit/test_coding_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -1088,10 +1088,12 @@ async def fake_stream(session_id: str, message: str, mcp_url: str, studio_system
assert "Current Studio workspace: default" in captured["studio_system_prompt"]
assert "Studio UI base URL: https://studio.test/studio" in captured["studio_system_prompt"]
assert "Current Studio route path: /workspaces/default/dashboard/code-agent" in captured["studio_system_prompt"]
assert "Use Claude Code's AskUserQuestion tool" in captured["studio_system_prompt"]
assert "finite set of agents, deployments, models, jobs, filesets" in captured["studio_system_prompt"]
assert "use Claude Code's AskUserQuestion tool" in captured["studio_system_prompt"]
assert "you MUST call mcp__nemo_studio__select_agent" in captured["studio_system_prompt"]
assert "never use AskUserQuestion for an agent choice" in captured["studio_system_prompt"]
assert "you MUST call mcp__nemo_studio__select_model" in captured["studio_system_prompt"]
assert "ask multiple AskUserQuestion questions" in captured["studio_system_prompt"]
assert "For a list of deployed agents, make each option label the agent name" in captured["studio_system_prompt"]
assert "no dedicated Studio picker" in captured["studio_system_prompt"]
assert "Default to trying to include a Studio link in Studio-related responses" in captured["studio_system_prompt"]
assert "link to the closest list page for the current workspace" in captured["studio_system_prompt"]
assert "Base Models or available base models use destination='base_models'" in captured["studio_system_prompt"]
Expand All @@ -1112,6 +1114,8 @@ async def fake_stream(session_id: str, message: str, mcp_url: str, studio_system
)
assert "Before your final response" in captured["studio_system_prompt"]
assert "mcp__nemo_studio__studio_link" in captured["studio_system_prompt"]
assert "Required job-progress behavior:" in captured["studio_system_prompt"]
assert "you MUST call mcp__nemo_studio__job_progress" in captured["studio_system_prompt"]
assert (
"For a newly created agent, use studio_link with destination='agent_chat'" in captured["studio_system_prompt"]
)
Expand Down
Loading