@tangle-network/agent-runtime 0.321.0 → 0.322.1

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 (54) hide show
  1. package/dist/{activation-CXFl5YVE.js → activation-CBv_0LUh.js} +2 -2
  2. package/dist/{activation-CXFl5YVE.js.map → activation-CBv_0LUh.js.map} +1 -1
  3. package/dist/{activation-BxOOvwjo.d.ts → activation-CZGz2kuu.d.ts} +2 -2
  4. package/dist/agent.d.ts +1 -1
  5. package/dist/agent.js +2 -2
  6. package/dist/{coordination-driver-Bpn05N-Y.js → coordination-driver-C2Zm5lU4.js} +69 -2
  7. package/dist/coordination-driver-C2Zm5lU4.js.map +1 -0
  8. package/dist/{delegate-BHlcTOdK.js → delegate-BV7AVmbB.js} +2 -2
  9. package/dist/{delegate-BHlcTOdK.js.map → delegate-BV7AVmbB.js.map} +1 -1
  10. package/dist/durable.d.ts +1 -1
  11. package/dist/durable.js +2 -2
  12. package/dist/{graph-DE2dLhDI.js → graph-CH3YiPog.js} +4 -4
  13. package/dist/{graph-DE2dLhDI.js.map → graph-CH3YiPog.js.map} +1 -1
  14. package/dist/{improvement-cycle-CyChbojL.js → improvement-cycle-CD1h5GSM.js} +3 -3
  15. package/dist/{improvement-cycle-CyChbojL.js.map → improvement-cycle-CD1h5GSM.js.map} +1 -1
  16. package/dist/{index-BxiHetnG.d.ts → index-CGNQWpge.d.ts} +633 -545
  17. package/dist/index.d.ts +4 -4
  18. package/dist/index.js +7 -7
  19. package/dist/intelligence.d.ts +2 -2
  20. package/dist/intelligence.js +3 -3
  21. package/dist/kernel.d.ts +2 -2
  22. package/dist/kernel.js +9 -9
  23. package/dist/{loop-runner-bin-CT02Vzco.js → loop-runner-bin-CFxE376A.js} +3 -3
  24. package/dist/{loop-runner-bin-CT02Vzco.js.map → loop-runner-bin-CFxE376A.js.map} +1 -1
  25. package/dist/{loop-runner-bin-DInJZNgs.d.ts → loop-runner-bin-C_jaLCUO.d.ts} +2 -2
  26. package/dist/loop-runner-bin.d.ts +1 -1
  27. package/dist/loop-runner-bin.js +1 -1
  28. package/dist/mcp/bin.js +3 -3
  29. package/dist/mcp/index.d.ts +2 -2
  30. package/dist/mcp/index.js +4 -4
  31. package/dist/{openai-tools-DLTw576v.d.ts → openai-tools-D1PDoBOz.d.ts} +2 -2
  32. package/dist/profiles.d.ts +1 -1
  33. package/dist/{provision-supervisor-DvgBNtoJ.js → provision-supervisor-ftJZhqBU.js} +3 -3
  34. package/dist/{provision-supervisor-DvgBNtoJ.js.map → provision-supervisor-ftJZhqBU.js.map} +1 -1
  35. package/dist/{runtime-wLgjMOaj.js → runtime-EiTCboO2.js} +77 -12
  36. package/dist/runtime-EiTCboO2.js.map +1 -0
  37. package/dist/{search-executor-TEKWC579.js → search-executor-ECJ2TmC-.js} +2 -2
  38. package/dist/{search-executor-TEKWC579.js.map → search-executor-ECJ2TmC-.js.map} +1 -1
  39. package/dist/{server-qYhzITTm.js → server-C2k5wX4k.js} +3 -3
  40. package/dist/{server-qYhzITTm.js.map → server-C2k5wX4k.js.map} +1 -1
  41. package/dist/{supervise-C4bLIU7J.js → supervise-BjrRk-AN.js} +160 -122
  42. package/dist/supervise-BjrRk-AN.js.map +1 -0
  43. package/dist/{supervisor-bkq2b8k-.js → supervisor-BMMdI4T-.js} +224 -39
  44. package/dist/supervisor-BMMdI4T-.js.map +1 -0
  45. package/dist/testing.d.ts +1 -1
  46. package/dist/testing.js +12 -12
  47. package/dist/tui/index.d.ts +1 -1
  48. package/dist/tui/index.js +1 -1
  49. package/package.json +3 -3
  50. package/skills/profile-authoring/SKILL.md +1 -0
  51. package/dist/coordination-driver-Bpn05N-Y.js.map +0 -1
  52. package/dist/runtime-wLgjMOaj.js.map +0 -1
  53. package/dist/supervise-C4bLIU7J.js.map +0 -1
  54. package/dist/supervisor-bkq2b8k-.js.map +0 -1
@@ -1,10 +1,10 @@
1
- import { $i as runtimeOwnedExecutorProviderEvidence, A as scopeOwnerExecutorNodeContext, Ai as promptControlProfileMaterialization, An as resolveAgentEnvironmentProvider, Ar as persistHarnessTranscript, At as captureReusableExecutorConfig, B as consumeScopeRetainedOwnerResult, C as deriveNodeExecutionIdentity, Ct as createContinuationKeeper, D as recordScopeOwnerMaterialization, Di as defineProfileMaterializationContract, Dr as runAbortable, E as recordScopeOwnerDriverAttempt, Ei as controlProfileMaterialization, Er as linkAbort, F as seatExecutionProfile, Fi as renderUnsupported, Fn as retainedExecutorSeamKey, Ft as snapshotExecutorConfig, G as scopeRetainedOwnerContext, H as prepareScopeRetainedOwnerSeatSwitch, I as abandonScopeRetainedOwnerInvocation, J as scopeRetainedOwnerResourceReader, Ji as providerAttemptEvidence, Jn as isNoEntError, Jt as createActivityLog, K as scopeRetainedOwnerJournalRoot, L as beginScopeRetainedOwnerDrive, Li as unsupportedProfileDimensions, M as SeatChain, N as SeatChainExhaustedError, Nt as createExecutor, O as recordScopeOwnerPause, Oi as fullProfileMaterialization, P as authoredSeatStages, Pn as registerRetainedExecutorPreparation, Pr as contentAddress, Qi as runtimeOwnedExecutorMaterialization, Qr as createOtelExporter, R as bindScopeRetainedOwnerEnvironmentId, St as checkVerdictOf, T as meterRuntimeOwnedProviderAttempt, U as prepareScopeRetainedOwnerTask, V as noteScopeRetainedOwnerCoordination, Vi as attestRuntimeOwnedScopeOwner, Vt as WORKER_TRACE_PROPAGATION, W as reconcileScopeRetainedOwnerEnvironment, Wi as inheritRuntimeOwnedExecutorAttestation, X as scopeRetainedOwnerResult, Xi as runtimeOwnedDriveHarnessProviderEvidence, Xn as readCommittedJsonLines, Xt as createInbox, Y as scopeRetainedOwnerRestorePoint, Yi as recordRuntimeOwnedDriveHarnessProviderEvidence, Yn as prepareJsonlAppend, Z as scopeRetainedOwnerTurnEnded, Zi as runtimeOwnedExecutorExecutionBinding, _ as isDriverSpec, an as isLiveNodeStatus, b as assertRecursiveReservationPolicy, c as runTree, cn as bridgeModelRouteRefusal, cr as meterUsageEvent, dr as spendFromUsageTotals, ea as runtimeOwnedPendingExecutorMaterialization, ei as generateSpanId, f as runDriverWithRetry, fr as bridgeRuntimeAttachmentsKey, g as driverExecutorFactory, gt as CONTINUATIONS_DIR, h as driverChild, i as bestDelivered, ii as toOtelAttributes, it as providerVisibleProfile, ji as promptModelProfileMaterialization, jr as readHarnessTranscript, k as restoreScopeOwnerAcceptedExecution, ki as profileMaterializationAxes$1, kt as bindReusableExecutorExecutionId, lr as newUsageTotals, mr as errMessage, mt as gateOnDeliverable, n as createRootHandle, nt as coordinationMcpAlias, or as assertValidBudget, p as summarizeDriverAttempts, pr as bridgeStopSignalKey, q as scopeRetainedOwnerPriorSpend, r as createSupervisor, rr as executorFailure, rt as coordinationProfileToolPrefix, s as runFinalizer, sa as detachedSnapshot, sn as bridgeAdmissionRefusal, ta as runtimeOwnedScopeOwnerRuntime, tr as parseWorkerToolTraceArtifact, u as HarnessTurnFailedError, vt as CheckUnavailableError, w as meterRuntimeOwnedAccounting, wi as assertProfileMaterialization, wn as routerBrain, wr as RunCancellationReason, x as beginScopeOwnerAttempt, xt as bestComposite, yt as admitContinuationPolicy, z as bindScopeRetainedOwnerProvider, zi as worktreeCliProfileMaterialization, zt as createRouterTranscript } from "./supervisor-bkq2b8k-.js";
1
+ import { $i as runtimeOwnedExecutorProviderEvidence, A as scopeOwnerExecutorNodeContext, Ai as promptControlProfileMaterialization, An as resolveAgentEnvironmentProvider, Ar as persistHarnessTranscript, At as captureReusableExecutorConfig, B as consumeScopeRetainedOwnerResult, C as deriveNodeExecutionIdentity, Ct as createContinuationKeeper, D as recordScopeOwnerMaterialization, Di as defineProfileMaterializationContract, Dr as runAbortable, E as recordScopeOwnerDriverAttempt, Ei as controlProfileMaterialization, Er as linkAbort, F as seatExecutionProfile, Fi as renderUnsupported, Fn as retainedExecutorSeamKey, Ft as snapshotExecutorConfig, G as scopeRetainedOwnerContext, H as prepareScopeRetainedOwnerSeatSwitch, I as abandonScopeRetainedOwnerInvocation, J as scopeRetainedOwnerResourceReader, Ji as providerAttemptEvidence, Jn as isNoEntError, Jt as createActivityLog, K as scopeRetainedOwnerJournalRoot, L as beginScopeRetainedOwnerDrive, Li as unsupportedProfileDimensions, M as SeatChain, N as SeatChainExhaustedError, Nt as createExecutor, O as recordScopeOwnerPause, Oi as fullProfileMaterialization, P as authoredSeatStages, Pn as registerRetainedExecutorPreparation, Pr as contentAddress, Qi as runtimeOwnedExecutorMaterialization, Qr as createOtelExporter, R as bindScopeRetainedOwnerEnvironmentId, St as checkVerdictOf, T as meterRuntimeOwnedProviderAttempt, U as prepareScopeRetainedOwnerTask, V as noteScopeRetainedOwnerCoordination, Vi as attestRuntimeOwnedScopeOwner, Vt as WORKER_TRACE_PROPAGATION, W as reconcileScopeRetainedOwnerEnvironment, Wi as inheritRuntimeOwnedExecutorAttestation, X as scopeRetainedOwnerResult, Xi as runtimeOwnedDriveHarnessProviderEvidence, Xn as readCommittedJsonLines, Xt as createInbox, Y as scopeRetainedOwnerRestorePoint, Yi as recordRuntimeOwnedDriveHarnessProviderEvidence, Yn as prepareJsonlAppend, Z as scopeRetainedOwnerTurnEnded, Zi as runtimeOwnedExecutorExecutionBinding, _ as isDriverSpec, an as isLiveNodeStatus, b as assertRecursiveReservationPolicy, c as runTree, cn as bridgeModelRouteRefusal, cr as meterUsageEvent, dr as spendFromUsageTotals, ea as runtimeOwnedPendingExecutorMaterialization, ei as generateSpanId, f as runDriverWithRetry, fr as bridgeRuntimeAttachmentsKey, g as driverExecutorFactory, gt as CONTINUATIONS_DIR, h as driverChild, i as bestDelivered, ii as toOtelAttributes, it as providerVisibleProfile, ji as promptModelProfileMaterialization, jr as readHarnessTranscript, k as restoreScopeOwnerAcceptedExecution, ki as profileMaterializationAxes$1, kt as bindReusableExecutorExecutionId, lr as newUsageTotals, mr as errMessage, mt as gateOnDeliverable, n as createRootHandle, nt as coordinationMcpAlias, or as assertValidBudget, p as summarizeDriverAttempts, pr as bridgeStopSignalKey, q as scopeRetainedOwnerPriorSpend, r as createSupervisor, rr as executorFailure, rt as coordinationProfileToolPrefix, s as runFinalizer, sa as detachedSnapshot, sn as bridgeAdmissionRefusal, ta as runtimeOwnedScopeOwnerRuntime, tr as parseWorkerToolTraceArtifact, u as HarnessTurnFailedError, vt as CheckUnavailableError, w as meterRuntimeOwnedAccounting, wi as assertProfileMaterialization, wn as routerBrain, wr as RunCancellationReason, x as beginScopeOwnerAttempt, xt as bestComposite, yt as admitContinuationPolicy, z as bindScopeRetainedOwnerProvider, zi as worktreeCliProfileMaterialization, zt as createRouterTranscript } from "./supervisor-BMMdI4T-.js";
2
2
  import { f as RuntimeRunStateError, i as ConfigError, m as ValidationError } from "./errors-DodWX-cb.js";
3
3
  import { Dt as teardownSurfaces, Et as teardownExecutor, V as addSpend, Z as isAsyncIterable$1, ct as withTimeout, dt as addResourceSpend, lt as zeroSpend, mt as withBudgetResources, pt as resourceTelemetry, q as errorMessage, rt as sleep, st as unmeteredSpend, yt as DEFAULT_SUCCESSFUL_SHUTDOWN_MS } from "./workspace-streams-DFAhW7hF.js";
4
4
  import { _ as agentHarness, a as concreteProfileModel, c as profileModelExecutionSettings, n as assertModelAllowed, o as enforceTokenLimits, r as assertProfileModelsAllowed, s as profileBridgeWireModel, t as assertExecutableAgentProfile, v as harnessRunsAgent } from "./model-policy-CNe257pB.js";
5
5
  import { n as assertNoSymlinkDescendant } from "./durable-file-DWQA4ooo.js";
6
6
  import { t as composeRuntimeHooks } from "./runtime-hooks-tXpAarhW.js";
7
- import { C as createFileRunContext, F as createCoordinationToolsForManager, N as coordinationVerbNames, O as applyRunCancellation, T as withRunContext, c as refreshedWake, g as progressStop, h as plateau, k as watchRunCancellation, l as resolveWakePolicy, n as createSteerAcknowledger, o as composeWakeInput, p as createProgressTracker, r as driverAgent, s as deadlineWarningAt, t as createCancelAcknowledger, w as createInMemoryRunContext } from "./coordination-driver-Bpn05N-Y.js";
7
+ import { C as createFileRunContext, F as createCoordinationToolsForManager, N as coordinationVerbNames, O as applyRunCancellation, T as withRunContext, c as refreshedWake, g as progressStop, h as plateau, k as watchRunCancellation, l as resolveWakePolicy, n as createSteerAcknowledger, o as composeWakeInput, p as createProgressTracker, r as driverAgent, s as deadlineWarningAt, t as createCancelAcknowledger, w as createInMemoryRunContext } from "./coordination-driver-C2Zm5lU4.js";
8
8
  import { r as createStdioToolServer, t as PROTOCOL_VERSION } from "./tool-server-Dqer2M4_.js";
9
9
  import { k as writeRunCancellation, o as readRunCancelRequest, s as readRunCancellation } from "./run-layout-DSCWdbX2.js";
10
10
  import { agentProfileSchema, canonicalAgentProfileDigest, canonicalCandidateDigest, canonicalCandidateJson, validateAgentProfileSecurity } from "@tangle-network/agent-interface";
@@ -523,6 +523,7 @@ function assertCoordinationTransport(options) {
523
523
  if (!signingKeys.activeKeyId || !Object.hasOwn(signingKeys.keys, signingKeys.activeKeyId)) throw new ConfigError("coordination signingKeys must contain the active key");
524
524
  for (const [id, key] of Object.entries(signingKeys.keys)) if (!/^[A-Za-z0-9_-]{1,64}$/.test(id) || typeof key !== "string" || Buffer.byteLength(key) < 32) throw new ConfigError("coordination signing keys require bounded key IDs and at least 32 secret bytes");
525
525
  }
526
+ if (options.onReadReady && !options.authentication) throw new ConfigError("coordination read capability publication requires authentication");
526
527
  coordinationHttpLimits(options);
527
528
  }
528
529
  /**
@@ -556,7 +557,6 @@ async function serveCoordinationMcpForManager(opts, lifetime) {
556
557
  assertCoordinationTransport(opts);
557
558
  const requestTimeoutMs = coordinationHttpLimits(opts).requestTimeoutMs;
558
559
  const responseFenceMs = coordinationResponseFenceMs(requestTimeoutMs);
559
- if (opts.peerMail && (!isLoopbackHost(host) || opts.publicUrl)) throw new ConfigError("remote peer mail requires a separate reachable capability transport; coordination authentication does not authorize the peer listener");
560
560
  const identity = Object.freeze({ ...opts.identity ?? {
561
561
  runId: opts.scope.view?.root ?? "",
562
562
  actorId: opts.scope.view?.root ?? ""
@@ -567,6 +567,7 @@ async function serveCoordinationMcpForManager(opts, lifetime) {
567
567
  activeKeyId: auth.signingKeys.activeKeyId,
568
568
  keys: { ...auth.signingKeys.keys }
569
569
  } : void 0;
570
+ let readerToken = Buffer.from(randomBytes(32).toString("base64url"));
570
571
  let token;
571
572
  let credentialExpiresAt;
572
573
  let headers = Object.freeze({});
@@ -596,6 +597,7 @@ async function serveCoordinationMcpForManager(opts, lifetime) {
596
597
  })).toString("base64url");
597
598
  text = `${payload}.${createHmac("sha256", signingKeys.keys[signingKeys.activeKeyId]).update(payload).digest("base64url")}`;
598
599
  }
600
+ readerToken = Buffer.from(randomBytes(32).toString("base64url"));
599
601
  token = Buffer.from(text);
600
602
  headers = Object.freeze({ Authorization: `Bearer ${text}` });
601
603
  };
@@ -698,7 +700,44 @@ async function serveCoordinationMcpForManager(opts, lifetime) {
698
700
  tools: servedTools
699
701
  });
700
702
  opts.onCoordinationTools?.([...mcp.tools.values()], coord);
701
- const server = createServer(coordinationHttpHandler({
703
+ const authority = (req) => {
704
+ const address = req.socket.localAddress?.replace(/^::ffff:/, "");
705
+ const localAuthority = address?.includes(":") ? `[${address}]:${req.socket.localPort}` : `${address}:${req.socket.localPort}`;
706
+ const boundAuthority = audiences.size > 0 && (host === "0.0.0.0" || host === "::") && address !== void 0 && req.socket.localPort !== void 0 && req.headers.host === localAuthority;
707
+ if (!audiences.has(req.headers.host ?? "") && !boundAuthority) return {
708
+ status: 403,
709
+ reason: "wrong-host"
710
+ };
711
+ if (closed) return {
712
+ status: 401,
713
+ reason: "listener-closed"
714
+ };
715
+ };
716
+ const readMcp = createStdioToolServer({
717
+ serverName: "supervisor-reader",
718
+ serverVersion: "1",
719
+ tools: coord.tools.filter((tool) => tool.name === "observe_agent" || tool.name === "read_journal")
720
+ });
721
+ const readPaths = /* @__PURE__ */ new Set();
722
+ const readHandler = coordinationHttpHandler({
723
+ options: opts,
724
+ identity,
725
+ toolNames: /* @__PURE__ */ new Set(["observe_agent", "read_journal"]),
726
+ backgroundActions: () => 0,
727
+ authorize: (req) => {
728
+ const refused = authority(req);
729
+ if (refused) return refused;
730
+ const supplied = typeof req.headers.authorization === "string" && req.headers.authorization.startsWith("Bearer ") ? Buffer.from(req.headers.authorization.slice(7)) : Buffer.alloc(0);
731
+ if (supplied.length !== readerToken.length || !timingSafeEqual(supplied, readerToken) || credentialExpiresAt !== void 0 && credentialExpiresAt <= Date.now()) return {
732
+ status: 401,
733
+ reason: "credential-refused"
734
+ };
735
+ },
736
+ handle: (message) => readMcp.handle(message)
737
+ });
738
+ const peerHandlers = /* @__PURE__ */ new Map();
739
+ const mailPaths = /* @__PURE__ */ new Set();
740
+ const mainHandler = coordinationHttpHandler({
702
741
  options: opts,
703
742
  identity,
704
743
  toolNames: new Set(servedTools.map((tool) => tool.name)),
@@ -713,17 +752,8 @@ async function serveCoordinationMcpForManager(opts, lifetime) {
713
752
  status: 404,
714
753
  reason: "unknown-path"
715
754
  };
716
- const address = req.socket.localAddress?.replace(/^::ffff:/, "");
717
- const localAuthority = address?.includes(":") ? `[${address}]:${req.socket.localPort}` : `${address}:${req.socket.localPort}`;
718
- const boundAuthority = audiences.size > 0 && (host === "0.0.0.0" || host === "::") && address !== void 0 && req.socket.localPort !== void 0 && req.headers.host === localAuthority;
719
- if (!audiences.has(req.headers.host ?? "") && !boundAuthority) return {
720
- status: 403,
721
- reason: "wrong-host"
722
- };
723
- if (closed) return {
724
- status: 401,
725
- reason: "listener-closed"
726
- };
755
+ const refusedAuthority = authority(req);
756
+ if (refusedAuthority) return refusedAuthority;
727
757
  if (!opts.authentication) return void 0;
728
758
  const authorization = req.headers.authorization;
729
759
  const supplied = typeof authorization === "string" && authorization.startsWith("Bearer ") ? Buffer.from(authorization.slice(7)) : Buffer.alloc(0);
@@ -733,7 +763,44 @@ async function serveCoordinationMcpForManager(opts, lifetime) {
733
763
  reason: refused
734
764
  };
735
765
  }
736
- }));
766
+ });
767
+ const server = createServer((req, res) => {
768
+ if (readPaths.has(req.url ?? "")) return readHandler(req, res);
769
+ for (const base of mailPaths) {
770
+ if (!(req.url ?? "").startsWith(base + "/")) continue;
771
+ const capabilityId = (req.url ?? "").slice(base.length + 1);
772
+ const mailbox = coord.peerMail;
773
+ if (!/^[0-9a-f]{32}$/.test(capabilityId) || !mailbox?.hasCapability(capabilityId)) {
774
+ res.writeHead(404).end();
775
+ return;
776
+ }
777
+ let handler = peerHandlers.get(capabilityId);
778
+ if (!handler) {
779
+ const peerMcp = createStdioToolServer({
780
+ serverName: "peer-mail",
781
+ serverVersion: "1",
782
+ tools: mailbox.tools(capabilityId)
783
+ });
784
+ handler = coordinationHttpHandler({
785
+ options: opts,
786
+ identity: {
787
+ runId: identity.runId,
788
+ actorId: "peer"
789
+ },
790
+ toolNames: /* @__PURE__ */ new Set(["send_mail", "read_mail"]),
791
+ backgroundActions: () => 0,
792
+ authorize: (request) => authority(request) ?? (!mailbox.hasCapability(capabilityId) ? {
793
+ status: 401,
794
+ reason: "credential-refused"
795
+ } : void 0),
796
+ handle: (message) => peerMcp.handle(message)
797
+ });
798
+ peerHandlers.set(capabilityId, handler);
799
+ }
800
+ return handler(req, res);
801
+ }
802
+ return mainHandler(req, res);
803
+ });
737
804
  server.requestTimeout = requestTimeoutMs;
738
805
  server.headersTimeout = requestTimeoutMs;
739
806
  const port = await new Promise((resolve, reject) => {
@@ -771,6 +838,10 @@ async function serveCoordinationMcpForManager(opts, lifetime) {
771
838
  audiences.add(publicAddress.host);
772
839
  if (host === "0.0.0.0" || host === "::") audiences.add(`127.0.0.1:${port}`);
773
840
  paths.add(publicAddress.pathname);
841
+ for (const path of paths) {
842
+ readPaths.add(path.replace(/\/$/, "") + "/read");
843
+ mailPaths.add(path.replace(/\/$/, "") + "/mail");
844
+ }
774
845
  if (configured !== void 0) await preflightPublicCoordination({
775
846
  url,
776
847
  headers,
@@ -788,108 +859,55 @@ async function serveCoordinationMcpForManager(opts, lifetime) {
788
859
  throw error;
789
860
  }
790
861
  const mailbox = coord.peerMail;
791
- const mailListener = mailbox === void 0 ? void 0 : await servePeerMail(mailbox, host);
792
- return {
793
- handle: {
794
- url,
795
- port,
796
- get headers() {
797
- return headers;
798
- },
799
- get credentialExpiresAt() {
800
- return credentialExpiresAt;
801
- },
802
- rotateCredential,
803
- settled: () => coord.settled(),
804
- submittedResult: () => coord.submittedResult(),
805
- drainResolved: () => coord.drainResolved(),
806
- finishAnalysis: (input) => coord.finishAnalysis(input),
807
- isStopped: () => coord.isStopped(),
808
- history: () => coord.history(),
809
- stats: () => coord.stats(),
810
- raiseFinding: (finding) => coord.raiseFinding(finding),
811
- mailHistory: () => mailbox?.history() ?? [],
812
- stopMailThread: (threadId) => mailbox?.stopThread(threadId) ?? false,
813
- close: async () => {
814
- releaseAddress();
815
- closed = true;
816
- await new Promise((resolve) => {
817
- server.close(() => resolve());
818
- });
819
- await mailListener?.close();
820
- }
862
+ mailbox?.setEndpoint(url.replace(/\/$/, "") + "/mail");
863
+ const handle = {
864
+ url,
865
+ port,
866
+ get readOnly() {
867
+ if (!opts.authentication) throw new ConfigError("coordination read access requires authentication");
868
+ return {
869
+ url: url.replace(/\/$/, "") + "/read",
870
+ headers: Object.freeze({ Authorization: `Bearer ${readerToken.toString()}` })
871
+ };
821
872
  },
822
- controls: coord
873
+ get headers() {
874
+ return headers;
875
+ },
876
+ get credentialExpiresAt() {
877
+ return credentialExpiresAt;
878
+ },
879
+ rotateCredential,
880
+ settled: () => coord.settled(),
881
+ submittedResult: () => coord.submittedResult(),
882
+ drainResolved: () => coord.drainResolved(),
883
+ finishAnalysis: (input) => coord.finishAnalysis(input),
884
+ isStopped: () => coord.isStopped(),
885
+ history: () => coord.history(),
886
+ stats: () => coord.stats(),
887
+ raiseFinding: (finding) => coord.raiseFinding(finding),
888
+ mailHistory: () => mailbox?.history() ?? [],
889
+ stopMailThread: (threadId) => mailbox?.stopThread(threadId) ?? false,
890
+ close: async () => {
891
+ releaseAddress();
892
+ closed = true;
893
+ await new Promise((resolve) => {
894
+ server.close(() => resolve());
895
+ });
896
+ }
823
897
  };
824
- }
825
- /**
826
- * Stand up the peer-mail capability listener: one HTTP server, one secret path per worker, and on
827
- * each path a tool server carrying ONLY `send_mail` / `read_mail` with that worker's identity
828
- * closed over. An unknown path is a flat 404 — the path is the credential, so a request that does
829
- * not present a minted one is not a client to reason with.
830
- *
831
- * The host is the coordination host, which the caller has already had to justify: the loopback gate
832
- * above governs both listeners, and there is deliberately no way to bind mail somewhere else.
833
- */
834
- async function servePeerMail(mailbox, host) {
835
- const servers = /* @__PURE__ */ new Map();
836
- const forCapability = (capabilityId) => {
837
- const existing = servers.get(capabilityId);
838
- if (existing) return existing;
839
- const created = createStdioToolServer({
840
- serverName: "peer-mail",
841
- serverVersion: "1",
842
- tools: mailbox.tools(capabilityId)
843
- });
844
- servers.set(capabilityId, created);
845
- return created;
898
+ try {
899
+ await runAbortable(async () => opts.onReadReady?.({
900
+ ...handle.readOnly,
901
+ ...identity
902
+ }), opts.scope.signal, "read capability publication aborted");
903
+ } catch (error) {
904
+ await handle.close();
905
+ throw error;
906
+ }
907
+ return {
908
+ handle,
909
+ controls: coord
846
910
  };
847
- const listener = createServer((req, res) => {
848
- const capabilityId = /^\/mail\/([0-9a-f]{32})$/.exec(req.url ?? "")?.[1];
849
- if (req.method !== "POST" || capabilityId === void 0 || !mailbox.hasCapability(capabilityId)) {
850
- res.writeHead(404).end();
851
- return;
852
- }
853
- let body = "";
854
- req.on("data", (chunk) => {
855
- body += chunk;
856
- });
857
- req.on("end", () => {
858
- (async () => {
859
- try {
860
- const message = JSON.parse(body);
861
- const response = await forCapability(capabilityId).handle(message);
862
- if (response === null) {
863
- res.writeHead(202).end();
864
- return;
865
- }
866
- res.writeHead(200, { "content-type": "application/json" });
867
- res.end(JSON.stringify(response));
868
- } catch (e) {
869
- res.writeHead(200, { "content-type": "application/json" });
870
- res.end(JSON.stringify({
871
- jsonrpc: "2.0",
872
- id: null,
873
- error: {
874
- code: -32700,
875
- message: e instanceof Error ? e.message : "parse error"
876
- }
877
- }));
878
- }
879
- })();
880
- });
881
- });
882
- const port = await new Promise((resolve, reject) => {
883
- listener.once("error", reject);
884
- listener.listen(0, host, () => {
885
- const addr = listener.address();
886
- resolve(typeof addr === "object" && addr ? addr.port : 0);
887
- });
888
- });
889
- mailbox.setEndpoint(`http://${host}:${port}/mail`);
890
- return { close: () => new Promise((resolve) => {
891
- listener.close(() => resolve());
892
- }) };
893
911
  }
894
912
  //#endregion
895
913
  //#region src/runtime/supervise/otel-spans.ts
@@ -2775,14 +2793,31 @@ function workerFromBackend(backend, deliverable, seams) {
2775
2793
  }));
2776
2794
  const boundSessionId = boundBackend.backend === "bridge" ? boundBackend.sessionId : void 0;
2777
2795
  const peerMailAttachment = peerMailRuntimeAttachment(profile, capturedBackend, spawnContext);
2778
- const baseFactory = createExecutor(boundBackend);
2796
+ if (spawnContext?.peerMailUrl && boundBackend.backend === "provider" && Object.hasOwn(boundBackend.defaults?.runtimeAttachments?.mcp ?? {}, peerMailMcpAlias)) throw new ValidationError("workerFromBackend: provider defaults contain the reserved peer-mail attachment alias");
2797
+ const baseFactory = createExecutor(spawnContext?.peerMailUrl && boundBackend.backend === "provider" ? {
2798
+ ...boundBackend,
2799
+ steering: boundBackend.steering ?? {},
2800
+ defaults: {
2801
+ ...boundBackend.defaults ?? {},
2802
+ runtimeAttachments: {
2803
+ ...boundBackend.defaults?.runtimeAttachments ?? {},
2804
+ mcp: {
2805
+ ...boundBackend.defaults?.runtimeAttachments?.mcp ?? {},
2806
+ [peerMailMcpAlias]: {
2807
+ transport: "http",
2808
+ url: spawnContext.peerMailUrl
2809
+ }
2810
+ }
2811
+ }
2812
+ }
2813
+ } : boundBackend);
2779
2814
  const executorFactory = (spec, ctx) => {
2780
2815
  if (boundSessionId !== void 0 && ctx.node?.nodeId !== void 0) bridgeSessionByWorker.set(ctx.node.nodeId, boundSessionId);
2781
2816
  const extraSeams = seams?.();
2782
- const seamsForChild = extraSeams === void 0 && peerMailAttachment === void 0 ? ctx.seams : {
2817
+ const seamsForChild = extraSeams === void 0 && (peerMailAttachment === void 0 || boundBackend.backend === "provider") ? ctx.seams : {
2783
2818
  ...extraSeams,
2784
2819
  ...ctx.seams,
2785
- ...peerMailAttachment === void 0 ? {} : { [bridgeRuntimeAttachmentsKey]: {
2820
+ ...peerMailAttachment === void 0 || boundBackend.backend === "provider" ? {} : { [bridgeRuntimeAttachmentsKey]: {
2786
2821
  ...readCallerRuntimeAttachments(ctx.seams),
2787
2822
  ...peerMailAttachment
2788
2823
  } }
@@ -2829,7 +2864,9 @@ const peerMailMcpAlias = "agent-runtime-peer-mail";
2829
2864
  *
2830
2865
  * - `bridge` MOUNTS it. cli-bridge advertises `capabilities.runtimeAttachments.mcp` and mounts
2831
2866
  * the named servers for the run without binding them into the session profile.
2832
- * - `router`, `router-tools` and `provider` mount NOTHING. Those workers are in-process tool
2867
+ * - `provider` mounts the same capability through runtimeAttachments.mcp and uses the existing
2868
+ * steerable session inbox so peer delivery can be acknowledged.
2869
+ * - `router` and `router-tools` mount NOTHING. Those workers are in-process tool
2833
2870
  * loops with no MCP client; their tool surface is the caller's own array, and
2834
2871
  * `WorkerSpawnContext.peerMailUrl` is the deliverable a caller uses directly.
2835
2872
  * - Every other backend REFUSES the spawn. A sandbox box or a local CLI harness receives tools
@@ -2840,10 +2877,11 @@ const peerMailMcpAlias = "agent-runtime-peer-mail";
2840
2877
  function peerMailRuntimeAttachment(profile, backend, spawnContext) {
2841
2878
  const url = spawnContext?.peerMailUrl;
2842
2879
  if (url === void 0) return void 0;
2880
+ if (backend.backend === "provider" && backend.shared) throw new ValidationError("provider peer mail requires a dedicated steerable session; shared placement is not supported");
2843
2881
  switch (backend.backend) {
2844
2882
  case "router":
2845
- case "router-tools":
2846
- case "provider": return;
2883
+ case "router-tools": return;
2884
+ case "provider":
2847
2885
  case "bridge": break;
2848
2886
  default: throw new ValidationError(`workerFromBackend: the '${backend.backend}' backend seam cannot mount a peer-mail endpoint — it materializes tools only through the AgentProfile, and writing a per-process capability URL there would move the canonical profile digest. Run peer-mail workers on the 'bridge' backend, mount the endpoint yourself from WorkerSpawnContext.peerMailUrl through makeLeafAgent or makeWorkerAgent, or drop peerMail for this run`);
2849
2887
  }
@@ -4889,4 +4927,4 @@ function rootProviderModelEvidenceFromExecution(evidence) {
4889
4927
  //#endregion
4890
4928
  export { readRootStreamReceipt as _, superviseWithTestBrain as a, createSupervisorSpanRecorder as b, resolveWorkerSpawnRetry as c, assertCoordinationBinding as d, resolveSupervisorProfile as f, readRootStream as g, ROOT_STREAM_FILE as h, superviseRootProfile as i, retryPreSpawnRefusals as l, supervisorAgentWithTestBrain as m, profileGuidanceComposer as n, workerFromBackend as o, supervisorAgent as p, supervise as r, isPreSpawnExecutorFailure as s, DEFAULT_AUTHORED_PROFILE_SECURITY_POLICY as t, withWorkerSpawnRetry as u, UNPROVEN_CONTINUITY as v, serveCoordinationMcp as x, composeReentryTask as y };
4891
4929
 
4892
- //# sourceMappingURL=supervise-C4bLIU7J.js.map
4930
+ //# sourceMappingURL=supervise-BjrRk-AN.js.map