Skip to content

refactor(tools): move native tools out of NAT - #355

Merged
nvddr merged 4 commits into
mainfrom
agent/move-native-tools
Aug 12, 2026
Merged

refactor(tools): move native tools out of NAT#355
nvddr merged 4 commits into
mainfrom
agent/move-native-tools

Conversation

@nvddr

@nvddr nvddr commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add the dedicated xr-ai-tools package and move toolkit-independent native tool code out of xr-ai-nat
  • replace agents.py and agent_runner.py with a small tool_calling.py convenience layer that adapts schemas and handles one model-selected call
  • split live vision into a finite LiveVisionTool and an independent StreamingVisionTool built on generic AsyncTool
  • remove the unused NAT StreamingVisionConfig surface now replaced by StreamingVisionTool
  • retain NAT function groups that do not yet have complete native replacements, including current/past vision because recorded-frame vision is still unmatched

Why

The native tool layer added in #348 and #349 is toolkit-independent and should not live under the NAT package while NAT is being retired. The tools package should not also define an agent runtime: real agents need the native schemas and a consistent way to dispatch their model-produced tool calls, while retaining ownership of prompts, model calls, history, iteration, and concurrency.

Impact

Consumers of the moved surface now import xr_ai_tools and depend on xr-ai-tools; unmatched legacy NAT functions remain under xr_ai_nat. tool_definitions(...) adapts native tools to xr-ai-models ToolDef values, and handle_tool_call(...) invokes exactly one ToolCall and returns a tool-role message plus the return_direct hint. There is no bundled Agent, AgentRunner, prompt, model loop, or conversation state.

Vision is separated by lifecycle: LiveVisionTool returns a complete VisionResponse, while StreamingVisionTool yields typed VisionChunk values and has no voice or output-transport dependency. The sample adapts that stream to VoiceSession locally.

Validation

  • focused native-tool, retained NAT vision, and streaming vision tests: 29 passed
  • repository Ruff: passed
  • targeted Pyright: 0 errors
  • strict Sphinx documentation build: passed
  • xr-ai-tools and xr-ai-nat source and wheel builds: passed
  • wheel-content verification: removed agent modules absent; tool_calling.py present
  • SPDX check for new modules: passed
  • stale current-code reference scan: passed

The repository-wide suite could not complete in this checkout because two unrelated modules fail collection (stt_server and openxr_service are not importable from the configured test paths); a follow-up run excluding them also encountered pre-existing async-fixture/plugin failures in integration tests.

Signed-off-by: Devdeep Ray <devdeepr@nvidia.com>
github-actions Bot added a commit that referenced this pull request Aug 12, 2026
Signed-off-by: Devdeep Ray <devdeepr@nvidia.com>
github-actions Bot added a commit that referenced this pull request Aug 12, 2026
Signed-off-by: Devdeep Ray <devdeepr@nvidia.com>
github-actions Bot added a commit that referenced this pull request Aug 12, 2026
@wenxind-nvidia

Copy link
Copy Markdown
Collaborator

Reviewed at 20e9d4e24a5acc23e0850ef4c0c43d3a742d61c2.

Blocker

  1. The streaming failure fallback corrupts responses after partial output. StreamingVisionTool._stream_current() catches every stream failure and yields "VLM server unavailable — please retry.", even after tokens have already been delivered. I reproduced the output ['The object is ', 'VLM server unavailable — please retry.']; TTS would speak that as one incoherent answer. Emit the fallback only before any non-empty chunk. Once output has begun, log the failure and terminate the stream.

Suggestions

  1. Remove the broad frame-conversion fallbacks in live_vision.py and streaming_vision.py. FrameUnavailable is the expected user-facing case; malformed pixels and programming errors should not be disguised as “VLM server unavailable.”

  2. The xr-ai-tools README example appends tool results without first appending the assistant message containing the corresponding tool_calls. That produces an invalid conversation for the next model request. The example also ignores return_direct.

  3. xr-ai-tools[relay,live-vision] is redundant for the sample: live-vision already installs xr-ai-models, while the sample does not import tool_calling. Use only xr-ai-tools[live-vision].

  4. LiveVisionTool no longer has an application consumer after the sample switches to StreamingVisionTool. Unless preserving that public API is an explicit requirement, defer the finite implementation until the agentic consumer lands; it currently duplicates most of the frame and VLM lifecycle.

Validation: all 29 focused tests passed and Ruff passed. The additional partial-stream probe exposed the blocker above.

@nvddr
nvddr marked this pull request as ready for review August 12, 2026 20:25
Signed-off-by: Devdeep Ray <devdeepr@nvidia.com>
github-actions Bot added a commit that referenced this pull request Aug 12, 2026
@nvddr

nvddr commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed in 67edd07:

  • Streaming failures now emit the retry fallback only if no non-empty chunk has been delivered. After partial output, the failure is logged and the stream terminates without corrupting the response.
  • Removed the broad frame-conversion fallbacks from both vision tools. FrameUnavailable remains user-facing; malformed pixels and programming errors now propagate.
  • Fixed the xr-ai-tools README example to append the assistant message containing tool_calls before tool results and to honor return_direct.
  • Removed the redundant relay extra from the simple-VLM worker (and the equivalent test dependency); live-vision already installs the required model dependency.
  • Added regressions for partial-stream failure, failure before output, and frame-conversion errors.

I intentionally retained LiveVisionTool. We want to preserve this new finite tool API for upcoming agentic consumers even though the current sample uses StreamingVisionTool.

Validation: 32 focused tests passed; repository Ruff, targeted Pyright, and the xr-ai-tools package build passed.

@nvddr
nvddr merged commit e95ebb9 into main Aug 12, 2026
14 checks passed
@nvddr
nvddr deleted the agent/move-native-tools branch August 12, 2026 20:44
github-actions Bot added a commit that referenced this pull request Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants