@probelabs/probe 0.6.0-rc319 → 0.6.0-rc320

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -147,6 +147,77 @@ export function debugLogToolResults(toolResults) {
147
147
  }
148
148
  }
149
149
 
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
+
150
221
  /**
151
222
  * ProbeAgent class to handle AI interactions with code search capabilities
152
223
  */
@@ -1888,7 +1959,8 @@ export class ProbeAgent {
1888
1959
  const wrapTool = (toolName, schema, description, executeFn) => {
1889
1960
  // Auto-wrap plain JSON Schema objects with jsonSchema() for AI SDK 5 compatibility
1890
1961
  // 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);
1892
1964
  return tool({
1893
1965
  description,
1894
1966
  inputSchema: resolvedSchema,
@@ -2090,8 +2162,9 @@ export class ProbeAgent {
2090
2162
  for (const [name, mcpTool] of Object.entries(mcpTools)) {
2091
2163
  // MCP tools have raw JSON Schema inputSchema that must be wrapped with jsonSchema()
2092
2164
  // 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);
2095
2168
  nativeTools[name] = tool({
2096
2169
  description: mcpTool.description || `MCP tool: ${name}`,
2097
2170
  inputSchema: wrappedSchema,