@tangle-network/agent-runtime 0.51.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.
Files changed (51) hide show
  1. package/dist/agent.d.ts +2 -2
  2. package/dist/agent.js +2 -2
  3. package/dist/analyst-loop.d.ts +1 -1
  4. package/dist/{chunk-HAA4KZUD.js → chunk-5M2WDWBI.js} +3 -3
  5. package/dist/{chunk-HYG4ISNS.js → chunk-AYRQZRDV.js} +2 -2
  6. package/dist/{chunk-47SWANFA.js → chunk-FO4DCM7R.js} +2 -2
  7. package/dist/{chunk-7JITYN6T.js → chunk-JFIYKDXF.js} +17 -2
  8. package/dist/chunk-JFIYKDXF.js.map +1 -0
  9. package/dist/{chunk-XEI7AIHU.js → chunk-K5M3SHEU.js} +3 -3
  10. package/dist/{chunk-FQH33M5N.js → chunk-K6WP7PYW.js} +67 -61
  11. package/dist/chunk-K6WP7PYW.js.map +1 -0
  12. package/dist/{chunk-FKHNHUXP.js → chunk-P4QNEXFC.js} +2 -2
  13. package/dist/{coder-_YCf3BAK.d.ts → coder-LKm3Mczw.d.ts} +1 -1
  14. package/dist/{delegation-profile-1GbW5yA3.d.ts → delegation-profile-Bvfro2m1.d.ts} +28 -2
  15. package/dist/{driver-DLI1io57.d.ts → driver-B2RKkVJW.d.ts} +1 -1
  16. package/dist/index.d.ts +121 -11
  17. package/dist/index.js +143 -16
  18. package/dist/index.js.map +1 -1
  19. package/dist/intelligence.d.ts +475 -5
  20. package/dist/intelligence.js +547 -3
  21. package/dist/intelligence.js.map +1 -1
  22. package/dist/{kb-gate-CHAyt4aI.d.ts → kb-gate-CKfykcYQ.d.ts} +2 -2
  23. package/dist/{loop-runner-bin-DFUNgpeK.d.ts → loop-runner-bin-D4Ir7b00.d.ts} +4 -4
  24. package/dist/loop-runner-bin.d.ts +5 -5
  25. package/dist/loop-runner-bin.js +3 -3
  26. package/dist/loops.d.ts +7 -5
  27. package/dist/loops.js +3 -1
  28. package/dist/mcp/bin.js +4 -4
  29. package/dist/mcp/index.d.ts +7 -7
  30. package/dist/mcp/index.js +6 -6
  31. package/dist/{openai-tools-D4HLDWgw.d.ts → openai-tools-CKfR3EMh.d.ts} +1 -1
  32. package/dist/profiles.d.ts +2 -2
  33. package/dist/router-client-B0Qi1NiN.d.ts +120 -0
  34. package/dist/{run-loop-BIineL1T.d.ts → run-loop-DgVhucoR.d.ts} +1 -1
  35. package/dist/runtime.d.ts +62 -126
  36. package/dist/runtime.js +3 -1
  37. package/dist/{types-5MGt5KTY.d.ts → types-CNDJCL_0.d.ts} +1 -1
  38. package/dist/{types-BEQsBhOE.d.ts → types-CklkW4Eh.d.ts} +2 -1
  39. package/dist/workflow.d.ts +2 -2
  40. package/dist/workflow.js +1 -1
  41. package/package.json +1 -1
  42. package/skills/agent-runtime-adoption/SKILL.md +41 -26
  43. package/skills/build-with-agent-runtime/SKILL.md +143 -0
  44. package/skills/loop-writer/SKILL.md +6 -7
  45. package/dist/chunk-7JITYN6T.js.map +0 -1
  46. package/dist/chunk-FQH33M5N.js.map +0 -1
  47. /package/dist/{chunk-HAA4KZUD.js.map → chunk-5M2WDWBI.js.map} +0 -0
  48. /package/dist/{chunk-HYG4ISNS.js.map → chunk-AYRQZRDV.js.map} +0 -0
  49. /package/dist/{chunk-47SWANFA.js.map → chunk-FO4DCM7R.js.map} +0 -0
  50. /package/dist/{chunk-XEI7AIHU.js.map → chunk-K5M3SHEU.js.map} +0 -0
  51. /package/dist/{chunk-FKHNHUXP.js.map → chunk-P4QNEXFC.js.map} +0 -0
@@ -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, { headers: { authorization: `Bearer ${apiKey}` } });
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 Object.keys(certified.artifacts).sort()) {
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,