fix(omega): pass tool inputSchema to LLM for proper parameter generation

The search API wasn't returning inputSchema, so dynamic tools were created
with empty schemas. The LLM saw tools with no parameters and called them
with {}. Now the search API returns inputSchema, and if it's null in the
database, we fetch it from the executor's loadAndDescribe endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Thomas Davis 2026-02-10 01:38:12 +10:00
parent 5ac3beab37
commit 66fb7ef226
2 changed files with 52 additions and 2 deletions

View file

@ -203,6 +203,49 @@ async function searchRelevantTools(
}));
}
/**
* Fetch the tool's inputSchema from the executor's loadAndDescribe endpoint.
* This is used when the schema isn't available in the database yet.
*/
async function fetchSchemaFromExecutor(toolMeta: {
packageName: string;
name: string;
version: string;
importUrl: string;
}): Promise<unknown | null> {
try {
console.log(`📋 Fetching schema from executor for ${toolMeta.packageName}/${toolMeta.name}`);
const response = await fetch(`${EXECUTOR_URL}/load-and-describe`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
packageName: toolMeta.packageName,
name: toolMeta.name,
version: toolMeta.version,
importUrl: toolMeta.importUrl,
}),
});
if (!response.ok) {
console.warn(
`⚠️ Schema fetch failed (${response.status}) for ${toolMeta.packageName}/${toolMeta.name}`
);
return null;
}
// biome-ignore lint/suspicious/noExplicitAny: Executor response format varies
const result = (await response.json()) as any;
if (result.success && result.tool?.inputSchema) {
console.log(`✅ Got schema from executor for ${toolMeta.packageName}/${toolMeta.name}`);
return result.tool.inputSchema;
}
return null;
} catch (error) {
console.warn(`⚠️ Schema fetch error for ${toolMeta.packageName}/${toolMeta.name}:`, error);
return null;
}
}
/**
* Create a dynamic tool wrapper that executes via the sandbox executor
*/
@ -221,10 +264,16 @@ async function createDynamicTool(
// Import tool() dynamically to avoid top-level await
const { tool } = await import('ai');
// If inputSchema is missing from the database, fetch it from the executor
let schema = toolMeta.inputSchema;
if (!schema) {
schema = await fetchSchemaFromExecutor(toolMeta);
}
return tool({
description: toolMeta.description,
inputSchema: toolMeta.inputSchema
? jsonSchema(toolMeta.inputSchema as Parameters<typeof jsonSchema>[0])
inputSchema: schema
? jsonSchema(schema as Parameters<typeof jsonSchema>[0])
: jsonSchema({
type: 'object',
properties: {},

View file

@ -235,6 +235,7 @@ export async function GET(request: NextRequest) {
id: tool.id,
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
qualityScore: tool.qualityScore,
importHealth: tool.importHealth,
executionHealth: tool.executionHealth,