Skip to content

feat(studio): Studio agent add tool usage info - #1067

Open
htolentino-nvidia wants to merge 3 commits into
mainfrom
studio-agent-add-tool-usage-info/htolentino
Open

feat(studio): Studio agent add tool usage info#1067
htolentino-nvidia wants to merge 3 commits into
mainfrom
studio-agent-add-tool-usage-info/htolentino

Conversation

@htolentino-nvidia

@htolentino-nvidia htolentino-nvidia commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
image

Summary by CodeRabbit

  • New Features

    • Added streaming responses for NeMo Agent interactions.
    • Tool activity and intermediate steps are displayed in the active session as they occur.
    • Added workspace access controls, consistent workspace links, and session-based authorization caching.
    • Improved session tracking and profiler integration for more complete interaction visibility.
  • Bug Fixes

    • Agent execution continues normally when optional profiling cannot be initialized.
    • Improved parsing, filtering, and deduplication of streamed tool-step data.
    • Added clearer handling for inaccessible workspaces and workspace service failures.

@htolentino-nvidia
htolentino-nvidia requested review from a team as code owners August 4, 2026 15:10
@github-actions github-actions Bot added the feat label Aug 4, 2026
Comment thread services/studio/src/nmp/studio/coding_agents.py Fixed
Signed-off-by: Henrique Tolentino <htolentino@nvidia.com>
@htolentino-nvidia
htolentino-nvidia force-pushed the studio-agent-add-tool-usage-info/htolentino branch from bf1b5c9 to 1fef8df Compare August 4, 2026 15:16
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The NeMo wrapper now attaches profiler callbacks. Studio authorizes workspaces through Entity Store, uses canonical names, streams agent responses, and emits sanitized tool-use events before final responses.

Changes

Interactive NeMo agent flow

Layer / File(s) Summary
NeMo wrapper profiler integration
agents/nemo-agent-local/src/nemo_agent/wrapper.py, agents/nemo-agent-local/tests/test_nemo_agent.py
The wrapper attaches LangchainProfilerHandler, preserves studio_session_id, and tolerates profiler failures. Tests validate the expanded configuration.
Workspace validation and canonicalization
services/studio/src/nmp/studio/coding_agents.py, services/studio/tests/unit/test_coding_agents.py
Studio authorizes workspaces with bounded Entity Store pagination, caches successful session lookups, maps failures to HTTP errors, and uses canonical names in prompts and agent URLs.
Streaming tool-event processing
services/studio/src/nmp/studio/coding_agents.py, services/studio/tests/unit/test_coding_agents.py
Studio enables streaming, parses Python-representation tool inputs, removes internal session IDs, deduplicates events, and flushes queued events before the final response. Tests cover parsing, event construction, ordering, and the streaming flag.

Sequence Diagram(s)

sequenceDiagram
  participant StudioCodingAgent
  participant EntityStore
  participant NeMoAgent
  participant SessionStream
  StudioCodingAgent->>EntityStore: authorize requested workspace
  EntityStore-->>StudioCodingAgent: canonical workspace name
  StudioCodingAgent->>NeMoAgent: streaming request with canonical workspace
  NeMoAgent-->>StudioCodingAgent: assistant content and tool-step data
  StudioCodingAgent->>StudioCodingAgent: parse and deduplicate tool steps
  StudioCodingAgent->>SessionStream: emit queued tool-use events
  StudioCodingAgent->>SessionStream: emit final assistant response
Loading

Possibly related PRs

Suggested labels: test

Suggested reviewers: steramae-nvidia

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the primary change: adding tool usage information to the Studio agent.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch studio-agent-add-tool-usage-info/htolentino

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
agents/nemo-agent-local/src/nemo_agent/wrapper.py (1)

245-256: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Remove the broad profiler fallback. NAT 1.8.0 does not require an active request context to construct LangchainProfilerHandler. Catching Exception still hides genuine regressions and disables streamed tool events. Construct the handler directly, and test callback attachment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agents/nemo-agent-local/src/nemo_agent/wrapper.py` around lines 245 - 256,
Remove the try-except block surrounding the LangchainProfilerHandler
construction since NAT 1.8.0 no longer requires an active request context.
Assign the LangchainProfilerHandler instance directly to config["callbacks"]
without the exception handler, eliminating the debug fallback path. This ensures
genuine errors are not masked and tool-call tracing is reliably enabled.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@agents/nemo-agent-local/src/nemo_agent/register.py`:
- Around line 597-606: Strengthen validation in the AskUserQuestion handling
around parsed and before _call_studio_tool: require each question object to
contain a non-empty string question, a non-empty options list with valid option
objects and non-empty string labels, and validate the types of any optional
fields according to the picker contract. Return the existing error format for
every rejected shape, and add tests covering each invalid question and option
case.

In `@services/studio/src/nmp/studio/coding_agents.py`:
- Around line 1420-1424: Update _stream_nemo_agent so invocation completion does
not end queue processing before pending tool-use events are emitted: after
invocation.done(), emit the completed queued_event, drain all remaining events
from queue, then emit the final assistant event. Add a test covering a tool step
and completion arriving in the same event-loop turn, verifying the tool event is
preserved before the final response.
- Around line 1415-1419: Update the deduplication logic around step_id so type
validation occurs before checking membership in seen_tool_ids. Skip non-string
IDs, and only test and add valid string IDs to the set while preserving the
existing duplicate-skipping behavior.
- Around line 1339-1354: Update _tool_use_stream_event and its
_invoke_nemo_agent call path to sanitize tool_input before json serialization,
removing studio_session_id and redacting other sensitive fields; preferably
expose only an explicit safe display-field allowlist per tool while preserving
the browser event structure.

---

Nitpick comments:
In `@agents/nemo-agent-local/src/nemo_agent/wrapper.py`:
- Around line 245-256: Remove the try-except block surrounding the
LangchainProfilerHandler construction since NAT 1.8.0 no longer requires an
active request context. Assign the LangchainProfilerHandler instance directly to
config["callbacks"] without the exception handler, eliminating the debug
fallback path. This ensures genuine errors are not masked and tool-call tracing
is reliably enabled.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b2cba84c-657b-4f02-8afd-e23f90ca9bec

📥 Commits

Reviewing files that changed from the base of the PR and between 2eb952f and 8eab05f.

📒 Files selected for processing (6)
  • agents/nemo-agent-local/src/nemo_agent/register.py
  • agents/nemo-agent-local/src/nemo_agent/wrapper.py
  • agents/nemo-agent-local/tests/test_nemo_agent.py
  • services/studio/src/nmp/studio/coding_agent_mcp_tools.py
  • services/studio/src/nmp/studio/coding_agents.py
  • services/studio/tests/unit/test_coding_agents.py

Comment thread services/studio/src/nmp/studio/coding_agents.py
Comment thread services/studio/src/nmp/studio/coding_agents.py
Comment thread services/studio/src/nmp/studio/coding_agents.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 4

🧹 Nitpick comments (1)
agents/nemo-agent-local/src/nemo_agent/wrapper.py (1)

245-256: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Remove the broad profiler fallback. NAT 1.8.0 does not require an active request context to construct LangchainProfilerHandler. Catching Exception still hides genuine regressions and disables streamed tool events. Construct the handler directly, and test callback attachment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agents/nemo-agent-local/src/nemo_agent/wrapper.py` around lines 245 - 256,
Remove the try-except block surrounding the LangchainProfilerHandler
construction since NAT 1.8.0 no longer requires an active request context.
Assign the LangchainProfilerHandler instance directly to config["callbacks"]
without the exception handler, eliminating the debug fallback path. This ensures
genuine errors are not masked and tool-call tracing is reliably enabled.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@agents/nemo-agent-local/src/nemo_agent/register.py`:
- Around line 597-606: Strengthen validation in the AskUserQuestion handling
around parsed and before _call_studio_tool: require each question object to
contain a non-empty string question, a non-empty options list with valid option
objects and non-empty string labels, and validate the types of any optional
fields according to the picker contract. Return the existing error format for
every rejected shape, and add tests covering each invalid question and option
case.

In `@services/studio/src/nmp/studio/coding_agents.py`:
- Around line 1420-1424: Update _stream_nemo_agent so invocation completion does
not end queue processing before pending tool-use events are emitted: after
invocation.done(), emit the completed queued_event, drain all remaining events
from queue, then emit the final assistant event. Add a test covering a tool step
and completion arriving in the same event-loop turn, verifying the tool event is
preserved before the final response.
- Around line 1415-1419: Update the deduplication logic around step_id so type
validation occurs before checking membership in seen_tool_ids. Skip non-string
IDs, and only test and add valid string IDs to the set while preserving the
existing duplicate-skipping behavior.
- Around line 1339-1354: Update _tool_use_stream_event and its
_invoke_nemo_agent call path to sanitize tool_input before json serialization,
removing studio_session_id and redacting other sensitive fields; preferably
expose only an explicit safe display-field allowlist per tool while preserving
the browser event structure.

---

Nitpick comments:
In `@agents/nemo-agent-local/src/nemo_agent/wrapper.py`:
- Around line 245-256: Remove the try-except block surrounding the
LangchainProfilerHandler construction since NAT 1.8.0 no longer requires an
active request context. Assign the LangchainProfilerHandler instance directly to
config["callbacks"] without the exception handler, eliminating the debug
fallback path. This ensures genuine errors are not masked and tool-call tracing
is reliably enabled.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b2cba84c-657b-4f02-8afd-e23f90ca9bec

📥 Commits

Reviewing files that changed from the base of the PR and between 2eb952f and 8eab05f.

📒 Files selected for processing (6)
  • agents/nemo-agent-local/src/nemo_agent/register.py
  • agents/nemo-agent-local/src/nemo_agent/wrapper.py
  • agents/nemo-agent-local/tests/test_nemo_agent.py
  • services/studio/src/nmp/studio/coding_agent_mcp_tools.py
  • services/studio/src/nmp/studio/coding_agents.py
  • services/studio/tests/unit/test_coding_agents.py
🛑 Comments failed to post (1)
agents/nemo-agent-local/src/nemo_agent/register.py (1)

597-606: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Validate each question object before calling Studio.

Line 601 accepts [{}], missing question, empty options, and malformed option entries. These values violate the documented picker contract and can block the interactive flow.

Validate required strings, a non-empty options list, option labels, and optional field types. Add tests for each rejected shape.

Proposed validation
-    if not isinstance(parsed, list) or not parsed or not all(isinstance(q, dict) for q in parsed):
+    if (
+        not isinstance(parsed, list)
+        or not parsed
+        or any(
+            not isinstance(question, dict)
+            or not isinstance(question.get("question"), str)
+            or not question["question"].strip()
+            or not isinstance(question.get("options"), list)
+            or not question["options"]
+            or any(
+                not isinstance(option, dict)
+                or not isinstance(option.get("label"), str)
+                or not option["label"].strip()
+                for option in question["options"]
+            )
+            for question in parsed
+        )
+    ):
         return "Error: `questions` must be a non-empty JSON array of question objects."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agents/nemo-agent-local/src/nemo_agent/register.py` around lines 597 - 606,
Strengthen validation in the AskUserQuestion handling around parsed and before
_call_studio_tool: require each question object to contain a non-empty string
question, a non-empty options list with valid option objects and non-empty
string labels, and validate the types of any optional fields according to the
picker contract. Return the existing error format for every rejected shape, and
add tests covering each invalid question and option case.

@htolentino-nvidia

Copy link
Copy Markdown
Contributor Author

@CodeRabbit re-review now

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@htolentino-nvidia Re-review requested.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 30257/38273 79.1% 63.7%
Integration Tests N/A N/A N/A

@htolentino-nvidia
htolentino-nvidia force-pushed the studio-agent-add-tool-usage-info/htolentino branch 3 times, most recently from e123125 to 308fe3c Compare August 4, 2026 17:23
@htolentino-nvidia

Copy link
Copy Markdown
Contributor Author

One more review please @CodeRabbit

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@htolentino-nvidia Review requested.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/studio/src/nmp/studio/coding_agents.py`:
- Around line 144-147: Update _session_workspace_cache and its access paths to
include the resolved caller identity, such as user ID, in the cache key
alongside session_id and requested workspace. Ensure workspace authorization
lookups use this caller-scoped key so cached membership results cannot be reused
by another caller.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d18a0803-f816-46ba-a186-e47b13266ab2

📥 Commits

Reviewing files that changed from the base of the PR and between 5700df1 and 308fe3c.

📒 Files selected for processing (2)
  • services/studio/src/nmp/studio/coding_agents.py
  • services/studio/tests/unit/test_coding_agents.py

Comment thread services/studio/src/nmp/studio/coding_agents.py Outdated
- Strip framework-injected studio_session_id from tool-use events before
  they reach the browser.
- Gate tool-step dedup on a validated string id.
- Drain queued tool-use events after the invocation completes so late
  events are not dropped before the final assistant message.
- Resolve the CodeQL partial-SSRF finding: validate the requested
  workspace against the Entity Store (scoped to the caller's forwarded
  auth) and build the agent URL from the platform's own copy of the name,
  so no client-derived value reaches the outbound request URL.
- Cache confirmed workspace names per session so the membership lookup
  runs once per session/workspace instead of on every message; only
  successful resolutions are cached, and the cache is cleared on session
  eviction.

Signed-off-by: Henrique Tolentino <htolentino@nvidia.com>
Session ids carry no caller identity: create_session mints a bare UUID and
nothing binds a session to a user. Keying the workspace-membership cache on
(session, workspace) alone therefore let a second caller reuse the first
caller's authorization decision and skip the Entity Store check.

Include a SHA-256 fingerprint of the caller's forwarded credentials in the
cache key so a cached decision is never reused across callers. Only the
digest is retained, never the raw credential.

Signed-off-by: Henrique Tolentino <htolentino@nvidia.com>
@htolentino-nvidia
htolentino-nvidia force-pushed the studio-agent-add-tool-usage-info/htolentino branch from 308fe3c to ecdc75e Compare August 4, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants