@@ -147,6 +147,77 @@ export function debugLogToolResults(toolResults) {
147147 }
148148}
149149
150+ function isPlainJsonSchemaObject ( value ) {
151+ return value && typeof value === 'object' && ! Array . isArray ( value ) && ! value . _def ;
152+ }
153+
154+ function sanitizeRequiredFieldsInJsonSchema ( schema ) {
155+ if ( ! isPlainJsonSchemaObject ( schema ) ) {
156+ return ;
157+ }
158+
159+ if ( Array . isArray ( schema . required ) && isPlainJsonSchemaObject ( schema . properties ) ) {
160+ const propertyNames = new Set ( Object . keys ( schema . properties ) ) ;
161+ const filteredRequired = schema . required . filter ( ( name ) => propertyNames . has ( name ) ) ;
162+ if ( filteredRequired . length > 0 ) {
163+ schema . required = filteredRequired ;
164+ } else {
165+ delete schema . required ;
166+ }
167+ }
168+
169+ const visitSchemaMap = ( schemaMap ) => {
170+ if ( ! isPlainJsonSchemaObject ( schemaMap ) ) return ;
171+ for ( const childSchema of Object . values ( schemaMap ) ) {
172+ sanitizeRequiredFieldsInJsonSchema ( childSchema ) ;
173+ }
174+ } ;
175+
176+ visitSchemaMap ( schema . properties ) ;
177+ visitSchemaMap ( schema . patternProperties ) ;
178+ visitSchemaMap ( schema . definitions ) ;
179+ visitSchemaMap ( schema . $defs ) ;
180+ visitSchemaMap ( schema . dependentSchemas ) ;
181+
182+ if ( isPlainJsonSchemaObject ( schema . items ) ) {
183+ sanitizeRequiredFieldsInJsonSchema ( schema . items ) ;
184+ } else if ( Array . isArray ( schema . items ) ) {
185+ for ( const itemSchema of schema . items ) {
186+ sanitizeRequiredFieldsInJsonSchema ( itemSchema ) ;
187+ }
188+ }
189+
190+ for ( const keyword of [ 'allOf' , 'anyOf' , 'oneOf' ] ) {
191+ if ( Array . isArray ( schema [ keyword ] ) ) {
192+ for ( const childSchema of schema [ keyword ] ) {
193+ sanitizeRequiredFieldsInJsonSchema ( childSchema ) ;
194+ }
195+ }
196+ }
197+
198+ if ( isPlainJsonSchemaObject ( schema . not ) ) {
199+ sanitizeRequiredFieldsInJsonSchema ( schema . not ) ;
200+ }
201+
202+ if ( isPlainJsonSchemaObject ( schema . additionalProperties ) ) {
203+ sanitizeRequiredFieldsInJsonSchema ( schema . additionalProperties ) ;
204+ }
205+ }
206+
207+ export function sanitizeToolInputSchema ( schema ) {
208+ if ( ! isPlainJsonSchemaObject ( schema ) ) {
209+ return schema ;
210+ }
211+
212+ try {
213+ const clonedSchema = JSON . parse ( JSON . stringify ( schema ) ) ;
214+ sanitizeRequiredFieldsInJsonSchema ( clonedSchema ) ;
215+ return clonedSchema ;
216+ } catch {
217+ return schema ;
218+ }
219+ }
220+
150221/**
151222 * ProbeAgent class to handle AI interactions with code search capabilities
152223 */
@@ -1888,7 +1959,8 @@ export class ProbeAgent {
18881959 const wrapTool = ( toolName , schema , description , executeFn ) => {
18891960 // Auto-wrap plain JSON Schema objects with jsonSchema() for AI SDK 5 compatibility
18901961 // Zod schemas have a _def property; plain objects need wrapping
1891- const resolvedSchema = schema && schema . _def ? schema : jsonSchema ( schema ) ;
1962+ const sanitizedSchema = sanitizeToolInputSchema ( schema ) ;
1963+ const resolvedSchema = sanitizedSchema && sanitizedSchema . _def ? sanitizedSchema : jsonSchema ( sanitizedSchema ) ;
18921964 return tool ( {
18931965 description,
18941966 inputSchema : resolvedSchema ,
@@ -2090,8 +2162,9 @@ export class ProbeAgent {
20902162 for ( const [ name , mcpTool ] of Object . entries ( mcpTools ) ) {
20912163 // MCP tools have raw JSON Schema inputSchema that must be wrapped with jsonSchema()
20922164 // for the Vercel AI SDK. Without wrapping, asSchema() misidentifies them as Zod schemas.
2093- const mcpSchema = mcpTool . inputSchema || mcpTool . parameters ;
2094- const wrappedSchema = mcpSchema && mcpSchema . _def ? mcpSchema : jsonSchema ( mcpSchema || { type : 'object' , properties : { } } ) ;
2165+ const mcpSchema = mcpTool . inputSchema || mcpTool . parameters || { type : 'object' , properties : { } } ;
2166+ const sanitizedSchema = sanitizeToolInputSchema ( mcpSchema ) ;
2167+ const wrappedSchema = sanitizedSchema && sanitizedSchema . _def ? sanitizedSchema : jsonSchema ( sanitizedSchema ) ;
20952168 nativeTools [ name ] = tool ( {
20962169 description : mcpTool . description || `MCP tool: ${ name } ` ,
20972170 inputSchema : wrappedSchema ,
0 commit comments