mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
test(ai): pin gateway tool schema conversion (#2063)
This commit is contained in:
+17
-15
@@ -2791,6 +2791,22 @@ async function classifyGatewayGuardrail(input: {
|
||||
}
|
||||
}
|
||||
|
||||
export function toAISDKTools(tools: ChatToolDef[] | undefined): Record<string, any> | undefined {
|
||||
if (!tools || tools.length === 0) return undefined;
|
||||
return tools.reduce((acc, t) => {
|
||||
acc[t.name] = {
|
||||
description: t.description,
|
||||
// AI SDK v6 requires a Schema (carrying the schema symbol), not a plain
|
||||
// `{jsonSchema}` object — the bare object makes asSchema() treat it as a
|
||||
// thunk and call schema(), throwing "schema is not a function". Wrap the
|
||||
// raw JSON Schema with the SDK's jsonSchema() helper so tool calls work
|
||||
// through the real toolLoop (skillopt rollouts + subagent jobs).
|
||||
inputSchema: jsonSchema(t.inputSchema as any),
|
||||
};
|
||||
return acc;
|
||||
}, {} as Record<string, any>);
|
||||
}
|
||||
|
||||
export async function chat(opts: ChatOpts): Promise<ChatResult> {
|
||||
const tracker = __budgetStore.getStore() ?? null;
|
||||
const modelStrEarly = opts.model ?? getChatModel();
|
||||
@@ -2878,21 +2894,7 @@ export async function chat(opts: ChatOpts): Promise<ChatResult> {
|
||||
const supportsCache = recipe.touchpoints.chat?.supports_prompt_cache === true;
|
||||
const useCache = !!opts.cacheSystem && supportsCache;
|
||||
|
||||
// Build messages. Anthropic prompt-cache markers ride on system + last tool
|
||||
// via providerOptions; the AI SDK accepts the system as a string for
|
||||
// generateText, so cache markers go through providerOptions.anthropic.
|
||||
const tools = (opts.tools ?? []).reduce((acc, t) => {
|
||||
acc[t.name] = {
|
||||
description: t.description,
|
||||
// AI SDK v6 requires a Schema (carrying the schema symbol), not a plain
|
||||
// `{jsonSchema}` object — the bare object makes asSchema() treat it as a
|
||||
// thunk and call schema(), throwing "schema is not a function". Wrap the
|
||||
// raw JSON Schema with the SDK's jsonSchema() helper so tool calls work
|
||||
// through the real toolLoop (skillopt rollouts + subagent jobs).
|
||||
inputSchema: jsonSchema(t.inputSchema as any),
|
||||
};
|
||||
return acc;
|
||||
}, {} as Record<string, any>);
|
||||
const tools = toAISDKTools(opts.tools);
|
||||
|
||||
const providerOptions: Record<string, any> = {};
|
||||
if (useCache) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, it } from 'bun:test';
|
||||
import { generateText, jsonSchema } from 'ai';
|
||||
import { MockLanguageModelV3 } from 'ai/test';
|
||||
import { toModelMessages, type ChatMessage } from '../../src/core/ai/gateway.ts';
|
||||
import { toAISDKTools, toModelMessages, type ChatMessage } from '../../src/core/ai/gateway.ts';
|
||||
|
||||
// v0.42 AI SDK v6 fix — the regression guard that the original bug evaded.
|
||||
// Every gateway/toolLoop test stubs the chat transport, which short-circuits
|
||||
@@ -36,13 +36,13 @@ const internalMessages: ChatMessage[] = [
|
||||
describe('gateway tool schema + message shape (real AI SDK v6)', () => {
|
||||
it('jsonSchema()-wrapped tools + adapted messages pass generateText without throwing', async () => {
|
||||
const model = mockModel();
|
||||
// Built exactly as gateway.chat() builds it (the primary fix).
|
||||
const tools = {
|
||||
search: {
|
||||
const tools = toAISDKTools([
|
||||
{
|
||||
name: 'search',
|
||||
description: 'search the brain',
|
||||
inputSchema: jsonSchema({ type: 'object', properties: { q: { type: 'string' } } } as any),
|
||||
inputSchema: { type: 'object', properties: { q: { type: 'string' } } },
|
||||
},
|
||||
};
|
||||
]);
|
||||
|
||||
const result = await generateText({
|
||||
model: model as any,
|
||||
|
||||
Reference in New Issue
Block a user