@tangle-network/agent-runtime 0.91.0 → 0.92.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 (86) hide show
  1. package/README.md +4 -2
  2. package/dist/agent.d.ts +3 -3
  3. package/dist/agent.js +88 -9
  4. package/dist/agent.js.map +1 -1
  5. package/dist/{mcp-serve-verifier-XsX8rkB9.d.ts → agentic-generator-B8oeE2Yv.d.ts} +6 -33
  6. package/dist/analyst-loop.d.ts +1 -1
  7. package/dist/candidate-execution/index.d.ts +104 -0
  8. package/dist/candidate-execution/index.js +34 -0
  9. package/dist/candidate-execution/index.js.map +1 -0
  10. package/dist/chunk-3BE7KTMU.js +1229 -0
  11. package/dist/chunk-3BE7KTMU.js.map +1 -0
  12. package/dist/chunk-3D2RHC4K.js +73 -0
  13. package/dist/chunk-3D2RHC4K.js.map +1 -0
  14. package/dist/chunk-3MDZX7YU.js +125 -0
  15. package/dist/chunk-3MDZX7YU.js.map +1 -0
  16. package/dist/{chunk-NC66AM3S.js → chunk-6O5USWVH.js} +32 -1413
  17. package/dist/chunk-6O5USWVH.js.map +1 -0
  18. package/dist/chunk-6O73TRHW.js +142 -0
  19. package/dist/chunk-6O73TRHW.js.map +1 -0
  20. package/dist/{chunk-JRS3YSRZ.js → chunk-7VJJJ2T2.js} +2 -2
  21. package/dist/chunk-A62TP7SK.js +4784 -0
  22. package/dist/chunk-A62TP7SK.js.map +1 -0
  23. package/dist/chunk-APVPRF4Y.js +2166 -0
  24. package/dist/chunk-APVPRF4Y.js.map +1 -0
  25. package/dist/{chunk-DWWII6N2.js → chunk-AUEIDTR3.js} +2 -2
  26. package/dist/{chunk-FF77IBQM.js → chunk-FRBHUNQ7.js} +2 -141
  27. package/dist/chunk-FRBHUNQ7.js.map +1 -0
  28. package/dist/{chunk-7ON74BQO.js → chunk-GDAQUFG6.js} +2 -2
  29. package/dist/{chunk-AD7JW4QG.js → chunk-I7WVPJBZ.js} +23 -1231
  30. package/dist/chunk-I7WVPJBZ.js.map +1 -0
  31. package/dist/{chunk-IOUUITQA.js → chunk-IGGZGKJD.js} +3 -3
  32. package/dist/chunk-PH65PR4F.js +860 -0
  33. package/dist/chunk-PH65PR4F.js.map +1 -0
  34. package/dist/chunk-RSWM2ZKM.js +659 -0
  35. package/dist/chunk-RSWM2ZKM.js.map +1 -0
  36. package/dist/{chunk-BZF3KQ6G.js → chunk-VSWBYWFK.js} +4 -122
  37. package/dist/chunk-VSWBYWFK.js.map +1 -0
  38. package/dist/{completion-gate-DkAnUmpb.d.ts → completion-gate-BLaiN0-X.d.ts} +1 -1
  39. package/dist/{coordination-rRj5hjJK.d.ts → coordination-DxJ83oZA.d.ts} +12 -5
  40. package/dist/environment-provider.d.ts +2 -2
  41. package/dist/environment-provider.js +2 -1
  42. package/dist/improve-CUVCq7xg.d.ts +152 -0
  43. package/dist/{improvement-adapter-CDR8QNVM.d.ts → improvement-adapter-BieWeK5J.d.ts} +16 -0
  44. package/dist/index.d.ts +27 -1092
  45. package/dist/index.js +108 -6491
  46. package/dist/index.js.map +1 -1
  47. package/dist/intelligence.d.ts +160 -13
  48. package/dist/intelligence.js +535 -59
  49. package/dist/intelligence.js.map +1 -1
  50. package/dist/knowledge.d.ts +6 -6
  51. package/dist/knowledge.js +6 -4
  52. package/dist/lifecycle.d.ts +2 -1
  53. package/dist/lifecycle.js +5 -3
  54. package/dist/lifecycle.js.map +1 -1
  55. package/dist/{loop-runner-bin-DTbZVGfM.d.ts → loop-runner-bin-kKUNGLyV.d.ts} +2 -2
  56. package/dist/loop-runner-bin.d.ts +5 -5
  57. package/dist/loop-runner-bin.js +8 -5
  58. package/dist/loops.d.ts +16 -16
  59. package/dist/loops.js +47 -41
  60. package/dist/mcp/bin.js +6 -4
  61. package/dist/mcp/bin.js.map +1 -1
  62. package/dist/mcp/index.d.ts +8 -8
  63. package/dist/mcp/index.js +9 -6
  64. package/dist/mcp/index.js.map +1 -1
  65. package/dist/mcp-serve-verifier-Bg4C3p5S.d.ts +34 -0
  66. package/dist/{openai-tools-C4ZfUD4L.d.ts → openai-tools-E3woykz9.d.ts} +1 -1
  67. package/dist/prepare-Z08a4heC.d.ts +713 -0
  68. package/dist/profiles.d.ts +1 -1
  69. package/dist/{router-client-DJImUDlm.d.ts → sanitize-C9go6tXj.d.ts} +113 -1
  70. package/dist/{structural-rollout-MwlpgQ-6.d.ts → structural-rollout-DHGDbhvR.d.ts} +3 -3
  71. package/dist/{supervise-DPmYPk0j.d.ts → supervise-T2pazU3G.d.ts} +4 -4
  72. package/dist/{types-SyuwunY_.d.ts → types-B00NtbCs.d.ts} +1 -1
  73. package/dist/{types-eMNgWgFi.d.ts → types-DAdIm4AC.d.ts} +1 -1
  74. package/dist/{worktree-fanout-BDFQIO-Y.d.ts → worktree-fanout-BUb2Ag02.d.ts} +3 -3
  75. package/package.json +26 -35
  76. package/skills/build-with-agent-runtime/SKILL.md +1 -1
  77. package/dist/chunk-AD7JW4QG.js.map +0 -1
  78. package/dist/chunk-BZF3KQ6G.js.map +0 -1
  79. package/dist/chunk-FF77IBQM.js.map +0 -1
  80. package/dist/chunk-IVGYLCFH.js +0 -381
  81. package/dist/chunk-IVGYLCFH.js.map +0 -1
  82. package/dist/chunk-NC66AM3S.js.map +0 -1
  83. /package/dist/{chunk-JRS3YSRZ.js.map → chunk-7VJJJ2T2.js.map} +0 -0
  84. /package/dist/{chunk-DWWII6N2.js.map → chunk-AUEIDTR3.js.map} +0 -0
  85. /package/dist/{chunk-7ON74BQO.js.map → chunk-GDAQUFG6.js.map} +0 -0
  86. /package/dist/{chunk-IOUUITQA.js.map → chunk-IGGZGKJD.js.map} +0 -0
@@ -1,10 +1,37 @@
1
+ import {
2
+ improve
3
+ } from "./chunk-RSWM2ZKM.js";
4
+ import {
5
+ canonicalCandidateBytes,
6
+ canonicalCandidateDigest,
7
+ canonicalCandidateDocument,
8
+ executePreparedAgentCandidate,
9
+ immutableCandidateValue,
10
+ omitTopLevelDigest,
11
+ prepareAgentCandidateExecution,
12
+ verifyAgentCandidateBundle
13
+ } from "./chunk-A62TP7SK.js";
14
+ import "./chunk-3BE7KTMU.js";
15
+ import {
16
+ runAnalystLoop
17
+ } from "./chunk-ZQZX77MM.js";
18
+ import "./chunk-FRBHUNQ7.js";
1
19
  import {
2
20
  buildLoopOtelSpans,
21
+ buildRuntimeEventOtelSpans,
3
22
  createOtelExporter,
4
23
  flatOtelSpan
5
- } from "./chunk-IVGYLCFH.js";
24
+ } from "./chunk-APVPRF4Y.js";
25
+ import "./chunk-3D2RHC4K.js";
26
+ import "./chunk-3MDZX7YU.js";
27
+ import "./chunk-FVJ7M3DA.js";
28
+ import "./chunk-CMYMTRGA.js";
29
+ import "./chunk-YEJR7IXO.js";
6
30
  import "./chunk-DGUM43GV.js";
7
31
 
32
+ // src/intelligence/index.ts
33
+ import { contentHash } from "@tangle-network/agent-eval";
34
+
8
35
  // src/intelligence/delivery.ts
9
36
  var defaultPlaneBaseUrl = "https://intelligence.tangle.tools";
10
37
  var defaultRefreshMs = 3e5;
@@ -385,6 +412,311 @@ function isJsonSchema(v) {
385
412
  return typeof v === "object" && v !== null && !Array.isArray(v);
386
413
  }
387
414
 
415
+ // src/intelligence/improvement-cycle.ts
416
+ import { assertNoJudgeVerdict } from "@tangle-network/agent-eval/analyst";
417
+ import { agentCandidateBundleSchema as agentCandidateBundleSchema2, agentProfileSchema } from "@tangle-network/agent-interface";
418
+
419
+ // src/candidate-execution/bundle.ts
420
+ import { agentCandidateBundleSchema } from "@tangle-network/agent-interface";
421
+ function sealAgentCandidateBundle(input) {
422
+ const digest = canonicalCandidateDigest(input);
423
+ const parsed = agentCandidateBundleSchema.parse({ ...input, digest });
424
+ const parsedDigest = canonicalCandidateDigest(omitTopLevelDigest(parsed));
425
+ if (parsedDigest !== digest) {
426
+ throw new Error("candidate bundle changed while validating its canonical wire shape");
427
+ }
428
+ return immutableCandidateValue(parsed);
429
+ }
430
+
431
+ // src/intelligence/improvement-cycle.ts
432
+ async function proposeAgentImprovement(options) {
433
+ if (options.improvement.skills?.writeBack) {
434
+ throw new Error("proposeAgentImprovement cannot write a skill before human approval");
435
+ }
436
+ const analysis = await runAnalystLoop({
437
+ ...options.analysis,
438
+ runId: options.runId
439
+ });
440
+ const findings = assertNoJudgeVerdict(
441
+ analysis.analystResult.findings,
442
+ "proposeAgentImprovement findings"
443
+ );
444
+ const improvement = await improve(options.profile, [...findings], options.improvement);
445
+ const candidateBundle = improvement.shipped && options.buildCandidate ? sealAgentCandidateBundle(await options.buildCandidate({ analysis, improvement })) : void 0;
446
+ if (candidateBundle) assertCandidateProfileBinding(improvement.profile, candidateBundle.profile);
447
+ const surface = options.improvement.surface ?? "prompt";
448
+ const evaluation = canonicalJsonValue(improvementEvaluation(improvement.raw));
449
+ const proposalFindings = canonicalJsonValue([...findings]);
450
+ const withoutDigest = {
451
+ schemaVersion: 1,
452
+ kind: "agent-improvement-proposal",
453
+ runId: options.runId,
454
+ surface,
455
+ proposedAt: (options.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
456
+ baselineProfileHash: canonicalCandidateDigest(options.profile),
457
+ candidateProfile: improvement.profile,
458
+ candidateProfileHash: canonicalCandidateDigest(improvement.profile),
459
+ findings: proposalFindings,
460
+ evaluation,
461
+ ...candidateBundle ? { candidateBundle } : {}
462
+ };
463
+ const proposal = canonicalCandidateDocument(withoutDigest).value;
464
+ return { analysis, improvement, proposal };
465
+ }
466
+ function reviewAgentImprovementProposal(inputProposal, input) {
467
+ const proposal = verifyAgentImprovementProposal(inputProposal);
468
+ if (!input.reviewedBy.trim()) throw new Error("candidate review requires reviewedBy");
469
+ if (!input.reason.trim()) throw new Error("candidate review requires a reason");
470
+ if (input.decision === "approve") {
471
+ if (proposal.evaluation.gateDecision !== "ship") {
472
+ throw new Error("candidate cannot be approved without a passing measured comparison");
473
+ }
474
+ if (!proposal.candidateBundle) {
475
+ throw new Error("candidate cannot be approved until an executable bundle is sealed");
476
+ }
477
+ }
478
+ const withoutDigest = {
479
+ schemaVersion: 1,
480
+ kind: "agent-improvement-review",
481
+ proposalDigest: proposal.digest,
482
+ ...proposal.candidateBundle ? { candidateBundleDigest: proposal.candidateBundle.digest } : {},
483
+ decision: input.decision,
484
+ reviewedBy: input.reviewedBy,
485
+ reviewedAt: (input.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
486
+ reason: input.reason,
487
+ ...input.feedback === void 0 ? {} : { feedback: input.feedback }
488
+ };
489
+ return canonicalCandidateDocument(withoutDigest).value;
490
+ }
491
+ async function executeApprovedAgentCandidate(options) {
492
+ const proposal = verifyAgentImprovementProposal(options.proposal);
493
+ const review = verifyAgentImprovementReview(options.review);
494
+ if (review.decision !== "approve") throw new Error("candidate review is not an approval");
495
+ if (review.proposalDigest !== proposal.digest) {
496
+ throw new Error("candidate approval does not match the proposed improvement");
497
+ }
498
+ const bundle = proposal.candidateBundle;
499
+ if (!bundle) throw new Error("approved proposal does not contain an executable candidate bundle");
500
+ if (review.candidateBundleDigest !== bundle.digest) {
501
+ throw new Error("candidate approval does not match the executable bundle");
502
+ }
503
+ if (!await options.authorizeReview(review, proposal)) {
504
+ throw new Error("candidate approval was not authorized by the configured authority");
505
+ }
506
+ const verified = await verifyAgentCandidateBundle(bundle, options.ports);
507
+ const prepared = await prepareAgentCandidateExecution(
508
+ verified,
509
+ options.task,
510
+ options.ports,
511
+ options.preparation
512
+ );
513
+ const finalization = await executePreparedAgentCandidate(prepared, options.execution);
514
+ return {
515
+ finalization,
516
+ evidence: {
517
+ proposalDigest: proposal.digest,
518
+ reviewDigest: review.digest,
519
+ bundleDigest: bundle.digest,
520
+ executionId: prepared.executionId,
521
+ executionPlanDigest: prepared.executionPlan.value.digest,
522
+ materializationReceiptDigest: prepared.materializationReceipt.digest,
523
+ succeeded: finalization.succeeded,
524
+ ...finalization.succeeded ? { runReceiptDigest: finalization.receipt.digest } : {}
525
+ }
526
+ };
527
+ }
528
+ function verifyAgentImprovementProposal(input) {
529
+ if (!isRecord(input) || input.kind !== "agent-improvement-proposal" || input.schemaVersion !== 1) {
530
+ throw new Error("invalid agent improvement proposal");
531
+ }
532
+ const proposal = input;
533
+ const parsedProfile = parseExactAgentProfile(proposal.candidateProfile);
534
+ if (proposal.candidateProfileHash !== canonicalCandidateDigest(parsedProfile)) {
535
+ throw new Error("proposal candidateProfileHash does not match candidateProfile");
536
+ }
537
+ if (!Array.isArray(proposal.findings)) throw new Error("proposal findings must be an array");
538
+ if (!isSha256Digest(proposal.digest)) throw new Error("proposal digest is invalid");
539
+ if (proposal.candidateBundle) {
540
+ const parsedBundle = agentCandidateBundleSchema2.parse(proposal.candidateBundle);
541
+ const sealed = sealAgentCandidateBundle(omitTopLevelDigest(parsedBundle));
542
+ if (sealed.digest !== parsedBundle.digest)
543
+ throw new Error("proposal candidate bundle digest is invalid");
544
+ assertCandidateProfileBinding(parsedProfile, sealed.profile);
545
+ }
546
+ const actual = canonicalCandidateDigest(omitTopLevelDigest(proposal));
547
+ if (actual !== proposal.digest)
548
+ throw new Error("agent improvement proposal digest does not match");
549
+ return immutableCandidateValue(proposal);
550
+ }
551
+ function parseExactAgentProfile(input) {
552
+ const parsed = agentProfileSchema.parse(input);
553
+ if (!Buffer.from(canonicalCandidateBytes(input)).equals(
554
+ Buffer.from(canonicalCandidateBytes(parsed))
555
+ )) {
556
+ throw new Error("proposal candidate profile contains fields unsupported by sealed candidates");
557
+ }
558
+ return parsed;
559
+ }
560
+ function assertCandidateProfileBinding(measuredInput, bundled) {
561
+ const measured = parseExactAgentProfile(measuredInput);
562
+ if (measured.connections || measured.metadata || measured.extensions) {
563
+ throw new Error("proposal candidate profile contains fields unsupported by sealed candidates");
564
+ }
565
+ const normalized = candidateProfileAsAgentProfile(bundled);
566
+ if (canonicalCandidateDigest(measured) !== canonicalCandidateDigest(normalized)) {
567
+ throw new Error("proposal candidateProfile does not match candidateBundle.profile");
568
+ }
569
+ }
570
+ function candidateProfileAsAgentProfile(candidate) {
571
+ const value = candidate;
572
+ const output = {};
573
+ for (const key of [
574
+ "name",
575
+ "description",
576
+ "version",
577
+ "tags",
578
+ "prompt",
579
+ "harness",
580
+ "permissions",
581
+ "tools",
582
+ "confidential"
583
+ ]) {
584
+ if (value[key] !== void 0) output[key] = value[key];
585
+ }
586
+ if (candidate.model) output.model = { ...candidate.model };
587
+ if (candidate.mcp) {
588
+ output.mcp = Object.fromEntries(
589
+ Object.entries(candidate.mcp).map(([name, server]) => [
590
+ name,
591
+ {
592
+ ...server,
593
+ ...server.args ? { args: server.args.map(publicValue) } : {},
594
+ ...server.env ? { env: mapPublicValues(server.env) } : {}
595
+ }
596
+ ])
597
+ );
598
+ }
599
+ if (candidate.subagents) output.subagents = mapRecord(candidate.subagents);
600
+ if (candidate.modes) output.modes = mapRecord(candidate.modes);
601
+ if (candidate.hooks) {
602
+ output.hooks = Object.fromEntries(
603
+ Object.entries(candidate.hooks).map(([event, hooks]) => [
604
+ event,
605
+ hooks.map((hook) => ({
606
+ ...hook,
607
+ command: [hook.executable, ...(hook.args ?? []).map(publicValue)].map(shellQuote).join(" "),
608
+ ...hook.env ? { env: mapPublicValues(hook.env) } : {}
609
+ }))
610
+ ])
611
+ );
612
+ }
613
+ if (candidate.resources) {
614
+ if (candidate.resources.failOnError !== true) {
615
+ throw new Error("proposal candidate profile contains fields unsupported by sealed candidates");
616
+ }
617
+ output.resources = {
618
+ failOnError: true,
619
+ ...candidate.resources.files ? {
620
+ files: candidate.resources.files.map((file) => ({
621
+ ...file,
622
+ resource: publicResource(file.resource)
623
+ }))
624
+ } : {},
625
+ ...candidate.resources.tools ? { tools: candidate.resources.tools.map(publicResource) } : {},
626
+ ...candidate.resources.skills ? { skills: candidate.resources.skills.map(publicResource) } : {},
627
+ ...candidate.resources.agents ? { agents: candidate.resources.agents.map(publicResource) } : {},
628
+ ...candidate.resources.commands ? { commands: candidate.resources.commands.map(publicResource) } : {},
629
+ ...candidate.resources.instructions !== void 0 ? {
630
+ instructions: typeof candidate.resources.instructions === "string" ? candidate.resources.instructions : publicResource(candidate.resources.instructions)
631
+ } : {}
632
+ };
633
+ }
634
+ return output;
635
+ }
636
+ function publicResource(resource) {
637
+ if (resource.kind === "inline") {
638
+ return { kind: "inline", name: resource.name, content: resource.content };
639
+ }
640
+ return {
641
+ kind: "github",
642
+ repository: `${resource.repository.owner}/${resource.repository.repo}`,
643
+ path: resource.path,
644
+ ref: resource.commit,
645
+ ...resource.name ? { name: resource.name } : {}
646
+ };
647
+ }
648
+ function publicValue(value) {
649
+ return value.value;
650
+ }
651
+ function mapPublicValues(values) {
652
+ return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, publicValue(value)]));
653
+ }
654
+ function mapRecord(values) {
655
+ return Object.fromEntries(
656
+ Object.entries(values).map(([key, value]) => [key, { ...value }])
657
+ );
658
+ }
659
+ function shellQuote(value) {
660
+ return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : `'${value.replaceAll("'", `'"'"'`)}'`;
661
+ }
662
+ function verifyAgentImprovementReview(input) {
663
+ if (!isRecord(input) || input.kind !== "agent-improvement-review" || input.schemaVersion !== 1) {
664
+ throw new Error("invalid agent improvement review");
665
+ }
666
+ const review = input;
667
+ if (!isSha256Digest(review.digest) || !isSha256Digest(review.proposalDigest)) {
668
+ throw new Error("candidate review digest is invalid");
669
+ }
670
+ if (review.candidateBundleDigest !== void 0 && !isSha256Digest(review.candidateBundleDigest)) {
671
+ throw new Error("candidate review bundle digest is invalid");
672
+ }
673
+ if (!["approve", "reject", "request-changes"].includes(review.decision)) {
674
+ throw new Error("candidate review decision is invalid");
675
+ }
676
+ const actual = canonicalCandidateDigest(omitTopLevelDigest(review));
677
+ if (actual !== review.digest) throw new Error("agent improvement review digest does not match");
678
+ return immutableCandidateValue(review);
679
+ }
680
+ function improvementEvaluation(result) {
681
+ return {
682
+ baseline: result.baseline,
683
+ winner: result.winner,
684
+ lift: result.lift,
685
+ diff: result.diff,
686
+ provenance: result.provenance,
687
+ gateDecision: result.gateDecision,
688
+ generationsExplored: result.generationsExplored,
689
+ durationMs: result.durationMs,
690
+ totalCostUsd: result.totalCostUsd,
691
+ insight: result.insight,
692
+ ...result.power === void 0 ? {} : { power: result.power }
693
+ };
694
+ }
695
+ function isRecord(value) {
696
+ return value !== null && typeof value === "object" && !Array.isArray(value);
697
+ }
698
+ function isSha256Digest(value) {
699
+ return typeof value === "string" && /^sha256:[a-f0-9]{64}$/.test(value);
700
+ }
701
+ function canonicalJsonValue(value, path = "$") {
702
+ if (value === null || typeof value === "string" || typeof value === "boolean") return value;
703
+ if (typeof value === "number") {
704
+ if (!Number.isFinite(value)) throw new Error(`non-finite number at ${path}`);
705
+ return value;
706
+ }
707
+ if (Array.isArray(value)) {
708
+ return value.map((entry, index) => {
709
+ if (entry === void 0) throw new Error(`undefined array entry at ${path}[${index}]`);
710
+ return canonicalJsonValue(entry, `${path}[${index}]`);
711
+ });
712
+ }
713
+ if (typeof value === "object") {
714
+ const entries = Object.entries(value).filter(([, entry]) => entry !== void 0).map(([key, entry]) => [key, canonicalJsonValue(entry, `${path}.${key}`)]);
715
+ return Object.fromEntries(entries);
716
+ }
717
+ throw new Error(`unsupported proposal value at ${path}`);
718
+ }
719
+
388
720
  // src/intelligence/resolver.ts
389
721
  function emptyAccumulator() {
390
722
  return {
@@ -762,6 +1094,46 @@ async function composeCertifiedProfileFromWire(base, profile, ctx = {}) {
762
1094
 
763
1095
  // src/intelligence/with-intelligence.ts
764
1096
  import { applyAgentProfileDiff } from "@tangle-network/agent-interface";
1097
+ function summarizeRuntimeEvents(events) {
1098
+ const summary = { inferenceUsd: 0, inputTokens: 0, outputTokens: 0 };
1099
+ for (const event of events) {
1100
+ if ("session" in event && event.session) summary.sessionId = event.session.id;
1101
+ if (event.type === "llm_call") {
1102
+ summary.model = event.model;
1103
+ summary.inferenceUsd += event.costUsd ?? 0;
1104
+ summary.inputTokens += event.tokensIn ?? 0;
1105
+ summary.outputTokens += event.tokensOut ?? 0;
1106
+ } else if (event.type === "backend_error") {
1107
+ summary.success = false;
1108
+ summary.error = {
1109
+ name: event.error?.kind ?? "BackendError",
1110
+ message: event.message,
1111
+ ...event.error?.status !== void 0 ? { code: String(event.error.status) } : {}
1112
+ };
1113
+ } else if (event.type === "final") {
1114
+ summary.success = event.status === "completed";
1115
+ if (event.error) {
1116
+ summary.error = {
1117
+ name: event.error.kind,
1118
+ message: event.error.message,
1119
+ ...event.error.status !== void 0 ? { code: String(event.error.status) } : {}
1120
+ };
1121
+ }
1122
+ }
1123
+ }
1124
+ return summary;
1125
+ }
1126
+ function runError(cause) {
1127
+ if (cause instanceof Error) {
1128
+ const code = cause.code;
1129
+ return {
1130
+ name: cause.name || "Error",
1131
+ message: cause.message,
1132
+ ...typeof code === "string" || typeof code === "number" ? { code: String(code) } : {}
1133
+ };
1134
+ }
1135
+ return { name: "Error", message: String(cause) };
1136
+ }
765
1137
  function withIntelligence(agent, config) {
766
1138
  const client = createIntelligenceClient(config);
767
1139
  const target = config.target ?? config.project;
@@ -788,43 +1160,70 @@ function withIntelligence(agent, config) {
788
1160
  signalProposals();
789
1161
  }
790
1162
  const wrapped = (async (input) => {
1163
+ const runId = client.freshRunId();
1164
+ const traceId = client.freshTraceId();
1165
+ const startedAt = Date.now();
791
1166
  await refresh();
792
1167
  const certified = source.current();
793
1168
  const proposals = currentProposals();
794
1169
  const report = {};
795
1170
  const applied = {
1171
+ runId,
1172
+ traceId,
796
1173
  certified,
797
1174
  composePrompt: (base) => composeCertifiedPrompt(base, certified),
798
1175
  proposals,
799
1176
  applyProfile: (base) => proposals.reduce((profile, p) => applyAgentProfileDiff(profile, p.diff), base),
800
1177
  record: (r) => Object.assign(report, r)
801
1178
  };
802
- const output = await agent(input, applied);
803
- const usage = {
804
- inferenceUsd: report.usage?.inferenceUsd ?? report.costUsd ?? 0,
805
- intelligenceUsd: report.usage?.intelligenceUsd ?? 0
806
- };
807
- const record = {
808
- runId: client.freshRunId(),
809
- traceId: client.freshTraceId(),
810
- project: config.project,
811
- target,
812
- input,
813
- output,
814
- outcome: {
815
- ...report.success !== void 0 ? { success: report.success } : {},
816
- ...report.score !== void 0 ? { score: report.score } : {},
817
- usage
818
- },
819
- ...report.model !== void 0 ? { model: report.model } : {},
820
- ...report.provider !== void 0 ? { provider: report.provider } : {},
821
- ...report.loopEvents !== void 0 ? { loopEvents: report.loopEvents } : {}
822
- };
823
- client.exportRunRecord(record);
824
- return output;
1179
+ function exportCompleted(output, caught) {
1180
+ const completedAt = Date.now();
1181
+ const eventSummary = summarizeRuntimeEvents(report.runtimeEvents ?? []);
1182
+ const error = report.error ?? (caught !== void 0 ? runError(caught) : eventSummary.error);
1183
+ const tokens = report.tokens ?? (eventSummary.inputTokens > 0 || eventSummary.outputTokens > 0 ? { input: eventSummary.inputTokens, output: eventSummary.outputTokens } : void 0);
1184
+ const profile = report.profile ?? config.profile;
1185
+ const record = {
1186
+ runId,
1187
+ traceId,
1188
+ project: config.project,
1189
+ target,
1190
+ input,
1191
+ output,
1192
+ outcome: {
1193
+ success: report.success ?? (caught !== void 0 ? false : eventSummary.success ?? error === void 0),
1194
+ ...report.score !== void 0 ? { score: report.score } : {},
1195
+ usage: {
1196
+ inferenceUsd: report.usage?.inferenceUsd ?? report.costUsd ?? eventSummary.inferenceUsd,
1197
+ intelligenceUsd: report.usage?.intelligenceUsd ?? 0
1198
+ }
1199
+ },
1200
+ timing: { startedAt, completedAt, durationMs: completedAt - startedAt },
1201
+ ...report.model ?? eventSummary.model ? { model: report.model ?? eventSummary.model } : {},
1202
+ ...report.provider !== void 0 ? { provider: report.provider } : {},
1203
+ ...report.loopEvents !== void 0 ? { loopEvents: report.loopEvents } : {},
1204
+ ...report.runtimeEvents !== void 0 ? { runtimeEvents: report.runtimeEvents } : {},
1205
+ ...profile !== void 0 ? { profile } : {},
1206
+ ...report.sessionId ?? eventSummary.sessionId ? { sessionId: report.sessionId ?? eventSummary.sessionId } : {},
1207
+ ...report.harness ?? profile?.harness ? { harness: report.harness ?? profile?.harness } : {},
1208
+ ...report.commitSha ?? config.commitSha ? { commitSha: report.commitSha ?? config.commitSha } : {},
1209
+ ...tokens !== void 0 ? { tokens } : {},
1210
+ ...error !== void 0 ? { error } : {},
1211
+ ...report.candidateExecution !== void 0 ? { candidateExecution: report.candidateExecution } : {}
1212
+ };
1213
+ client.exportRunRecord(record);
1214
+ }
1215
+ try {
1216
+ const output = await agent(input, applied);
1217
+ exportCompleted(output);
1218
+ return output;
1219
+ } catch (cause) {
1220
+ exportCompleted(void 0, cause);
1221
+ throw cause;
1222
+ }
825
1223
  });
826
1224
  wrapped.refresh = refresh;
827
1225
  wrapped.proposals = currentProposals;
1226
+ wrapped.flush = client.flush;
828
1227
  return wrapped;
829
1228
  }
830
1229
 
@@ -840,8 +1239,7 @@ function freshTraceId() {
840
1239
  function freshRunId() {
841
1240
  return `run-${randomHex(16)}`;
842
1241
  }
843
- var previewMaxChars = 4096;
844
- function previewJson(value) {
1242
+ function serializeJson(value) {
845
1243
  let s;
846
1244
  if (typeof value === "string") s = value;
847
1245
  else {
@@ -851,7 +1249,13 @@ function previewJson(value) {
851
1249
  s = String(value);
852
1250
  }
853
1251
  }
854
- return s.length > previewMaxChars ? `${s.slice(0, previewMaxChars)}\u2026[truncated]` : s;
1252
+ return s;
1253
+ }
1254
+ function addPayloadAttributes(labels, key, value, includeFullPayload) {
1255
+ const serialized = serializeJson(value);
1256
+ labels[`${key}_hash`] = contentHash(serialized);
1257
+ labels[`${key}_bytes`] = Buffer.byteLength(serialized, "utf8");
1258
+ if (includeFullPayload) labels[key] = serialized;
855
1259
  }
856
1260
  function randomHex(chars) {
857
1261
  const bytes = new Uint8Array(Math.ceil(chars / 2));
@@ -869,6 +1273,7 @@ function createIntelligenceClient(config) {
869
1273
  const effort = resolveEffortConfig(config.effort);
870
1274
  const intelligenceOff = isIntelligenceOff(effort);
871
1275
  const redactor = resolveRedactor(config.redact);
1276
+ const includeFullPayload = config.payloadAttributes === "full";
872
1277
  const apiKey = config.apiKey ?? (typeof process !== "undefined" ? process.env.TANGLE_API_KEY : void 0);
873
1278
  const otlpEndpoint = `${resolveIntelligenceBaseUrl(config.baseUrl)}/v1/otlp`;
874
1279
  let exporter;
@@ -888,22 +1293,26 @@ function createIntelligenceClient(config) {
888
1293
  function exportTrace(meta, outcome, output) {
889
1294
  const ex = getExporter();
890
1295
  if (!ex) return;
891
- const labels = {
892
- project: config.project,
893
- "tangle.effort.intelligence_off": outcome.intelligenceOff,
894
- "tangle.usage.inference_usd": outcome.usage.inferenceUsd,
895
- "tangle.usage.intelligence_usd": outcome.usage.intelligenceUsd,
896
- ...meta.model ? { "gen_ai.request.model": meta.model } : {},
897
- ...meta.provider ? { "provider.name": meta.provider } : {},
898
- ...typeof outcome.success === "boolean" ? { "tangle.outcome.success": outcome.success } : {},
899
- ...typeof outcome.score === "number" ? { "tangle.outcome.score": outcome.score } : {},
900
- ...meta.labels ?? {}
901
- };
902
- const redactedInput = meta.input !== void 0 ? redactor(meta.input) : void 0;
903
- const redactedOutput = output !== void 0 ? redactor(output) : void 0;
904
- if (redactedInput !== void 0) labels["tangle.input"] = previewJson(redactedInput);
905
- if (redactedOutput !== void 0) labels["tangle.output"] = previewJson(redactedOutput);
906
1296
  try {
1297
+ const labels = {
1298
+ project: config.project,
1299
+ "tangle.effort.intelligence_off": outcome.intelligenceOff,
1300
+ "tangle.usage.inference_usd": outcome.usage.inferenceUsd,
1301
+ "tangle.usage.intelligence_usd": outcome.usage.intelligenceUsd,
1302
+ ...meta.model ? { "gen_ai.request.model": meta.model } : {},
1303
+ ...meta.provider ? { "provider.name": meta.provider } : {},
1304
+ ...typeof outcome.success === "boolean" ? { "tangle.outcome.success": outcome.success } : {},
1305
+ ...typeof outcome.score === "number" ? { "tangle.outcome.score": outcome.score } : {},
1306
+ ...meta.labels ?? {}
1307
+ };
1308
+ const redactedInput = meta.input !== void 0 ? redactor(meta.input) : void 0;
1309
+ const redactedOutput = output !== void 0 ? redactor(output) : void 0;
1310
+ if (redactedInput !== void 0) {
1311
+ addPayloadAttributes(labels, "tangle.input", redactedInput, includeFullPayload);
1312
+ }
1313
+ if (redactedOutput !== void 0) {
1314
+ addPayloadAttributes(labels, "tangle.output", redactedOutput, includeFullPayload);
1315
+ }
907
1316
  ex.exportSpan(
908
1317
  flatOtelSpan(
909
1318
  "tangle.intelligence.run",
@@ -918,30 +1327,92 @@ function createIntelligenceClient(config) {
918
1327
  function exportRunRecord(record) {
919
1328
  const ex = getExporter();
920
1329
  if (!ex) return record.traceId;
921
- const intelligenceUsd = intelligenceOff ? 0 : record.outcome.usage.intelligenceUsd;
922
- const labels = {
923
- project: record.project,
924
- "tangle.target": record.target,
925
- "tangle.effort.intelligence_off": intelligenceOff,
926
- "tangle.usage.inference_usd": record.outcome.usage.inferenceUsd,
927
- "tangle.usage.intelligence_usd": intelligenceUsd,
928
- ...record.model ? { "gen_ai.request.model": record.model } : {},
929
- ...record.provider ? { "provider.name": record.provider } : {},
930
- ...typeof record.outcome.success === "boolean" ? { "tangle.outcome.success": record.outcome.success } : {},
931
- ...typeof record.outcome.score === "number" ? { "tangle.outcome.score": record.outcome.score } : {}
932
- };
933
- const redactedInput = record.input !== void 0 ? redactor(record.input) : void 0;
934
- const redactedOutput = record.output !== void 0 ? redactor(record.output) : void 0;
935
- if (redactedInput !== void 0) labels["tangle.input"] = previewJson(redactedInput);
936
- if (redactedOutput !== void 0) labels["tangle.output"] = previewJson(redactedOutput);
937
1330
  try {
1331
+ const intelligenceUsd = intelligenceOff ? 0 : record.outcome.usage.intelligenceUsd;
1332
+ const repository = record.repository ?? (config.repo ? `${config.repo.owner}/${config.repo.name}` : void 0);
1333
+ const labels = {
1334
+ project: record.project,
1335
+ "tangle.target": record.target,
1336
+ "tangle.effort.intelligence_off": intelligenceOff,
1337
+ "tangle.usage.inference_usd": record.outcome.usage.inferenceUsd,
1338
+ "tangle.usage.intelligence_usd": intelligenceUsd,
1339
+ ...record.model ? { "gen_ai.request.model": record.model } : {},
1340
+ ...record.provider ? { "provider.name": record.provider } : {},
1341
+ ...record.sessionId ? {
1342
+ "tangle.sessionId": record.sessionId,
1343
+ "gen_ai.conversation.id": record.sessionId
1344
+ } : {},
1345
+ ...record.harness ? { "tangle.agent.harness": record.harness } : {},
1346
+ ...repository ? { "vcs.repository.name": repository } : {},
1347
+ ...record.commitSha ? { "vcs.ref.head.revision": record.commitSha } : {},
1348
+ ...record.timing ? {
1349
+ "tangle.started_at_ms": record.timing.startedAt,
1350
+ "tangle.completed_at_ms": record.timing.completedAt,
1351
+ "tangle.duration_ms": record.timing.durationMs
1352
+ } : {},
1353
+ ...record.tokens ? {
1354
+ "gen_ai.usage.input_tokens": record.tokens.input,
1355
+ "gen_ai.usage.output_tokens": record.tokens.output,
1356
+ ...record.tokens.cachedInput !== void 0 ? { "gen_ai.usage.cache_read_input_tokens": record.tokens.cachedInput } : {},
1357
+ ...record.tokens.reasoning !== void 0 ? { "gen_ai.usage.reasoning_tokens": record.tokens.reasoning } : {}
1358
+ } : {},
1359
+ ...typeof record.outcome.success === "boolean" ? { "tangle.outcome.success": record.outcome.success } : {},
1360
+ ...typeof record.outcome.score === "number" ? { "tangle.outcome.score": record.outcome.score } : {},
1361
+ ...record.error ? {
1362
+ "error.type": record.error.code ?? record.error.name,
1363
+ "error.message": serializeJson(redactor(record.error.message))
1364
+ } : {},
1365
+ ...record.runtimeEvents ? { "tangle.runtime.event_count": record.runtimeEvents.length } : {},
1366
+ ...record.candidateExecution ? {
1367
+ "tangle.candidate.proposal_digest": record.candidateExecution.proposalDigest,
1368
+ "tangle.candidate.review_digest": record.candidateExecution.reviewDigest,
1369
+ "tangle.candidate.bundle_digest": record.candidateExecution.bundleDigest,
1370
+ "tangle.candidate.execution_id": record.candidateExecution.executionId,
1371
+ "tangle.candidate.execution_plan_digest": record.candidateExecution.executionPlanDigest,
1372
+ "tangle.candidate.materialization_receipt_digest": record.candidateExecution.materializationReceiptDigest,
1373
+ "tangle.candidate.succeeded": record.candidateExecution.succeeded,
1374
+ ...record.candidateExecution.runReceiptDigest ? {
1375
+ "tangle.candidate.run_receipt_digest": record.candidateExecution.runReceiptDigest
1376
+ } : {}
1377
+ } : {}
1378
+ };
1379
+ if (record.profile) {
1380
+ addPayloadAttributes(
1381
+ labels,
1382
+ "tangle.agent.profile",
1383
+ redactor(record.profile),
1384
+ includeFullPayload
1385
+ );
1386
+ labels["tangle.agent.profile_hash"] = contentHash(record.profile);
1387
+ if (record.profile.name) labels["gen_ai.agent.name"] = record.profile.name;
1388
+ }
1389
+ const redactedInput = record.input !== void 0 ? redactor(record.input) : void 0;
1390
+ const redactedOutput = record.output !== void 0 ? redactor(record.output) : void 0;
1391
+ if (redactedInput !== void 0) {
1392
+ addPayloadAttributes(labels, "tangle.input", redactedInput, includeFullPayload);
1393
+ }
1394
+ if (redactedOutput !== void 0) {
1395
+ addPayloadAttributes(labels, "tangle.output", redactedOutput, includeFullPayload);
1396
+ }
1397
+ const now = Date.now();
938
1398
  const runSpan = flatOtelSpan(
939
1399
  "tangle.intelligence.run",
940
1400
  { "tangle.runId": record.runId, ...labels },
941
1401
  record.traceId,
942
- Date.now()
1402
+ record.timing?.startedAt ?? now,
1403
+ void 0,
1404
+ record.timing?.completedAt ?? now
943
1405
  );
944
1406
  ex.exportSpan(runSpan);
1407
+ if (record.runtimeEvents && record.runtimeEvents.length > 0) {
1408
+ const spans = buildRuntimeEventOtelSpans(
1409
+ record.runtimeEvents,
1410
+ record.traceId,
1411
+ runSpan.spanId,
1412
+ { ...config.runtimeTelemetry, redact: redactor }
1413
+ );
1414
+ for (const span of spans) ex.exportSpan(span);
1415
+ }
945
1416
  if (record.loopEvents && record.loopEvents.length > 0) {
946
1417
  const spans = buildLoopOtelSpans(
947
1418
  record.loopEvents,
@@ -1062,13 +1533,18 @@ export {
1062
1533
  createIntelligenceClient,
1063
1534
  defaultEffortTier,
1064
1535
  defaultRedactor,
1536
+ executeApprovedAgentCandidate,
1065
1537
  isIntelligenceOff,
1066
1538
  manifestFromProfile,
1067
1539
  normalizeCertifiedProfile,
1540
+ proposeAgentImprovement,
1068
1541
  pullCertified,
1069
1542
  resolveEffort,
1070
1543
  resolveIntelligenceBaseUrl,
1071
1544
  resolveRedactor,
1545
+ reviewAgentImprovementProposal,
1546
+ verifyAgentImprovementProposal,
1547
+ verifyAgentImprovementReview,
1072
1548
  withIntelligence
1073
1549
  };
1074
1550
  //# sourceMappingURL=intelligence.js.map