Skip to content

Commit 0add1f8

Browse files
committed
Fix tool definition generation for union schemas
1 parent da5c25e commit 0add1f8

2 files changed

Lines changed: 40 additions & 2 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { describe, expect, test } from 'bun:test'
2+
3+
import { compileToolDefinitions } from '../compile-tool-definitions'
4+
5+
describe('compileToolDefinitions', () => {
6+
test('emits type aliases for root union tool schemas', () => {
7+
const definitions = compileToolDefinitions()
8+
9+
expect(definitions).toContain('export type GravityIndexParams =')
10+
expect(definitions).not.toContain('export interface GravityIndexParams {')
11+
expect(definitions).toContain('"action": "search"')
12+
expect(definitions).toContain('"action": "report_integration"')
13+
})
14+
15+
test('keeps object tool schemas as interfaces', () => {
16+
const definitions = compileToolDefinitions()
17+
18+
expect(definitions).toContain('export interface WebSearchParams {')
19+
})
20+
})

common/src/tools/compile-tool-definitions.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,24 @@ export function compileToolDefinitions(): string {
1818

1919
// Convert Zod schema to TypeScript interface using JSON schema
2020
let typeDefinition: string
21+
let jsonSchema: unknown
2122
try {
22-
const jsonSchema = z.toJSONSchema(parameterSchema, { io: 'input' })
23+
jsonSchema = z.toJSONSchema(parameterSchema, { io: 'input' })
2324
typeDefinition = jsonSchemaToTypeScript(jsonSchema)
2425
} catch (error) {
2526
console.warn(`Failed to convert schema for ${toolName}:`, error)
2627
typeDefinition = '{ [key: string]: any }'
2728
}
2829

30+
const typeName = `${toPascalCase(toolName)}Params`
31+
const declaration = canEmitInterface(jsonSchema)
32+
? `export interface ${typeName} ${typeDefinition}`
33+
: `export type ${typeName} = ${typeDefinition}`
34+
2935
return `/**
3036
* ${parameterSchema.description || `Parameters for ${toolName} tool`}
3137
*/
32-
export interface ${toPascalCase(toolName)}Params ${typeDefinition}`
38+
${declaration}`
3339
})
3440
.join('\n\n')
3541

@@ -89,10 +95,22 @@ function jsonSchemaToTypeScript(schema: any): string {
8995
return getTypeFromJsonSchema(schema)
9096
}
9197

98+
function canEmitInterface(schema: any): boolean {
99+
return (
100+
schema.type === 'object' &&
101+
!!schema.properties &&
102+
!schema.anyOf &&
103+
!schema.oneOf
104+
)
105+
}
106+
92107
/**
93108
* Gets TypeScript type from JSON Schema property
94109
*/
95110
function getTypeFromJsonSchema(prop: any): string {
111+
if (prop.const !== undefined) {
112+
return JSON.stringify(prop.const)
113+
}
96114
if (prop.type === 'string') {
97115
if (prop.enum) {
98116
return prop.enum.map((v: string) => `"${v}"`).join(' | ')

0 commit comments

Comments
 (0)