@mcoda/codali 0.1.86 → 0.1.88
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/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/runtime/CodaliJobRuntime.d.ts +211 -0
- package/dist/runtime/CodaliJobRuntime.d.ts.map +1 -0
- package/dist/runtime/CodaliJobRuntime.js +590 -0
- package/dist/runtime/CodaliRuntime.d.ts +74 -1
- package/dist/runtime/CodaliRuntime.d.ts.map +1 -1
- package/dist/runtime/CodaliRuntime.js +573 -2
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodaliRuntime.d.ts","sourceRoot":"","sources":["../../src/runtime/CodaliRuntime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iCAAiC,EACjC,mBAAmB,EACnB,eAAe,EACf,iCAAiC,EAClC,MAAM,eAAe,CAAC;AAavB,OAAO,KAAK,EAEV,gBAAgB,EAChB,QAAQ,EAER,eAAe,EAEf,aAAa,EACd,MAAM,+BAA+B,CAAC;AAWvC,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"CodaliRuntime.d.ts","sourceRoot":"","sources":["../../src/runtime/CodaliRuntime.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ import { createFileTools } from "../tools/filesystem/FileTools.js";
|
|
|
12
12
|
import { createSearchTool } from "../tools/search/SearchTool.js";
|
|
13
13
|
import { createShellTool } from "../tools/shell/ShellTool.js";
|
|
14
14
|
import { ToolRegistry } from "../tools/ToolRegistry.js";
|
|
15
|
+
import { ToolExecutionError, } from "../tools/ToolTypes.js";
|
|
15
16
|
import { formatInstructionBlocks, loadInstructionBlocks } from "../session/InstructionLoader.js";
|
|
16
17
|
import { SessionStore } from "../session/SessionStore.js";
|
|
17
18
|
import { SubagentOrchestrator, } from "../subagents/SubagentOrchestrator.js";
|
|
@@ -30,6 +31,33 @@ const WEB_TOOL_NAMES = new Set(["docdex_web_research"]);
|
|
|
30
31
|
const MEMORY_WRITE_TOOL_NAMES = new Set(["docdex_memory_save"]);
|
|
31
32
|
const PROFILE_WRITE_TOOL_NAMES = new Set(["docdex_save_preference"]);
|
|
32
33
|
const INDEX_REBUILD_TOOL_NAMES = new Set(["docdex_index_rebuild", "docdex_index_ingest"]);
|
|
34
|
+
const READ_ONLY_DYNAMIC_BACKING_TOOLS = new Set([
|
|
35
|
+
"docdex_search",
|
|
36
|
+
"docdex_batch_search",
|
|
37
|
+
"docdex_open",
|
|
38
|
+
"docdex_files",
|
|
39
|
+
"docdex_tree",
|
|
40
|
+
"docdex_stats",
|
|
41
|
+
]);
|
|
42
|
+
const FORBIDDEN_DYNAMIC_ARG_KEYS = new Set([
|
|
43
|
+
"authorization",
|
|
44
|
+
"apiKey",
|
|
45
|
+
"api_key",
|
|
46
|
+
"baseUrl",
|
|
47
|
+
"base_url",
|
|
48
|
+
"credential",
|
|
49
|
+
"credentials",
|
|
50
|
+
"credentialSource",
|
|
51
|
+
"credential_source",
|
|
52
|
+
"repoId",
|
|
53
|
+
"repo_id",
|
|
54
|
+
"repoRoot",
|
|
55
|
+
"repo_root",
|
|
56
|
+
"tenantId",
|
|
57
|
+
"tenant_id",
|
|
58
|
+
"workspaceRoot",
|
|
59
|
+
"workspace_root",
|
|
60
|
+
]);
|
|
33
61
|
const DOCDEX_TOOL_OPERATIONS = new Map([
|
|
34
62
|
["docdex_health", ["health"]],
|
|
35
63
|
["docdex_initialize", ["initialize"]],
|
|
@@ -103,6 +131,391 @@ const stripUndefined = (input) => {
|
|
|
103
131
|
const isRecord = (value) => {
|
|
104
132
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
105
133
|
};
|
|
134
|
+
const createDynamicToolRegistryState = () => ({
|
|
135
|
+
consideredTools: [],
|
|
136
|
+
registeredDynamicTools: [],
|
|
137
|
+
skippedDynamicTools: [],
|
|
138
|
+
dynamicToolCalls: [],
|
|
139
|
+
});
|
|
140
|
+
const pushUnique = (target, value) => {
|
|
141
|
+
if (!target.includes(value))
|
|
142
|
+
target.push(value);
|
|
143
|
+
};
|
|
144
|
+
const recordSkippedDynamicTool = (state, name, reason) => {
|
|
145
|
+
if (!state.skippedDynamicTools.some((entry) => entry.name === name && entry.reason === reason)) {
|
|
146
|
+
state.skippedDynamicTools.push({ name, reason });
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
const stringArrayFromUnknown = (value) => {
|
|
150
|
+
if (Array.isArray(value)) {
|
|
151
|
+
return value.filter((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
152
|
+
}
|
|
153
|
+
if (typeof value === "string" && value.trim()) {
|
|
154
|
+
return [value.trim()];
|
|
155
|
+
}
|
|
156
|
+
return [];
|
|
157
|
+
};
|
|
158
|
+
const toolNameFromRecord = (value) => {
|
|
159
|
+
for (const key of ["name", "tool", "toolName", "tool_name", "id"]) {
|
|
160
|
+
const entry = value[key];
|
|
161
|
+
if (typeof entry === "string" && entry.trim())
|
|
162
|
+
return entry.trim();
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
};
|
|
166
|
+
const toolNamesFromManifestEntries = (entries) => {
|
|
167
|
+
if (!Array.isArray(entries))
|
|
168
|
+
return [];
|
|
169
|
+
const names = [];
|
|
170
|
+
for (const entry of entries) {
|
|
171
|
+
if (typeof entry === "string" && entry.trim()) {
|
|
172
|
+
pushUnique(names, entry.trim());
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (isRecord(entry)) {
|
|
176
|
+
const name = toolNameFromRecord(entry);
|
|
177
|
+
if (name)
|
|
178
|
+
pushUnique(names, name);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return names;
|
|
182
|
+
};
|
|
183
|
+
const toolNamesFromManifest = (manifest) => {
|
|
184
|
+
if (!manifest)
|
|
185
|
+
return [];
|
|
186
|
+
const names = [];
|
|
187
|
+
for (const list of [
|
|
188
|
+
manifest.actualTools,
|
|
189
|
+
manifest.virtualTools,
|
|
190
|
+
manifest.actual_tools,
|
|
191
|
+
manifest.virtual_tools,
|
|
192
|
+
]) {
|
|
193
|
+
for (const name of toolNamesFromManifestEntries(list))
|
|
194
|
+
pushUnique(names, name);
|
|
195
|
+
}
|
|
196
|
+
return names;
|
|
197
|
+
};
|
|
198
|
+
const normalizeRuntimeToolContractEntries = (contracts) => {
|
|
199
|
+
if (!contracts)
|
|
200
|
+
return [];
|
|
201
|
+
if (Array.isArray(contracts)) {
|
|
202
|
+
const entries = [];
|
|
203
|
+
for (const contract of contracts) {
|
|
204
|
+
if (!isRecord(contract))
|
|
205
|
+
continue;
|
|
206
|
+
const name = toolNameFromRecord(contract);
|
|
207
|
+
if (name)
|
|
208
|
+
entries.push([name, contract]);
|
|
209
|
+
}
|
|
210
|
+
return entries;
|
|
211
|
+
}
|
|
212
|
+
if (!isRecord(contracts))
|
|
213
|
+
return [];
|
|
214
|
+
const entries = [];
|
|
215
|
+
for (const [key, value] of Object.entries(contracts)) {
|
|
216
|
+
if (!key.trim())
|
|
217
|
+
continue;
|
|
218
|
+
const contract = isRecord(value)
|
|
219
|
+
? { name: key, ...value }
|
|
220
|
+
: { name: key, metadata: { valueType: typeof value } };
|
|
221
|
+
entries.push([key, contract]);
|
|
222
|
+
}
|
|
223
|
+
return entries;
|
|
224
|
+
};
|
|
225
|
+
const contractString = (contract, camelKey, snakeKey) => {
|
|
226
|
+
const value = contract[camelKey] ?? contract[snakeKey];
|
|
227
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
228
|
+
};
|
|
229
|
+
const contractBoolean = (contract, camelKey, snakeKey) => {
|
|
230
|
+
const value = contract[camelKey] ?? contract[snakeKey];
|
|
231
|
+
return typeof value === "boolean" ? value : undefined;
|
|
232
|
+
};
|
|
233
|
+
const contractStringArray = (contract, camelKey, snakeKey) => {
|
|
234
|
+
return stringArrayFromUnknown(contract[camelKey] ?? contract[snakeKey]);
|
|
235
|
+
};
|
|
236
|
+
const contractCallSchema = (contract) => {
|
|
237
|
+
const schema = contract.callSchema ?? contract.call_schema;
|
|
238
|
+
if (isRecord(schema) && (schema.type === undefined || schema.type === "object")) {
|
|
239
|
+
return {
|
|
240
|
+
...schema,
|
|
241
|
+
type: "object",
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return { type: "object", additionalProperties: true };
|
|
245
|
+
};
|
|
246
|
+
const findForbiddenDynamicArgKeys = (value, path = "$", matches = []) => {
|
|
247
|
+
if (Array.isArray(value)) {
|
|
248
|
+
value.forEach((entry, index) => findForbiddenDynamicArgKeys(entry, `${path}[${index}]`, matches));
|
|
249
|
+
return matches;
|
|
250
|
+
}
|
|
251
|
+
if (!isRecord(value))
|
|
252
|
+
return matches;
|
|
253
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
254
|
+
const childPath = `${path}.${key}`;
|
|
255
|
+
if (FORBIDDEN_DYNAMIC_ARG_KEYS.has(key)) {
|
|
256
|
+
matches.push(childPath);
|
|
257
|
+
}
|
|
258
|
+
findForbiddenDynamicArgKeys(entry, childPath, matches);
|
|
259
|
+
}
|
|
260
|
+
return matches;
|
|
261
|
+
};
|
|
262
|
+
const assertDynamicArgsStayInScope = (toolName, args) => {
|
|
263
|
+
const forbidden = findForbiddenDynamicArgKeys(args);
|
|
264
|
+
if (forbidden.length) {
|
|
265
|
+
throw new ToolExecutionError("tool_permission_denied", "Dynamic tool arguments cannot override tenant or repo scope", {
|
|
266
|
+
retryable: false,
|
|
267
|
+
details: { tool: toolName, forbidden },
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
const readStringArg = (args, keys) => {
|
|
272
|
+
for (const key of keys) {
|
|
273
|
+
const value = args[key];
|
|
274
|
+
if (typeof value === "string" && value.trim())
|
|
275
|
+
return value.trim();
|
|
276
|
+
}
|
|
277
|
+
return undefined;
|
|
278
|
+
};
|
|
279
|
+
const readStringArrayArg = (args, keys) => {
|
|
280
|
+
for (const key of keys) {
|
|
281
|
+
const values = stringArrayFromUnknown(args[key]);
|
|
282
|
+
if (values.length)
|
|
283
|
+
return values;
|
|
284
|
+
}
|
|
285
|
+
return [];
|
|
286
|
+
};
|
|
287
|
+
const readNumberArg = (args, keys) => {
|
|
288
|
+
for (const key of keys) {
|
|
289
|
+
const value = args[key];
|
|
290
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
291
|
+
return value;
|
|
292
|
+
}
|
|
293
|
+
return undefined;
|
|
294
|
+
};
|
|
295
|
+
const readBooleanArg = (args, keys) => {
|
|
296
|
+
for (const key of keys) {
|
|
297
|
+
const value = args[key];
|
|
298
|
+
if (typeof value === "boolean")
|
|
299
|
+
return value;
|
|
300
|
+
}
|
|
301
|
+
return undefined;
|
|
302
|
+
};
|
|
303
|
+
const selectDocdexBackingCall = (toolName, backingTools, args) => {
|
|
304
|
+
const record = isRecord(args) ? args : {};
|
|
305
|
+
const limit = readNumberArg(record, ["limit", "maxResults", "max_results"]);
|
|
306
|
+
const queries = readStringArrayArg(record, ["queries"]);
|
|
307
|
+
if (queries.length && backingTools.includes("docdex_batch_search")) {
|
|
308
|
+
return {
|
|
309
|
+
toolName: "docdex_batch_search",
|
|
310
|
+
args: stripUndefined({
|
|
311
|
+
queries,
|
|
312
|
+
limit,
|
|
313
|
+
includeLibs: readBooleanArg(record, ["includeLibs", "include_libs"]),
|
|
314
|
+
}),
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
const query = readStringArg(record, ["query", "q", "search", "question", "prompt", "text"]);
|
|
318
|
+
if (query && backingTools.includes("docdex_search")) {
|
|
319
|
+
return { toolName: "docdex_search", args: stripUndefined({ query, limit }) };
|
|
320
|
+
}
|
|
321
|
+
const path = readStringArg(record, ["path", "relPath", "rel_path", "file", "sourcePath", "source_path"]);
|
|
322
|
+
const docId = readStringArg(record, ["docId", "doc_id"]);
|
|
323
|
+
if ((path || docId) && backingTools.includes("docdex_open")) {
|
|
324
|
+
return {
|
|
325
|
+
toolName: "docdex_open",
|
|
326
|
+
args: stripUndefined({
|
|
327
|
+
path,
|
|
328
|
+
docId,
|
|
329
|
+
window: readNumberArg(record, ["window"]),
|
|
330
|
+
textOnly: readBooleanArg(record, ["textOnly", "text_only"]),
|
|
331
|
+
startLine: readNumberArg(record, ["startLine", "start_line"]),
|
|
332
|
+
endLine: readNumberArg(record, ["endLine", "end_line"]),
|
|
333
|
+
head: readNumberArg(record, ["head"]),
|
|
334
|
+
clamp: readBooleanArg(record, ["clamp"]),
|
|
335
|
+
}),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
if (backingTools.includes("docdex_tree")) {
|
|
339
|
+
return {
|
|
340
|
+
toolName: "docdex_tree",
|
|
341
|
+
args: stripUndefined({
|
|
342
|
+
path,
|
|
343
|
+
maxDepth: readNumberArg(record, ["maxDepth", "max_depth"]),
|
|
344
|
+
dirsOnly: readBooleanArg(record, ["dirsOnly", "dirs_only"]),
|
|
345
|
+
includeHidden: readBooleanArg(record, ["includeHidden", "include_hidden"]),
|
|
346
|
+
}),
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
if (backingTools.includes("docdex_files")) {
|
|
350
|
+
return {
|
|
351
|
+
toolName: "docdex_files",
|
|
352
|
+
args: stripUndefined({
|
|
353
|
+
limit,
|
|
354
|
+
offset: readNumberArg(record, ["offset"]),
|
|
355
|
+
}),
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
if (backingTools.includes("docdex_stats")) {
|
|
359
|
+
return { toolName: "docdex_stats", args: {} };
|
|
360
|
+
}
|
|
361
|
+
throw new ToolExecutionError("tool_invalid_args", "Dynamic tool arguments do not match its read-only backing tools", {
|
|
362
|
+
retryable: false,
|
|
363
|
+
details: { tool: toolName, backingTools },
|
|
364
|
+
});
|
|
365
|
+
};
|
|
366
|
+
const createDocdexBackedDynamicTool = (options) => {
|
|
367
|
+
const { name, contract, registry, backingTools, state } = options;
|
|
368
|
+
const executionMode = contractString(contract, "executionMode", "execution_mode") ?? "server_supplied_snapshot_plus_docdex";
|
|
369
|
+
return {
|
|
370
|
+
name,
|
|
371
|
+
description: contract.description ??
|
|
372
|
+
`Read-only runtime tool. Uses ${backingTools.join(", ")} and returns ${contract.resultContract ?? contract.result_contract ?? "contracted app context"}.`,
|
|
373
|
+
inputSchema: contractCallSchema(contract),
|
|
374
|
+
handler: async (args, context) => {
|
|
375
|
+
const startedAt = Date.now();
|
|
376
|
+
let backingTool;
|
|
377
|
+
let recorded = false;
|
|
378
|
+
try {
|
|
379
|
+
assertDynamicArgsStayInScope(name, args);
|
|
380
|
+
const backingCall = selectDocdexBackingCall(name, backingTools, args);
|
|
381
|
+
backingTool = backingCall.toolName;
|
|
382
|
+
const result = await registry.execute(backingCall.toolName, backingCall.args, context);
|
|
383
|
+
if (!result.ok) {
|
|
384
|
+
state.dynamicToolCalls.push({
|
|
385
|
+
name,
|
|
386
|
+
backingTool,
|
|
387
|
+
status: "failed",
|
|
388
|
+
latencyMs: Date.now() - startedAt,
|
|
389
|
+
errorCode: result.error?.code,
|
|
390
|
+
errorMessage: result.error?.message,
|
|
391
|
+
});
|
|
392
|
+
recorded = true;
|
|
393
|
+
throw new ToolExecutionError(result.error?.code ?? "tool_execution_failed", result.error?.message ?? "Backing tool failed", {
|
|
394
|
+
retryable: result.error?.retryable,
|
|
395
|
+
details: { tool: name, backingTool, backingError: result.error?.details },
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
const data = {
|
|
399
|
+
tool: name,
|
|
400
|
+
executionMode,
|
|
401
|
+
resultContract: contract.resultContract ?? contract.result_contract,
|
|
402
|
+
resultSources: contractStringArray(contract, "resultSources", "result_sources"),
|
|
403
|
+
sourcePaths: contractStringArray(contract, "sourcePaths", "source_paths"),
|
|
404
|
+
sourceTypes: contractStringArray(contract, "sourceTypes", "source_types"),
|
|
405
|
+
suppliedSnapshots: contractStringArray(contract, "suppliedSnapshots", "supplied_snapshots"),
|
|
406
|
+
backingTool,
|
|
407
|
+
result: payloadForToolResult(result),
|
|
408
|
+
};
|
|
409
|
+
state.dynamicToolCalls.push({
|
|
410
|
+
name,
|
|
411
|
+
backingTool,
|
|
412
|
+
status: "success",
|
|
413
|
+
latencyMs: Date.now() - startedAt,
|
|
414
|
+
});
|
|
415
|
+
recorded = true;
|
|
416
|
+
return {
|
|
417
|
+
output: JSON.stringify(data, null, 2),
|
|
418
|
+
data,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
catch (error) {
|
|
422
|
+
if (!recorded) {
|
|
423
|
+
state.dynamicToolCalls.push({
|
|
424
|
+
name,
|
|
425
|
+
backingTool,
|
|
426
|
+
status: "failed",
|
|
427
|
+
latencyMs: Date.now() - startedAt,
|
|
428
|
+
errorCode: error instanceof ToolExecutionError ? error.code : "tool_execution_failed",
|
|
429
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
throw error;
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
};
|
|
436
|
+
};
|
|
437
|
+
const resolveGatewayContract = (contract, policyGateway) => {
|
|
438
|
+
const gateway = contract.gateway;
|
|
439
|
+
if (!gateway && !policyGateway)
|
|
440
|
+
return undefined;
|
|
441
|
+
return { ...(policyGateway ?? {}), ...(gateway ?? {}) };
|
|
442
|
+
};
|
|
443
|
+
const createGatewayDynamicTool = (options) => {
|
|
444
|
+
const { name, contract, gateway, input, state } = options;
|
|
445
|
+
const endpoint = typeof gateway.endpoint === "string" ? gateway.endpoint : undefined;
|
|
446
|
+
const signature = typeof gateway.signature === "string" ? gateway.signature : undefined;
|
|
447
|
+
return {
|
|
448
|
+
name,
|
|
449
|
+
description: contract.description ??
|
|
450
|
+
`Read-only app tool dispatched through the runtime app_tool_gateway for ${name}.`,
|
|
451
|
+
inputSchema: contractCallSchema(contract),
|
|
452
|
+
handler: async (args, context) => {
|
|
453
|
+
const startedAt = Date.now();
|
|
454
|
+
try {
|
|
455
|
+
assertDynamicArgsStayInScope(name, args);
|
|
456
|
+
if (!endpoint) {
|
|
457
|
+
throw new ToolExecutionError("tool_permission_denied", "App tool gateway endpoint is not configured", {
|
|
458
|
+
retryable: false,
|
|
459
|
+
details: { tool: name },
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
const signatureRequired = gateway.signatureRequired === true || gateway.signature_required === true;
|
|
463
|
+
if (signatureRequired && !signature) {
|
|
464
|
+
throw new ToolExecutionError("tool_permission_denied", "App tool gateway signature is required", {
|
|
465
|
+
retryable: false,
|
|
466
|
+
details: { tool: name },
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
const response = await fetch(endpoint, {
|
|
470
|
+
method: "POST",
|
|
471
|
+
headers: stripUndefined({
|
|
472
|
+
"content-type": "application/json",
|
|
473
|
+
"x-codali-app-tool-signature": signature,
|
|
474
|
+
}),
|
|
475
|
+
body: JSON.stringify({
|
|
476
|
+
tenant: input.metadata?.tenantId ? { id: input.metadata.tenantId } : undefined,
|
|
477
|
+
tool: name,
|
|
478
|
+
args,
|
|
479
|
+
run_id: context.runId,
|
|
480
|
+
session_id: input.session?.id,
|
|
481
|
+
request_id: input.metadata?.requestId,
|
|
482
|
+
read_only: true,
|
|
483
|
+
result_contract: contract.resultContract ?? contract.result_contract,
|
|
484
|
+
}),
|
|
485
|
+
});
|
|
486
|
+
const text = await response.text();
|
|
487
|
+
if (!response.ok) {
|
|
488
|
+
throw new ToolExecutionError("tool_execution_failed", `App tool gateway failed with HTTP ${response.status}`, {
|
|
489
|
+
retryable: response.status >= 500,
|
|
490
|
+
details: { tool: name, status: response.status, body: text.slice(0, 1000) },
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
const parsed = parseJsonPayload(text);
|
|
494
|
+
state.dynamicToolCalls.push({
|
|
495
|
+
name,
|
|
496
|
+
backingTool: "app_tool_gateway",
|
|
497
|
+
status: "success",
|
|
498
|
+
latencyMs: Date.now() - startedAt,
|
|
499
|
+
});
|
|
500
|
+
return {
|
|
501
|
+
output: text,
|
|
502
|
+
data: parsed ?? text,
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
state.dynamicToolCalls.push({
|
|
507
|
+
name,
|
|
508
|
+
backingTool: "app_tool_gateway",
|
|
509
|
+
status: "failed",
|
|
510
|
+
latencyMs: Date.now() - startedAt,
|
|
511
|
+
errorCode: error instanceof ToolExecutionError ? error.code : "tool_execution_failed",
|
|
512
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
513
|
+
});
|
|
514
|
+
throw error;
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
};
|
|
518
|
+
};
|
|
106
519
|
const parseJsonPayload = (output) => {
|
|
107
520
|
const trimmed = output.trim();
|
|
108
521
|
if (!trimmed || (!trimmed.startsWith("{") && !trimmed.startsWith("[")))
|
|
@@ -624,8 +1037,128 @@ const registerRuntimeTool = (registry, tool, policy, docdex) => {
|
|
|
624
1037
|
registry.register(tool);
|
|
625
1038
|
}
|
|
626
1039
|
};
|
|
627
|
-
const
|
|
1040
|
+
const collectRuntimeToolContractCandidates = (input) => {
|
|
1041
|
+
const contracts = new Map();
|
|
1042
|
+
for (const [name, contract] of normalizeRuntimeToolContractEntries(input.policy.okacamToolContracts)) {
|
|
1043
|
+
contracts.set(name, contract);
|
|
1044
|
+
}
|
|
1045
|
+
for (const [name, contract] of normalizeRuntimeToolContractEntries(input.policy.appToolContracts)) {
|
|
1046
|
+
contracts.set(name, contract);
|
|
1047
|
+
}
|
|
1048
|
+
const names = new Set();
|
|
1049
|
+
for (const name of toolNamesFromManifest(input.docdex?.toolManifest))
|
|
1050
|
+
names.add(name);
|
|
1051
|
+
for (const name of stringArrayFromUnknown(input.policy.okacamVirtualTools))
|
|
1052
|
+
names.add(name);
|
|
1053
|
+
for (const name of stringArrayFromUnknown(input.policy.appVirtualTools))
|
|
1054
|
+
names.add(name);
|
|
1055
|
+
for (const name of contracts.keys())
|
|
1056
|
+
names.add(name);
|
|
1057
|
+
return Array.from(names)
|
|
1058
|
+
.sort()
|
|
1059
|
+
.map((name) => ({ name, contract: contracts.get(name) }));
|
|
1060
|
+
};
|
|
1061
|
+
const registerRuntimeContractTools = (registry, input, state, warnings) => {
|
|
1062
|
+
const candidates = collectRuntimeToolContractCandidates(input);
|
|
1063
|
+
if (!candidates.length)
|
|
1064
|
+
return;
|
|
1065
|
+
const registryNames = new Set(registry.list().map((tool) => tool.name));
|
|
1066
|
+
for (const candidate of candidates) {
|
|
1067
|
+
const name = candidate.name.trim();
|
|
1068
|
+
if (!name)
|
|
1069
|
+
continue;
|
|
1070
|
+
pushUnique(state.consideredTools, name);
|
|
1071
|
+
if (!candidate.contract) {
|
|
1072
|
+
if (!registryNames.has(name))
|
|
1073
|
+
recordSkippedDynamicTool(state, name, "missing_contract");
|
|
1074
|
+
continue;
|
|
1075
|
+
}
|
|
1076
|
+
if (candidate.contract.enabled === false) {
|
|
1077
|
+
recordSkippedDynamicTool(state, name, "contract_disabled");
|
|
1078
|
+
continue;
|
|
1079
|
+
}
|
|
1080
|
+
if (!isRuntimeToolAllowed(name, input.policy) || !isDocdexToolAllowed(name, input.docdex)) {
|
|
1081
|
+
recordSkippedDynamicTool(state, name, "policy_disallowed");
|
|
1082
|
+
continue;
|
|
1083
|
+
}
|
|
1084
|
+
if (registryNames.has(name)) {
|
|
1085
|
+
recordSkippedDynamicTool(state, name, "already_registered");
|
|
1086
|
+
continue;
|
|
1087
|
+
}
|
|
1088
|
+
const readOnly = contractBoolean(candidate.contract, "readOnly", "read_only");
|
|
1089
|
+
if (readOnly === false) {
|
|
1090
|
+
recordSkippedDynamicTool(state, name, "not_read_only");
|
|
1091
|
+
continue;
|
|
1092
|
+
}
|
|
1093
|
+
const executionMode = contractString(candidate.contract, "executionMode", "execution_mode") ??
|
|
1094
|
+
"server_supplied_snapshot_plus_docdex";
|
|
1095
|
+
const gateway = resolveGatewayContract(candidate.contract, input.policy.appToolGateway);
|
|
1096
|
+
if (executionMode === "app_tool_gateway" || gateway?.endpoint) {
|
|
1097
|
+
if (!gateway) {
|
|
1098
|
+
recordSkippedDynamicTool(state, name, "gateway_not_configured");
|
|
1099
|
+
continue;
|
|
1100
|
+
}
|
|
1101
|
+
if (gateway.readOnly === false) {
|
|
1102
|
+
recordSkippedDynamicTool(state, name, "gateway_not_read_only");
|
|
1103
|
+
continue;
|
|
1104
|
+
}
|
|
1105
|
+
const gatewayEndpoint = typeof gateway.endpoint === "string" && gateway.endpoint.trim()
|
|
1106
|
+
? gateway.endpoint.trim()
|
|
1107
|
+
: undefined;
|
|
1108
|
+
if (!gatewayEndpoint) {
|
|
1109
|
+
recordSkippedDynamicTool(state, name, "gateway_endpoint_missing");
|
|
1110
|
+
continue;
|
|
1111
|
+
}
|
|
1112
|
+
if ((gateway.signatureRequired === true || gateway.signature_required === true) && !gateway.signature) {
|
|
1113
|
+
recordSkippedDynamicTool(state, name, "gateway_signature_missing");
|
|
1114
|
+
continue;
|
|
1115
|
+
}
|
|
1116
|
+
registerRuntimeTool(registry, createGatewayDynamicTool({
|
|
1117
|
+
name,
|
|
1118
|
+
contract: candidate.contract,
|
|
1119
|
+
gateway: { ...gateway, endpoint: gatewayEndpoint },
|
|
1120
|
+
input,
|
|
1121
|
+
state,
|
|
1122
|
+
}), input.policy, input.docdex);
|
|
1123
|
+
registryNames.add(name);
|
|
1124
|
+
pushUnique(state.registeredDynamicTools, name);
|
|
1125
|
+
continue;
|
|
1126
|
+
}
|
|
1127
|
+
const declaredBackingTools = contractStringArray(candidate.contract, "backingTools", "backing_tools");
|
|
1128
|
+
if (!declaredBackingTools.length) {
|
|
1129
|
+
recordSkippedDynamicTool(state, name, "missing_backing_tools");
|
|
1130
|
+
continue;
|
|
1131
|
+
}
|
|
1132
|
+
const unsafeBackingTool = declaredBackingTools.find((toolName) => !READ_ONLY_DYNAMIC_BACKING_TOOLS.has(toolName));
|
|
1133
|
+
if (unsafeBackingTool) {
|
|
1134
|
+
recordSkippedDynamicTool(state, name, `unsafe_backing_tool:${unsafeBackingTool}`);
|
|
1135
|
+
continue;
|
|
1136
|
+
}
|
|
1137
|
+
const availableBackingTools = declaredBackingTools.filter((toolName) => registryNames.has(toolName));
|
|
1138
|
+
if (!availableBackingTools.length) {
|
|
1139
|
+
recordSkippedDynamicTool(state, name, "backing_tool_unavailable");
|
|
1140
|
+
continue;
|
|
1141
|
+
}
|
|
1142
|
+
registerRuntimeTool(registry, createDocdexBackedDynamicTool({
|
|
1143
|
+
name,
|
|
1144
|
+
contract: candidate.contract,
|
|
1145
|
+
registry,
|
|
1146
|
+
backingTools: availableBackingTools,
|
|
1147
|
+
state,
|
|
1148
|
+
}), input.policy, input.docdex);
|
|
1149
|
+
registryNames.add(name);
|
|
1150
|
+
pushUnique(state.registeredDynamicTools, name);
|
|
1151
|
+
}
|
|
1152
|
+
const warningSkips = state.skippedDynamicTools.filter((entry) => entry.reason !== "already_registered");
|
|
1153
|
+
if (warningSkips.length) {
|
|
1154
|
+
warnings.push(`Runtime tool contracts skipped: ${warningSkips
|
|
1155
|
+
.map((entry) => `${entry.name}:${entry.reason}`)
|
|
1156
|
+
.join(", ")}`);
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
const buildRuntimeToolRegistry = (input, dynamicToolState, warnings) => {
|
|
628
1160
|
if (input.toolRegistry) {
|
|
1161
|
+
registerRuntimeContractTools(input.toolRegistry, input, dynamicToolState, warnings);
|
|
629
1162
|
return input.toolRegistry;
|
|
630
1163
|
}
|
|
631
1164
|
const registry = new ToolRegistry();
|
|
@@ -634,6 +1167,7 @@ const buildRuntimeToolRegistry = (input) => {
|
|
|
634
1167
|
if (explicitTools) {
|
|
635
1168
|
for (const tool of explicitTools)
|
|
636
1169
|
register(tool);
|
|
1170
|
+
registerRuntimeContractTools(registry, input, dynamicToolState, warnings);
|
|
637
1171
|
return registry;
|
|
638
1172
|
}
|
|
639
1173
|
for (const tool of createFileTools())
|
|
@@ -656,6 +1190,7 @@ const buildRuntimeToolRegistry = (input) => {
|
|
|
656
1190
|
});
|
|
657
1191
|
for (const tool of createDocdexTools(docdexClient))
|
|
658
1192
|
register(tool);
|
|
1193
|
+
registerRuntimeContractTools(registry, input, dynamicToolState, warnings);
|
|
659
1194
|
return registry;
|
|
660
1195
|
};
|
|
661
1196
|
const buildResponseFormat = (response) => {
|
|
@@ -930,6 +1465,25 @@ const emitRuntimeEvent = (event, sink, warnings) => {
|
|
|
930
1465
|
warnings.push(error instanceof Error ? error.message : String(error));
|
|
931
1466
|
}
|
|
932
1467
|
};
|
|
1468
|
+
const buildRuntimeTelemetry = (options) => {
|
|
1469
|
+
const calledTools = [];
|
|
1470
|
+
for (const event of options.events) {
|
|
1471
|
+
if (event.type === "tool_call")
|
|
1472
|
+
pushUnique(calledTools, event.name);
|
|
1473
|
+
}
|
|
1474
|
+
return {
|
|
1475
|
+
runId: options.runId,
|
|
1476
|
+
runtime: "codali",
|
|
1477
|
+
mode: options.input.policy.mode,
|
|
1478
|
+
toolCallCount: options.toolCallsExecuted,
|
|
1479
|
+
calledTools,
|
|
1480
|
+
consideredTools: [...options.dynamicToolState.consideredTools],
|
|
1481
|
+
registeredDynamicTools: [...options.dynamicToolState.registeredDynamicTools],
|
|
1482
|
+
skippedDynamicTools: [...options.dynamicToolState.skippedDynamicTools],
|
|
1483
|
+
dynamicToolCalls: [...options.dynamicToolState.dynamicToolCalls],
|
|
1484
|
+
warnings: [...options.warnings],
|
|
1485
|
+
};
|
|
1486
|
+
};
|
|
933
1487
|
const createSubagentRunner = (options) => {
|
|
934
1488
|
const { input, registry, toolContext, runId, remainingToolBudget } = options;
|
|
935
1489
|
return async ({ spec }) => {
|
|
@@ -1322,6 +1876,7 @@ export const runCodaliTask = async (input) => {
|
|
|
1322
1876
|
const touchedFiles = new Set();
|
|
1323
1877
|
const warnings = [];
|
|
1324
1878
|
const events = [];
|
|
1879
|
+
const dynamicToolState = createDynamicToolRegistryState();
|
|
1325
1880
|
let eventSequence = 0;
|
|
1326
1881
|
const session = await initializeRuntimeSession(input, runId, warnings);
|
|
1327
1882
|
const emit = (event) => {
|
|
@@ -1329,7 +1884,7 @@ export const runCodaliTask = async (input) => {
|
|
|
1329
1884
|
emitRuntimeEvent(event, input.onEvent, warnings);
|
|
1330
1885
|
};
|
|
1331
1886
|
const provider = input.providerInstance ?? createRuntimeProvider(input.provider);
|
|
1332
|
-
const registry = buildRuntimeToolRegistry(input);
|
|
1887
|
+
const registry = buildRuntimeToolRegistry(input, dynamicToolState, warnings);
|
|
1333
1888
|
const originalRecordTouchedFile = input.toolContext?.recordTouchedFile;
|
|
1334
1889
|
const toolContext = {
|
|
1335
1890
|
...input.toolContext,
|
|
@@ -1385,6 +1940,14 @@ export const runCodaliTask = async (input) => {
|
|
|
1385
1940
|
warnings,
|
|
1386
1941
|
events,
|
|
1387
1942
|
runId,
|
|
1943
|
+
telemetry: buildRuntimeTelemetry({
|
|
1944
|
+
input,
|
|
1945
|
+
runId,
|
|
1946
|
+
toolCallsExecuted: result.toolCallsExecuted,
|
|
1947
|
+
events,
|
|
1948
|
+
warnings,
|
|
1949
|
+
dynamicToolState,
|
|
1950
|
+
}),
|
|
1388
1951
|
session: toSessionSummary(finalSession),
|
|
1389
1952
|
};
|
|
1390
1953
|
}
|
|
@@ -1436,6 +1999,14 @@ export const runCodaliTask = async (input) => {
|
|
|
1436
1999
|
warnings,
|
|
1437
2000
|
events,
|
|
1438
2001
|
runId,
|
|
2002
|
+
telemetry: buildRuntimeTelemetry({
|
|
2003
|
+
input,
|
|
2004
|
+
runId,
|
|
2005
|
+
toolCallsExecuted: result.toolCallsExecuted,
|
|
2006
|
+
events,
|
|
2007
|
+
warnings,
|
|
2008
|
+
dynamicToolState,
|
|
2009
|
+
}),
|
|
1439
2010
|
session: toSessionSummary(finalSession),
|
|
1440
2011
|
};
|
|
1441
2012
|
}
|