Bug description
When agent.use_gateway_loop=true and the subagent model is a non-Anthropic
provider (e.g. DeepSeek, OpenRouter, any OpenAI-compatible recipe), the gateway
tool loop fails with:
[chat(deepseek:deepseek-v4-flash)] schema is not a function.
(In 'schema()', 'schema' is an instance of Object)
Root cause
In src/core/ai/gateway.ts, the chat() function passes tool schemas as raw
JSON Schema objects under the inputSchema key to the AI SDK's generateText():
// gateway.ts ~line 2360
const tools = (opts.tools ?? []).reduce((acc, t) => {
acc[t.name] = {
description: t.description,
inputSchema: { jsonSchema: t.inputSchema } as any,
};
return acc;
}, {} as Record<string, any>);
The Vercel AI SDK expects tools to use the parameters key with a
jsonSchema()-wrapped value (the jsonSchema helper from the ai package).
The inputSchema key is silently ignored for openai-compatible providers.
When the SDK resolves tool definitions, it attempts to call .schema() on
whatever lands under parameters — which is undefined since that key is
never set. This falls through to the inputSchema value (a plain Object),
and the .schema() call fails.
Scope of impact
This bug affects all non-Anthropic providers using the gateway tool loop
path (agent.use_gateway_loop=true). The default Anthropic-direct subagent
path is unaffected because it bypasses gateway.chat() entirely.
Affected versions: all releases that include agent.use_gateway_loop
support — introduced in the v0.38 series and present through current HEAD
(v0.41.14.0).
Reproduction
Prerequisites: a configured non-Anthropic chat model with API key set.
gbrain config set agent.use_gateway_loop true
# Create a transcript file >2000 chars
gbrain dream --phase synthesize --input <transcript>
Result: the significance judge phase completes, but the subagent job dies
with schema is not a function.
Fix
Import jsonSchema from the ai package and use the correct parameters
key with jsonSchema() wrapping:
-import { embed as aiEmbed, embedMany, generateObject, generateText } from 'ai';
+import { embed as aiEmbed, embedMany, generateObject, generateText, jsonSchema } from 'ai';
- inputSchema: { jsonSchema: t.inputSchema } as any,
+ parameters: jsonSchema(t.inputSchema),
Additional context
Discovered while running a Hermes multi-agent cluster with DeepSeek as the
primary LLM. A fix branch is available at
justemu/gbrain:fix/gateway-tool-json-schema for reference.
Bug description
When
agent.use_gateway_loop=trueand the subagent model is a non-Anthropicprovider (e.g. DeepSeek, OpenRouter, any OpenAI-compatible recipe), the gateway
tool loop fails with:
Root cause
In
src/core/ai/gateway.ts, thechat()function passes tool schemas as rawJSON Schema objects under the
inputSchemakey to the AI SDK'sgenerateText():The Vercel AI SDK expects tools to use the
parameterskey with ajsonSchema()-wrapped value (thejsonSchemahelper from theaipackage).The
inputSchemakey is silently ignored for openai-compatible providers.When the SDK resolves tool definitions, it attempts to call
.schema()onwhatever lands under
parameters— which isundefinedsince that key isnever set. This falls through to the
inputSchemavalue (a plain Object),and the
.schema()call fails.Scope of impact
This bug affects all non-Anthropic providers using the gateway tool loop
path (
agent.use_gateway_loop=true). The default Anthropic-direct subagentpath is unaffected because it bypasses
gateway.chat()entirely.Affected versions: all releases that include
agent.use_gateway_loopsupport — introduced in the v0.38 series and present through current HEAD
(v0.41.14.0).
Reproduction
Prerequisites: a configured non-Anthropic chat model with API key set.
Result: the significance judge phase completes, but the subagent job dies
with
schema is not a function.Fix
Import
jsonSchemafrom theaipackage and use the correctparameterskey with
jsonSchema()wrapping:Additional context
Discovered while running a Hermes multi-agent cluster with DeepSeek as the
primary LLM. A fix branch is available at
justemu/gbrain:fix/gateway-tool-json-schemafor reference.