* feat: use vercel ai gateway * fix: correct response handling * ci: add pipeline
67 lines
1.6 KiB
TypeScript
67 lines
1.6 KiB
TypeScript
import 'dotenv/config';
|
|
import { generateText, tool, jsonSchema } from 'ai';
|
|
import type { JSONSchema7 } from 'json-schema';
|
|
|
|
export interface BaseTool {
|
|
readonly name: string;
|
|
readonly input_schema: {
|
|
readonly type: 'object';
|
|
readonly properties: Record<string, unknown>;
|
|
readonly required?: readonly string[];
|
|
readonly description?: string;
|
|
};
|
|
}
|
|
|
|
export interface ToolUseBlock {
|
|
type: 'tool_use';
|
|
id: string;
|
|
name: string;
|
|
input: Record<string, unknown>;
|
|
}
|
|
|
|
export async function makeRequest<T extends BaseTool>(
|
|
prompt: string,
|
|
toolDef: T
|
|
): Promise<Record<string, unknown>> {
|
|
try {
|
|
const { steps } = await generateText({
|
|
model: 'anthropic/claude-sonnet-4.5',
|
|
temperature: 1,
|
|
tools: {
|
|
[toolDef.name]: tool({
|
|
description: toolDef.input_schema.description || '',
|
|
inputSchema: jsonSchema(toolDef.input_schema as JSONSchema7),
|
|
execute: async args => args
|
|
})
|
|
},
|
|
toolChoice: {
|
|
type: 'tool',
|
|
toolName: toolDef.name
|
|
},
|
|
prompt
|
|
});
|
|
|
|
const toolCalls = steps.flatMap(step => step.toolCalls);
|
|
|
|
if (!toolCalls || toolCalls.length === 0) {
|
|
throw new Error('No tool calls found in response');
|
|
}
|
|
|
|
const typedCall = toolCalls[0] as unknown as {
|
|
toolName: string;
|
|
input: Record<string, unknown>;
|
|
};
|
|
|
|
if (typedCall.toolName !== toolDef.name) {
|
|
throw new Error(
|
|
`Expected tool ${toolDef.name} but got ${typedCall.toolName}`
|
|
);
|
|
}
|
|
|
|
return typedCall.input;
|
|
} catch (error) {
|
|
console.error('Error making request:', error);
|
|
throw Error('Vercel AI Gateway client error.');
|
|
}
|
|
}
|