feat(tools): enable strict mode for specific tools#2036
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c2c0f02eb6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| parameters=deref_json_schema( | ||
| self.params.model_json_schema(schema_generator=_GenerateJsonSchemaNoTitles) | ||
| ), | ||
| strict=strict, |
There was a problem hiding this comment.
Normalize schema before setting strict tool mode
This now passes strict=True for several CallableTool2 subclasses without converting the generated Pydantic schema into OpenAI strict-compatible form. model_json_schema() leaves optional/defaulted fields and omits additionalProperties: false, but strict tool mode requires a tighter schema shape; as a result, requests that include these tools can fail with API-side schema validation errors before any tool call runs. Please normalize the schema for strict tools (or gate strict until the schema is transformed) before sending strict.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
This PR introduces a strict flag on Kosong tool definitions and propagates it through multiple chat-provider adapters, then enables strict schema validation for a small set of core built-in tools in kimi_cli to reduce invalid tool calls.
Changes:
- Add
strict: bool = Falsetokosong.tooling.Tooland plumb it fromCallableTool2into provider tool payloads (OpenAI Chat Completions, OpenAI Responses, Anthropic). - Enable
strict = Truefor core built-in tools:Shell,ReadFile,Grep,WriteFile,StrReplaceFile,SetTodoList. - Update changelogs/release notes to document the change.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/kimi_cli/tools/todo/init.py | Enable strict mode for SetTodoList. |
| src/kimi_cli/tools/shell/init.py | Enable strict mode for Shell. |
| src/kimi_cli/tools/file/write.py | Enable strict mode for WriteFile. |
| src/kimi_cli/tools/file/replace.py | Enable strict mode for StrReplaceFile. |
| src/kimi_cli/tools/file/read.py | Enable strict mode for ReadFile. |
| src/kimi_cli/tools/file/grep_local.py | Enable strict mode for Grep. |
| packages/kosong/src/kosong/tooling/init.py | Add Tool.strict and propagate CallableTool2.strict into the base Tool definition. |
| packages/kosong/src/kosong/contrib/chat_provider/openai_responses.py | Emit tool.strict in OpenAI Responses tool conversion. |
| packages/kosong/src/kosong/contrib/chat_provider/anthropic.py | Emit tool.strict in Anthropic tool conversion. |
| packages/kosong/src/kosong/chat_provider/openai_common.py | Emit tool.strict in OpenAI Chat Completions tool conversion helper. |
| packages/kosong/CHANGELOG.md | Document new strict field propagation in Kosong. |
| docs/zh/release-notes/changelog.md | Document strict tool validation and Tool/CallableTool2 strict in release notes (ZH). |
| docs/en/release-notes/changelog.md | Document strict tool validation and Tool/CallableTool2 strict in release notes (EN). |
| CHANGELOG.md | Document strict tool validation and Tool/CallableTool2 strict at repo level. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| raise ValueError("Tool params must be a subclass of pydantic.BaseModel") | ||
|
|
||
| strict = getattr(cls, "strict", False) | ||
| if not isinstance(strict, bool): # type: ignore[reportUnnecessaryIsInstance] | ||
| strict = False | ||
|
|
||
| self._base = Tool( | ||
| name=self.name, | ||
| description=self.description, | ||
| parameters=deref_json_schema( | ||
| self.params.model_json_schema(schema_generator=_GenerateJsonSchemaNoTitles) | ||
| ), |
| def tool_to_openai(tool: Tool) -> ChatCompletionToolParam: | ||
| """Convert a single tool to OpenAI tool format.""" | ||
| # simply `model_dump` because the `Tool` type is OpenAI-compatible | ||
| return { | ||
| "type": "function", | ||
| "function": { | ||
| "name": tool.name, | ||
| "description": tool.description, | ||
| "parameters": tool.parameters, | ||
| "strict": tool.strict, | ||
| }, | ||
| } |
| def _convert_tool(tool: Tool) -> ToolParam: | ||
| return { | ||
| "name": tool.name, | ||
| "description": tool.description, | ||
| "input_schema": tool.parameters, | ||
| "strict": tool.strict, | ||
| } |
b75f00b to
a4124b6
Compare
a4124b6 to
b12cc23
Compare
OpenAI strict mode requires additionalProperties: false and all properties in required. Pydantic does not generate these by default. Previously, a generic make_openai_strict_schema was added to kosong's tooling layer. This is wrong because Anthropic's API validator rejects additionalProperties: false in tool schemas. Move the transform into the OpenAI-specific adapters (openai_common.py and openai_responses.py) using the official openai.lib._pydantic._ensure_strict_json_schema. Kimi and openai_legacy adapters automatically benefit since they reuse tool_to_openai().
Related Issue
N/A
Description
Enable OpenAI/Anthropic strict schema validation for a subset of core tools to improve reliability:
Shell(Bash/PowerShell)ReadFileGrepWriteFileStrReplaceFileSetTodoListChanges:
strict: bool = Falseto theToolbase model (kosong).CallableTool2to read thestrictclass attribute and pass it toTool.tool.strict.strict: bool = Trueto each of the 6 tool classes above.Other tools remain
strict=Falseby default.Checklist