-
Notifications
You must be signed in to change notification settings - Fork 500
Open
Labels
feature requestNew feature or requestNew feature or request
Description
Is this a new feature, an improvement, or a change to existing functionality?
Improvement
How would you describe the priority of this feature request
Medium
Please provide a clear description of problem this feature solves
When using NeMo-Agent-Toolkit-UI alongside nat serve, the workflow is failing if it is missing a ChatResponseChunk converter.
For example,
async def _response_fn(input_message: str) -> MyOutputClass
return MyOutputClass(...)
yield FunctionInfo.from_fn(
_response_fn,
description="dummy agent",
converters=[my_output_class_to_str],
)
will fail with
ValueError: Cannot convert type <class 'MyOutputClass'>
to <class 'nat.data_models.api_server.ChatResponseChunk'>. No match found.
Describe your ideal solution
It would be nice UX to have NeMo-Agent-Toolkit-UI work with any agent/function that has a convert to string method.
- The consumer of the UI doesn't need to know about the internals about how the response is expected.
- The calcualtor example mentioned in https://github.com/NVIDIA/NeMo-Agent-Toolkit-UI has return types float and string which seem to work nice.
- There is
ChatResponseChunk.from_string(str(output))which could be triggered automatically if a string converter exists.
In addition, it would be helpful to check upfront if a required converter is missing to have better debugging experience.
Additional context
Minimal example generated by opus 4.5 ( I haven't run it).
from pydantic import BaseModel, Field
from typing import List
from nat.builder.builder import Builder
from nat.builder.framework_enum import LLMFrameworkEnum
from nat.builder.function_info import FunctionInfo
from nat.cli.register_workflow import register_function
from nat.data_models.api_server import ChatResponseChunk
from nat.data_models.function import FunctionBaseConfig
class MyOutput(BaseModel):
"""Custom structured output from the agent."""
items: List[str] = Field(default_factory=list)
# Converter 1: MyOutput -> str (works with nat run)
def my_output_to_str(output: MyOutput) -> str:
return output.model_dump_json()
# Converter 2: MyOutput -> ChatResponseChunk (WORKAROUND for nat serve)
# Without this, nat serve fails with:
# ValueError: Cannot convert type <class 'MyOutput'> to <class 'ChatResponseChunk'>
def my_output_to_chat_response_chunk(output: MyOutput) -> ChatResponseChunk:
return ChatResponseChunk.from_string(output.model_dump_json())
class MyAgentConfig(FunctionBaseConfig, name="my_agent"): # type: ignore[call-arg]
pass
@register_function(config_type=MyAgentConfig, framework_wrappers=[LLMFrameworkEnum.LANGCHAIN])
async def my_agent(config: MyAgentConfig, builder: Builder):
async def _response_fn(query: str) -> MyOutput:
return MyOutput(items=["result1", "result2"])
yield FunctionInfo.from_fn(
_response_fn,
description="Example agent",
# Both converters needed: str for nat run, ChatResponseChunk for nat serve
converters=[my_output_to_str, my_output_to_chat_response_chunk],
)
Note that I'm using NAT with #1363, as I cannot run nat serve with main.
Finally, I can provide you with the actual intenral codebase if needed.
Code of Conduct
- I agree to follow this project's Code of Conduct
- I have searched the open feature requests and have found no duplicates for this feature request
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
feature requestNew feature or requestNew feature or request