@tangle-network/agent-runtime 0.52.0 → 0.53.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/agent.d.ts +2 -2
- package/dist/agent.js +2 -2
- package/dist/analyst-loop.d.ts +1 -1
- package/dist/{chunk-7SP2OVYZ.js → chunk-5M2WDWBI.js} +3 -3
- package/dist/{chunk-4JI4BCBI.js → chunk-AYRQZRDV.js} +2 -2
- package/dist/{chunk-BERLUBAP.js → chunk-FO4DCM7R.js} +2 -2
- package/dist/{chunk-7JITYN6T.js → chunk-JFIYKDXF.js} +17 -2
- package/dist/chunk-JFIYKDXF.js.map +1 -0
- package/dist/{chunk-COAVO6QB.js → chunk-K5M3SHEU.js} +3 -3
- package/dist/{chunk-2OU7ZQPD.js → chunk-K6WP7PYW.js} +42 -57
- package/dist/chunk-K6WP7PYW.js.map +1 -0
- package/dist/{chunk-V2K35HF2.js → chunk-P4QNEXFC.js} +2 -2
- package/dist/{coder-_YCf3BAK.d.ts → coder-LKm3Mczw.d.ts} +1 -1
- package/dist/{delegation-profile-1GbW5yA3.d.ts → delegation-profile-Bvfro2m1.d.ts} +28 -2
- package/dist/{driver-DLI1io57.d.ts → driver-B2RKkVJW.d.ts} +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +475 -5
- package/dist/intelligence.js +547 -3
- package/dist/intelligence.js.map +1 -1
- package/dist/{kb-gate-CHAyt4aI.d.ts → kb-gate-CKfykcYQ.d.ts} +2 -2
- package/dist/{loop-runner-bin-DFUNgpeK.d.ts → loop-runner-bin-D4Ir7b00.d.ts} +4 -4
- package/dist/loop-runner-bin.d.ts +5 -5
- package/dist/loop-runner-bin.js +3 -3
- package/dist/loops.d.ts +6 -5
- package/dist/loops.js +1 -1
- package/dist/mcp/bin.js +4 -4
- package/dist/mcp/index.d.ts +7 -7
- package/dist/mcp/index.js +6 -6
- package/dist/{openai-tools-D4HLDWgw.d.ts → openai-tools-CKfR3EMh.d.ts} +1 -1
- package/dist/profiles.d.ts +2 -2
- package/dist/router-client-B0Qi1NiN.d.ts +120 -0
- package/dist/{run-loop-BIineL1T.d.ts → run-loop-DgVhucoR.d.ts} +1 -1
- package/dist/runtime.d.ts +16 -119
- package/dist/runtime.js +1 -1
- package/dist/{types-5MGt5KTY.d.ts → types-CNDJCL_0.d.ts} +1 -1
- package/dist/{types-BEQsBhOE.d.ts → types-CklkW4Eh.d.ts} +2 -1
- package/dist/workflow.d.ts +2 -2
- package/dist/workflow.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2OU7ZQPD.js.map +0 -1
- package/dist/chunk-7JITYN6T.js.map +0 -1
- /package/dist/{chunk-7SP2OVYZ.js.map → chunk-5M2WDWBI.js.map} +0 -0
- /package/dist/{chunk-4JI4BCBI.js.map → chunk-AYRQZRDV.js.map} +0 -0
- /package/dist/{chunk-BERLUBAP.js.map → chunk-FO4DCM7R.js.map} +0 -0
- /package/dist/{chunk-COAVO6QB.js.map → chunk-K5M3SHEU.js.map} +0 -0
- /package/dist/{chunk-V2K35HF2.js.map → chunk-P4QNEXFC.js.map} +0 -0
package/dist/intelligence.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
buildLoopOtelSpans,
|
|
2
3
|
createOtelExporter,
|
|
3
4
|
loopEventToOtelSpan
|
|
4
5
|
} from "./chunk-G3RGMA7C.js";
|
|
@@ -55,6 +56,14 @@ function resolveEffort(tier, overrides) {
|
|
|
55
56
|
function isIntelligenceOff(settings) {
|
|
56
57
|
return settings.analysts === false && settings.corpus === "off" && settings.fanout <= 1 && settings.loops === false && settings.intelligenceBudgetUsd === 0;
|
|
57
58
|
}
|
|
59
|
+
function compileEffort(settings) {
|
|
60
|
+
return {
|
|
61
|
+
withAnalyst: settings.analysts,
|
|
62
|
+
fanout: settings.fanout,
|
|
63
|
+
withLoops: settings.loops,
|
|
64
|
+
intelligenceBudgetUsd: settings.intelligenceBudgetUsd
|
|
65
|
+
};
|
|
66
|
+
}
|
|
58
67
|
|
|
59
68
|
// src/intelligence/redact.ts
|
|
60
69
|
var redactedMarker = "[redacted]";
|
|
@@ -107,9 +116,141 @@ function resolveRedactor(redact) {
|
|
|
107
116
|
return redact ?? defaultRedactor;
|
|
108
117
|
}
|
|
109
118
|
|
|
119
|
+
// src/intelligence/capability.ts
|
|
120
|
+
var CapabilityNotAdmittedError = class extends Error {
|
|
121
|
+
kind;
|
|
122
|
+
capabilityId;
|
|
123
|
+
constructor(kind, capabilityId, reason) {
|
|
124
|
+
super(`capability '${capabilityId}': binding '${kind}' not admitted \u2014 ${reason}`);
|
|
125
|
+
this.name = "CapabilityNotAdmittedError";
|
|
126
|
+
this.kind = kind;
|
|
127
|
+
this.capabilityId = capabilityId;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
var provenanceFromArtifact = (a) => ({
|
|
131
|
+
contentHash: a.contentHash,
|
|
132
|
+
version: a.version,
|
|
133
|
+
lift: a.lift,
|
|
134
|
+
promotedAt: a.promotedAt,
|
|
135
|
+
sourcePath: a.path
|
|
136
|
+
});
|
|
137
|
+
var contextKindForType = (type) => type === "prompt-surface" || type === "skill" ? type : "instructions";
|
|
138
|
+
function inferCapability(type, a) {
|
|
139
|
+
const id = `${type}:${a.path ?? a.index}`;
|
|
140
|
+
const provenance = provenanceFromArtifact(a);
|
|
141
|
+
const parsed = tryParseJson(a.content);
|
|
142
|
+
if (parsed && typeof parsed === "object") {
|
|
143
|
+
const obj = parsed;
|
|
144
|
+
if (typeof obj.command === "string") {
|
|
145
|
+
return {
|
|
146
|
+
id,
|
|
147
|
+
iface: { surface: "mcp", serverName: String(obj.name ?? type) },
|
|
148
|
+
binding: {
|
|
149
|
+
kind: "mcp-stdio",
|
|
150
|
+
command: obj.command,
|
|
151
|
+
...Array.isArray(obj.args) ? { args: obj.args.map(String) } : {},
|
|
152
|
+
...isStringRecord(obj.env) ? { env: obj.env } : {},
|
|
153
|
+
...typeof obj.cwd === "string" ? { cwd: obj.cwd } : {}
|
|
154
|
+
},
|
|
155
|
+
auth: { mode: "none" },
|
|
156
|
+
provenance
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (typeof obj.url === "string" && (obj.transport === "http" || obj.transport === "sse")) {
|
|
160
|
+
return {
|
|
161
|
+
id,
|
|
162
|
+
iface: { surface: "mcp", serverName: String(obj.name ?? type) },
|
|
163
|
+
binding: {
|
|
164
|
+
kind: "mcp-remote",
|
|
165
|
+
url: obj.url,
|
|
166
|
+
transport: obj.transport,
|
|
167
|
+
...isStringRecord(obj.headers) ? { headers: obj.headers } : {}
|
|
168
|
+
},
|
|
169
|
+
auth: { mode: "none" },
|
|
170
|
+
provenance
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if (typeof obj.name === "string" && isJsonSchema(obj.parameters)) {
|
|
174
|
+
const iface = {
|
|
175
|
+
surface: "tool",
|
|
176
|
+
name: obj.name,
|
|
177
|
+
...typeof obj.description === "string" ? { description: obj.description } : {},
|
|
178
|
+
parameters: obj.parameters
|
|
179
|
+
};
|
|
180
|
+
if (typeof obj.url === "string") {
|
|
181
|
+
return {
|
|
182
|
+
id,
|
|
183
|
+
iface,
|
|
184
|
+
binding: {
|
|
185
|
+
kind: "http",
|
|
186
|
+
url: obj.url,
|
|
187
|
+
...typeof obj.method === "string" ? { method: obj.method } : {}
|
|
188
|
+
},
|
|
189
|
+
auth: { mode: "none" },
|
|
190
|
+
provenance
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
id,
|
|
195
|
+
iface,
|
|
196
|
+
binding: { kind: "inline", content: { kind: "inline", content: a.content } },
|
|
197
|
+
auth: { mode: "none" },
|
|
198
|
+
provenance
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
id,
|
|
204
|
+
iface: { surface: "context", kind: "instructions", name: a.path ?? type },
|
|
205
|
+
binding: { kind: "inline", content: { kind: "inline", content: a.content } },
|
|
206
|
+
auth: { mode: "none" },
|
|
207
|
+
provenance
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function manifestFromProfile(profile) {
|
|
211
|
+
const capabilities = [];
|
|
212
|
+
for (const type of Object.keys(profile.artifacts).sort()) {
|
|
213
|
+
const bucket = profile.artifacts[type] ?? [];
|
|
214
|
+
const sorted = [...bucket].map((a, index) => ({ ...a, index })).sort((x, y) => (x.path ?? "").localeCompare(y.path ?? ""));
|
|
215
|
+
for (const a of sorted) {
|
|
216
|
+
if (type === "prompt-surface" || type === "skill") {
|
|
217
|
+
capabilities.push({
|
|
218
|
+
id: `${type}:${a.path ?? a.index}`,
|
|
219
|
+
iface: { surface: "context", kind: contextKindForType(type), name: a.path ?? type },
|
|
220
|
+
binding: { kind: "inline", content: { kind: "inline", content: a.content } },
|
|
221
|
+
auth: { mode: "none" },
|
|
222
|
+
provenance: provenanceFromArtifact(a)
|
|
223
|
+
});
|
|
224
|
+
} else {
|
|
225
|
+
capabilities.push(inferCapability(type, a));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
target: profile.target,
|
|
231
|
+
generatedAt: profile.generatedAt,
|
|
232
|
+
promptSurface: profile.promptSurface,
|
|
233
|
+
capabilities
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function tryParseJson(s) {
|
|
237
|
+
try {
|
|
238
|
+
return JSON.parse(s);
|
|
239
|
+
} catch {
|
|
240
|
+
return void 0;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function isStringRecord(v) {
|
|
244
|
+
return typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every((x) => typeof x === "string");
|
|
245
|
+
}
|
|
246
|
+
function isJsonSchema(v) {
|
|
247
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
248
|
+
}
|
|
249
|
+
|
|
110
250
|
// src/intelligence/delivery.ts
|
|
111
251
|
var defaultPlaneBaseUrl = "https://intelligence.tangle.tools";
|
|
112
252
|
var defaultRefreshMs = 3e5;
|
|
253
|
+
var defaultPullTimeoutMs = 1e4;
|
|
113
254
|
function resolvePlaneBaseUrl(baseUrl) {
|
|
114
255
|
if (baseUrl) return baseUrl.replace(/\/+$/, "");
|
|
115
256
|
if (typeof process !== "undefined" && process.env.TANGLE_INTELLIGENCE_URL) {
|
|
@@ -132,7 +273,10 @@ async function pullCertified(opts) {
|
|
|
132
273
|
const url = `${baseUrl}/v1/profiles/${encodeURIComponent(opts.target)}/composed`;
|
|
133
274
|
let res;
|
|
134
275
|
try {
|
|
135
|
-
res = await doFetch(url, {
|
|
276
|
+
res = await doFetch(url, {
|
|
277
|
+
headers: { authorization: `Bearer ${apiKey}` },
|
|
278
|
+
signal: AbortSignal.timeout(opts.timeoutMs ?? defaultPullTimeoutMs)
|
|
279
|
+
});
|
|
136
280
|
} catch (err) {
|
|
137
281
|
return {
|
|
138
282
|
succeeded: false,
|
|
@@ -163,12 +307,12 @@ async function pullCertified(opts) {
|
|
|
163
307
|
};
|
|
164
308
|
}
|
|
165
309
|
}
|
|
310
|
+
var promptFoldTypes = ["prompt-surface", "skill", "instructions"];
|
|
166
311
|
function composeCertifiedPrompt(base, certified) {
|
|
167
312
|
if (!certified) return base;
|
|
168
313
|
const parts = [];
|
|
169
314
|
if (certified.promptSurface?.surface.trim()) parts.push(certified.promptSurface.surface.trim());
|
|
170
|
-
for (const type of
|
|
171
|
-
if (type !== "prompt-surface" && type !== "skill") continue;
|
|
315
|
+
for (const type of promptFoldTypes) {
|
|
172
316
|
const bucket = certified.artifacts[type] ?? [];
|
|
173
317
|
for (const a of [...bucket].sort((x, y) => (x.path ?? "").localeCompare(y.path ?? ""))) {
|
|
174
318
|
if (a.content.trim()) parts.push(a.content.trim());
|
|
@@ -196,6 +340,7 @@ function withCertifiedDelivery(agent, config) {
|
|
|
196
340
|
target,
|
|
197
341
|
apiKey: config.apiKey,
|
|
198
342
|
baseUrl: config.baseUrl,
|
|
343
|
+
timeoutMs: config.timeoutMs,
|
|
199
344
|
fetchImpl: config.fetchImpl
|
|
200
345
|
});
|
|
201
346
|
lastPullAt = Date.now();
|
|
@@ -226,6 +371,385 @@ function withCertifiedDelivery(agent, config) {
|
|
|
226
371
|
return wrapped;
|
|
227
372
|
}
|
|
228
373
|
|
|
374
|
+
// src/intelligence/resolver.ts
|
|
375
|
+
function emptyAccumulator() {
|
|
376
|
+
return {
|
|
377
|
+
tools: [],
|
|
378
|
+
executors: /* @__PURE__ */ new Map(),
|
|
379
|
+
mcpConnections: {},
|
|
380
|
+
contextArtifacts: {},
|
|
381
|
+
files: [],
|
|
382
|
+
retrieval: [],
|
|
383
|
+
hooks: [],
|
|
384
|
+
subagents: [],
|
|
385
|
+
teardowns: [],
|
|
386
|
+
toolCapabilityId: /* @__PURE__ */ new Map(),
|
|
387
|
+
mcpCapability: /* @__PURE__ */ new Map()
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
async function composeCertifiedProfile(base, manifest, ctx = {}) {
|
|
391
|
+
if (!manifest || manifest.capabilities.length === 0) {
|
|
392
|
+
return baseSurface(base.systemPrompt, manifest?.promptSurface ?? null);
|
|
393
|
+
}
|
|
394
|
+
const acc = emptyAccumulator();
|
|
395
|
+
for (const cap of manifest.capabilities) {
|
|
396
|
+
try {
|
|
397
|
+
await resolveCapability(cap, ctx, acc);
|
|
398
|
+
} catch (err) {
|
|
399
|
+
if (err instanceof CapabilityNotAdmittedError) throw err;
|
|
400
|
+
ctx.onDrop?.(cap.id, err instanceof Error ? err : new Error(String(err)));
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
await driftDropTools(acc, ctx);
|
|
404
|
+
const promptAdditions = collectPromptAdditions(manifest.promptSurface, acc.contextArtifacts);
|
|
405
|
+
const systemPrompt = composeCertifiedPrompt(base.systemPrompt, {
|
|
406
|
+
target: manifest.target,
|
|
407
|
+
generatedAt: manifest.generatedAt,
|
|
408
|
+
promptSurface: manifest.promptSurface,
|
|
409
|
+
artifacts: acc.contextArtifacts
|
|
410
|
+
});
|
|
411
|
+
const teardowns = acc.teardowns;
|
|
412
|
+
return {
|
|
413
|
+
tools: acc.tools,
|
|
414
|
+
async execute(name, args, task) {
|
|
415
|
+
const fn = acc.executors.get(name);
|
|
416
|
+
if (!fn) throw new Error(`composeCertifiedProfile.execute: unknown tool '${name}'`);
|
|
417
|
+
return fn(args, task);
|
|
418
|
+
},
|
|
419
|
+
mcpConnections: acc.mcpConnections,
|
|
420
|
+
promptAdditions,
|
|
421
|
+
files: acc.files,
|
|
422
|
+
retrieval: acc.retrieval,
|
|
423
|
+
hooks: acc.hooks,
|
|
424
|
+
subagents: acc.subagents,
|
|
425
|
+
systemPrompt,
|
|
426
|
+
async dispose() {
|
|
427
|
+
for (let i = teardowns.length - 1; i >= 0; i -= 1) {
|
|
428
|
+
const teardown = teardowns[i];
|
|
429
|
+
if (teardown) await teardown();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
function baseSurface(systemPrompt, promptSurface) {
|
|
435
|
+
const folded = composeCertifiedPrompt(systemPrompt, {
|
|
436
|
+
target: "",
|
|
437
|
+
generatedAt: "",
|
|
438
|
+
promptSurface,
|
|
439
|
+
artifacts: {}
|
|
440
|
+
});
|
|
441
|
+
return {
|
|
442
|
+
tools: [],
|
|
443
|
+
async execute(name) {
|
|
444
|
+
throw new Error(`composeCertifiedProfile.execute: unknown tool '${name}'`);
|
|
445
|
+
},
|
|
446
|
+
mcpConnections: {},
|
|
447
|
+
promptAdditions: collectPromptAdditions(promptSurface, {}),
|
|
448
|
+
files: [],
|
|
449
|
+
retrieval: [],
|
|
450
|
+
hooks: [],
|
|
451
|
+
subagents: [],
|
|
452
|
+
systemPrompt: folded,
|
|
453
|
+
async dispose() {
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function collectPromptAdditions(promptSurface, contextArtifacts) {
|
|
458
|
+
const parts = [];
|
|
459
|
+
if (promptSurface?.surface.trim()) parts.push(promptSurface.surface.trim());
|
|
460
|
+
for (const type of promptFoldTypes) {
|
|
461
|
+
const bucket = contextArtifacts[type] ?? [];
|
|
462
|
+
for (const a of [...bucket].sort((x, y) => (x.path ?? "").localeCompare(y.path ?? ""))) {
|
|
463
|
+
if (a.content.trim()) parts.push(a.content.trim());
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return parts;
|
|
467
|
+
}
|
|
468
|
+
async function resolveCapability(cap, ctx, acc) {
|
|
469
|
+
await resolveBinding(cap, cap.binding, ctx, acc);
|
|
470
|
+
}
|
|
471
|
+
async function resolveBinding(cap, binding, ctx, acc) {
|
|
472
|
+
switch (binding.kind) {
|
|
473
|
+
case "inline":
|
|
474
|
+
resolveInline(cap, binding, acc);
|
|
475
|
+
return;
|
|
476
|
+
case "file":
|
|
477
|
+
resolveFile(cap, binding, acc);
|
|
478
|
+
return;
|
|
479
|
+
case "http":
|
|
480
|
+
resolveHttp(cap, binding, ctx, acc);
|
|
481
|
+
return;
|
|
482
|
+
case "mcp-stdio":
|
|
483
|
+
case "mcp-remote":
|
|
484
|
+
resolveMcp(cap, binding, acc);
|
|
485
|
+
return;
|
|
486
|
+
case "sandbox-code":
|
|
487
|
+
resolveSandboxCode(cap, binding, ctx, acc);
|
|
488
|
+
return;
|
|
489
|
+
case "process-on-infra":
|
|
490
|
+
await resolveProcessOnInfra(cap, binding, ctx, acc, /* @__PURE__ */ new Set());
|
|
491
|
+
return;
|
|
492
|
+
case "rag-index":
|
|
493
|
+
throw new CapabilityNotAdmittedError(
|
|
494
|
+
binding.kind,
|
|
495
|
+
cap.id,
|
|
496
|
+
"rag retrieval lift must clear the E3 score-superiority admission bar before a store is trusted (memory/e3-certified-memory-verdict)"
|
|
497
|
+
);
|
|
498
|
+
case "memory-store":
|
|
499
|
+
throw new CapabilityNotAdmittedError(
|
|
500
|
+
binding.kind,
|
|
501
|
+
cap.id,
|
|
502
|
+
"memory-store admission is gated on the E3 score-superiority bar (memory/e3-certified-memory-verdict)"
|
|
503
|
+
);
|
|
504
|
+
case "wasm":
|
|
505
|
+
throw new CapabilityNotAdmittedError(
|
|
506
|
+
binding.kind,
|
|
507
|
+
cap.id,
|
|
508
|
+
"wasm is an extension-point arm, not yet admitted"
|
|
509
|
+
);
|
|
510
|
+
case "a2a":
|
|
511
|
+
throw new CapabilityNotAdmittedError(
|
|
512
|
+
binding.kind,
|
|
513
|
+
cap.id,
|
|
514
|
+
"a2a is an extension-point arm, not yet admitted"
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
function resolveInline(cap, binding, acc) {
|
|
519
|
+
const content = inlineContent(cap, binding.content);
|
|
520
|
+
if (cap.iface.surface === "context") {
|
|
521
|
+
pushContextArtifact(acc, cap, content);
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
if (cap.iface.surface === "tool") {
|
|
525
|
+
registerInlineTool(cap, content, acc);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
pushContextArtifact(acc, cap, content);
|
|
529
|
+
}
|
|
530
|
+
function registerInlineTool(cap, content, acc) {
|
|
531
|
+
if (cap.iface.surface !== "tool") return;
|
|
532
|
+
const iface = cap.iface;
|
|
533
|
+
acc.tools.push({
|
|
534
|
+
type: "function",
|
|
535
|
+
function: {
|
|
536
|
+
name: iface.name,
|
|
537
|
+
...iface.description ? { description: iface.description } : {},
|
|
538
|
+
parameters: iface.parameters
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
acc.toolCapabilityId.set(iface.name, cap.id);
|
|
542
|
+
acc.executors.set(iface.name, async () => content);
|
|
543
|
+
}
|
|
544
|
+
function resolveFile(cap, binding, acc) {
|
|
545
|
+
const content = inlineContent(cap, binding.content);
|
|
546
|
+
acc.files.push({
|
|
547
|
+
path: binding.path,
|
|
548
|
+
content,
|
|
549
|
+
...binding.executable ? { executable: true } : {}
|
|
550
|
+
});
|
|
551
|
+
if (cap.iface.surface === "context") pushContextArtifact(acc, cap, content);
|
|
552
|
+
}
|
|
553
|
+
function resolveMcp(cap, binding, acc) {
|
|
554
|
+
const serverName = cap.iface.surface === "mcp" ? cap.iface.serverName : cap.id;
|
|
555
|
+
acc.mcpConnections[serverName] = mcpServerFromBinding(binding, cap);
|
|
556
|
+
acc.mcpCapability.set(serverName, {
|
|
557
|
+
capabilityId: cap.id,
|
|
558
|
+
certifiedNames: cap.iface.surface === "mcp" ? cap.iface.toolset ?? [] : []
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
function mcpServerFromBinding(binding, cap) {
|
|
562
|
+
const metadata = { capabilityId: cap.id };
|
|
563
|
+
if (cap.iface.surface === "mcp" && cap.iface.toolset) metadata.tools = cap.iface.toolset;
|
|
564
|
+
if (binding.kind === "mcp-stdio") {
|
|
565
|
+
return {
|
|
566
|
+
transport: "stdio",
|
|
567
|
+
command: binding.command,
|
|
568
|
+
...binding.args ? { args: binding.args } : {},
|
|
569
|
+
...binding.env ? { env: binding.env } : {},
|
|
570
|
+
...binding.cwd ? { cwd: binding.cwd } : {},
|
|
571
|
+
enabled: true,
|
|
572
|
+
metadata
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
return {
|
|
576
|
+
transport: binding.transport,
|
|
577
|
+
url: binding.url,
|
|
578
|
+
...binding.headers ? { headers: binding.headers } : {},
|
|
579
|
+
enabled: true,
|
|
580
|
+
metadata
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
function resolveHttp(cap, binding, ctx, acc) {
|
|
584
|
+
if (cap.iface.surface !== "tool") {
|
|
585
|
+
throw new Error(`capability '${cap.id}': http binding requires a 'tool' interface`);
|
|
586
|
+
}
|
|
587
|
+
const iface = cap.iface;
|
|
588
|
+
acc.tools.push({
|
|
589
|
+
type: "function",
|
|
590
|
+
function: {
|
|
591
|
+
name: iface.name,
|
|
592
|
+
...iface.description ? { description: iface.description } : {},
|
|
593
|
+
parameters: iface.parameters
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
acc.toolCapabilityId.set(iface.name, cap.id);
|
|
597
|
+
const method = binding.method ?? "POST";
|
|
598
|
+
const auth = binding.auth ?? cap.auth;
|
|
599
|
+
acc.executors.set(iface.name, async (args) => {
|
|
600
|
+
const doFetch = ctx.fetchImpl ?? globalThis.fetch;
|
|
601
|
+
if (!doFetch) throw new Error(`capability '${cap.id}': no fetch implementation for http tool`);
|
|
602
|
+
const headers = { "content-type": "application/json" };
|
|
603
|
+
if (auth.mode !== "none") {
|
|
604
|
+
if (!ctx.resolveSecret) {
|
|
605
|
+
throw new Error(
|
|
606
|
+
`capability '${cap.id}': http auth '${auth.mode}' requires ResolveCtx.resolveSecret`
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
const secret = await ctx.resolveSecret(auth, ctx.tenant);
|
|
610
|
+
if (!secret.succeeded) {
|
|
611
|
+
throw new Error(`capability '${cap.id}': secret resolution failed \u2014 ${secret.error}`);
|
|
612
|
+
}
|
|
613
|
+
headers.authorization = `Bearer ${secret.value}`;
|
|
614
|
+
}
|
|
615
|
+
const res = await doFetch(binding.url, {
|
|
616
|
+
method,
|
|
617
|
+
headers,
|
|
618
|
+
...method === "GET" ? {} : { body: JSON.stringify(args) }
|
|
619
|
+
});
|
|
620
|
+
if (!res.ok) {
|
|
621
|
+
const body = await res.text().catch(() => "");
|
|
622
|
+
throw new Error(`capability '${cap.id}': http ${res.status}: ${body.slice(0, 200)}`);
|
|
623
|
+
}
|
|
624
|
+
return res.text();
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
function resolveSandboxCode(cap, binding, ctx, acc) {
|
|
628
|
+
if (cap.iface.surface !== "tool") {
|
|
629
|
+
throw new Error(`capability '${cap.id}': sandbox-code binding requires a 'tool' interface`);
|
|
630
|
+
}
|
|
631
|
+
const iface = cap.iface;
|
|
632
|
+
acc.tools.push({
|
|
633
|
+
type: "function",
|
|
634
|
+
function: {
|
|
635
|
+
name: iface.name,
|
|
636
|
+
...iface.description ? { description: iface.description } : {},
|
|
637
|
+
parameters: iface.parameters
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
acc.toolCapabilityId.set(iface.name, cap.id);
|
|
641
|
+
acc.executors.set(iface.name, async (args, task) => {
|
|
642
|
+
if (!ctx.runSandboxCode) {
|
|
643
|
+
throw new Error(
|
|
644
|
+
`capability '${cap.id}': sandbox-code binding requires ResolveCtx.runSandboxCode`
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
return ctx.runSandboxCode(binding.code, binding.entry, args, task);
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
async function resolveProcessOnInfra(cap, binding, ctx, acc, visited) {
|
|
651
|
+
if (visited.has(binding)) {
|
|
652
|
+
throw new Error(`capability '${cap.id}': process-on-infra cycle detected`);
|
|
653
|
+
}
|
|
654
|
+
visited.add(binding);
|
|
655
|
+
if (!ctx.provisionHost) {
|
|
656
|
+
throw new Error(
|
|
657
|
+
`capability '${cap.id}': process-on-infra binding requires ResolveCtx.provisionHost`
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
if (binding.inner.kind === "process-on-infra") {
|
|
661
|
+
const outer = await ctx.provisionHost(
|
|
662
|
+
binding.host,
|
|
663
|
+
binding.inner,
|
|
664
|
+
hostCostTag(cap, binding.host)
|
|
665
|
+
);
|
|
666
|
+
acc.teardowns.push(() => outer.teardown());
|
|
667
|
+
await resolveProcessOnInfra(cap, binding.inner, ctx, acc, visited);
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
const provisioned = await ctx.provisionHost(
|
|
671
|
+
binding.host,
|
|
672
|
+
binding.inner,
|
|
673
|
+
hostCostTag(cap, binding.host)
|
|
674
|
+
);
|
|
675
|
+
acc.teardowns.push(() => provisioned.teardown());
|
|
676
|
+
if (provisioned.mcpConnection) {
|
|
677
|
+
const serverName = cap.iface.surface === "mcp" ? cap.iface.serverName : cap.id;
|
|
678
|
+
acc.mcpConnections[serverName] = provisioned.mcpConnection;
|
|
679
|
+
acc.mcpCapability.set(serverName, {
|
|
680
|
+
capabilityId: cap.id,
|
|
681
|
+
certifiedNames: cap.iface.surface === "mcp" ? cap.iface.toolset ?? [] : []
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
function hostCostTag(cap, host) {
|
|
686
|
+
return host.costTag ?? `capability/${cap.id}`;
|
|
687
|
+
}
|
|
688
|
+
async function driftDropTools(acc, ctx) {
|
|
689
|
+
const specNames = new Set(acc.tools.map((t) => t.function.name));
|
|
690
|
+
for (const name of acc.executors.keys()) {
|
|
691
|
+
if (!specNames.has(name)) acc.executors.delete(name);
|
|
692
|
+
}
|
|
693
|
+
acc.tools = acc.tools.filter((t) => acc.executors.has(t.function.name));
|
|
694
|
+
if (!ctx.probeLiveToolNames) return;
|
|
695
|
+
const droppedTools = /* @__PURE__ */ new Set();
|
|
696
|
+
for (const tool of acc.tools) {
|
|
697
|
+
const capId = acc.toolCapabilityId.get(tool.function.name);
|
|
698
|
+
if (!capId) continue;
|
|
699
|
+
const live = await ctx.probeLiveToolNames(capId);
|
|
700
|
+
if (!live.includes(tool.function.name)) droppedTools.add(tool.function.name);
|
|
701
|
+
}
|
|
702
|
+
for (const name of droppedTools) {
|
|
703
|
+
acc.executors.delete(name);
|
|
704
|
+
}
|
|
705
|
+
acc.tools = acc.tools.filter((t) => !droppedTools.has(t.function.name));
|
|
706
|
+
for (const [serverName, info] of acc.mcpCapability) {
|
|
707
|
+
if (info.certifiedNames.length === 0) continue;
|
|
708
|
+
const live = await ctx.probeLiveToolNames(info.capabilityId);
|
|
709
|
+
if (!setsEqual(new Set(live), new Set(info.certifiedNames))) {
|
|
710
|
+
delete acc.mcpConnections[serverName];
|
|
711
|
+
acc.mcpCapability.delete(serverName);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
function setsEqual(a, b) {
|
|
716
|
+
if (a.size !== b.size) return false;
|
|
717
|
+
for (const x of a) if (!b.has(x)) return false;
|
|
718
|
+
return true;
|
|
719
|
+
}
|
|
720
|
+
function inlineContent(cap, ref) {
|
|
721
|
+
if (ref.kind === "inline") return ref.content;
|
|
722
|
+
throw new Error(
|
|
723
|
+
`capability '${cap.id}': content ref '${ref.kind}' is not inline \u2014 wire a content fetcher to resolve it`
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
function pushContextArtifact(acc, cap, content) {
|
|
727
|
+
const type = contextArtifactType(cap);
|
|
728
|
+
const bucket = acc.contextArtifacts[type] ?? [];
|
|
729
|
+
acc.contextArtifacts[type] = bucket;
|
|
730
|
+
bucket.push({
|
|
731
|
+
path: contextArtifactPath(cap),
|
|
732
|
+
content,
|
|
733
|
+
contentHash: cap.provenance.contentHash,
|
|
734
|
+
version: cap.provenance.version,
|
|
735
|
+
lift: cap.provenance.lift,
|
|
736
|
+
promotedAt: cap.provenance.promotedAt
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
function contextArtifactType(cap) {
|
|
740
|
+
if (cap.iface.surface === "context") {
|
|
741
|
+
return cap.iface.kind === "instructions" ? "instructions" : cap.iface.kind;
|
|
742
|
+
}
|
|
743
|
+
return "instructions";
|
|
744
|
+
}
|
|
745
|
+
function contextArtifactPath(cap) {
|
|
746
|
+
return cap.provenance.sourcePath;
|
|
747
|
+
}
|
|
748
|
+
async function composeCertifiedProfileFromWire(base, profile, ctx = {}) {
|
|
749
|
+
if (!profile) return composeCertifiedProfile(base, null, ctx);
|
|
750
|
+
return composeCertifiedProfile(base, manifestFromProfile(profile), ctx);
|
|
751
|
+
}
|
|
752
|
+
|
|
229
753
|
// src/intelligence/index.ts
|
|
230
754
|
function resolveEffortConfig(effort) {
|
|
231
755
|
if (effort === void 0) return resolveEffort(defaultEffortTier);
|
|
@@ -365,6 +889,21 @@ function createIntelligenceClient(config) {
|
|
|
365
889
|
exportTrace(meta, outcome, recordedOutput);
|
|
366
890
|
return result;
|
|
367
891
|
},
|
|
892
|
+
recordTrace(events, meta) {
|
|
893
|
+
const traceId = meta?.traceId ?? freshTraceId();
|
|
894
|
+
const ex = getExporter();
|
|
895
|
+
if (!ex || events.length === 0) return traceId;
|
|
896
|
+
try {
|
|
897
|
+
const spans = buildLoopOtelSpans(
|
|
898
|
+
events,
|
|
899
|
+
traceId,
|
|
900
|
+
meta?.rootParentSpanId
|
|
901
|
+
);
|
|
902
|
+
for (const span of spans) ex.exportSpan(span);
|
|
903
|
+
} catch {
|
|
904
|
+
}
|
|
905
|
+
return traceId;
|
|
906
|
+
},
|
|
368
907
|
doctor() {
|
|
369
908
|
const hasRepo = Boolean(config.repo?.owner && config.repo?.name && config.repo?.baseBranch);
|
|
370
909
|
const hasChecks = Boolean(config.checks && config.checks.length > 0);
|
|
@@ -413,11 +952,16 @@ function withTangleIntelligence(agent, clientOrConfig) {
|
|
|
413
952
|
};
|
|
414
953
|
}
|
|
415
954
|
export {
|
|
955
|
+
CapabilityNotAdmittedError,
|
|
956
|
+
compileEffort,
|
|
957
|
+
composeCertifiedProfile,
|
|
958
|
+
composeCertifiedProfileFromWire,
|
|
416
959
|
composeCertifiedPrompt,
|
|
417
960
|
createIntelligenceClient,
|
|
418
961
|
defaultEffortTier,
|
|
419
962
|
defaultRedactor,
|
|
420
963
|
isIntelligenceOff,
|
|
964
|
+
manifestFromProfile,
|
|
421
965
|
pullCertified,
|
|
422
966
|
resolveEffort,
|
|
423
967
|
resolveRedactor,
|