anthropics / anthropics/anthropic-sdk-python
beta_tool generates a type: array input_schema and an uncallable tool for positional-only parameters (and *args)
- 主要語言
- Python
- 星號
- 3.9k
- 分支
- 853
- 平均合併
- 1 天 18 小時
- 30 天內合併 PR
- 11
描述
### Summary
`@beta_tool` / `@beta_async_tool` on a function with a positional-only parameter (`def f(a: int, /, b: str)`) produces an `input_schema` of `type: "array"` and a tool whose `.call()` can never succeed. A function with `*args` gets the same `type: "array"` schema. Nothing raises at decoration time.
### Reproduction
```python
import json
from anthropic import beta_tool
@beta_tool
def lookup(user_id: int, /, field: str = "name") -> str:
"""Look up a field on a user record."""
return f"{user_id}:{field}"
print(json.dumps(lookup.input_schema))
lookup.call({"user_id": 7, "field": "email"})
```
Output on `anthropic==1.3.0` (same code on current `main`, `src/anthropic/lib/tools/_beta_functions.py`):
```
{"maxItems": 2, "minItems": 1, "prefixItems": [{"title": "User Id", "type": "integer"}, {"default": "name", "title": "Field", "type": "string"}], "type": "array"}
ValueError: Invalid arguments for function lookup
(cause: 2 validation errors for lookup — missing_positional_only_argument / unexpected_keyword_argument)
```
`def collect(*values: int)` gives `{"items": {"type": "integer"}, "type": "array"}`.
### Why this is wrong
- `InputSchema` in this SDK is typed with `type: Required[Literal["object"]]` (`src/anthropic/types/tool_param.py`), and the API only accepts object schemas for `tools[].input_schema`. The generated `type: array` schema violates the SDK's own type and is sent to the API as-is.
- Even with a hand-written `input_schema=`, `BetaFunctionTool.call` does `self._func_with_validate(**input)`, so a positional-only parameter is always reported as `unexpected_keyword_argument` and the tool cannot be invoked by the tool runner.
- Positional-only plus keyword-only in the same signature already fails loudly (`PydanticInvalidForJsonSchema`), so only the all-positional-only / `*args` cases fail silently.
### Root cause
`_create_schema_from_function` delegates to pydantic's `GenerateJsonSchema.arguments_schema`, which renders the positional form (an array schema) whenever a signature has positional-only parameters or `*args`, and no keyword-only parameters. The docstring hook in `kw_arguments_schema` is never reached for those signatures. `call()` then forwards the input object purely by keyword.
### Proposed fix
Tool inputs are JSON objects passed by name, so:
- treat positional-only parameters as named properties when generating the schema, and have `call()` route those values back into positional slots (missing/extra values still go through `validate_call`);
- raise a `TypeError` at decoration time for `*args`, which a JSON object cannot represent.
I have a small patch with tests for this and will open a PR.
貢獻指南
評估
這個 Issue 還沒有評估資料。