edwin-sdk
Version:
SDK for integrating AI agents with DeFi protocols
141 lines (117 loc) • 4.2 kB
text/typescript
import { z } from 'zod';
import { EdwinTool } from '../../core/types';
/**
* Base template for extracting tool parameters
*/
export const toolParametersTemplate = `
You are an AI assistant specialized in extracting specific information from user messages and format it into a structured JSON response. Your task is to extract specific information from user messages and format it into a structured JSON response. Return the JSON object only, nothing else.
First, review the recent messages from the conversation:
<recent_messages>
{{recentMessages}}
</recent_messages>
Your goal is to extract the following parameters:
{{schemaParameters}}
Provide the final output in JSON format:
\`\`\`json
{{schemaJson}}
\`\`\`
Remember to only return the JSON object, nothing else.
`;
/**
* Generates a tool parameters prompt from a tool and template
* @param tool - The EdwinTool containing the schema
* @returns The populated tool parameters prompt
*/
export function generateToolParametersPrompt(tool: EdwinTool): string {
const schema = tool.schema as z.ZodTypeAny;
// Generate parameter descriptions
const schemaParameters = generateParameterDescriptions(schema);
// Generate JSON template
const jsonTemplate = generateJsonTemplate(schema);
// Replace template placeholders
return toolParametersTemplate
.replace('{{schemaParameters}}', schemaParameters)
.replace('{{schemaJson}}', JSON.stringify(jsonTemplate, null, 2));
}
/**
* Generates parameter descriptions from a schema
*/
function generateParameterDescriptions(schema: z.ZodTypeAny): string {
// Only process object schemas
if (schema._def?.typeName !== 'ZodObject') {
return '';
}
const shape = schema._def.shape();
// Generate a description line for each parameter
const paramLines = Object.entries<z.ZodTypeAny>(shape).map(([key, value]) => {
const isOptional = value.isOptional?.() || false;
const description = value.description || 'No description provided';
const type = getTypeString(value);
return `- ${key}${isOptional ? ' (optional)' : ''}: ${description}. Type: ${type}`;
});
return paramLines.join('\n');
}
/**
* Generates a JSON template from a schema
*/
function generateJsonTemplate(schema: z.ZodTypeAny): Record<string, unknown> {
if (schema._def?.typeName !== 'ZodObject') {
return {};
}
const shape = schema._def.shape();
const template: Record<string, unknown> = {};
Object.entries<z.ZodTypeAny>(shape).forEach(([key, value]) => {
template[key] = getPlaceholderValue(value);
});
return template;
}
/**
* Gets a human-readable type name
*/
function getTypeString(schema: z.ZodTypeAny): string {
const typeName = schema._def?.typeName;
switch (typeName) {
case 'ZodOptional':
return getTypeString((schema as z.ZodOptional<z.ZodTypeAny>).unwrap());
case 'ZodString':
return 'string';
case 'ZodNumber':
return 'number';
case 'ZodBoolean':
return 'boolean';
case 'ZodArray':
return 'array';
case 'ZodObject':
return 'object';
default:
return 'unknown';
}
}
/**
* Creates an appropriate placeholder value for the JSON template
*/
function getPlaceholderValue(schema: z.ZodTypeAny): unknown {
const typeName = schema._def?.typeName;
switch (typeName) {
case 'ZodOptional':
return getPlaceholderValue((schema as z.ZodOptional<z.ZodTypeAny>).unwrap());
case 'ZodString':
return '<string>';
case 'ZodNumber':
return '<number>';
case 'ZodBoolean':
return '<true|false>';
case 'ZodArray':
return ['<items>'];
case 'ZodObject': {
const shape = schema._def.shape();
const result: Record<string, unknown> = {};
Object.entries<z.ZodTypeAny>(shape).forEach(([key, value]) => {
result[key] = getPlaceholderValue(value);
});
return result;
}
default:
return '<value>';
}
}