Skip to content

automatically set capabilities for wrapped agents#38

Open
pmeier wants to merge 6 commits into
mainfrom
auto-capabilities
Open

automatically set capabilities for wrapped agents#38
pmeier wants to merge 6 commits into
mainfrom
auto-capabilities

Conversation

@pmeier
Copy link
Copy Markdown
Member

@pmeier pmeier commented May 21, 2026

Closes #5, closes #6, closes #7. Using a demo agent from the nebari-chat-pack

from _ravnar.config import ImportStringWithParams


async def main():
    agent = await ravnar_setup(
        {
            "cls_or_fn": "demo_agents.make_austin_permits_agent",
            "params": {
                "agent": {
                    "cls_or_fn": "pydantic_ai.Agent",
                    "params": {
                        "model": {
                            "cls_or_fn": "pydantic_ai.models.openrouter.OpenRouterModel",
                            "params": {
                                "model_name": "anthropic/claude-sonnet-4.6",
                                "provider": {
                                    "cls_or_fn": "pydantic_ai.providers.openrouter.OpenRouterProvider",
                                    "params": {"api_key": "secret"},
                                },
                            },
                        },
                        "name": "Austin Permits Agent (Claude Sonnet 4.6)",
                    },
                },
                "database_url": "postgresql+psycopg://postgres:password@host/austin_permits",
            },
        }
    )

    print(agent.get_capabilities().model_dump_json(indent=2, exclude_none=True))


async def ravnar_setup(agent_config):
    agent_factory = ImportStringWithParams.model_validate(agent_config)
    agent = agent_factory()
    await agent.setup()
    return agent


if __name__ == "__main__":
    import asyncio

    asyncio.run(main())

we get the following output

{
  "identity": {
    "name": "Austin Permits Agent (Claude Sonnet 4.6)",
    "type": "pydantic-ai"
  },
  "transport": {
    "streaming": true
  },
  "tools": {
    "supported": true,
    "items": [
      {
        "name": "get_database_schema",
        "description": "Get the schema for the database.\n\nUse this tool to understand the database structure before issuing\nany queries to the database.",
        "parameters": {
          "additionalProperties": false,
          "properties": {},
          "type": "object"
        }
      },
      {
        "name": "execute_query",
        "description": "Execute a query against the database.\n\nThe query should not attempt to modify the db in any way.\n\nThe database is mounted as readonly, so queries that attempt to modify it will fail.\n\nThis tool takes a single argument, which is the SQL query to execute\nagainst the database.",
        "parameters": {
          "additionalProperties": false,
          "properties": {
            "query": {
              "type": "string"
            }
          },
          "required": [
            "query"
          ],
          "type": "object"
        }
      },
      {
        "name": "create_chart",
        "description": "Create a chart from data using Apache ECharts.",
        "parameters": {
          "additionalProperties": true,
          "description": "Apache ECharts configuration object.\n\nOnly use features that can be serialized as plain JSON data.\nJS function callbacks are not supported.",
          "properties": {},
          "title": "ChartConfig",
          "type": "object"
        }
      },
      {
        "name": "create_map",
        "description": "\n            Create a map with markers from the data.\n\n            If a link to the permit is available, include it in any popup.\n            ",
        "parameters": {
          "$defs": {
            "GeoJSONFeature": {
              "description": "A single GeoJSON feature with optional popup properties.",
              "properties": {
                "type": {
                  "default": "Feature",
                  "description": "Must be 'Feature'.",
                  "type": "string"
                },
                "geometry": {
                  "additionalProperties": true,
                  "description": "GeoJSON geometry object (Point, LineString, Polygon, etc.).",
                  "type": "object"
                },
                "properties": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "Feature properties. Use a 'popup' key with an HTML string to add a popup."
                }
              },
              "required": [
                "geometry"
              ],
              "title": "GeoJSONFeature",
              "type": "object"
            },
            "GeoJSONFeatureCollection": {
              "description": "A GeoJSON FeatureCollection.",
              "properties": {
                "type": {
                  "default": "FeatureCollection",
                  "description": "Must be 'FeatureCollection'.",
                  "type": "string"
                },
                "features": {
                  "description": "List of GeoJSON features.",
                  "items": {
                    "$ref": "#/$defs/GeoJSONFeature"
                  },
                  "type": "array"
                }
              },
              "required": [
                "features"
              ],
              "title": "GeoJSONFeatureCollection",
              "type": "object"
            }
          },
          "additionalProperties": true,
          "properties": {
            "center": {
              "description": "Map center as [latitude, longitude] in floating point numbers.",
              "items": {
                "type": "number"
              },
              "maxItems": 2,
              "minItems": 2,
              "type": "array"
            },
            "features": {
              "$ref": "#/$defs/GeoJSONFeatureCollection",
              "description": "GeoJSON feature collection with markers and popup metadata."
            }
          },
          "required": [
            "center"
          ],
          "title": "MapData",
          "type": "object"
        }
      }
    ],
    "client_provided": true
  },
  "output": {
    "structured_output": false
  }
}

Comment thread src/_ravnar/agents.py
return self._quick_prompts

@staticmethod
async def extract_capabilities(
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I've opened pydantic/pydantic-ai#5686 to hopefully push this upstream.

Comment thread src/_ravnar/agents.py
return run_agent(self._agent, input) # type: ignore[return-value]

@staticmethod
def extract_capabilities(agent: agno.agent.Agent) -> ag_ui.core.AgentCapabilities:
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I've opened agno-agi/agno#8127 to hopefully push this upstream.

Comment thread src/_ravnar/agents.py
tools=ag_ui.core.ToolsCapabilities(
supported=True,
items=tools,
client_provided=False,
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@pmeier pmeier marked this pull request as ready for review May 27, 2026 13:22
@pmeier pmeier requested a review from jbouder May 27, 2026 13:41
Copy link
Copy Markdown

@jbouder jbouder left a comment

Choose a reason for hiding this comment

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

Looks great!

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.

Map agno agent metadata into AG-UI capabilities Map pydantic-ai agent metadata into AG-UI capabilities autofill third-party agent capabilities

2 participants