@probelabs/probe 0.6.0-rc318 → 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.
- package/bin/binaries/{probe-v0.6.0-rc318-aarch64-apple-darwin.tar.gz → probe-v0.6.0-rc320-aarch64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc318-aarch64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc320-aarch64-unknown-linux-musl.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc318-x86_64-apple-darwin.tar.gz → probe-v0.6.0-rc320-x86_64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc318-x86_64-pc-windows-msvc.zip → probe-v0.6.0-rc320-x86_64-pc-windows-msvc.zip} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc318-x86_64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc320-x86_64-unknown-linux-musl.tar.gz} +0 -0
- package/build/agent/ProbeAgent.js +76 -3
- package/build/tools/vercel.js +7 -9
- package/cjs/agent/ProbeAgent.cjs +314 -309
- package/cjs/index.cjs +312 -308
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +76 -3
- package/src/tools/vercel.js +7 -9
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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
|
|
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
|
|
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,
|
package/build/tools/vercel.js
CHANGED
|
@@ -719,14 +719,12 @@ export const searchTool = (options = {}) => {
|
|
|
719
719
|
// ── Delegate-level semantic dedup ────────────────────────────
|
|
720
720
|
// Each delegate is a full flash agent session (minutes, not seconds).
|
|
721
721
|
// Use LLM to detect semantic duplicates and suggest rewrites.
|
|
722
|
-
// Compare against ALL previous delegations (not filtered by path) because
|
|
723
|
-
// the parent model often narrows the path while asking the same concept
|
|
724
|
-
// (e.g., "dedup" at /src → "deduplicate" at /src/search.js).
|
|
725
722
|
const delegatePath = searchPath || '';
|
|
723
|
+
const samePathDelegations = previousDelegations.filter(d => d.path === delegatePath);
|
|
726
724
|
|
|
727
725
|
let effectiveQuery = searchQuery;
|
|
728
726
|
|
|
729
|
-
if (
|
|
727
|
+
if (samePathDelegations.length > 0) {
|
|
730
728
|
const dedupProvider = options.searchDelegateProvider || process.env.PROBE_SEARCH_DELEGATE_PROVIDER || options.provider || process.env.FORCE_PROVIDER || null;
|
|
731
729
|
const dedupModelName = options.searchDelegateModel || process.env.PROBE_SEARCH_DELEGATE_MODEL || options.model || process.env.MODEL_NAME || null;
|
|
732
730
|
// Lazily create the dedup model (same provider/model as delegate)
|
|
@@ -742,8 +740,8 @@ export const searchTool = (options = {}) => {
|
|
|
742
740
|
|
|
743
741
|
const dedupSpanAttrs = {
|
|
744
742
|
'dedup.query': searchQuery,
|
|
745
|
-
'dedup.previous_count': String(
|
|
746
|
-
'dedup.previous_queries':
|
|
743
|
+
'dedup.previous_count': String(samePathDelegations.length),
|
|
744
|
+
'dedup.previous_queries': samePathDelegations.map(d => d.query).join(' | '),
|
|
747
745
|
'dedup.provider': dedupProvider || '',
|
|
748
746
|
'dedup.model': dedupModelName || '',
|
|
749
747
|
'dedup.model_available': cachedDedupModel ? 'true' : 'false',
|
|
@@ -751,7 +749,7 @@ export const searchTool = (options = {}) => {
|
|
|
751
749
|
|
|
752
750
|
const dedup = options.tracer?.withSpan
|
|
753
751
|
? await options.tracer.withSpan('search.delegate.dedup', async () => {
|
|
754
|
-
return await checkDelegateDedup(searchQuery,
|
|
752
|
+
return await checkDelegateDedup(searchQuery, samePathDelegations, cachedDedupModel, debug);
|
|
755
753
|
}, dedupSpanAttrs, (span, result) => {
|
|
756
754
|
span.setAttributes({
|
|
757
755
|
'dedup.action': result.action,
|
|
@@ -760,14 +758,14 @@ export const searchTool = (options = {}) => {
|
|
|
760
758
|
'dedup.error': result.error || '',
|
|
761
759
|
});
|
|
762
760
|
})
|
|
763
|
-
: await checkDelegateDedup(searchQuery,
|
|
761
|
+
: await checkDelegateDedup(searchQuery, samePathDelegations, cachedDedupModel, debug);
|
|
764
762
|
|
|
765
763
|
if (debug) {
|
|
766
764
|
console.error(`[DEDUP-LLM] Query: "${searchQuery}" → ${dedup.action}: ${dedup.reason}${dedup.rewritten ? ` → "${dedup.rewritten}"` : ''}`);
|
|
767
765
|
}
|
|
768
766
|
|
|
769
767
|
if (dedup.action === 'block') {
|
|
770
|
-
const prevQueries =
|
|
768
|
+
const prevQueries = samePathDelegations.map(d => `"${d.query}"`).join(', ');
|
|
771
769
|
return `DELEGATE BLOCKED: "${searchQuery}" is semantically duplicate of previous delegation(s) [${prevQueries}]. ${dedup.reason}\n\nDo NOT re-delegate the same concept. Use extract() on files already found, or synthesize your answer from existing results.`;
|
|
772
770
|
}
|
|
773
771
|
|