@modelprofile.com/flexharness 10.12.0 → 10.14.0
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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.codesandbox.d.ts +39 -0
- package/dist_ts/classes.codesandbox.js +539 -0
- package/dist_ts/classes.flexharness.d.ts +17 -0
- package/dist_ts/classes.flexharness.js +222 -8
- package/dist_ts/classes.toolcatalog.d.ts +90 -0
- package/dist_ts/classes.toolcatalog.js +1398 -0
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +2 -1
- package/dist_ts/interfaces.d.ts +237 -3
- package/dist_ts/interfaces.js +50 -1
- package/dist_ts/plugins.d.ts +66 -1
- package/dist_ts/plugins.js +19 -1
- package/dist_ts/utils.harnessoptions.d.ts +7 -1
- package/dist_ts/utils.harnessoptions.js +48 -2
- package/dist_ts/utils.json.js +3 -1
- package/dist_ts/utils.schemadeclarations.d.ts +53 -0
- package/dist_ts/utils.schemadeclarations.js +315 -0
- package/dist_ts/utils.tooloutput.d.ts +2 -0
- package/dist_ts/utils.tooloutput.js +11 -1
- package/dist_ts_compaction/plugins.d.ts +3 -3
- package/dist_ts_compaction/plugins.js +3 -3
- package/dist_ts_compaction/smartagent.compaction.d.ts +10 -1
- package/dist_ts_compaction/smartagent.compaction.js +79 -38
- package/package.json +17 -4
- package/readme.md +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.codesandbox.ts +565 -0
- package/ts/classes.flexharness.ts +242 -7
- package/ts/classes.toolcatalog.ts +1512 -0
- package/ts/index.ts +1 -0
- package/ts/interfaces.ts +285 -3
- package/ts/plugins.ts +86 -0
- package/ts/readme.md +1 -1
- package/ts/utils.harnessoptions.ts +55 -0
- package/ts/utils.json.ts +2 -0
- package/ts/utils.schemadeclarations.ts +322 -0
- package/ts/utils.tooloutput.ts +9 -0
- package/ts_compaction/plugins.ts +3 -3
- package/ts_compaction/smartagent.compaction.ts +90 -34
|
@@ -0,0 +1,1398 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { FlexHarnessValidationError } from './errors.js';
|
|
3
|
+
import { FLEX_CODE_MODE_TOOL_NAME, FLEX_TOOL_CATALOG_LIMITS as limits, FLEX_TOOL_CATALOG_TOOL_NAMES as toolNames, } from './interfaces.js';
|
|
4
|
+
import { SchemaDeclarationWriter, countOf, docBlock, indentLines, isIdentifier, isSchemaRecord, } from './utils.schemadeclarations.js';
|
|
5
|
+
import { normalizeToolCatalogOptions } from './utils.harnessoptions.js';
|
|
6
|
+
import { validateUtf8String } from './utils.validation.js';
|
|
7
|
+
const aiSchemaSymbol = Symbol.for('vercel.ai.schema');
|
|
8
|
+
const methodPathPattern = /^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;
|
|
9
|
+
const typeNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
10
|
+
/** Words a declaration cannot use as a function, namespace or type name. */
|
|
11
|
+
const reservedWords = new Set([
|
|
12
|
+
'await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do',
|
|
13
|
+
'else', 'enum', 'export', 'extends', 'false', 'finally', 'for', 'function', 'if', 'implements', 'import',
|
|
14
|
+
'in', 'instanceof', 'interface', 'let', 'new', 'null', 'package', 'private', 'protected', 'public',
|
|
15
|
+
'return', 'static', 'super', 'switch', 'this', 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while',
|
|
16
|
+
'with', 'yield',
|
|
17
|
+
]);
|
|
18
|
+
const controlPattern = /[\u0000-\u001f\u007f]/;
|
|
19
|
+
const definitionRefPattern = /^#\/(\$defs|definitions)\/([^/]+)$/;
|
|
20
|
+
const declaredTypesHeader = '// Declares types: ';
|
|
21
|
+
const identifierScanPattern = /[A-Za-z_$][A-Za-z0-9_$]*/g;
|
|
22
|
+
const methodKeys = new Set([
|
|
23
|
+
'method', 'summary', 'description', 'tags', 'examples', 'inputSchema', 'outputSchema', 'declaration', 'run', 'onCall',
|
|
24
|
+
]);
|
|
25
|
+
const catalogKeys = new Set(['methods', 'types', 'onProposals']);
|
|
26
|
+
const typeKeys = new Set(['name', 'description', 'schema', 'declaration']);
|
|
27
|
+
const stopWords = new Set([
|
|
28
|
+
'a', 'an', 'and', 'are', 'all', 'as', 'be', 'by', 'for', 'from', 'get', 'i', 'in', 'is', 'it', 'me', 'my',
|
|
29
|
+
'of', 'on', 'or', 'that', 'the', 'this', 'to', 'with',
|
|
30
|
+
]);
|
|
31
|
+
const fieldWeights = { name: 3, namespace: 1.5, summary: 2, tags: 2, description: 1 };
|
|
32
|
+
const bm25K1 = 1.2;
|
|
33
|
+
const bm25B = 0.75;
|
|
34
|
+
const coreCache = new WeakMap();
|
|
35
|
+
const isPlainObject = (value) => typeof value === 'object'
|
|
36
|
+
&& value !== null
|
|
37
|
+
&& !Array.isArray(value)
|
|
38
|
+
&& [Object.prototype, null].includes(Object.getPrototypeOf(value));
|
|
39
|
+
const compareCodePoints = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
40
|
+
const stableStringify = (value) => {
|
|
41
|
+
if (Array.isArray(value))
|
|
42
|
+
return `[${value.map(stableStringify).join(',')}]`;
|
|
43
|
+
if (isSchemaRecord(value)) {
|
|
44
|
+
return `{${Object.keys(value).sort(compareCodePoints)
|
|
45
|
+
.map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`).join(',')}}`;
|
|
46
|
+
}
|
|
47
|
+
return JSON.stringify(value) ?? 'null';
|
|
48
|
+
};
|
|
49
|
+
const deepFreeze = (value) => {
|
|
50
|
+
if (typeof value === 'object' && value !== null && !Object.isFrozen(value)) {
|
|
51
|
+
Object.freeze(value);
|
|
52
|
+
for (const child of Object.values(value))
|
|
53
|
+
deepFreeze(child);
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
};
|
|
57
|
+
const decodePointerToken = (token) => {
|
|
58
|
+
let decoded = token;
|
|
59
|
+
try {
|
|
60
|
+
decoded = decodeURI(token);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
decoded = token;
|
|
64
|
+
}
|
|
65
|
+
return decoded.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
66
|
+
};
|
|
67
|
+
const pointerTokens = (pointer) => pointer.replace(/^#/, '').split('/').slice(1).map(decodePointerToken);
|
|
68
|
+
/** Resolves a local JSON pointer against `root`, following `$ref` tokens of keyword locations. */
|
|
69
|
+
const resolvePointer = (root, pointer) => {
|
|
70
|
+
let node = root;
|
|
71
|
+
for (const token of pointerTokens(pointer)) {
|
|
72
|
+
if (token === '$ref' && isSchemaRecord(node) && typeof node.$ref === 'string') {
|
|
73
|
+
node = node.$ref.startsWith('#') ? resolvePointer(root, node.$ref) : undefined;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (Array.isArray(node))
|
|
77
|
+
node = node[Number(token)];
|
|
78
|
+
else if (isSchemaRecord(node))
|
|
79
|
+
node = Object.prototype.hasOwnProperty.call(node, token) ? node[token] : undefined;
|
|
80
|
+
else
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
return node;
|
|
84
|
+
};
|
|
85
|
+
const collectRefs = (node, refs) => {
|
|
86
|
+
if (Array.isArray(node)) {
|
|
87
|
+
for (const child of node)
|
|
88
|
+
collectRefs(child, refs);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (!isSchemaRecord(node))
|
|
92
|
+
return;
|
|
93
|
+
for (const [key, child] of Object.entries(node)) {
|
|
94
|
+
if (key === '$ref' && typeof child === 'string')
|
|
95
|
+
refs.add(child);
|
|
96
|
+
else if (key !== 'const' && key !== 'enum' && key !== 'default' && key !== 'examples')
|
|
97
|
+
collectRefs(child, refs);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const schemaDraft = (root) => {
|
|
101
|
+
const declared = isSchemaRecord(root) && typeof root.$schema === 'string' ? root.$schema : '';
|
|
102
|
+
if (declared.includes('draft-04'))
|
|
103
|
+
return '4';
|
|
104
|
+
if (declared.includes('draft-06') || declared.includes('draft-07'))
|
|
105
|
+
return '7';
|
|
106
|
+
if (declared.includes('2019-09'))
|
|
107
|
+
return '2019-09';
|
|
108
|
+
return '2020-12';
|
|
109
|
+
};
|
|
110
|
+
const withoutDraft = (schema) => {
|
|
111
|
+
if (!isSchemaRecord(schema) || schema.$schema === undefined)
|
|
112
|
+
return schema;
|
|
113
|
+
const { $schema: _draft, ...rest } = schema;
|
|
114
|
+
return rest;
|
|
115
|
+
};
|
|
116
|
+
const stem = (word) => {
|
|
117
|
+
if (word.length > 4 && word.endsWith('ies'))
|
|
118
|
+
return `${word.slice(0, -3)}y`;
|
|
119
|
+
if (word.length > 3 && word.endsWith('s') && !word.endsWith('ss'))
|
|
120
|
+
return word.slice(0, -1);
|
|
121
|
+
return word;
|
|
122
|
+
};
|
|
123
|
+
const searchTerms = (text) => text
|
|
124
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
125
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
|
|
126
|
+
.toLowerCase()
|
|
127
|
+
.split(/[^\p{L}\p{N}]+/u)
|
|
128
|
+
.filter(Boolean)
|
|
129
|
+
.map(stem);
|
|
130
|
+
const editDistance = (left, right, limit) => {
|
|
131
|
+
if (Math.abs(left.length - right.length) > limit)
|
|
132
|
+
return limit + 1;
|
|
133
|
+
let previous = Array.from({ length: right.length + 1 }, (_, index) => index);
|
|
134
|
+
for (let row = 1; row <= left.length; row++) {
|
|
135
|
+
const current = [row];
|
|
136
|
+
let best = row;
|
|
137
|
+
for (let column = 1; column <= right.length; column++) {
|
|
138
|
+
const cost = left[row - 1] === right[column - 1] ? 0 : 1;
|
|
139
|
+
current[column] = Math.min(previous[column] + 1, current[column - 1] + 1, previous[column - 1] + cost);
|
|
140
|
+
best = Math.min(best, current[column]);
|
|
141
|
+
}
|
|
142
|
+
if (best > limit)
|
|
143
|
+
return limit + 1;
|
|
144
|
+
previous = current;
|
|
145
|
+
}
|
|
146
|
+
return previous[right.length];
|
|
147
|
+
};
|
|
148
|
+
const closeMatches = (wanted, candidates, count = 3) => {
|
|
149
|
+
const normalized = wanted.toLowerCase();
|
|
150
|
+
const limit = Math.max(2, Math.floor(normalized.length / 3));
|
|
151
|
+
const scored = [];
|
|
152
|
+
for (const candidate of candidates) {
|
|
153
|
+
const lower = candidate.toLowerCase();
|
|
154
|
+
const lastSegment = lower.slice(lower.lastIndexOf('.') + 1);
|
|
155
|
+
const distance = Math.min(editDistance(normalized, lower, limit), lower.includes(normalized) || normalized.includes(lastSegment) ? 1 : limit + 1);
|
|
156
|
+
if (distance <= limit)
|
|
157
|
+
scored.push({ name: candidate, distance });
|
|
158
|
+
}
|
|
159
|
+
return scored
|
|
160
|
+
.sort((left, right) => left.distance - right.distance || compareCodePoints(left.name, right.name))
|
|
161
|
+
.slice(0, count)
|
|
162
|
+
.map((entry) => entry.name);
|
|
163
|
+
};
|
|
164
|
+
const preview = (value) => {
|
|
165
|
+
if (value === undefined)
|
|
166
|
+
return 'missing';
|
|
167
|
+
let text;
|
|
168
|
+
try {
|
|
169
|
+
text = JSON.stringify(value) ?? String(value);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
text = String(value);
|
|
173
|
+
}
|
|
174
|
+
return text.length > 80 ? `${text.slice(0, 77)}...` : text;
|
|
175
|
+
};
|
|
176
|
+
const paramsPath = (tokens) => tokens.reduce((path, token) => {
|
|
177
|
+
if (typeof token === 'number' || /^\d+$/.test(token))
|
|
178
|
+
return `${path}[${token}]`;
|
|
179
|
+
return isIdentifier(token) ? `${path}.${token}` : `${path}[${JSON.stringify(token)}]`;
|
|
180
|
+
}, 'params');
|
|
181
|
+
const valueAt = (value, tokens) => {
|
|
182
|
+
let node = value;
|
|
183
|
+
for (const token of tokens) {
|
|
184
|
+
if (Array.isArray(node))
|
|
185
|
+
node = node[Number(token)];
|
|
186
|
+
else if (isSchemaRecord(node))
|
|
187
|
+
node = Object.prototype.hasOwnProperty.call(node, token) ? node[String(token)] : undefined;
|
|
188
|
+
else
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
return node;
|
|
192
|
+
};
|
|
193
|
+
const compactType = (text) => {
|
|
194
|
+
const compact = text.replace(/\/\*\*[\s\S]*?\*\//g, '').replace(/\s+/g, ' ').trim();
|
|
195
|
+
return compact.length > 200 ? `${compact.slice(0, 197)}...` : compact;
|
|
196
|
+
};
|
|
197
|
+
const textOf = (value, label, options) => {
|
|
198
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
199
|
+
throw new FlexHarnessValidationError(`${label} must be a non-empty string.`);
|
|
200
|
+
}
|
|
201
|
+
if (options.maxBytes !== undefined)
|
|
202
|
+
validateUtf8String(value, label, options.maxBytes, true);
|
|
203
|
+
if (options.maxCharacters !== undefined && [...value].length > options.maxCharacters) {
|
|
204
|
+
throw new FlexHarnessValidationError(`${label} must be at most ${options.maxCharacters} characters.`);
|
|
205
|
+
}
|
|
206
|
+
if (options.singleLine && controlPattern.test(value)) {
|
|
207
|
+
throw new FlexHarnessValidationError(`${label} must be one line without control characters.`);
|
|
208
|
+
}
|
|
209
|
+
return value;
|
|
210
|
+
};
|
|
211
|
+
const textListOf = (value, label, maxItems, options) => {
|
|
212
|
+
if (value === undefined)
|
|
213
|
+
return [];
|
|
214
|
+
if (!Array.isArray(value) || value.length > maxItems) {
|
|
215
|
+
throw new FlexHarnessValidationError(`${label} must be an array with at most ${maxItems} entries.`);
|
|
216
|
+
}
|
|
217
|
+
return value.map((entry, index) => textOf(entry, `${label}[${index}]`, options));
|
|
218
|
+
};
|
|
219
|
+
async function resolveCatalogSchema(schema, label) {
|
|
220
|
+
let json;
|
|
221
|
+
let validate;
|
|
222
|
+
if (typeof schema === 'function'
|
|
223
|
+
|| (isSchemaRecord(schema) && (aiSchemaSymbol in schema || '~standard' in schema))) {
|
|
224
|
+
let resolved;
|
|
225
|
+
try {
|
|
226
|
+
resolved = plugins.asSchema(schema);
|
|
227
|
+
json = await resolved.jsonSchema;
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
throw new FlexHarnessValidationError(`${label} cannot be converted to JSON Schema.`, { cause: error });
|
|
231
|
+
}
|
|
232
|
+
if (resolved.validate) {
|
|
233
|
+
const validator = resolved.validate;
|
|
234
|
+
validate = (value) => validator(value);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else if (isPlainObject(schema) || typeof schema === 'boolean') {
|
|
238
|
+
json = schema;
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
throw new FlexHarnessValidationError(`${label} must be a JSON Schema object, or a zod, Standard Schema or AI SDK schema.`);
|
|
242
|
+
}
|
|
243
|
+
let copy;
|
|
244
|
+
try {
|
|
245
|
+
copy = structuredClone(json);
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
throw new FlexHarnessValidationError(`${label} must be plain JSON.`, { cause: error });
|
|
249
|
+
}
|
|
250
|
+
if (!isSchemaRecord(copy) && typeof copy !== 'boolean') {
|
|
251
|
+
throw new FlexHarnessValidationError(`${label} must be a JSON Schema object.`);
|
|
252
|
+
}
|
|
253
|
+
validateUtf8String(JSON.stringify(copy), label, limits.maxSchemaBytes, true);
|
|
254
|
+
return { json: deepFreeze(copy), ...(validate ? { validate } : {}) };
|
|
255
|
+
}
|
|
256
|
+
class CatalogSearchIndex {
|
|
257
|
+
entries;
|
|
258
|
+
postings = new Map();
|
|
259
|
+
idf = new Map();
|
|
260
|
+
constructor(entries) {
|
|
261
|
+
this.entries = entries;
|
|
262
|
+
const fieldTexts = (entry) => ({
|
|
263
|
+
name: searchTerms(entry.name),
|
|
264
|
+
namespace: searchTerms(entry.namespace),
|
|
265
|
+
summary: searchTerms(entry.summary),
|
|
266
|
+
tags: entry.tags.flatMap(searchTerms),
|
|
267
|
+
description: searchTerms(entry.description ?? ''),
|
|
268
|
+
});
|
|
269
|
+
const documents = entries.map(fieldTexts);
|
|
270
|
+
const fields = Object.keys(fieldWeights);
|
|
271
|
+
const averageLength = Object.fromEntries(fields.map((field) => [
|
|
272
|
+
field,
|
|
273
|
+
Math.max(1, documents.reduce((sum, document) => sum + document[field].length, 0) / Math.max(1, documents.length)),
|
|
274
|
+
]));
|
|
275
|
+
const documentFrequency = new Map();
|
|
276
|
+
documents.forEach((document, index) => {
|
|
277
|
+
const weights = new Map();
|
|
278
|
+
for (const field of fields) {
|
|
279
|
+
const frequencies = new Map();
|
|
280
|
+
for (const term of document[field])
|
|
281
|
+
frequencies.set(term, (frequencies.get(term) ?? 0) + 1);
|
|
282
|
+
const norm = 1 - bm25B + bm25B * (document[field].length / averageLength[field]);
|
|
283
|
+
for (const [term, frequency] of frequencies) {
|
|
284
|
+
weights.set(term, (weights.get(term) ?? 0) + fieldWeights[field] * frequency / norm);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
for (const [term, weight] of weights) {
|
|
288
|
+
documentFrequency.set(term, (documentFrequency.get(term) ?? 0) + 1);
|
|
289
|
+
const postings = this.postings.get(term) ?? [];
|
|
290
|
+
postings.push({ index, weight });
|
|
291
|
+
this.postings.set(term, postings);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
for (const [term, frequency] of documentFrequency) {
|
|
295
|
+
this.idf.set(term, Math.log(1 + (entries.length - frequency + 0.5) / (frequency + 0.5)));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/** Methods ranked by BM25 over name, namespace, summary, tags and description. */
|
|
299
|
+
search(query, accept) {
|
|
300
|
+
const allTerms = [...new Set(searchTerms(query))];
|
|
301
|
+
const meaningful = allTerms.filter((term) => !stopWords.has(term));
|
|
302
|
+
const terms = meaningful.length > 0 ? meaningful : allTerms;
|
|
303
|
+
const scores = new Map();
|
|
304
|
+
for (const term of terms) {
|
|
305
|
+
const idf = this.idf.get(term);
|
|
306
|
+
if (idf === undefined)
|
|
307
|
+
continue;
|
|
308
|
+
for (const { index, weight } of this.postings.get(term)) {
|
|
309
|
+
scores.set(index, (scores.get(index) ?? 0) + idf * weight * (bm25K1 + 1) / (weight + bm25K1));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const exact = query.trim().toLowerCase();
|
|
313
|
+
return [...scores.entries()]
|
|
314
|
+
.map(([index, score]) => {
|
|
315
|
+
const entry = this.entries[index];
|
|
316
|
+
const bonus = entry.path.toLowerCase() === exact || entry.name.toLowerCase() === exact ? 1000 : 0;
|
|
317
|
+
return { entry, score: score + bonus };
|
|
318
|
+
})
|
|
319
|
+
.filter(({ entry }) => accept(entry))
|
|
320
|
+
.sort((left, right) => right.score - left.score || compareCodePoints(left.entry.path, right.entry.path))
|
|
321
|
+
.map(({ entry }) => entry);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
class FlexToolCatalogCore {
|
|
325
|
+
mode;
|
|
326
|
+
methods;
|
|
327
|
+
types;
|
|
328
|
+
onProposals;
|
|
329
|
+
renderedMethods = new Map();
|
|
330
|
+
renderedTypes = new Map();
|
|
331
|
+
validators = new Map();
|
|
332
|
+
selfContainedInputs = new Map();
|
|
333
|
+
index;
|
|
334
|
+
constructor(mode, methods, types, onProposals) {
|
|
335
|
+
this.mode = mode;
|
|
336
|
+
this.methods = methods;
|
|
337
|
+
this.types = types;
|
|
338
|
+
this.onProposals = onProposals;
|
|
339
|
+
this.index = new CatalogSearchIndex([...methods.values()]);
|
|
340
|
+
}
|
|
341
|
+
static async build(catalog, mode) {
|
|
342
|
+
if (!isPlainObject(catalog))
|
|
343
|
+
throw new FlexHarnessValidationError('A tool catalog must be a plain object.');
|
|
344
|
+
const unsupported = Object.keys(catalog).find((key) => !catalogKeys.has(key));
|
|
345
|
+
if (unsupported)
|
|
346
|
+
throw new FlexHarnessValidationError(`A tool catalog does not support "${unsupported}".`);
|
|
347
|
+
const onProposals = catalog.onProposals;
|
|
348
|
+
if (onProposals !== undefined && typeof onProposals !== 'function') {
|
|
349
|
+
throw new FlexHarnessValidationError('A tool catalog onProposals must be a function.');
|
|
350
|
+
}
|
|
351
|
+
if (!Array.isArray(catalog.methods) || catalog.methods.length > limits.maxMethods) {
|
|
352
|
+
throw new FlexHarnessValidationError(`Tool catalog methods must be an array with at most ${limits.maxMethods} entries.`);
|
|
353
|
+
}
|
|
354
|
+
if (catalog.types !== undefined && (!Array.isArray(catalog.types) || catalog.types.length > limits.maxTypes)) {
|
|
355
|
+
throw new FlexHarnessValidationError(`Tool catalog types must be an array with at most ${limits.maxTypes} entries.`);
|
|
356
|
+
}
|
|
357
|
+
const catalogTypes = new Map();
|
|
358
|
+
for (const [index, type] of (catalog.types ?? []).entries()) {
|
|
359
|
+
const entry = await FlexToolCatalogCore.normalizeType(type, `Tool catalog type ${index}`);
|
|
360
|
+
if (catalogTypes.has(entry.name)) {
|
|
361
|
+
throw new FlexHarnessValidationError(`Tool catalog type "${entry.name}" is defined twice.`);
|
|
362
|
+
}
|
|
363
|
+
catalogTypes.set(entry.name, entry);
|
|
364
|
+
}
|
|
365
|
+
const methodInputs = [];
|
|
366
|
+
for (const [index, method] of catalog.methods.entries()) {
|
|
367
|
+
methodInputs.push(await FlexToolCatalogCore.normalizeMethod(method, `Tool catalog method ${index}`));
|
|
368
|
+
}
|
|
369
|
+
methodInputs.sort((left, right) => compareCodePoints(left.path, right.path));
|
|
370
|
+
const paths = new Set();
|
|
371
|
+
for (const method of methodInputs) {
|
|
372
|
+
if (paths.has(method.path))
|
|
373
|
+
throw new FlexHarnessValidationError(`Tool catalog method "${method.path}" is defined twice.`);
|
|
374
|
+
paths.add(method.path);
|
|
375
|
+
}
|
|
376
|
+
for (const method of methodInputs) {
|
|
377
|
+
for (let end = method.path.indexOf('.'); end !== -1; end = method.path.indexOf('.', end + 1)) {
|
|
378
|
+
const namespace = method.path.slice(0, end);
|
|
379
|
+
if (paths.has(namespace)) {
|
|
380
|
+
throw new FlexHarnessValidationError(`Tool catalog path "${namespace}" is both a method and a namespace.`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
const registry = new Map(catalogTypes);
|
|
385
|
+
const canonicalDefinitions = new Map();
|
|
386
|
+
const scopeOf = (root, label, requireSchemas) => {
|
|
387
|
+
const scope = { root, localNames: new Map() };
|
|
388
|
+
FlexToolCatalogCore.checkRefs(root, label, catalogTypes, requireSchemas);
|
|
389
|
+
if (!isSchemaRecord(root))
|
|
390
|
+
return scope;
|
|
391
|
+
for (const container of ['$defs', 'definitions']) {
|
|
392
|
+
const definitions = root[container];
|
|
393
|
+
if (!isSchemaRecord(definitions))
|
|
394
|
+
continue;
|
|
395
|
+
for (const key of Object.keys(definitions).sort(compareCodePoints)) {
|
|
396
|
+
if (!typeNamePattern.test(key) || reservedWords.has(key) || key.length > limits.maxIdentifierCharacters)
|
|
397
|
+
continue;
|
|
398
|
+
const definition = definitions[key];
|
|
399
|
+
const canonical = stableStringify(definition);
|
|
400
|
+
let name = key;
|
|
401
|
+
for (let suffix = 2;; suffix++) {
|
|
402
|
+
const existing = registry.get(name);
|
|
403
|
+
if (!existing) {
|
|
404
|
+
registry.set(name, { name, definition, scope });
|
|
405
|
+
canonicalDefinitions.set(name, canonical);
|
|
406
|
+
break;
|
|
407
|
+
}
|
|
408
|
+
if (existing.definition === undefined || canonicalDefinitions.get(name) === canonical)
|
|
409
|
+
break;
|
|
410
|
+
name = `${key}_${suffix}`;
|
|
411
|
+
}
|
|
412
|
+
scope.localNames.set(`${container}/${key}`, name);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return scope;
|
|
416
|
+
};
|
|
417
|
+
for (const type of catalogTypes.values()) {
|
|
418
|
+
if (!type.schema)
|
|
419
|
+
continue;
|
|
420
|
+
registry.set(type.name, { ...type, scope: scopeOf(type.schema.json, `Tool catalog type "${type.name}"`, true) });
|
|
421
|
+
}
|
|
422
|
+
const methods = new Map();
|
|
423
|
+
for (const method of methodInputs) {
|
|
424
|
+
methods.set(method.path, {
|
|
425
|
+
...method,
|
|
426
|
+
inputScope: scopeOf(method.input.json, `Tool catalog method "${method.path}" inputSchema`, true),
|
|
427
|
+
...(method.output
|
|
428
|
+
? { outputScope: scopeOf(method.output.json, `Tool catalog method "${method.path}" outputSchema`, false) }
|
|
429
|
+
: {}),
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
const types = new Map([...registry.entries()].sort(([left], [right]) => compareCodePoints(left, right)));
|
|
433
|
+
return new FlexToolCatalogCore(mode, methods, types, onProposals === undefined
|
|
434
|
+
? undefined
|
|
435
|
+
: (proposals, context) => onProposals.call(catalog, proposals, context));
|
|
436
|
+
}
|
|
437
|
+
static async normalizeType(value, label) {
|
|
438
|
+
if (!isPlainObject(value))
|
|
439
|
+
throw new FlexHarnessValidationError(`${label} must be a plain object.`);
|
|
440
|
+
const unsupported = Object.keys(value).find((key) => !typeKeys.has(key));
|
|
441
|
+
if (unsupported)
|
|
442
|
+
throw new FlexHarnessValidationError(`${label} does not support "${unsupported}".`);
|
|
443
|
+
const name = textOf(value.name, `${label} name`, { maxCharacters: limits.maxIdentifierCharacters, singleLine: true });
|
|
444
|
+
if (!typeNamePattern.test(name) || reservedWords.has(name)) {
|
|
445
|
+
throw new FlexHarnessValidationError(`${label} name must be an identifier that is not a reserved word.`);
|
|
446
|
+
}
|
|
447
|
+
if (value.schema === undefined && value.declaration === undefined) {
|
|
448
|
+
throw new FlexHarnessValidationError(`Tool catalog type "${name}" needs a schema or a declaration.`);
|
|
449
|
+
}
|
|
450
|
+
const description = value.description === undefined
|
|
451
|
+
? undefined
|
|
452
|
+
: textOf(value.description, `Tool catalog type "${name}" description`, { maxBytes: limits.maxDescriptionBytes });
|
|
453
|
+
const declaration = value.declaration === undefined
|
|
454
|
+
? undefined
|
|
455
|
+
: textOf(value.declaration, `Tool catalog type "${name}" declaration`, { maxBytes: limits.maxDeclarationBytes });
|
|
456
|
+
if (declaration !== undefined && !new RegExp(`\\b(?:interface|type|enum|class)\\s+${name}\\b`).test(declaration)) {
|
|
457
|
+
throw new FlexHarnessValidationError(`Tool catalog type "${name}" declaration must declare "${name}".`);
|
|
458
|
+
}
|
|
459
|
+
const schema = value.schema === undefined
|
|
460
|
+
? undefined
|
|
461
|
+
: await resolveCatalogSchema(value.schema, `Tool catalog type "${name}" schema`);
|
|
462
|
+
if (schema && isSchemaRecord(schema.json) && (schema.json.$defs !== undefined || schema.json.definitions !== undefined)) {
|
|
463
|
+
throw new FlexHarnessValidationError(`Tool catalog type "${name}" schema must refer to other catalog types instead of defining $defs.`);
|
|
464
|
+
}
|
|
465
|
+
return {
|
|
466
|
+
name,
|
|
467
|
+
...(description === undefined ? {} : { description }),
|
|
468
|
+
...(declaration === undefined ? {} : { declaration }),
|
|
469
|
+
...(schema === undefined ? {} : { schema }),
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
static async normalizeMethod(value, label) {
|
|
473
|
+
if (!isPlainObject(value))
|
|
474
|
+
throw new FlexHarnessValidationError(`${label} must be a plain object.`);
|
|
475
|
+
const unsupported = Object.keys(value).find((key) => !methodKeys.has(key));
|
|
476
|
+
if (unsupported)
|
|
477
|
+
throw new FlexHarnessValidationError(`${label} does not support "${unsupported}".`);
|
|
478
|
+
const path = textOf(value.method, `${label} method`, { maxCharacters: limits.maxMethodPathCharacters, singleLine: true });
|
|
479
|
+
const segments = path.split('.');
|
|
480
|
+
if (!methodPathPattern.test(path)
|
|
481
|
+
|| segments.length > limits.maxMethodPathSegments
|
|
482
|
+
|| segments.some((segment) => segment.length > limits.maxIdentifierCharacters)) {
|
|
483
|
+
throw new FlexHarnessValidationError(`${label} method "${path}" must be a dotted path of at most ${limits.maxMethodPathSegments} identifiers.`);
|
|
484
|
+
}
|
|
485
|
+
const reserved = segments.find((segment) => reservedWords.has(segment));
|
|
486
|
+
if (reserved) {
|
|
487
|
+
throw new FlexHarnessValidationError(`${label} method "${path}" uses the reserved word "${reserved}", which a declaration cannot name.`);
|
|
488
|
+
}
|
|
489
|
+
const methodLabel = `Tool catalog method "${path}"`;
|
|
490
|
+
const summary = textOf(value.summary, `${methodLabel} summary`, {
|
|
491
|
+
maxCharacters: limits.maxSummaryCharacters, singleLine: true,
|
|
492
|
+
}).trim();
|
|
493
|
+
const description = value.description === undefined
|
|
494
|
+
? undefined
|
|
495
|
+
: textOf(value.description, `${methodLabel} description`, { maxBytes: limits.maxDescriptionBytes }).trim();
|
|
496
|
+
const tags = textListOf(value.tags, `${methodLabel} tags`, limits.maxTags, {
|
|
497
|
+
maxCharacters: limits.maxTagCharacters, singleLine: true,
|
|
498
|
+
});
|
|
499
|
+
const examples = textListOf(value.examples, `${methodLabel} examples`, limits.maxExamples, {
|
|
500
|
+
maxBytes: limits.maxExampleBytes,
|
|
501
|
+
});
|
|
502
|
+
const name = segments[segments.length - 1];
|
|
503
|
+
const declaration = value.declaration === undefined
|
|
504
|
+
? undefined
|
|
505
|
+
: textOf(value.declaration, `${methodLabel} declaration`, { maxBytes: limits.maxDeclarationBytes });
|
|
506
|
+
if (declaration !== undefined && !new RegExp(`\\bfunction\\s+${name}\\s*[<(]`).test(declaration)) {
|
|
507
|
+
throw new FlexHarnessValidationError(`${methodLabel} declaration must declare "function ${name}(".`);
|
|
508
|
+
}
|
|
509
|
+
if (typeof value.run !== 'function')
|
|
510
|
+
throw new FlexHarnessValidationError(`${methodLabel} run must be a function.`);
|
|
511
|
+
if (value.onCall !== undefined && typeof value.onCall !== 'function') {
|
|
512
|
+
throw new FlexHarnessValidationError(`${methodLabel} onCall must be a function.`);
|
|
513
|
+
}
|
|
514
|
+
if (value.inputSchema === undefined)
|
|
515
|
+
throw new FlexHarnessValidationError(`${methodLabel} needs an inputSchema.`);
|
|
516
|
+
const input = await resolveCatalogSchema(value.inputSchema, `${methodLabel} inputSchema`);
|
|
517
|
+
const inputJson = input.json;
|
|
518
|
+
const describesObject = isSchemaRecord(inputJson) && (inputJson.type === 'object'
|
|
519
|
+
|| (Array.isArray(inputJson.type) && inputJson.type.includes('object'))
|
|
520
|
+
|| (inputJson.type === undefined && (inputJson.properties !== undefined || inputJson.$ref !== undefined
|
|
521
|
+
|| inputJson.anyOf !== undefined || inputJson.oneOf !== undefined || inputJson.allOf !== undefined)));
|
|
522
|
+
if (!describesObject)
|
|
523
|
+
throw new FlexHarnessValidationError(`${methodLabel} inputSchema must describe an object.`);
|
|
524
|
+
const output = value.outputSchema === undefined
|
|
525
|
+
? undefined
|
|
526
|
+
: await resolveCatalogSchema(value.outputSchema, `${methodLabel} outputSchema`);
|
|
527
|
+
const run = value.run;
|
|
528
|
+
const onCall = value.onCall;
|
|
529
|
+
return {
|
|
530
|
+
path,
|
|
531
|
+
namespace: segments.slice(0, -1).join('.'),
|
|
532
|
+
name,
|
|
533
|
+
summary,
|
|
534
|
+
...(description ? { description } : {}),
|
|
535
|
+
tags: Object.freeze(tags),
|
|
536
|
+
examples: Object.freeze(examples),
|
|
537
|
+
input,
|
|
538
|
+
...(output ? { output } : {}),
|
|
539
|
+
...(declaration === undefined ? {} : { declaration }),
|
|
540
|
+
run: (params, context) => run.call(value, params, context),
|
|
541
|
+
...(onCall === undefined ? {} : {
|
|
542
|
+
onCall: (params, context) => onCall.call(value, params, context),
|
|
543
|
+
}),
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
/** Every `$ref` must be local and resolve here or, as a definition reference, to a catalog type. */
|
|
547
|
+
static checkRefs(root, label, catalogTypes, requireSchemas) {
|
|
548
|
+
const refs = new Set();
|
|
549
|
+
collectRefs(root, refs);
|
|
550
|
+
const pending = [...refs];
|
|
551
|
+
const visited = new Set();
|
|
552
|
+
while (pending.length > 0) {
|
|
553
|
+
const ref = pending.pop();
|
|
554
|
+
if (visited.has(ref))
|
|
555
|
+
continue;
|
|
556
|
+
visited.add(ref);
|
|
557
|
+
if (!ref.startsWith('#'))
|
|
558
|
+
throw new FlexHarnessValidationError(`${label} has the non-local $ref "${ref}".`);
|
|
559
|
+
if (resolvePointer(root, ref) !== undefined)
|
|
560
|
+
continue;
|
|
561
|
+
const match = definitionRefPattern.exec(ref);
|
|
562
|
+
const type = match ? catalogTypes.get(decodePointerToken(match[2])) : undefined;
|
|
563
|
+
if (!type)
|
|
564
|
+
throw new FlexHarnessValidationError(`${label} has the unresolved $ref "${ref}".`);
|
|
565
|
+
if (!requireSchemas)
|
|
566
|
+
continue;
|
|
567
|
+
if (!type.schema) {
|
|
568
|
+
throw new FlexHarnessValidationError(`${label} refers to type "${type.name}", which has no schema to validate with.`);
|
|
569
|
+
}
|
|
570
|
+
const nested = new Set();
|
|
571
|
+
collectRefs(type.schema.json, nested);
|
|
572
|
+
pending.push(...nested);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
scopeContext(scope) {
|
|
576
|
+
return {
|
|
577
|
+
namedType: (ref) => {
|
|
578
|
+
const match = definitionRefPattern.exec(ref);
|
|
579
|
+
if (!match)
|
|
580
|
+
return undefined;
|
|
581
|
+
const key = decodePointerToken(match[2]);
|
|
582
|
+
const local = scope.localNames.get(`${match[1]}/${key}`);
|
|
583
|
+
if (local)
|
|
584
|
+
return local;
|
|
585
|
+
if (resolvePointer(scope.root, ref) !== undefined)
|
|
586
|
+
return undefined;
|
|
587
|
+
return this.types.has(key) ? key : undefined;
|
|
588
|
+
},
|
|
589
|
+
resolve: (ref) => {
|
|
590
|
+
const target = resolvePointer(scope.root, ref);
|
|
591
|
+
return isSchemaRecord(target) || typeof target === 'boolean' ? target : undefined;
|
|
592
|
+
},
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
renderType(name) {
|
|
596
|
+
const cached = this.renderedTypes.get(name);
|
|
597
|
+
if (cached)
|
|
598
|
+
return cached;
|
|
599
|
+
const type = this.types.get(name);
|
|
600
|
+
let rendered;
|
|
601
|
+
if (type.declaration !== undefined) {
|
|
602
|
+
rendered = { text: type.declaration.trim(), types: this.scanTypes(type.declaration, name) };
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
const schema = type.definition ?? type.schema.json;
|
|
606
|
+
const writer = new SchemaDeclarationWriter(this.scopeContext(type.scope));
|
|
607
|
+
const text = writer.namedDeclaration(name, schema, type.description);
|
|
608
|
+
rendered = { text, types: writer.usedTypes.filter((used) => used !== name) };
|
|
609
|
+
}
|
|
610
|
+
this.renderedTypes.set(name, rendered);
|
|
611
|
+
return rendered;
|
|
612
|
+
}
|
|
613
|
+
renderMethod(entry) {
|
|
614
|
+
const cached = this.renderedMethods.get(entry.path);
|
|
615
|
+
if (cached)
|
|
616
|
+
return cached;
|
|
617
|
+
let rendered;
|
|
618
|
+
if (entry.declaration !== undefined) {
|
|
619
|
+
rendered = { text: entry.declaration.trim(), types: this.scanTypes(entry.declaration) };
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
const inputWriter = new SchemaDeclarationWriter(this.scopeContext(entry.inputScope));
|
|
623
|
+
const members = inputWriter.objectMembers(entry.input.json);
|
|
624
|
+
const paramsType = inputWriter.type(entry.input.json, '', 0, members !== undefined);
|
|
625
|
+
const optional = inputWriter.hasNoRequiredProperties(entry.input.json) ? '?' : '';
|
|
626
|
+
const outputWriter = entry.output && entry.outputScope
|
|
627
|
+
? new SchemaDeclarationWriter(this.scopeContext(entry.outputScope))
|
|
628
|
+
: undefined;
|
|
629
|
+
const resultType = outputWriter ? outputWriter.type(entry.output.json) : 'unknown';
|
|
630
|
+
const lines = [entry.summary];
|
|
631
|
+
if (entry.description && entry.description !== entry.summary)
|
|
632
|
+
lines.push('', ...entry.description.split('\n'));
|
|
633
|
+
for (const member of members ?? []) {
|
|
634
|
+
if (member.doc === undefined)
|
|
635
|
+
continue;
|
|
636
|
+
const key = isIdentifier(member.name) ? `.${member.name}` : `[${JSON.stringify(member.name)}]`;
|
|
637
|
+
lines.push(`@param params${key} ${member.doc.replace(/\s*\n\s*/g, ' ')}`);
|
|
638
|
+
}
|
|
639
|
+
for (const example of entry.examples) {
|
|
640
|
+
lines.push(...(example.includes('\n') ? ['@example', ...example.split('\n')] : [`@example ${example}`]));
|
|
641
|
+
}
|
|
642
|
+
const signature = `function ${entry.name}(params${optional}: ${paramsType}): Promise<${resultType}>;`;
|
|
643
|
+
rendered = {
|
|
644
|
+
text: `${docBlock(lines.join('\n'), '')}${signature}`,
|
|
645
|
+
types: [...new Set([...inputWriter.usedTypes, ...(outputWriter?.usedTypes ?? [])])].sort(compareCodePoints),
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
this.renderedMethods.set(entry.path, rendered);
|
|
649
|
+
return rendered;
|
|
650
|
+
}
|
|
651
|
+
scanTypes(text, self) {
|
|
652
|
+
const found = new Set();
|
|
653
|
+
for (const match of text.matchAll(identifierScanPattern)) {
|
|
654
|
+
if (match[0] !== self && this.types.has(match[0]))
|
|
655
|
+
found.add(match[0]);
|
|
656
|
+
}
|
|
657
|
+
return [...found].sort(compareCodePoints);
|
|
658
|
+
}
|
|
659
|
+
/** `names` and every type they use, transitively, sorted. */
|
|
660
|
+
typeClosure(names, stop = new Set()) {
|
|
661
|
+
const result = new Set();
|
|
662
|
+
const pending = [...names];
|
|
663
|
+
while (pending.length > 0) {
|
|
664
|
+
const name = pending.pop();
|
|
665
|
+
if (result.has(name) || stop.has(name) || !this.types.has(name))
|
|
666
|
+
continue;
|
|
667
|
+
result.add(name);
|
|
668
|
+
pending.push(...this.renderType(name).types);
|
|
669
|
+
}
|
|
670
|
+
return [...result].sort(compareCodePoints);
|
|
671
|
+
}
|
|
672
|
+
/** The method's input schema with the catalog types it refers to added as definitions. */
|
|
673
|
+
selfContainedInput(entry) {
|
|
674
|
+
const cached = this.selfContainedInputs.get(entry.path);
|
|
675
|
+
if (cached !== undefined)
|
|
676
|
+
return cached;
|
|
677
|
+
const root = structuredClone(entry.input.json);
|
|
678
|
+
if (isSchemaRecord(root)) {
|
|
679
|
+
const pending = new Set();
|
|
680
|
+
collectRefs(root, pending);
|
|
681
|
+
const queue = [...pending];
|
|
682
|
+
while (queue.length > 0) {
|
|
683
|
+
const ref = queue.pop();
|
|
684
|
+
const match = definitionRefPattern.exec(ref);
|
|
685
|
+
if (!match || resolvePointer(root, ref) !== undefined)
|
|
686
|
+
continue;
|
|
687
|
+
const type = this.types.get(decodePointerToken(match[2]));
|
|
688
|
+
if (!type?.schema)
|
|
689
|
+
continue;
|
|
690
|
+
const container = (isSchemaRecord(root[match[1]]) ? root[match[1]] : (root[match[1]] = {}));
|
|
691
|
+
container[decodePointerToken(match[2])] = withoutDraft(structuredClone(type.schema.json));
|
|
692
|
+
const nested = new Set();
|
|
693
|
+
collectRefs(type.schema.json, nested);
|
|
694
|
+
queue.push(...nested);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
deepFreeze(root);
|
|
698
|
+
this.selfContainedInputs.set(entry.path, root);
|
|
699
|
+
return root;
|
|
700
|
+
}
|
|
701
|
+
validator(entry) {
|
|
702
|
+
let validator = this.validators.get(entry.path);
|
|
703
|
+
if (!validator) {
|
|
704
|
+
const root = structuredClone(this.selfContainedInput(entry));
|
|
705
|
+
validator = new plugins.JsonSchemaValidator(root, schemaDraft(root), false);
|
|
706
|
+
this.validators.set(entry.path, validator);
|
|
707
|
+
}
|
|
708
|
+
return validator;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* A tool catalog prepared for the model: search, TypeScript declarations, parameter validation and
|
|
713
|
+
* dispatch. FlexHarness builds one for every catalog a tool provider returns; it is public so a
|
|
714
|
+
* host can check what its catalog shows the model, and measure it, without running a session.
|
|
715
|
+
*/
|
|
716
|
+
export class FlexToolCatalog {
|
|
717
|
+
core;
|
|
718
|
+
admitted;
|
|
719
|
+
codeMode;
|
|
720
|
+
namespaceTree;
|
|
721
|
+
constructor(core, admitted,
|
|
722
|
+
/** The limits of `run_code`; absent while code mode is off. */
|
|
723
|
+
codeMode) {
|
|
724
|
+
this.core = core;
|
|
725
|
+
this.admitted = admitted;
|
|
726
|
+
this.codeMode = codeMode;
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Prepares `catalog`. Preparing the same object again returns the cached preparation, so a host
|
|
730
|
+
* that returns one catalog object for every run pays for it once.
|
|
731
|
+
*/
|
|
732
|
+
static async create(catalog, options = {}) {
|
|
733
|
+
const normalized = normalizeToolCatalogOptions(options);
|
|
734
|
+
const mode = normalized.declarations;
|
|
735
|
+
if (typeof catalog !== 'object' || catalog === null) {
|
|
736
|
+
throw new FlexHarnessValidationError('A tool catalog must be a plain object.');
|
|
737
|
+
}
|
|
738
|
+
let byMode = coreCache.get(catalog);
|
|
739
|
+
if (!byMode) {
|
|
740
|
+
byMode = new Map();
|
|
741
|
+
coreCache.set(catalog, byMode);
|
|
742
|
+
}
|
|
743
|
+
let core = byMode.get(mode);
|
|
744
|
+
if (!core) {
|
|
745
|
+
core = FlexToolCatalogCore.build(catalog, mode);
|
|
746
|
+
byMode.set(mode, core);
|
|
747
|
+
}
|
|
748
|
+
return new FlexToolCatalog(await core, undefined, normalized.codeMode);
|
|
749
|
+
}
|
|
750
|
+
/** Every method path this catalog offers, sorted. */
|
|
751
|
+
get methods() {
|
|
752
|
+
return [...this.core.methods.keys()].filter((path) => this.isAdmitted(path));
|
|
753
|
+
}
|
|
754
|
+
/** Every named type, sorted. */
|
|
755
|
+
get types() {
|
|
756
|
+
return [...this.core.types.keys()];
|
|
757
|
+
}
|
|
758
|
+
/** The same catalog offering only `paths`. */
|
|
759
|
+
restrict(paths) {
|
|
760
|
+
const allowed = new Set(paths);
|
|
761
|
+
return new FlexToolCatalog(this.core, new Set([...this.core.methods.keys()].filter((path) => allowed.has(path) && this.isAdmitted(path))), this.codeMode);
|
|
762
|
+
}
|
|
763
|
+
has(path) {
|
|
764
|
+
return this.core.methods.has(path) && this.isAdmitted(path);
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* The built-in tools as the model sees them: the three catalog tools, and `run_code` in code
|
|
768
|
+
* mode. Their text depends only on the catalog and its options.
|
|
769
|
+
*/
|
|
770
|
+
toolDefinitions() {
|
|
771
|
+
const typescript = this.core.mode === 'typescript';
|
|
772
|
+
const methodPath = { type: 'string', maxLength: limits.maxMethodPathCharacters };
|
|
773
|
+
return {
|
|
774
|
+
[toolNames.search]: {
|
|
775
|
+
description: [
|
|
776
|
+
'Search the API catalog. Its methods are called with execute, not as tools. `query` ranks methods by',
|
|
777
|
+
'name, summary and description; `namespace` (a dotted path) narrows the search or, without `query`, lists',
|
|
778
|
+
`the namespace like ls. Read a method's ${typescript ? 'TypeScript declaration' : 'description and JSON Schema'}`,
|
|
779
|
+
'with describe_tools before calling it.',
|
|
780
|
+
this.topLevelLine(),
|
|
781
|
+
].join(' '),
|
|
782
|
+
inputSchema: {
|
|
783
|
+
type: 'object',
|
|
784
|
+
properties: {
|
|
785
|
+
query: { type: 'string', maxLength: limits.maxQueryCharacters },
|
|
786
|
+
namespace: methodPath,
|
|
787
|
+
limit: { type: 'integer', minimum: 1, maximum: limits.maxSearchResults },
|
|
788
|
+
offset: { type: 'integer', minimum: 0 },
|
|
789
|
+
},
|
|
790
|
+
additionalProperties: false,
|
|
791
|
+
},
|
|
792
|
+
},
|
|
793
|
+
[toolNames.describe]: {
|
|
794
|
+
description: typescript
|
|
795
|
+
? 'Return the TypeScript declarations of catalog methods (`methods`: dotted paths) and named types (`types`). '
|
|
796
|
+
+ 'A declaration comes with the named types it uses that this conversation has not declared yet.'
|
|
797
|
+
: 'Return the description and JSON Schema of catalog methods (`methods`: dotted paths) and named types (`types`).',
|
|
798
|
+
inputSchema: {
|
|
799
|
+
type: 'object',
|
|
800
|
+
properties: {
|
|
801
|
+
methods: { type: 'array', items: methodPath, maxItems: limits.maxDescribeMethods },
|
|
802
|
+
types: {
|
|
803
|
+
type: 'array',
|
|
804
|
+
items: { type: 'string', maxLength: limits.maxIdentifierCharacters },
|
|
805
|
+
maxItems: limits.maxDescribeTypes,
|
|
806
|
+
},
|
|
807
|
+
},
|
|
808
|
+
additionalProperties: false,
|
|
809
|
+
},
|
|
810
|
+
},
|
|
811
|
+
[toolNames.execute]: {
|
|
812
|
+
description: 'Call a catalog method: `method` is its dotted path, `params` the parameter object of its '
|
|
813
|
+
+ 'declaration. Invalid params return an error naming each path, what was expected and what was given.',
|
|
814
|
+
inputSchema: {
|
|
815
|
+
type: 'object',
|
|
816
|
+
properties: {
|
|
817
|
+
method: { ...methodPath, minLength: 1 },
|
|
818
|
+
params: { type: 'object' },
|
|
819
|
+
},
|
|
820
|
+
required: ['method'],
|
|
821
|
+
additionalProperties: false,
|
|
822
|
+
},
|
|
823
|
+
},
|
|
824
|
+
...(this.codeMode ? { [FLEX_CODE_MODE_TOOL_NAME]: this.codeToolDefinition(this.codeMode) } : {}),
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
codeToolDefinition(codeMode) {
|
|
828
|
+
return {
|
|
829
|
+
description: [
|
|
830
|
+
'Run a short TypeScript or JavaScript program against the catalog, for work that takes several calls:',
|
|
831
|
+
'loops, filters, joins. Call a method as `await api.<dotted path>(params)`, for example',
|
|
832
|
+
'`await api.banking.listMovements({ accountId })`, with the declarations describe_tools returns; a refused',
|
|
833
|
+
'call throws an `ApiError` whose `details` say why. `return` a JSON value: it and the `console.log` output',
|
|
834
|
+
'come back, nothing else does. No network, files, timers or imports;',
|
|
835
|
+
`at most ${codeMode.maxCalls} calls and ${Math.round(codeMode.wallMs / 1000)} seconds.`,
|
|
836
|
+
].join(' '),
|
|
837
|
+
inputSchema: {
|
|
838
|
+
type: 'object',
|
|
839
|
+
properties: { code: { type: 'string', minLength: 1, maxLength: codeMode.maxSourceBytes } },
|
|
840
|
+
required: ['code'],
|
|
841
|
+
additionalProperties: false,
|
|
842
|
+
},
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
/** Hands proposed calls to the catalog's `onProposals` and returns what the model sees for them. */
|
|
846
|
+
async propose(proposals, context) {
|
|
847
|
+
if (!this.core.onProposals) {
|
|
848
|
+
throw new FlexHarnessValidationError(`Tool catalog method "${proposals[0]?.method}" proposed a call, but the catalog has no onProposals.`);
|
|
849
|
+
}
|
|
850
|
+
return await this.core.onProposals(proposals, context);
|
|
851
|
+
}
|
|
852
|
+
/** Search results or a namespace listing as text. */
|
|
853
|
+
search(input = {}) {
|
|
854
|
+
const limit = input.limit ?? limits.defaultSearchResults;
|
|
855
|
+
const offset = input.offset ?? 0;
|
|
856
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > limits.maxSearchResults) {
|
|
857
|
+
throw new FlexHarnessValidationError(`limit must be an integer from 1 through ${limits.maxSearchResults}.`);
|
|
858
|
+
}
|
|
859
|
+
if (!Number.isSafeInteger(offset) || offset < 0)
|
|
860
|
+
throw new FlexHarnessValidationError('offset must be a non-negative integer.');
|
|
861
|
+
const namespace = (input.namespace ?? '').trim().replace(/\.\*?$/, '');
|
|
862
|
+
const tree = this.tree();
|
|
863
|
+
if (namespace && !tree.has(namespace)) {
|
|
864
|
+
if (this.has(namespace)) {
|
|
865
|
+
return `${namespace} is a method, not a namespace; read it with describe_tools.`;
|
|
866
|
+
}
|
|
867
|
+
const suggestions = closeMatches(namespace, [...tree.keys()].filter(Boolean));
|
|
868
|
+
return [
|
|
869
|
+
`There is no namespace ${namespace}.${suggestions.length ? ` Did you mean ${suggestions.join(', ')}?` : ''}`,
|
|
870
|
+
this.topLevelLine(),
|
|
871
|
+
].join('\n');
|
|
872
|
+
}
|
|
873
|
+
const query = (input.query ?? '').trim();
|
|
874
|
+
if (query) {
|
|
875
|
+
const prefix = namespace ? `${namespace}.` : '';
|
|
876
|
+
const matches = this.core.index.search(query, (entry) => this.isAdmitted(entry.path) && entry.path.startsWith(prefix));
|
|
877
|
+
if (matches.length === 0) {
|
|
878
|
+
return [`No methods match "${query}"${namespace ? ` in ${namespace}` : ''}.`, this.topLevelLine()].join('\n');
|
|
879
|
+
}
|
|
880
|
+
return this.page(matches.map((entry) => `${entry.path} - ${entry.summary}`), offset, limit, 'matches');
|
|
881
|
+
}
|
|
882
|
+
const node = tree.get(namespace);
|
|
883
|
+
const lines = [...node.children.entries()].map(([child, count]) => `${child}.* (${count} method${count === 1 ? '' : 's'})`);
|
|
884
|
+
const methodLines = node.methods.map((entry) => `${entry.path} - ${entry.summary}`);
|
|
885
|
+
if (methodLines.length === 0)
|
|
886
|
+
return lines.join('\n') || 'The catalog has no methods.';
|
|
887
|
+
return [...lines, this.page(methodLines, offset, limit, 'methods')].filter(Boolean).join('\n');
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* The declarations of `input.methods` and `input.types`. Method declarations bring the named
|
|
891
|
+
* types they use, minus `declaredTypes`, which a session already has.
|
|
892
|
+
*/
|
|
893
|
+
describe(input, options = {}) {
|
|
894
|
+
const requestedMethods = [...new Set(input.methods ?? [])];
|
|
895
|
+
const requestedTypes = [...new Set(input.types ?? [])];
|
|
896
|
+
if (requestedMethods.length > limits.maxDescribeMethods || requestedTypes.length > limits.maxDescribeTypes) {
|
|
897
|
+
throw new FlexHarnessValidationError(`describe_tools takes at most ${limits.maxDescribeMethods} methods and ${limits.maxDescribeTypes} types.`);
|
|
898
|
+
}
|
|
899
|
+
const maxBytes = Math.min(options.maxBytes ?? limits.maxDescribeBytes, limits.maxDescribeBytes);
|
|
900
|
+
const entries = requestedMethods.filter((path) => this.has(path)).sort(compareCodePoints)
|
|
901
|
+
.map((path) => this.core.methods.get(path));
|
|
902
|
+
const unknownMethods = requestedMethods.filter((path) => !this.has(path)).sort(compareCodePoints);
|
|
903
|
+
const knownTypes = requestedTypes.filter((name) => this.core.types.has(name)).sort(compareCodePoints);
|
|
904
|
+
const unknownTypes = requestedTypes.filter((name) => !this.core.types.has(name)).sort(compareCodePoints);
|
|
905
|
+
const notes = [
|
|
906
|
+
...unknownMethods.map((path) => {
|
|
907
|
+
const suggestions = closeMatches(path, this.methods);
|
|
908
|
+
return `Unknown method ${path}.${suggestions.length ? ` Did you mean ${suggestions.join(', ')}?` : ' Find methods with search_tools.'}`;
|
|
909
|
+
}),
|
|
910
|
+
...unknownTypes.map((name) => {
|
|
911
|
+
const suggestions = closeMatches(name, this.core.types.keys());
|
|
912
|
+
return `Unknown type ${name}.${suggestions.length ? ` Did you mean ${suggestions.join(', ')}?` : ''}`;
|
|
913
|
+
}),
|
|
914
|
+
];
|
|
915
|
+
if (requestedMethods.length === 0 && requestedTypes.length === 0) {
|
|
916
|
+
notes.push('Pass methods (dotted paths) or types to describe.');
|
|
917
|
+
}
|
|
918
|
+
return this.core.mode === 'json-schema'
|
|
919
|
+
? this.describeJson(entries, knownTypes, notes, maxBytes)
|
|
920
|
+
: this.describeTypescript(entries, knownTypes, notes, new Set(options.declaredTypes ?? []), maxBytes);
|
|
921
|
+
}
|
|
922
|
+
/** The named types `describe_tools` results in `messages` declared. */
|
|
923
|
+
declaredTypesIn(messages) {
|
|
924
|
+
const declared = new Set();
|
|
925
|
+
for (const message of messages ?? []) {
|
|
926
|
+
if (message.role !== 'tool' || !Array.isArray(message.content))
|
|
927
|
+
continue;
|
|
928
|
+
for (const part of message.content) {
|
|
929
|
+
if (part.type !== 'tool-result' || part.toolName !== toolNames.describe)
|
|
930
|
+
continue;
|
|
931
|
+
const output = part.output;
|
|
932
|
+
if (output.type !== 'text' || typeof output.value !== 'string' || !output.value.startsWith(declaredTypesHeader))
|
|
933
|
+
continue;
|
|
934
|
+
const lineEnd = output.value.indexOf('\n');
|
|
935
|
+
const header = output.value.slice(declaredTypesHeader.length, lineEnd === -1 ? undefined : lineEnd);
|
|
936
|
+
for (const name of header.split(', '))
|
|
937
|
+
if (this.core.types.has(name))
|
|
938
|
+
declared.add(name);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
return declared;
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Resolves and validates a call. A failure is the error `execute` reports to the model; success
|
|
945
|
+
* returns the run with the validated parameters. A schema validator that throws rejects.
|
|
946
|
+
*/
|
|
947
|
+
async prepareCall(method, params) {
|
|
948
|
+
const path = typeof method === 'string' ? method : '';
|
|
949
|
+
if (!this.has(path)) {
|
|
950
|
+
const isNamespace = path !== '' && this.tree().has(path);
|
|
951
|
+
return {
|
|
952
|
+
success: false,
|
|
953
|
+
error: {
|
|
954
|
+
error: 'unknown_method',
|
|
955
|
+
method: path,
|
|
956
|
+
didYouMean: isNamespace ? [] : closeMatches(path, this.methods),
|
|
957
|
+
hint: isNamespace
|
|
958
|
+
? `${path} is a namespace; list it with search_tools({"namespace":"${path}"}).`
|
|
959
|
+
: 'Find methods with search_tools.',
|
|
960
|
+
},
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
const entry = this.core.methods.get(path);
|
|
964
|
+
const value = params === undefined ? {} : params;
|
|
965
|
+
const issues = this.validateStructure(entry, value);
|
|
966
|
+
let validated = value;
|
|
967
|
+
if (issues.length === 0 && entry.input.validate) {
|
|
968
|
+
// A validator that throws failed itself; only a failure it reports is the model's to repair.
|
|
969
|
+
const result = await entry.input.validate(value);
|
|
970
|
+
if (result.success)
|
|
971
|
+
validated = result.value;
|
|
972
|
+
else
|
|
973
|
+
issues.push(...this.foreignIssues(result.error, value));
|
|
974
|
+
}
|
|
975
|
+
if (issues.length > 0) {
|
|
976
|
+
const listed = issues.slice(0, limits.maxParamIssues);
|
|
977
|
+
return {
|
|
978
|
+
success: false,
|
|
979
|
+
error: {
|
|
980
|
+
error: 'invalid_params',
|
|
981
|
+
method: path,
|
|
982
|
+
issues: listed,
|
|
983
|
+
...(issues.length > listed.length ? { more: issues.length - listed.length } : {}),
|
|
984
|
+
see: `describe_tools({"methods":["${path}"]})`,
|
|
985
|
+
},
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
return {
|
|
989
|
+
success: true,
|
|
990
|
+
method: path,
|
|
991
|
+
params: validated,
|
|
992
|
+
decide: async (context) => {
|
|
993
|
+
const decision = entry.onCall ? await entry.onCall(validated, context) : 'run';
|
|
994
|
+
if (decision === 'run' || decision === 'propose')
|
|
995
|
+
return decision;
|
|
996
|
+
if (isSchemaRecord(decision)
|
|
997
|
+
&& Object.keys(decision).length === 1
|
|
998
|
+
&& typeof decision.deny === 'string'
|
|
999
|
+
&& decision.deny.trim()) {
|
|
1000
|
+
return { deny: decision.deny.slice(0, 2000) };
|
|
1001
|
+
}
|
|
1002
|
+
throw new FlexHarnessValidationError(`Tool catalog method "${path}" onCall returned an invalid decision.`);
|
|
1003
|
+
},
|
|
1004
|
+
run: (context) => entry.run(validated, context),
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
/** The real method and params of an `execute` input, when it names a method of this catalog. */
|
|
1008
|
+
callTarget(input) {
|
|
1009
|
+
if (!isSchemaRecord(input) || typeof input.method !== 'string' || !this.has(input.method))
|
|
1010
|
+
return undefined;
|
|
1011
|
+
return { method: input.method, params: input.params === undefined ? {} : input.params };
|
|
1012
|
+
}
|
|
1013
|
+
isAdmitted(path) {
|
|
1014
|
+
return this.admitted === undefined || this.admitted.has(path);
|
|
1015
|
+
}
|
|
1016
|
+
tree() {
|
|
1017
|
+
if (this.namespaceTree)
|
|
1018
|
+
return this.namespaceTree;
|
|
1019
|
+
const tree = new Map();
|
|
1020
|
+
const node = (namespace) => {
|
|
1021
|
+
let entry = tree.get(namespace);
|
|
1022
|
+
if (!entry) {
|
|
1023
|
+
entry = { methods: [], children: new Map() };
|
|
1024
|
+
tree.set(namespace, entry);
|
|
1025
|
+
}
|
|
1026
|
+
return entry;
|
|
1027
|
+
};
|
|
1028
|
+
node('');
|
|
1029
|
+
for (const entry of this.core.methods.values()) {
|
|
1030
|
+
if (!this.isAdmitted(entry.path))
|
|
1031
|
+
continue;
|
|
1032
|
+
node(entry.namespace).methods.push(entry);
|
|
1033
|
+
const segments = entry.path.split('.');
|
|
1034
|
+
for (let depth = 1; depth < segments.length; depth++) {
|
|
1035
|
+
const parent = segments.slice(0, depth - 1).join('.');
|
|
1036
|
+
const child = segments.slice(0, depth).join('.');
|
|
1037
|
+
const children = node(parent).children;
|
|
1038
|
+
children.set(child, (children.get(child) ?? 0) + 1);
|
|
1039
|
+
node(child);
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
for (const entry of tree.values()) {
|
|
1043
|
+
entry.children = new Map([...entry.children.entries()].sort(([left], [right]) => compareCodePoints(left, right)));
|
|
1044
|
+
}
|
|
1045
|
+
this.namespaceTree = tree;
|
|
1046
|
+
return tree;
|
|
1047
|
+
}
|
|
1048
|
+
topLevelLine() {
|
|
1049
|
+
const root = this.tree().get('');
|
|
1050
|
+
const namespaces = [...root.children.entries()];
|
|
1051
|
+
const shown = namespaces.slice(0, 40).map(([name, count]) => `${name}.* (${count})`);
|
|
1052
|
+
if (namespaces.length > shown.length)
|
|
1053
|
+
shown.push(`${namespaces.length - shown.length} more namespaces`);
|
|
1054
|
+
if (root.methods.length > 0) {
|
|
1055
|
+
shown.push(namespaces.length > 0
|
|
1056
|
+
? `${root.methods.length} top-level method${root.methods.length === 1 ? '' : 's'}`
|
|
1057
|
+
: `${root.methods.length} method${root.methods.length === 1 ? '' : 's'}`);
|
|
1058
|
+
}
|
|
1059
|
+
return `Top level: ${shown.join(', ') || 'no methods'}.`;
|
|
1060
|
+
}
|
|
1061
|
+
page(lines, offset, limit, noun) {
|
|
1062
|
+
const shown = lines.slice(offset, offset + limit);
|
|
1063
|
+
if (shown.length === 0)
|
|
1064
|
+
return `No more ${noun}: there are ${lines.length}.`;
|
|
1065
|
+
if (offset === 0 && shown.length === lines.length)
|
|
1066
|
+
return shown.join('\n');
|
|
1067
|
+
const end = offset + shown.length;
|
|
1068
|
+
const more = end < lines.length ? `; pass offset ${end} for more` : '';
|
|
1069
|
+
return [...shown, `Showing ${offset + 1}-${end} of ${lines.length} ${noun}${more}.`].join('\n');
|
|
1070
|
+
}
|
|
1071
|
+
describeTypescript(entries, requestedTypes, notes, declared, maxBytes) {
|
|
1072
|
+
const included = [];
|
|
1073
|
+
const omitted = [];
|
|
1074
|
+
const alreadyDeclared = new Set([...declared].filter((name) => !requestedTypes.includes(name)));
|
|
1075
|
+
let types = this.core.typeClosure(requestedTypes, alreadyDeclared);
|
|
1076
|
+
const assemble = (methods, typeNames, skipped) => {
|
|
1077
|
+
const used = new Set(methods.flatMap((entry) => this.core.typeClosure(this.core.renderMethod(entry).types)));
|
|
1078
|
+
const earlier = [...used].filter((name) => declared.has(name) && !typeNames.includes(name)).sort(compareCodePoints);
|
|
1079
|
+
const blocks = [];
|
|
1080
|
+
if (typeNames.length)
|
|
1081
|
+
blocks.push(`${declaredTypesHeader}${typeNames.join(', ')}`);
|
|
1082
|
+
for (const name of typeNames)
|
|
1083
|
+
blocks.push(this.core.renderType(name).text);
|
|
1084
|
+
const byNamespace = new Map();
|
|
1085
|
+
for (const entry of methods)
|
|
1086
|
+
byNamespace.set(entry.namespace, [...(byNamespace.get(entry.namespace) ?? []), entry]);
|
|
1087
|
+
for (const [namespace, members] of byNamespace) {
|
|
1088
|
+
const texts = members.map((entry) => this.core.renderMethod(entry).text);
|
|
1089
|
+
if (namespace)
|
|
1090
|
+
blocks.push(`declare namespace ${namespace} {\n${indentLines(texts.join('\n'), ' ')}\n}`);
|
|
1091
|
+
else
|
|
1092
|
+
blocks.push(...texts.map(withDeclare));
|
|
1093
|
+
}
|
|
1094
|
+
const trailing = [
|
|
1095
|
+
...(earlier.length ? [`Declared earlier: ${earlier.join(', ')}; describe_tools({"types":[...]}) declares them again.`] : []),
|
|
1096
|
+
...notes,
|
|
1097
|
+
...(skipped.length ? [`Not included to stay within the size limit: ${skipped.join(', ')}; describe them in another call.`] : []),
|
|
1098
|
+
];
|
|
1099
|
+
if (trailing.length)
|
|
1100
|
+
blocks.push(trailing.map((note) => `// ${note}`).join('\n'));
|
|
1101
|
+
return blocks.join('\n\n');
|
|
1102
|
+
};
|
|
1103
|
+
for (const entry of entries) {
|
|
1104
|
+
const candidate = [...included, entry];
|
|
1105
|
+
const candidateTypes = this.core.typeClosure([...requestedTypes, ...candidate.flatMap((method) => this.core.renderMethod(method).types)], alreadyDeclared);
|
|
1106
|
+
const text = assemble(candidate, candidateTypes, entries.slice(candidate.length).map((method) => method.path));
|
|
1107
|
+
if (Buffer.byteLength(JSON.stringify(text), 'utf8') > maxBytes && included.length > 0) {
|
|
1108
|
+
omitted.push(...entries.slice(included.length).map((method) => method.path));
|
|
1109
|
+
break;
|
|
1110
|
+
}
|
|
1111
|
+
included.push(entry);
|
|
1112
|
+
types = candidateTypes;
|
|
1113
|
+
}
|
|
1114
|
+
const text = assemble(included, types, omitted);
|
|
1115
|
+
return { output: text, declaredTypes: types };
|
|
1116
|
+
}
|
|
1117
|
+
describeJson(entries, requestedTypes, notes, maxBytes) {
|
|
1118
|
+
const methods = [];
|
|
1119
|
+
const omitted = [];
|
|
1120
|
+
const typeSchemas = requestedTypes.flatMap((name) => {
|
|
1121
|
+
const type = this.core.types.get(name);
|
|
1122
|
+
const schema = type.definition ?? type.schema?.json;
|
|
1123
|
+
return [{
|
|
1124
|
+
name,
|
|
1125
|
+
...(type.description ? { description: type.description } : {}),
|
|
1126
|
+
...(schema === undefined ? { declaration: type.declaration } : { schema: withoutDraft(schema) }),
|
|
1127
|
+
}];
|
|
1128
|
+
});
|
|
1129
|
+
let size = Buffer.byteLength(JSON.stringify({ types: typeSchemas, notes }), 'utf8');
|
|
1130
|
+
for (const entry of entries) {
|
|
1131
|
+
const method = {
|
|
1132
|
+
method: entry.path,
|
|
1133
|
+
summary: entry.summary,
|
|
1134
|
+
...(entry.description ? { description: entry.description } : {}),
|
|
1135
|
+
inputSchema: withoutDraft(this.core.selfContainedInput(entry)),
|
|
1136
|
+
...(entry.output ? { outputSchema: withoutDraft(entry.output.json) } : {}),
|
|
1137
|
+
...(entry.examples.length ? { examples: [...entry.examples] } : {}),
|
|
1138
|
+
};
|
|
1139
|
+
const bytes = Buffer.byteLength(JSON.stringify(method), 'utf8') + 1;
|
|
1140
|
+
if (methods.length > 0 && size + bytes > maxBytes) {
|
|
1141
|
+
omitted.push(...entries.slice(methods.length).map((skipped) => skipped.path));
|
|
1142
|
+
break;
|
|
1143
|
+
}
|
|
1144
|
+
size += bytes;
|
|
1145
|
+
methods.push(method);
|
|
1146
|
+
}
|
|
1147
|
+
return {
|
|
1148
|
+
output: JSON.parse(JSON.stringify({
|
|
1149
|
+
methods,
|
|
1150
|
+
...(typeSchemas.length ? { types: typeSchemas } : {}),
|
|
1151
|
+
...(notes.length ? { notes } : {}),
|
|
1152
|
+
...(omitted.length ? { omitted } : {}),
|
|
1153
|
+
})),
|
|
1154
|
+
declaredTypes: [],
|
|
1155
|
+
};
|
|
1156
|
+
}
|
|
1157
|
+
/** Issues the method's JSON Schema finds in `value`. */
|
|
1158
|
+
validateStructure(entry, value) {
|
|
1159
|
+
const result = this.core.validator(entry).validate(value);
|
|
1160
|
+
if (result.valid)
|
|
1161
|
+
return [];
|
|
1162
|
+
const root = this.core.selfContainedInput(entry);
|
|
1163
|
+
const writer = new SchemaDeclarationWriter({
|
|
1164
|
+
namedType: (ref) => {
|
|
1165
|
+
const match = definitionRefPattern.exec(ref);
|
|
1166
|
+
const key = match ? decodePointerToken(match[2]) : undefined;
|
|
1167
|
+
return key && typeNamePattern.test(key) ? key : undefined;
|
|
1168
|
+
},
|
|
1169
|
+
resolve: (ref) => {
|
|
1170
|
+
const target = resolvePointer(root, ref);
|
|
1171
|
+
return isSchemaRecord(target) || typeof target === 'boolean' ? target : undefined;
|
|
1172
|
+
},
|
|
1173
|
+
});
|
|
1174
|
+
const typeText = (schema) => isSchemaRecord(schema) || typeof schema === 'boolean' ? compactType(writer.type(schema)) : 'a value';
|
|
1175
|
+
const issues = [];
|
|
1176
|
+
const covered = [];
|
|
1177
|
+
let container;
|
|
1178
|
+
for (const unit of result.errors) {
|
|
1179
|
+
if (covered.some((prefix) => unit.keywordLocation.startsWith(`${prefix}/`)))
|
|
1180
|
+
continue;
|
|
1181
|
+
const tokens = pointerTokens(unit.instanceLocation);
|
|
1182
|
+
const path = paramsPath(tokens);
|
|
1183
|
+
const got = preview(valueAt(value, tokens));
|
|
1184
|
+
const schemaHere = resolvePointer(root, unit.keywordLocation);
|
|
1185
|
+
const parent = resolvePointer(root, unit.keywordLocation.slice(0, unit.keywordLocation.lastIndexOf('/')));
|
|
1186
|
+
switch (unit.keyword) {
|
|
1187
|
+
case 'additionalProperties':
|
|
1188
|
+
case 'unevaluatedProperties':
|
|
1189
|
+
container = unit;
|
|
1190
|
+
continue;
|
|
1191
|
+
case 'properties':
|
|
1192
|
+
case 'patternProperties':
|
|
1193
|
+
case 'items':
|
|
1194
|
+
case 'prefixItems':
|
|
1195
|
+
case 'additionalItems':
|
|
1196
|
+
case 'unevaluatedItems':
|
|
1197
|
+
case 'allOf':
|
|
1198
|
+
case '$ref':
|
|
1199
|
+
case '$recursiveRef':
|
|
1200
|
+
case '$dynamicRef':
|
|
1201
|
+
case 'dependentSchemas':
|
|
1202
|
+
case 'if':
|
|
1203
|
+
case 'then':
|
|
1204
|
+
case 'else':
|
|
1205
|
+
continue;
|
|
1206
|
+
case 'false': {
|
|
1207
|
+
const name = tokens[tokens.length - 1] ?? '';
|
|
1208
|
+
const owner = container && unit.instanceLocation.startsWith(`${container.instanceLocation}/`)
|
|
1209
|
+
? resolvePointer(root, container.keywordLocation.slice(0, container.keywordLocation.lastIndexOf('/')))
|
|
1210
|
+
: undefined;
|
|
1211
|
+
if (isSchemaRecord(owner)) {
|
|
1212
|
+
const declaredProperty = isSchemaRecord(owner.properties)
|
|
1213
|
+
&& Object.prototype.hasOwnProperty.call(owner.properties, name);
|
|
1214
|
+
const matchesPattern = isSchemaRecord(owner.patternProperties)
|
|
1215
|
+
&& Object.keys(owner.patternProperties).some((pattern) => {
|
|
1216
|
+
try {
|
|
1217
|
+
return new RegExp(pattern, 'u').test(name);
|
|
1218
|
+
}
|
|
1219
|
+
catch {
|
|
1220
|
+
return false;
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
1223
|
+
if (declaredProperty || matchesPattern)
|
|
1224
|
+
continue;
|
|
1225
|
+
const known = isSchemaRecord(owner.properties) ? Object.keys(owner.properties) : [];
|
|
1226
|
+
issues.push({
|
|
1227
|
+
path,
|
|
1228
|
+
expected: known.length
|
|
1229
|
+
? `no such property; known properties: ${known.slice(0, 20).join(', ')}`
|
|
1230
|
+
: 'no such property',
|
|
1231
|
+
got,
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
else {
|
|
1235
|
+
issues.push({ path, expected: 'no value', got });
|
|
1236
|
+
}
|
|
1237
|
+
continue;
|
|
1238
|
+
}
|
|
1239
|
+
case 'required': {
|
|
1240
|
+
const required = Array.isArray(schemaHere) ? schemaHere.filter((key) => typeof key === 'string') : [];
|
|
1241
|
+
const instance = valueAt(value, tokens);
|
|
1242
|
+
for (const key of required) {
|
|
1243
|
+
if (isSchemaRecord(instance) && Object.prototype.hasOwnProperty.call(instance, key))
|
|
1244
|
+
continue;
|
|
1245
|
+
const property = isSchemaRecord(parent) && isSchemaRecord(parent.properties) ? parent.properties[key] : undefined;
|
|
1246
|
+
issues.push({ path: paramsPath([...tokens, key]), expected: typeText(property), got: 'missing' });
|
|
1247
|
+
}
|
|
1248
|
+
continue;
|
|
1249
|
+
}
|
|
1250
|
+
case 'anyOf':
|
|
1251
|
+
case 'oneOf':
|
|
1252
|
+
case 'not':
|
|
1253
|
+
covered.push(unit.keywordLocation);
|
|
1254
|
+
issues.push({ path, expected: unit.keyword === 'not' ? `not ${typeText(schemaHere)}` : typeText(parent), got });
|
|
1255
|
+
continue;
|
|
1256
|
+
case 'type':
|
|
1257
|
+
issues.push({
|
|
1258
|
+
path,
|
|
1259
|
+
expected: Array.isArray(schemaHere) ? schemaHere.join(' | ') : String(schemaHere),
|
|
1260
|
+
got,
|
|
1261
|
+
});
|
|
1262
|
+
continue;
|
|
1263
|
+
case 'enum':
|
|
1264
|
+
case 'const':
|
|
1265
|
+
issues.push({ path, expected: typeText(parent), got });
|
|
1266
|
+
continue;
|
|
1267
|
+
case 'minimum':
|
|
1268
|
+
case 'exclusiveMinimum':
|
|
1269
|
+
case 'maximum':
|
|
1270
|
+
case 'exclusiveMaximum':
|
|
1271
|
+
case 'multipleOf':
|
|
1272
|
+
case 'minLength':
|
|
1273
|
+
case 'maxLength':
|
|
1274
|
+
case 'minItems':
|
|
1275
|
+
case 'maxItems':
|
|
1276
|
+
case 'uniqueItems':
|
|
1277
|
+
case 'pattern':
|
|
1278
|
+
case 'format': {
|
|
1279
|
+
const constraint = new SchemaDeclarationWriter({ namedType: () => undefined, resolve: () => undefined });
|
|
1280
|
+
const text = isSchemaRecord(parent) ? compactType(constraint.type(parent)) : 'a value';
|
|
1281
|
+
const subset = isSchemaRecord(parent) ? { type: parent.type, [unit.keyword]: schemaHere } : {};
|
|
1282
|
+
const doc = Object.keys(subset).length ? constraintText(subset) : unit.error;
|
|
1283
|
+
issues.push({ path, expected: doc ? `${text} (${doc})` : text, got });
|
|
1284
|
+
continue;
|
|
1285
|
+
}
|
|
1286
|
+
default:
|
|
1287
|
+
issues.push({ path, expected: unit.error, got });
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
const seen = new Set();
|
|
1291
|
+
return issues.filter((issue) => {
|
|
1292
|
+
const key = `${issue.path}\u0000${issue.expected}`;
|
|
1293
|
+
if (seen.has(key))
|
|
1294
|
+
return false;
|
|
1295
|
+
seen.add(key);
|
|
1296
|
+
return true;
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
/** Issues reported by a zod, Standard Schema or AI SDK validator. */
|
|
1300
|
+
foreignIssues(error, value) {
|
|
1301
|
+
const source = error;
|
|
1302
|
+
const list = Array.isArray(source.issues)
|
|
1303
|
+
? source.issues
|
|
1304
|
+
: isSchemaRecord(source.cause) && Array.isArray(source.cause.issues)
|
|
1305
|
+
? source.cause.issues
|
|
1306
|
+
: Array.isArray(source.cause) ? source.cause : undefined;
|
|
1307
|
+
if (!list || list.length === 0)
|
|
1308
|
+
return [{ path: 'params', expected: error.message || 'valid params', got: preview(value) }];
|
|
1309
|
+
return list.map((issue) => {
|
|
1310
|
+
const record = isSchemaRecord(issue) ? issue : {};
|
|
1311
|
+
const tokens = (Array.isArray(record.path) ? record.path : []).map((segment) => {
|
|
1312
|
+
const key = isSchemaRecord(segment) ? segment.key : segment;
|
|
1313
|
+
return typeof key === 'number' ? key : String(key);
|
|
1314
|
+
});
|
|
1315
|
+
const expected = typeof record.expected === 'string'
|
|
1316
|
+
? record.expected
|
|
1317
|
+
: typeof record.message === 'string' ? record.message : 'a valid value';
|
|
1318
|
+
return { path: paramsPath(tokens), expected, got: preview(valueAt(value, tokens)) };
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
const constraintText = (subset) => {
|
|
1323
|
+
const parts = [];
|
|
1324
|
+
const value = (key) => subset[key];
|
|
1325
|
+
if (typeof value('minimum') === 'number')
|
|
1326
|
+
parts.push(`>= ${value('minimum')}`);
|
|
1327
|
+
if (typeof value('exclusiveMinimum') === 'number')
|
|
1328
|
+
parts.push(`> ${value('exclusiveMinimum')}`);
|
|
1329
|
+
if (typeof value('maximum') === 'number')
|
|
1330
|
+
parts.push(`<= ${value('maximum')}`);
|
|
1331
|
+
if (typeof value('exclusiveMaximum') === 'number')
|
|
1332
|
+
parts.push(`< ${value('exclusiveMaximum')}`);
|
|
1333
|
+
if (typeof value('multipleOf') === 'number')
|
|
1334
|
+
parts.push(`multiple of ${value('multipleOf')}`);
|
|
1335
|
+
if (typeof value('minLength') === 'number')
|
|
1336
|
+
parts.push(`at least ${countOf(value('minLength'), 'character')}`);
|
|
1337
|
+
if (typeof value('maxLength') === 'number')
|
|
1338
|
+
parts.push(`at most ${countOf(value('maxLength'), 'character')}`);
|
|
1339
|
+
if (typeof value('minItems') === 'number')
|
|
1340
|
+
parts.push(`at least ${countOf(value('minItems'), 'item')}`);
|
|
1341
|
+
if (typeof value('maxItems') === 'number')
|
|
1342
|
+
parts.push(`at most ${countOf(value('maxItems'), 'item')}`);
|
|
1343
|
+
if (value('uniqueItems') === true)
|
|
1344
|
+
parts.push('unique items');
|
|
1345
|
+
if (typeof value('pattern') === 'string')
|
|
1346
|
+
parts.push(`matching /${value('pattern')}/`);
|
|
1347
|
+
if (typeof value('format') === 'string')
|
|
1348
|
+
parts.push(`format ${value('format')}`);
|
|
1349
|
+
return parts.join(', ');
|
|
1350
|
+
};
|
|
1351
|
+
/**
|
|
1352
|
+
* While a run has a catalog, its tool names are reserved (`run_code` in code mode too), and a
|
|
1353
|
+
* method path must differ from every tool name.
|
|
1354
|
+
*/
|
|
1355
|
+
export const assertNoCatalogCollisions = (catalog, tools) => {
|
|
1356
|
+
const catalogToolNames = new Set([
|
|
1357
|
+
...Object.values(toolNames),
|
|
1358
|
+
...(catalog.codeMode ? [FLEX_CODE_MODE_TOOL_NAME] : []),
|
|
1359
|
+
]);
|
|
1360
|
+
for (const name of catalogToolNames) {
|
|
1361
|
+
if (Object.prototype.hasOwnProperty.call(tools, name)) {
|
|
1362
|
+
throw new FlexHarnessValidationError(`Tool provider cannot define enabled built-in tool "${name}".`);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
for (const path of catalog.methods) {
|
|
1366
|
+
if (Object.prototype.hasOwnProperty.call(tools, path) || catalogToolNames.has(path) || path === 'invalid') {
|
|
1367
|
+
throw new FlexHarnessValidationError(`Tool catalog method "${path}" has the name of a tool.`);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
/**
|
|
1372
|
+
* The AI SDK schema of a built-in catalog tool: the definition's JSON Schema, validated with it, so a
|
|
1373
|
+
* malformed call goes back to the model like any other invalid tool input.
|
|
1374
|
+
*/
|
|
1375
|
+
export const catalogToolInputSchema = (definition) => {
|
|
1376
|
+
const validator = new plugins.JsonSchemaValidator(structuredClone(definition.inputSchema), '2020-12', false);
|
|
1377
|
+
return plugins.jsonSchema(definition.inputSchema, {
|
|
1378
|
+
validate: (value) => {
|
|
1379
|
+
const result = validator.validate(value);
|
|
1380
|
+
if (result.valid)
|
|
1381
|
+
return { success: true, value: value };
|
|
1382
|
+
const message = result.errors
|
|
1383
|
+
.filter((unit) => !['properties', 'items', 'additionalProperties'].includes(unit.keyword))
|
|
1384
|
+
.map((unit) => `${unit.instanceLocation.replace(/^#/, '') || '/'}: ${unit.error}`)
|
|
1385
|
+
.join(' ');
|
|
1386
|
+
return { success: false, error: new Error(message || 'Invalid input.') };
|
|
1387
|
+
},
|
|
1388
|
+
});
|
|
1389
|
+
};
|
|
1390
|
+
/** A root-level method declaration gets `declare`, as a namespace member does not need it. */
|
|
1391
|
+
const withDeclare = (text) => {
|
|
1392
|
+
const lines = text.split('\n');
|
|
1393
|
+
const index = lines.findIndex((line) => /^(?:async\s+)?function\s/.test(line));
|
|
1394
|
+
if (index !== -1)
|
|
1395
|
+
lines[index] = `declare ${lines[index]}`;
|
|
1396
|
+
return lines.join('\n');
|
|
1397
|
+
};
|
|
1398
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50b29sY2F0YWxvZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMudG9vbGNhdGFsb2cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pELE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIsd0JBQXdCLElBQUksTUFBTSxFQUNsQyw0QkFBNEIsSUFBSSxTQUFTLEdBZ0IxQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsT0FBTyxFQUNQLFFBQVEsRUFDUixXQUFXLEVBQ1gsWUFBWSxFQUNaLGNBQWMsR0FHZixNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBOEQzRCxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFDdEQsTUFBTSxpQkFBaUIsR0FBRyx1REFBdUQsQ0FBQztBQUNsRixNQUFNLGVBQWUsR0FBRywwQkFBMEIsQ0FBQztBQUNuRCw0RUFBNEU7QUFDNUUsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDNUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLElBQUk7SUFDdEcsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLFFBQVE7SUFDeEcsSUFBSSxFQUFFLFlB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
|