openzoo 0.48.67 → 0.48.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/anthropic.js +15 -1
  2. package/package.json +1 -1
package/lib/anthropic.js CHANGED
@@ -96,7 +96,21 @@ export function anthropicToOpenAI(body) {
96
96
  }));
97
97
  if (!out.tools.length) delete out.tools;
98
98
  }
99
- if (body.tool_choice?.type === 'auto') out.tool_choice = 'auto';
99
+ // TOOL_CHOICE MAY NOT OUTLIVE TOOLS.
100
+ //
101
+ // The block above DROPS any tool without a name+input_schema — which is every
102
+ // server-side tool (web_search, computer, bash), because those carry no schema
103
+ // in the Anthropic shape. When that empties the list, `out.tools` is deleted.
104
+ // But tool_choice was set unconditionally, so the body went upstream with a
105
+ // choice and nothing to choose from.
106
+ //
107
+ // OBSERVED on grok-4.6: a Claude Code Web Search 400'd with "A tool_choice was
108
+ // set on the request but no tools were specified." Every provider rejects this
109
+ // shape; it just words it differently. Gate the choice on tools surviving.
110
+ const hasTools = Array.isArray(out.tools) && out.tools.length > 0;
111
+ if (!hasTools) {
112
+ delete out.tool_choice;
113
+ } else if (body.tool_choice?.type === 'auto') out.tool_choice = 'auto';
100
114
  else if (body.tool_choice?.type === 'any') out.tool_choice = 'required';
101
115
  else if (body.tool_choice?.type === 'tool') {
102
116
  out.tool_choice = { type: 'function', function: { name: body.tool_choice.name } };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.48.67",
3
+ "version": "0.48.68",
4
4
  "description": "Local x402-paying proxy + MCP server for openzoo.fun — point any OpenAI-compatible harness (Cursor, Claude Code, aider, SDKs) at localhost and it pays per call from a local burner wallet. Solana and Base rails live; Robinhood experimental.",
5
5
  "license": "MIT",
6
6
  "type": "module",