Skip to content

feat(tools): parameter descriptions via Annotated and docstring Args - #271

Open
jaygupta17 wants to merge 1 commit into
vercel-labs:mainfrom
jaygupta17:feat/tool-param-descriptions
Open

jaygupta17 wants to merge 1 commit into
vercel-labs:mainfrom
jaygupta17:feat/tool-param-descriptions

Conversation

@jaygupta17

Copy link
Copy Markdown
Contributor

Closes #270

What

Two mechanisms for parameter descriptions on @ai.tool functions:

  1. Annotated[str, Field(description=...)] now survives into the schema — the fix is get_type_hints(fn, include_extras=True); pydantic carries the metadata through create_model().model_json_schema() unchanged.
  2. A Google-style Args: docstring section fills descriptions for parameters without a Field description. Field wins when both exist.

Why

Descriptions are how the model judges which tool to call and what each argument means. Both idiomatic typed-Python patterns were silently dropped, so every tool built this way shipped undocumented arguments.

Notes

  • No new dependencies (the parser is ~40 lines in agent.py, Google-style only).
  • Tools using neither mechanism get byte-identical schemas; there is a regression test pinning that.
  • The tool description itself stays the full docstring — trimming the Args: block from it felt like a separate behavior decision, happy to follow up if wanted.
  • Every provider protocol embeds spec.params verbatim (openai/protocol.py, anthropic/protocol.py, ai_gateway/protocol.py), so descriptions reach all models with no per-provider changes.

Validation

  • uv run pytest: 768 passed (8 new tests covering annotated fields, nested Annotated[...] | None unions keeping constraints + description, multiline Args entries, Field-over-docstring precedence, unknown-name tolerance, and the byte-identical regression)
  • uv run ruff format --check / ruff check: clean
  • uv run mypy: 35 errors, identical to baseline on main (all pre-existing, none in touched code)
  • uv run ty check: clean

@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

@jaygupta17 is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@jaygupta17

Copy link
Copy Markdown
Contributor Author

Could a maintainer add the feature label? (External PRs can't set labels.) The two red checks are permission artifacts: changelog-label needs triage rights and the Vercel deploy needs collaborator status.

@jaygupta17

Copy link
Copy Markdown
Contributor Author

hey folks quick ping on #271 and #273 when you get a sec, been open since Aug 26. both are mergeable and green across 3.12-3.15 and Socket. the two reds are just fork perms (Vercel needs collaborator auth and changelog-label needs the feature tag which I can't set). happy to jump on any feedback fast. thanks!

@jaygupta17
jaygupta17 force-pushed the feat/tool-param-descriptions branch from 204f90e to 9528108 Compare September 4, 2026 06:07
@jaygupta17

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main. The only conflict was in test_tools.py (upstream added to_model_input tests where mine go), kept both suites. Ruff, mypy, ty, and pytest all green locally. The two reds still need a maintainer: the feature label and Vercel auth.

Tool schemas stripped Annotated metadata because get_type_hints() was
called without include_extras=True, so
`city: Annotated[str, Field(description=...)]` lost its description and
the model picked tools with undocumented arguments.

- resolve hints with include_extras=True; pydantic already carries
  Field metadata through create_model().model_json_schema()
- parse a Google-style Args: section from the docstring and fill in
  descriptions for parameters that have no Field description; Field wins
- no behavior change for tools without descriptions: plain-hint schemas
  are byte-identical to before

The schema is embedded verbatim by every provider protocol (openai,
anthropic, gateway), so descriptions reach all models without per-provider
changes.
@jaygupta17
jaygupta17 force-pushed the feat/tool-param-descriptions branch from 9528108 to aa74ab1 Compare September 8, 2026 07:42
@jaygupta17

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main, no code changes. Ruff, ty, mypy, and pytest green locally.

Still needs a maintainer for the feature label and Vercel auth.

This branch has not been deployed

No deployments
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.

Tool parameters lose descriptions from Annotated[...] and docstring Args sections

1 participant