abtars 0.3.4-alpha.7 → 0.3.4-alpha.8

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 (103) hide show
  1. package/bundle/{_registry.generated-WGR4WOPT.js → _registry.generated-YP5GLSG7.js} +8 -5
  2. package/bundle/{_registry.generated-WGR4WOPT.js.map → _registry.generated-YP5GLSG7.js.map} +1 -1
  3. package/bundle/abtars-cli.js +4 -4
  4. package/bundle/abtars-task.js.map +2 -2
  5. package/bundle/abtars.js +349 -113
  6. package/bundle/abtars.js.map +4 -4
  7. package/bundle/{agent-api-adapter-YAHKQMMZ.js → agent-api-adapter-WRGEQ6DV.js} +2 -2
  8. package/bundle/{agent-registry-GI6CLT3Z.js → agent-registry-GHNG2PH3.js} +2 -2
  9. package/bundle/{bootstrap-X2QYIZIJ.js → bootstrap-PZIDBPEJ.js} +2 -2
  10. package/bundle/{browser-DMARZJIN.js → browser-D3LZV7ZK.js} +2 -2
  11. package/bundle/{chunk-LGP6TYFI.js → chunk-374NCXFZ.js} +89 -2
  12. package/bundle/chunk-374NCXFZ.js.map +7 -0
  13. package/bundle/{chunk-UPRZDU6T.js → chunk-75ATTOW4.js} +3 -3
  14. package/bundle/{chunk-4UL3KINB.js → chunk-7JN2MMU7.js} +2 -2
  15. package/bundle/chunk-C7K6VZNY.js +186 -0
  16. package/bundle/chunk-C7K6VZNY.js.map +7 -0
  17. package/bundle/{chunk-GXL7HJPT.js → chunk-CXXU3HAU.js} +2 -2
  18. package/bundle/{chunk-HKRSMUXJ.js → chunk-IHYKTDIP.js} +50 -28
  19. package/bundle/chunk-IHYKTDIP.js.map +7 -0
  20. package/bundle/{chunk-ONBF5DDU.js → chunk-M3JEX6L4.js} +244 -178
  21. package/bundle/chunk-M3JEX6L4.js.map +7 -0
  22. package/bundle/{chunk-5B5B6EHL.js → chunk-N4EB6LA7.js} +2 -2
  23. package/bundle/{chunk-W4EA4GCA.js → chunk-P2K2K6XL.js} +10 -10
  24. package/bundle/{chunk-5GCLBUBS.js → chunk-PU5HSKWH.js} +1 -1
  25. package/bundle/{chunk-BROFMHC2.js → chunk-SMPHE3ZM.js} +168 -123
  26. package/bundle/chunk-SMPHE3ZM.js.map +7 -0
  27. package/bundle/{chunk-SIFPBTI4.js → chunk-UNM3OXHB.js} +4 -2
  28. package/bundle/chunk-UNM3OXHB.js.map +7 -0
  29. package/bundle/{chunk-YRU2K3O6.js → chunk-VXCETPZU.js} +7 -7
  30. package/bundle/{chunk-KTYGKPYM.js → chunk-W2R2HFOQ.js} +2 -2
  31. package/bundle/{chunk-XWRADSXO.js → chunk-YPAQEQSC.js} +2 -2
  32. package/bundle/{commands-XYEGVUZF.js → commands-OIISYHTD.js} +3 -3
  33. package/bundle/{delegation-tools-QKNYQGTQ.js → delegation-tools-YATZFKYO.js} +4 -4
  34. package/bundle/{deploy-EPDWNHJU.js → deploy-T6R45OZJ.js} +2 -2
  35. package/bundle/{direct-api-transport-E3LNDBJT.js → direct-api-transport-S2RDH2I7.js} +13 -9
  36. package/bundle/direct-api-transport-S2RDH2I7.js.map +7 -0
  37. package/bundle/{discord-adapter-IT3KP3VB.js → discord-adapter-UTXUWX3A.js} +3 -3
  38. package/bundle/{heartbeat-tier3-ABWL3P7M.js → heartbeat-tier3-6KH45CL6.js} +10 -10
  39. package/bundle/kanban-channel-IJ52OMNA.js +1 -1
  40. package/bundle/{message-pipeline-P5GAQU4Z.js → message-pipeline-AUIUNM5R.js} +3 -3
  41. package/bundle/meta.json +1291 -1262
  42. package/bundle/{orc-tools-4CHEFWSN.js → orc-tools-TOD4WHTM.js} +2 -2
  43. package/bundle/{peer-transport-I6JPLFZ2.js → peer-transport-5VKK2I7P.js} +2 -2
  44. package/bundle/{phase-transport-PGKU2KD4.js → phase-transport-FS6NL4A5.js} +5 -5
  45. package/bundle/{reconciler-EBKH3JNU.js → reconciler-NZ4O4BCP.js} +4 -4
  46. package/bundle/{skill-session-BMSRQSHV.js → skill-session-VJXTKOKL.js} +2 -2
  47. package/bundle/{sleep-36XS6MHJ.js → sleep-BEWAUFCL.js} +5 -2
  48. package/bundle/{spin-TI3TSVVT.js → spin-E3ZDEDKT.js} +5 -5
  49. package/bundle/{spin-types-BLPYAETA.js → spin-types-OIE67MJK.js} +2 -2
  50. package/bundle/{system-status-JZU5FO7B.js → system-status-FAVNIUFJ.js} +2 -2
  51. package/bundle/{telegram-adapter-H6PMFPMB.js → telegram-adapter-4TX7QWKC.js} +12 -6
  52. package/bundle/{telegram-adapter-H6PMFPMB.js.map → telegram-adapter-4TX7QWKC.js.map} +2 -2
  53. package/bundle/{tool-registry-IZX2IOBM.js → tool-registry-7FK3OQGL.js} +8 -8
  54. package/bundle/{update-MESYO4LO.js → update-CKFP6LBE.js} +3 -3
  55. package/package.json +1 -1
  56. package/scripts/abtars-watchdog.service +2 -1
  57. package/scripts/emergency-update.sh +53 -5
  58. package/bundle/chunk-3AAENI2K.js +0 -210
  59. package/bundle/chunk-3AAENI2K.js.map +0 -7
  60. package/bundle/chunk-BROFMHC2.js.map +0 -7
  61. package/bundle/chunk-HKRSMUXJ.js.map +0 -7
  62. package/bundle/chunk-LGP6TYFI.js.map +0 -7
  63. package/bundle/chunk-ONBF5DDU.js.map +0 -7
  64. package/bundle/chunk-SIFPBTI4.js.map +0 -7
  65. package/bundle/chunk-Y76VUJSF.js +0 -75
  66. package/bundle/chunk-Y76VUJSF.js.map +0 -7
  67. package/bundle/direct-api-transport-E3LNDBJT.js.map +0 -7
  68. package/bundle/public/css/dashboard.css +0 -542
  69. package/bundle/public/index.html +0 -180
  70. package/bundle/public/js/app.js +0 -437
  71. package/bundle/public/memory-universe.js +0 -384
  72. package/bundle/subagent-runtime-5QUVES3W.js +0 -14
  73. package/bundle/update-MESYO4LO.js.map +0 -7
  74. /package/bundle/{agent-api-adapter-YAHKQMMZ.js.map → agent-api-adapter-WRGEQ6DV.js.map} +0 -0
  75. /package/bundle/{agent-registry-GI6CLT3Z.js.map → agent-registry-GHNG2PH3.js.map} +0 -0
  76. /package/bundle/{bootstrap-X2QYIZIJ.js.map → bootstrap-PZIDBPEJ.js.map} +0 -0
  77. /package/bundle/{browser-DMARZJIN.js.map → browser-D3LZV7ZK.js.map} +0 -0
  78. /package/bundle/{chunk-UPRZDU6T.js.map → chunk-75ATTOW4.js.map} +0 -0
  79. /package/bundle/{chunk-4UL3KINB.js.map → chunk-7JN2MMU7.js.map} +0 -0
  80. /package/bundle/{chunk-GXL7HJPT.js.map → chunk-CXXU3HAU.js.map} +0 -0
  81. /package/bundle/{chunk-5B5B6EHL.js.map → chunk-N4EB6LA7.js.map} +0 -0
  82. /package/bundle/{chunk-W4EA4GCA.js.map → chunk-P2K2K6XL.js.map} +0 -0
  83. /package/bundle/{chunk-5GCLBUBS.js.map → chunk-PU5HSKWH.js.map} +0 -0
  84. /package/bundle/{chunk-YRU2K3O6.js.map → chunk-VXCETPZU.js.map} +0 -0
  85. /package/bundle/{chunk-KTYGKPYM.js.map → chunk-W2R2HFOQ.js.map} +0 -0
  86. /package/bundle/{chunk-XWRADSXO.js.map → chunk-YPAQEQSC.js.map} +0 -0
  87. /package/bundle/{commands-XYEGVUZF.js.map → commands-OIISYHTD.js.map} +0 -0
  88. /package/bundle/{delegation-tools-QKNYQGTQ.js.map → delegation-tools-YATZFKYO.js.map} +0 -0
  89. /package/bundle/{deploy-EPDWNHJU.js.map → deploy-T6R45OZJ.js.map} +0 -0
  90. /package/bundle/{discord-adapter-IT3KP3VB.js.map → discord-adapter-UTXUWX3A.js.map} +0 -0
  91. /package/bundle/{heartbeat-tier3-ABWL3P7M.js.map → heartbeat-tier3-6KH45CL6.js.map} +0 -0
  92. /package/bundle/{message-pipeline-P5GAQU4Z.js.map → message-pipeline-AUIUNM5R.js.map} +0 -0
  93. /package/bundle/{orc-tools-4CHEFWSN.js.map → orc-tools-TOD4WHTM.js.map} +0 -0
  94. /package/bundle/{peer-transport-I6JPLFZ2.js.map → peer-transport-5VKK2I7P.js.map} +0 -0
  95. /package/bundle/{phase-transport-PGKU2KD4.js.map → phase-transport-FS6NL4A5.js.map} +0 -0
  96. /package/bundle/{reconciler-EBKH3JNU.js.map → reconciler-NZ4O4BCP.js.map} +0 -0
  97. /package/bundle/{skill-session-BMSRQSHV.js.map → skill-session-VJXTKOKL.js.map} +0 -0
  98. /package/bundle/{sleep-36XS6MHJ.js.map → sleep-BEWAUFCL.js.map} +0 -0
  99. /package/bundle/{spin-TI3TSVVT.js.map → spin-E3ZDEDKT.js.map} +0 -0
  100. /package/bundle/{spin-types-BLPYAETA.js.map → spin-types-OIE67MJK.js.map} +0 -0
  101. /package/bundle/{system-status-JZU5FO7B.js.map → system-status-FAVNIUFJ.js.map} +0 -0
  102. /package/bundle/{subagent-runtime-5QUVES3W.js.map → tool-registry-7FK3OQGL.js.map} +0 -0
  103. /package/bundle/{tool-registry-IZX2IOBM.js.map → update-CKFP6LBE.js.map} +0 -0
package/bundle/abtars.js CHANGED
@@ -19,10 +19,10 @@ import {
19
19
  createSkillStatsFlushTask,
20
20
  createUpdateCheckTask,
21
21
  phasePipelineDeps
22
- } from "./chunk-HKRSMUXJ.js";
22
+ } from "./chunk-IHYKTDIP.js";
23
23
  import {
24
24
  loadNLMConfig
25
- } from "./chunk-BROFMHC2.js";
25
+ } from "./chunk-SMPHE3ZM.js";
26
26
  import "./chunk-63A7ZRIH.js";
27
27
  import "./chunk-OKAQICWY.js";
28
28
  import {
@@ -37,7 +37,7 @@ import {
37
37
  } from "./chunk-7BSQ5UQO.js";
38
38
  import {
39
39
  phaseTransport
40
- } from "./chunk-YRU2K3O6.js";
40
+ } from "./chunk-VXCETPZU.js";
41
41
  import {
42
42
  resetAllCtxStarts
43
43
  } from "./chunk-JQDJPUHM.js";
@@ -45,11 +45,8 @@ import "./chunk-ZAA7B5BN.js";
45
45
  import {
46
46
  loadAndValidateConfig
47
47
  } from "./chunk-NDCRWEEJ.js";
48
- import "./chunk-GXL7HJPT.js";
48
+ import "./chunk-CXXU3HAU.js";
49
49
  import "./chunk-5QUTMUIK.js";
50
- import {
51
- SubagentRuntime
52
- } from "./chunk-3AAENI2K.js";
53
50
  import {
54
51
  createCapabilityRegistry
55
52
  } from "./chunk-XX6BGTPO.js";
@@ -60,16 +57,17 @@ import {
60
57
  } from "./chunk-YRSMGJFP.js";
61
58
  import {
62
59
  setPeerActivityCallback
63
- } from "./chunk-W4EA4GCA.js";
64
- import "./chunk-4UL3KINB.js";
60
+ } from "./chunk-P2K2K6XL.js";
61
+ import "./chunk-7JN2MMU7.js";
65
62
  import "./chunk-MV6CJFWR.js";
66
63
  import "./chunk-URQPDCK5.js";
67
64
  import "./chunk-VOLAZHA2.js";
68
- import "./chunk-XWRADSXO.js";
65
+ import "./chunk-YPAQEQSC.js";
69
66
  import {
70
67
  init_spin,
71
68
  spin
72
- } from "./chunk-ONBF5DDU.js";
69
+ } from "./chunk-M3JEX6L4.js";
70
+ import "./chunk-C7K6VZNY.js";
73
71
  import "./chunk-FRKW6LWB.js";
74
72
  import "./chunk-YWZPKBO6.js";
75
73
  import {
@@ -81,18 +79,17 @@ import {
81
79
  resetAbmindCache
82
80
  } from "./chunk-IKUZPMVA.js";
83
81
  import "./chunk-TEFZ4JA4.js";
82
+ import "./chunk-PU5HSKWH.js";
84
83
  import {
85
84
  init_kanban_channel,
86
85
  kanban_channel_exports
87
- } from "./chunk-KTYGKPYM.js";
88
- import "./chunk-5GCLBUBS.js";
89
- import "./chunk-EFJVUJBE.js";
86
+ } from "./chunk-W2R2HFOQ.js";
90
87
  import "./chunk-AFREM7FX.js";
88
+ import "./chunk-EFJVUJBE.js";
91
89
  import {
92
90
  init_user_registry,
93
91
  loadUsers
94
92
  } from "./chunk-ZV4IWKDJ.js";
95
- import "./chunk-Y76VUJSF.js";
96
93
  import {
97
94
  gossip_exports,
98
95
  init_gossip
@@ -654,9 +651,209 @@ import { execFileSync } from "node:child_process";
654
651
  // src/boot/context.ts
655
652
  init_spin();
656
653
 
654
+ // src/components/subagent-runtime.ts
655
+ init_log_and_swallow();
656
+ init_logger();
657
+ import { randomBytes } from "node:crypto";
658
+ var TAG = "runtime";
659
+ var DEFAULT_SESSION = {
660
+ professor: "reuse",
661
+ dreamy: "fresh",
662
+ browsie: "fresh",
663
+ coding: "reuse",
664
+ task: "fresh"
665
+ };
666
+ var DEFAULT_SPAWN_TIMEOUT_MS = 6e5;
667
+ var SubagentRuntime = class {
668
+ cache = /* @__PURE__ */ new Map();
669
+ activeSpawns = /* @__PURE__ */ new Map();
670
+ _registry = null;
671
+ _mainTransport = null;
672
+ _lastUsage = null;
673
+ /** Token usage from last complete() call. */
674
+ get lastUsage() {
675
+ return this._lastUsage;
676
+ }
677
+ _sessionManager = null;
678
+ _sandboxEnabled = false;
679
+ /** Set shared model health registry (from boot ctx). */
680
+ setRegistry(registry) {
681
+ this._registry = registry;
682
+ }
683
+ /** Set main transport reference for currentModel reads. */
684
+ setMainTransport(transport) {
685
+ this._mainTransport = transport;
686
+ }
687
+ /** Set session manager for auto-spawn sub-session creation (#510). */
688
+ setSessionManager(mgr) {
689
+ this._sessionManager = mgr;
690
+ }
691
+ /** Get session manager (may be null before boot completes). */
692
+ get sessionManager() {
693
+ return this._sessionManager;
694
+ }
695
+ /** Enable Docker sandbox for W/B/C sessions (#478). */
696
+ setSandboxEnabled(enabled) {
697
+ this._sandboxEnabled = enabled;
698
+ }
699
+ /** Send a prompt to a named agent and get the response. */
700
+ async complete(agent, prompt, opts) {
701
+ const { checkBudget, sendBudgetNotification } = await import("./budget-45QOBDWA.js");
702
+ const budgetCheck = checkBudget(agent);
703
+ if (!budgetCheck.allowed) {
704
+ const reason = budgetCheck.remaining.tokens <= 0 ? "token" : "call";
705
+ void sendBudgetNotification(agent, reason);
706
+ throw new Error(`Daily ${reason} budget exceeded for ${agent}. Resets at midnight.`);
707
+ }
708
+ const sessionStrategy = opts?.session ?? DEFAULT_SESSION[agent] ?? "fresh";
709
+ const start = Date.now();
710
+ const cached = this.cache.get(agent);
711
+ if (cached && sessionStrategy === "fresh") {
712
+ await cached.transport.resetSession?.(cached.sessionKey);
713
+ (await import("./tool-registry-7FK3OQGL.js")).resetStoreCounter();
714
+ }
715
+ const { transport, model, sessionKey } = cached ?? await this.createAgent(agent, opts?.sessionType);
716
+ if (opts?.timeoutMs && transport.setTimeoutOverride) {
717
+ transport.setTimeoutOverride(opts.timeoutMs);
718
+ }
719
+ if (opts?.maxToolRounds != null && transport.setMaxToolRoundsOverride) {
720
+ transport.setMaxToolRoundsOverride(opts.maxToolRounds);
721
+ }
722
+ try {
723
+ const response = await transport.sendPrompt(sessionKey, prompt);
724
+ const elapsed = Date.now() - start;
725
+ this._lastUsage = transport.lastUsage?.() ?? null;
726
+ logInfo(TAG, `${agent} complete: ${prompt.length}ch \u2192 ${response?.length ?? 0}ch (${elapsed}ms, ${model})`);
727
+ return response ?? "";
728
+ } catch (err) {
729
+ logWarn(TAG, `${agent} complete failed: ${err instanceof Error ? err.message : String(err)}`);
730
+ this.cache.delete(agent);
731
+ throw err;
732
+ } finally {
733
+ if (opts?.timeoutMs && transport.setTimeoutOverride) {
734
+ transport.setTimeoutOverride(null);
735
+ }
736
+ if (opts?.maxToolRounds != null && transport.setMaxToolRoundsOverride) {
737
+ transport.setMaxToolRoundsOverride(null);
738
+ }
739
+ }
740
+ }
741
+ /** Get a persistent session handle for multi-turn callers. */
742
+ async session(agent, key) {
743
+ const cacheKey = key ? `${agent}:${key}` : agent;
744
+ const cached = this.cache.get(cacheKey) ?? await this.createAgent(agent, void 0, cacheKey);
745
+ return {
746
+ sendPrompt: (sessionKey, prompt) => cached.transport.sendPrompt(sessionKey, prompt),
747
+ destroy: async () => {
748
+ try {
749
+ cached.transport.destroy();
750
+ } catch (err) {
751
+ logAndSwallow("subagent_runtime", "op", err);
752
+ }
753
+ this.cache.delete(cacheKey);
754
+ logInfo(TAG, `${cacheKey} session destroyed`);
755
+ },
756
+ get isReady() {
757
+ return cached.transport.isReady;
758
+ },
759
+ get transport() {
760
+ return cached.transport;
761
+ }
762
+ };
763
+ }
764
+ /** Fire-and-forget: run complete() in background, deliver result via callback. */
765
+ async spawn(agent, prompt, opts) {
766
+ const taskId = randomBytes(4).toString("hex");
767
+ const abort = new AbortController();
768
+ this.activeSpawns.set(taskId, { abort, startedAt: Date.now() });
769
+ const timeoutMs = opts?.timeoutMs ?? DEFAULT_SPAWN_TIMEOUT_MS;
770
+ const timer = setTimeout(() => abort.abort(), timeoutMs);
771
+ void (async () => {
772
+ try {
773
+ const result = await this.complete(agent, prompt);
774
+ if (!abort.signal.aborted) opts?.onComplete?.(taskId, result);
775
+ } catch (err) {
776
+ if (!abort.signal.aborted) opts?.onError?.(taskId, err instanceof Error ? err : new Error(String(err)));
777
+ } finally {
778
+ clearTimeout(timer);
779
+ this.activeSpawns.delete(taskId);
780
+ }
781
+ })();
782
+ logInfo(TAG, `${agent} spawned: taskId=${taskId}, timeout=${timeoutMs}ms`);
783
+ return { taskId };
784
+ }
785
+ /** Shut down all cached transports and abort active spawns. */
786
+ async shutdown() {
787
+ for (const [id, { abort }] of this.activeSpawns) {
788
+ abort.abort();
789
+ logInfo(TAG, `spawn ${id} aborted`);
790
+ }
791
+ this.activeSpawns.clear();
792
+ for (const [name, cached] of this.cache) {
793
+ try {
794
+ cached.transport.destroy();
795
+ } catch (err) {
796
+ logAndSwallow("subagent_runtime", "op", err);
797
+ }
798
+ logInfo(TAG, `${name} transport closed`);
799
+ }
800
+ this.cache.clear();
801
+ }
802
+ /** Active registry: list running background spawns. */
803
+ listActive() {
804
+ return [...this.activeSpawns.entries()].map(([taskId, entry]) => ({
805
+ taskId,
806
+ startedAt: entry.startedAt ?? 0
807
+ }));
808
+ }
809
+ /** Interrupt a specific spawn by taskId. Returns true if found. */
810
+ interruptSpawn(taskId) {
811
+ const entry = this.activeSpawns.get(taskId);
812
+ if (!entry) return false;
813
+ entry.abort.abort();
814
+ this.activeSpawns.delete(taskId);
815
+ logInfo(TAG, `spawn ${taskId} interrupted`);
816
+ return true;
817
+ }
818
+ async createAgent(agent, sessionType, cacheKey) {
819
+ const typeMap = { browsie: "B", coding: "C", task: "T" };
820
+ const resolvedType = sessionType || typeMap[agent];
821
+ const sandboxTypes = /* @__PURE__ */ new Set(["B", "C", "W"]);
822
+ if (this._sandboxEnabled && resolvedType && sandboxTypes.has(resolvedType)) {
823
+ const { logInfo: logInfo2 } = await import("./logger-OWCSNYCA.js");
824
+ logInfo2("subagent", `Sandbox spawn: ${agent} (type=${resolvedType}) \u2192 Docker container`);
825
+ }
826
+ const { createSubagentTransport } = await import("./agent-registry-GHNG2PH3.js");
827
+ const role = AGENT_TO_ROLE[agent];
828
+ const mainModel = this._mainTransport && "currentModel" in this._mainTransport ? this._mainTransport.currentModel : void 0;
829
+ const { transport, model } = await createSubagentTransport(role, this._registry ?? void 0, mainModel);
830
+ if (transport.agent?.pid) {
831
+ import("./bridge-lock-transport-4ZH7QTJP.js").then(({ trackAcpPid }) => trackAcpPid(transport.agent.pid)).catch(() => {
832
+ });
833
+ }
834
+ if (resolvedType && "setSystemPrompt" in transport && typeof transport.setSystemPrompt === "function") {
835
+ const { buildSoulBundle } = await import("./soul-bundle-VWAVHCZ6.js");
836
+ const bundle = buildSoulBundle(resolvedType);
837
+ if (bundle) transport.setSystemPrompt(bundle);
838
+ }
839
+ const sessionKey = `system:${cacheKey ?? agent}`;
840
+ const entry = { transport, model, sessionKey };
841
+ this.cache.set(cacheKey ?? agent, entry);
842
+ (await import("./tool-registry-7FK3OQGL.js")).resetStoreCounter();
843
+ return entry;
844
+ }
845
+ };
846
+ var AGENT_TO_ROLE = {
847
+ professor: "task",
848
+ dreamy: "sleep",
849
+ browsie: "browse",
850
+ coding: "coding",
851
+ task: "task"
852
+ };
853
+
657
854
  // src/components/service-registry.ts
658
855
  init_logger();
659
- var TAG = "service-registry";
856
+ var TAG2 = "service-registry";
660
857
  function jitter(ms) {
661
858
  return Math.round(ms * (0.8 + Math.random() * 0.4));
662
859
  }
@@ -688,20 +885,20 @@ var ServiceRegistry = class {
688
885
  await instance.start();
689
886
  this.instances.set(name, instance);
690
887
  this.pending.delete(name);
691
- logInfo(TAG, `Started service: ${name}${attempt > 1 ? ` (attempt ${attempt})` : ""}`);
888
+ logInfo(TAG2, `Started service: ${name}${attempt > 1 ? ` (attempt ${attempt})` : ""}`);
692
889
  return { ok: true };
693
890
  } catch (err) {
694
891
  lastError = err instanceof Error ? err.message : String(err);
695
892
  if (attempt < retries) {
696
- logWarn(TAG, `Failed to start ${name} (attempt ${attempt}/${retries}): ${lastError} \u2014 retrying in ${delayMs / 1e3}s`);
893
+ logWarn(TAG2, `Failed to start ${name} (attempt ${attempt}/${retries}): ${lastError} \u2014 retrying in ${delayMs / 1e3}s`);
697
894
  await new Promise((r) => setTimeout(r, delayMs));
698
895
  } else {
699
896
  if (backgroundRetry) {
700
- logWarn(TAG, `Failed to start ${name} after ${retries} attempts: ${lastError} \u2014 retrying in background`);
897
+ logWarn(TAG2, `Failed to start ${name} after ${retries} attempts: ${lastError} \u2014 retrying in background`);
701
898
  this.spawnBackgroundRetry(name, factory);
702
899
  return { ok: false, error: lastError, retryingInBackground: true };
703
900
  }
704
- logError(TAG, `Failed to start ${name} after ${retries} attempts: ${lastError}`);
901
+ logError(TAG2, `Failed to start ${name} after ${retries} attempts: ${lastError}`);
705
902
  return { ok: false, error: lastError };
706
903
  }
707
904
  }
@@ -711,7 +908,7 @@ var ServiceRegistry = class {
711
908
  stop(name) {
712
909
  if (this.pending.has(name)) {
713
910
  this.cancelPending(name);
714
- logInfo(TAG, `Cancelled pending retry for ${name}`);
911
+ logInfo(TAG2, `Cancelled pending retry for ${name}`);
715
912
  return { ok: true };
716
913
  }
717
914
  const instance = this.instances.get(name);
@@ -719,11 +916,11 @@ var ServiceRegistry = class {
719
916
  try {
720
917
  instance.stop();
721
918
  this.instances.delete(name);
722
- logInfo(TAG, `Stopped service: ${name}`);
919
+ logInfo(TAG2, `Stopped service: ${name}`);
723
920
  return { ok: true };
724
921
  } catch (err) {
725
922
  const msg = err instanceof Error ? err.message : String(err);
726
- logError(TAG, `Failed to stop ${name}: ${msg}`);
923
+ logError(TAG2, `Failed to stop ${name}: ${msg}`);
727
924
  return { ok: false, error: msg };
728
925
  }
729
926
  }
@@ -770,7 +967,7 @@ var ServiceRegistry = class {
770
967
  scheduleNextAttempt(name, factory, state) {
771
968
  const delay = backoffDelay(state.attempt);
772
969
  state.nextAttemptAt = Date.now() + delay;
773
- logDebug(TAG, `Background retry for ${name}: attempt ${state.attempt + 4} in ${Math.round(delay / 1e3)}s`);
970
+ logDebug(TAG2, `Background retry for ${name}: attempt ${state.attempt + 4} in ${Math.round(delay / 1e3)}s`);
774
971
  state.timer = setTimeout(async () => {
775
972
  state.timer = null;
776
973
  if (state.aborted) return;
@@ -792,12 +989,12 @@ var ServiceRegistry = class {
792
989
  if (state.aborted) return;
793
990
  this.instances.set(name, instance);
794
991
  this.pending.delete(name);
795
- logInfo(TAG, `Started service: ${name} (background retry, attempt ${state.attempt + 4})`);
992
+ logInfo(TAG2, `Started service: ${name} (background retry, attempt ${state.attempt + 4})`);
796
993
  } catch (err) {
797
994
  if (state.aborted) return;
798
995
  state.lastError = err instanceof Error ? err.message : String(err);
799
996
  state.attempt++;
800
- logWarn(TAG, `Background retry for ${name} failed (attempt ${state.attempt + 3}): ${state.lastError}`);
997
+ logWarn(TAG2, `Background retry for ${name} failed (attempt ${state.attempt + 3}): ${state.lastError}`);
801
998
  this.scheduleNextAttempt(name, factory, state);
802
999
  }
803
1000
  }, delay);
@@ -806,7 +1003,7 @@ var ServiceRegistry = class {
806
1003
 
807
1004
  // src/components/conversation-buffer.ts
808
1005
  init_logger();
809
- var TAG2 = "ConversationBuffer";
1006
+ var TAG3 = "ConversationBuffer";
810
1007
  var ConversationBuffer = class {
811
1008
  limit;
812
1009
  history = /* @__PURE__ */ new Map();
@@ -822,7 +1019,7 @@ var ConversationBuffer = class {
822
1019
  }
823
1020
  entries.push({ sender, text, ts: Date.now() });
824
1021
  while (entries.length > this.limit) entries.shift();
825
- logDebug(TAG2, `Buffered message in ${channelKey} (size=${entries.length})`);
1022
+ logDebug(TAG3, `Buffered message in ${channelKey} (size=${entries.length})`);
826
1023
  }
827
1024
  /**
828
1025
  * Drain all buffered messages for a channel key, returning them as
@@ -834,7 +1031,7 @@ var ConversationBuffer = class {
834
1031
  if (!entries || entries.length === 0) return "";
835
1032
  const lines = entries.map((e) => `[${e.sender}]: ${e.text}`);
836
1033
  this.history.delete(channelKey);
837
- logDebug(TAG2, `Drained ${lines.length} entries from ${channelKey}`);
1034
+ logDebug(TAG3, `Drained ${lines.length} entries from ${channelKey}`);
838
1035
  return "--- Recent conversation context ---\n" + lines.join("\n") + "\n--- End context ---\n\n";
839
1036
  }
840
1037
  /** Clear the buffer for a specific channel key. */
@@ -1059,7 +1256,7 @@ async function phaseMemory(ctx) {
1059
1256
  await memory.initialize();
1060
1257
  ctx.memory = memory;
1061
1258
  logDebug("main", `\u{1F9E0} Memory enabled (dir=${ctx.memoryConfig.memoryDir})`);
1062
- const { setMemoryBackend } = await import("./tool-registry-IZX2IOBM.js");
1259
+ const { setMemoryBackend } = await import("./tool-registry-7FK3OQGL.js");
1063
1260
  const mm = ctx.memory;
1064
1261
  const backend = {
1065
1262
  initialize: async () => {
@@ -1171,7 +1368,7 @@ async function phasePlatformsConnect(ctx) {
1171
1368
  registry.register("telegram", {
1172
1369
  configured: Boolean(config.telegram.botToken && config.telegram.allowedUserIds.size > 0),
1173
1370
  async create() {
1174
- const { TelegramAdapter } = await import("./telegram-adapter-H6PMFPMB.js");
1371
+ const { TelegramAdapter } = await import("./telegram-adapter-4TX7QWKC.js");
1175
1372
  const adapter = new TelegramAdapter(
1176
1373
  { botToken: config.telegram.botToken, allowedUserIds: config.telegram.allowedUserIds, pollTimeoutS: config.telegram.pollTimeoutS },
1177
1374
  { pipeline: { handleInbound: (msg) => recovery.handle(msg, adapter) }, conversationBuffer: ctx.conversationBuffer, transport: null, memory: null, sessionManager: ctx.sessionManager, actionGate: ctx.actionGate }
@@ -1203,7 +1400,7 @@ async function phasePlatformsConnect(ctx) {
1203
1400
  if (!config.discord.appId || !isValidSnowflake(config.discord.appId)) {
1204
1401
  throw new Error("DISCORD_APP_ID missing or invalid \u2014 Discord disabled");
1205
1402
  }
1206
- const { DiscordAdapter } = await import("./discord-adapter-IT3KP3VB.js");
1403
+ const { DiscordAdapter } = await import("./discord-adapter-UTXUWX3A.js");
1207
1404
  const adapter = new DiscordAdapter(
1208
1405
  { botToken: config.discord.botToken, appId: config.discord.appId, allowedUserIds: config.discord.allowedUserIds },
1209
1406
  { pipeline: { handleInbound: (msg) => recovery.handle(msg, adapter) }, transport: null, memory: null, conversationBuffer: ctx.conversationBuffer }
@@ -1281,13 +1478,13 @@ async function phaseCapabilities(ctx) {
1281
1478
  let loaded = [];
1282
1479
  let staticCaps;
1283
1480
  try {
1284
- ({ capabilities: staticCaps } = await import("./_registry.generated-WGR4WOPT.js"));
1481
+ ({ capabilities: staticCaps } = await import("./_registry.generated-YP5GLSG7.js"));
1285
1482
  } catch (err) {
1286
1483
  logError("capabilities", `Registry import failed: ${err instanceof Error ? err.message : String(err)}. Loading individually.`);
1287
1484
  staticCaps = [];
1288
1485
  const individualCaps = [
1289
1486
  { name: "hotskills", load: () => import("./hotskills-FWX4QI7V.js") },
1290
- { name: "browser", load: () => import("./browser-DMARZJIN.js") }
1487
+ { name: "browser", load: () => import("./browser-D3LZV7ZK.js") }
1291
1488
  ];
1292
1489
  for (const { name, load } of individualCaps) {
1293
1490
  if (disabled.has(name)) continue;
@@ -1379,7 +1576,7 @@ function startInProcWatchdog(opts) {
1379
1576
  }
1380
1577
 
1381
1578
  // src/boot/phase-heartbeat.ts
1382
- var TAG3 = "heartbeat";
1579
+ var TAG4 = "heartbeat";
1383
1580
  async function phaseHeartbeat(ctx) {
1384
1581
  const { init: initSkillStats } = await import("./skill-stats-JORH5DGM.js");
1385
1582
  initSkillStats();
@@ -1413,7 +1610,7 @@ async function phaseHeartbeat(ctx) {
1413
1610
  heartbeat.registerTask(createSkillStatsFlushTask());
1414
1611
  heartbeat.registerTask(createSkillReloadTask());
1415
1612
  heartbeat.registerTask(createUpdateCheckTask((msg) => {
1416
- import("./notification-BFSIEECG.js").then(({ sendNotification: sendNotification2 }) => sendNotification2(ctx, msg)).catch((err) => logAndSwallow(TAG3, "sendNotification update-check", err));
1613
+ import("./notification-BFSIEECG.js").then(({ sendNotification: sendNotification2 }) => sendNotification2(ctx, msg)).catch((err) => logAndSwallow(TAG4, "sendNotification update-check", err));
1417
1614
  }));
1418
1615
  heartbeat.registerTask({
1419
1616
  name: "restart-check",
@@ -1425,7 +1622,7 @@ async function phaseHeartbeat(ctx) {
1425
1622
  }
1426
1623
  }
1427
1624
  });
1428
- const { spin: spin2 } = await import("./spin-TI3TSVVT.js");
1625
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
1429
1626
  const masterUser = loadUsers().users.find((u) => u.role === "master");
1430
1627
  const masterUserId = masterUser?.userId ?? "master";
1431
1628
  ctx.sendSystemMessage = async (prompt) => {
@@ -1443,21 +1640,29 @@ async function phaseHeartbeat(ctx) {
1443
1640
  // src/boot/phase-sleep.ts
1444
1641
  init_logger();
1445
1642
  async function phaseSleep(ctx) {
1446
- const { memoryConfig, memory, sendSystemMessage } = ctx;
1643
+ const { memoryConfig, memory, sendSystemMessage, sessionManager } = ctx;
1447
1644
  if (!sendSystemMessage) {
1448
1645
  ctx.phaseHealth.set(phaseSleep.name, { status: "skipped", error: "no sendSystemMessage" });
1449
1646
  logWarn("boot", `${phaseSleep.name}: skipping \u2014 heartbeat not available`);
1450
1647
  return "skipped";
1451
1648
  }
1452
- const { createSleepHandle } = await import("./sleep-36XS6MHJ.js");
1453
- const { killWakeInhibit } = await import("./commands-XYEGVUZF.js");
1649
+ const { createSleepHandle } = await import("./sleep-BEWAUFCL.js");
1650
+ const { killWakeInhibit } = await import("./commands-OIISYHTD.js");
1454
1651
  const SLEEP_HOUR = parseInt(readEnvWithDefault("BED_TIME", "2", "bedtime hour").split(":")[0] ?? "2", 10);
1455
- let subagent = null;
1652
+ let nightSessionId;
1456
1653
  const { getEnv: getEnv2 } = await import("./env-schema-4JXQUOH4.js");
1457
1654
  const runtime = {
1458
1655
  async complete(prompt) {
1459
- if (!subagent) subagent = new SubagentRuntime();
1460
- return subagent.complete("dreamy", prompt, { session: "reuse", timeoutMs: getEnv2().modelApiTimeoutMs * 3 });
1656
+ const { result, sessionId } = await sessionManager.spin({
1657
+ type: "D",
1658
+ prompt,
1659
+ sessionId: nightSessionId,
1660
+ // undefined on step 1 → transient alloc; reused on steps 2+
1661
+ timeoutMs: getEnv2().modelApiTimeoutMs * 3,
1662
+ await: true
1663
+ });
1664
+ if (sessionId && !nightSessionId) nightSessionId = sessionId;
1665
+ return result ?? "";
1461
1666
  }
1462
1667
  };
1463
1668
  ctx.sleepHandle = createSleepHandle({
@@ -1465,10 +1670,21 @@ async function phaseSleep(ctx) {
1465
1670
  sleepAuditDir: ctx.sleepAuditDir,
1466
1671
  memoryEnabled: memoryConfig.memoryEnabled,
1467
1672
  runtime,
1468
- onComplete: () => resetAllCtxStarts(memoryConfig.memoryDir),
1673
+ onComplete: () => {
1674
+ if (nightSessionId) {
1675
+ const s = sessionManager.getSessionById(nightSessionId);
1676
+ if (s) s.status = "ended";
1677
+ nightSessionId = void 0;
1678
+ }
1679
+ resetAllCtxStarts(memoryConfig.memoryDir);
1680
+ },
1469
1681
  getLastMsgTs: () => memory?.getLastMessageTimestamp(true) ?? 0,
1470
1682
  sendSystemMessage,
1471
- killWakeInhibit
1683
+ killWakeInhibit,
1684
+ allocateSleepSession: (name) => {
1685
+ const s = sessionManager.allocateDreamySession(name);
1686
+ nightSessionId = s.id;
1687
+ }
1472
1688
  });
1473
1689
  return "ran";
1474
1690
  }
@@ -1640,7 +1856,7 @@ var AuthGate = class {
1640
1856
 
1641
1857
  // src/components/memory-search-controller.ts
1642
1858
  init_logger();
1643
- var TAG4 = "memory-search-ctrl";
1859
+ var TAG5 = "memory-search-ctrl";
1644
1860
  var VALID_STAGES = /* @__PURE__ */ new Set(["Sf", "Ss", "Se", "S6"]);
1645
1861
  var MemorySearchController = class {
1646
1862
  deps;
@@ -1653,7 +1869,7 @@ var MemorySearchController = class {
1653
1869
  return { status: 200, body: { userIds } };
1654
1870
  } catch (err) {
1655
1871
  const msg = err instanceof Error ? err.message : String(err);
1656
- logWarn(TAG4, `listChats failed: ${msg}`);
1872
+ logWarn(TAG5, `listChats failed: ${msg}`);
1657
1873
  return { status: 500, body: { error: msg } };
1658
1874
  }
1659
1875
  }
@@ -1663,7 +1879,7 @@ var MemorySearchController = class {
1663
1879
  return { status: 200, body: { memories } };
1664
1880
  } catch (err) {
1665
1881
  const msg = err instanceof Error ? err.message : String(err);
1666
- logWarn(TAG4, `listAll failed: ${msg}`);
1882
+ logWarn(TAG5, `listAll failed: ${msg}`);
1667
1883
  return { status: 500, body: { error: msg } };
1668
1884
  }
1669
1885
  }
@@ -1693,7 +1909,7 @@ var MemorySearchController = class {
1693
1909
  return { status: 200, body: response };
1694
1910
  } catch (err) {
1695
1911
  const msg = err instanceof Error ? err.message : String(err);
1696
- logWarn(TAG4, `search failed: ${msg}`);
1912
+ logWarn(TAG5, `search failed: ${msg}`);
1697
1913
  return { status: 500, body: { error: msg } };
1698
1914
  }
1699
1915
  }
@@ -1829,7 +2045,7 @@ var StatusBroadcaster = class {
1829
2045
 
1830
2046
  // src/components/dashboard/dashboard-server.ts
1831
2047
  init_logger();
1832
- var TAG5 = "dashboard-server";
2048
+ var TAG6 = "dashboard-server";
1833
2049
  var DashboardServer = class {
1834
2050
  deps;
1835
2051
  _broadcaster;
@@ -1861,7 +2077,7 @@ var DashboardServer = class {
1861
2077
  reject(err);
1862
2078
  });
1863
2079
  this.server.listen(config.webPort, config.webHost, () => {
1864
- logInfo(TAG5, `Dashboard listening on ${config.webHost}:${config.webPort}`);
2080
+ logInfo(TAG6, `Dashboard listening on ${config.webHost}:${config.webPort}`);
1865
2081
  resolve3();
1866
2082
  });
1867
2083
  });
@@ -2045,25 +2261,25 @@ var DashboardServer = class {
2045
2261
  }
2046
2262
  const token = this.deps.authGate.extractToken(req);
2047
2263
  if (!token || !this.deps.authGate.validate(token)) {
2048
- logInfo(TAG5, `WebSocket auth failed (token ${token ? "provided but invalid" : "missing"}) from ${req.socket.remoteAddress}`);
2264
+ logInfo(TAG6, `WebSocket auth failed (token ${token ? "provided but invalid" : "missing"}) from ${req.socket.remoteAddress}`);
2049
2265
  socket.write(
2050
2266
  "HTTP/1.1 401 Unauthorized\r\nContent-Type: application/json\r\n\r\n" + JSON.stringify({ error: "Unauthorized" })
2051
2267
  );
2052
2268
  socket.destroy();
2053
2269
  return;
2054
2270
  }
2055
- logInfo(TAG5, `WebSocket client authenticated from ${req.socket.remoteAddress}`);
2271
+ logInfo(TAG6, `WebSocket client authenticated from ${req.socket.remoteAddress}`);
2056
2272
  this.wss.handleUpgrade(req, socket, head, (ws) => {
2057
2273
  this.wss.emit("connection", ws, req);
2058
2274
  this._broadcaster.addClient(ws);
2059
- logInfo(TAG5, "WebSocket client connected");
2275
+ logInfo(TAG6, "WebSocket client connected");
2060
2276
  });
2061
2277
  }
2062
2278
  // ── Helpers ───────────────────────────────────────────────────────────
2063
2279
  /** Send an error response, logging the error. */
2064
2280
  sendError(res, status, err) {
2065
2281
  const message = err instanceof Error ? err.message : String(err);
2066
- logError(TAG5, `Request error: ${message}`);
2282
+ logError(TAG6, `Request error: ${message}`);
2067
2283
  if (!res.headersSent) {
2068
2284
  res.writeHead(status, { "Content-Type": "application/json" });
2069
2285
  res.end(JSON.stringify({ error: message }));
@@ -2115,7 +2331,7 @@ function loadAgentApiConfig(env) {
2115
2331
  }
2116
2332
 
2117
2333
  // src/boot/phase-dashboard.ts
2118
- var TAG6 = "dashboard";
2334
+ var TAG7 = "dashboard";
2119
2335
  async function phaseDashboard(ctx) {
2120
2336
  const { platforms, memory, transport, registry, heartbeat, nlmConfig } = ctx;
2121
2337
  if (!platforms.web) return "skipped";
@@ -2126,9 +2342,9 @@ async function phaseDashboard(ctx) {
2126
2342
  }
2127
2343
  const dashConfig = loadDashboardConfig(process.env);
2128
2344
  if (!dashConfig.webAuthToken) {
2129
- const { randomBytes } = await import("node:crypto");
2345
+ const { randomBytes: randomBytes2 } = await import("node:crypto");
2130
2346
  const { readFile, writeFile } = await import("node:fs/promises");
2131
- const token = randomBytes(32).toString("hex");
2347
+ const token = randomBytes2(32).toString("hex");
2132
2348
  dashConfig.webAuthToken = token;
2133
2349
  process.env["WEB_AUTH"] = token;
2134
2350
  const envPath = join5(process.cwd(), "config", ".env");
@@ -2153,7 +2369,7 @@ WEB_AUTH=${token}
2153
2369
  try {
2154
2370
  return loadAgentApiConfig(process.env);
2155
2371
  } catch (err) {
2156
- logAndSwallow(TAG6, "loadAgentApiConfig", err);
2372
+ logAndSwallow(TAG7, "loadAgentApiConfig", err);
2157
2373
  return null;
2158
2374
  }
2159
2375
  })() : null;
@@ -2235,11 +2451,11 @@ WEB_AUTH=${token}
2235
2451
  }
2236
2452
  }
2237
2453
  if (!bound) {
2238
- logWarn(TAG6, `All ports ${basePort}-${basePort + 10} in use \u2014 dashboard disabled`);
2454
+ logWarn(TAG7, `All ports ${basePort}-${basePort + 10} in use \u2014 dashboard disabled`);
2239
2455
  return "skipped";
2240
2456
  }
2241
2457
  ctx.dashboardServer = dashboardServer;
2242
- if (dashConfig.webPort !== basePort) logWarn(TAG6, `Port ${basePort} in use \u2014 dashboard bound to :${dashConfig.webPort}`);
2458
+ if (dashConfig.webPort !== basePort) logWarn(TAG7, `Port ${basePort} in use \u2014 dashboard bound to :${dashConfig.webPort}`);
2243
2459
  logInfo("main", `Web dashboard on ${dashConfig.webHost}:${dashConfig.webPort}${customModule ? ` (custom: ${customModule})` : ""}`);
2244
2460
  return "ran";
2245
2461
  }
@@ -2291,7 +2507,7 @@ function bufferedStreamBody(content, opts) {
2291
2507
 
2292
2508
  // src/components/openai-compat-routes.ts
2293
2509
  init_logger();
2294
- var TAG7 = "openai-compat";
2510
+ var TAG8 = "openai-compat";
2295
2511
  function handleModels() {
2296
2512
  return {
2297
2513
  status: 200,
@@ -2375,7 +2591,7 @@ async function handleChatCompletions(rawBody, req, deps) {
2375
2591
  const stream = body.stream === true;
2376
2592
  const model = body.model;
2377
2593
  if (body.tools || body.tool_choice) {
2378
- logDebug(TAG7, `tools[]/tool_choice present in request \u2014 ignored in v1`);
2594
+ logDebug(TAG8, `tools[]/tool_choice present in request \u2014 ignored in v1`);
2379
2595
  }
2380
2596
  const flat = flattenMessages(messages);
2381
2597
  for (let i = 0; i < flat.allContents.length; i++) {
@@ -2384,7 +2600,7 @@ async function handleChatCompletions(rawBody, req, deps) {
2384
2600
  const scan = abmind().scanForInjection(content);
2385
2601
  if (!scan.safe) {
2386
2602
  const top = scan.flags[0];
2387
- logWarn(TAG7, `BLOCKED /v1/chat/completions \u2014 injection in messages[${i}]: ${top.category} (score=${scan.score}) from guest=${deps.guestName}`);
2603
+ logWarn(TAG8, `BLOCKED /v1/chat/completions \u2014 injection in messages[${i}]: ${top.category} (score=${scan.score}) from guest=${deps.guestName}`);
2388
2604
  const refusal = buildChatResponse({
2389
2605
  model,
2390
2606
  content: "I can't process that request \u2014 it triggered the injection guard. Please rephrase."
@@ -2414,8 +2630,19 @@ ${fullPrompt}`;
2414
2630
  const effectiveSessionKey = isPeer ? `${Math.floor(Date.now() / 1e3)}_P_01` : sessionKey;
2415
2631
  const now = Date.now();
2416
2632
  if (!isPeer) deps.memory?.recordMessage({ role: "user", content: flat.prompt, timestamp: now, userId: "master", sessionId: effectiveSessionKey });
2417
- logInfo(TAG7, `/v1/chat/completions guest=${deps.guestName} session=${effectiveSessionKey} promptLen=${flat.prompt.length} stream=${stream}`);
2418
- const reply = await deps.session.sendPrompt(effectiveSessionKey, fullPrompt);
2633
+ logInfo(TAG8, `/v1/chat/completions guest=${deps.guestName} session=${effectiveSessionKey} promptLen=${flat.prompt.length} stream=${stream}`);
2634
+ let reply;
2635
+ if (deps.sessionManager) {
2636
+ const r = await deps.sessionManager.spin({
2637
+ type: "A",
2638
+ sessionId: effectiveSessionKey,
2639
+ prompt: fullPrompt,
2640
+ await: true
2641
+ });
2642
+ reply = r.result ?? "";
2643
+ } else {
2644
+ reply = await deps.session.sendPrompt(effectiveSessionKey, fullPrompt);
2645
+ }
2419
2646
  if (!isPeer) deps.memory?.recordMessage({ role: "assistant", content: reply, timestamp: Date.now(), userId: "master", sessionId: effectiveSessionKey });
2420
2647
  if (stream) {
2421
2648
  return {
@@ -2451,7 +2678,7 @@ function writeResult(res, result) {
2451
2678
  }
2452
2679
 
2453
2680
  // src/components/agent-api-server.ts
2454
- var TAG8 = "agent-api";
2681
+ var TAG9 = "agent-api";
2455
2682
  var MAX_TRAFFIC_LOG = 50;
2456
2683
  var IDLE_TIMEOUT_MS = 10 * 60 * 1e3;
2457
2684
  function normalizeIp(raw) {
@@ -2488,6 +2715,7 @@ var AgentApiServer = class {
2488
2715
  agentSession = null;
2489
2716
  idleTimer = null;
2490
2717
  runtime;
2718
+ sessionManager;
2491
2719
  guestName = "GUEST";
2492
2720
  onPeerActivity;
2493
2721
  tlsEnabled = false;
@@ -2499,6 +2727,7 @@ var AgentApiServer = class {
2499
2727
  this.workingDir = deps.workingDir;
2500
2728
  this.memory = deps.memory;
2501
2729
  this.runtime = deps.runtime;
2730
+ this.sessionManager = deps.sessionManager;
2502
2731
  this.onPeerActivity = deps.onPeerActivity;
2503
2732
  this.a2aAdapter = deps.a2aAdapter;
2504
2733
  const configDir = join6(abtarsHome(), "config");
@@ -2514,12 +2743,12 @@ var AgentApiServer = class {
2514
2743
  }, (req, res) => this.handle(req, res));
2515
2744
  hasTls = true;
2516
2745
  this.tlsEnabled = true;
2517
- logInfo(TAG8, "TLS 1.3 enabled for agent-api (self-signed cert)");
2746
+ logInfo(TAG9, "TLS 1.3 enabled for agent-api (self-signed cert)");
2518
2747
  } catch (err) {
2519
- logAndSwallow(TAG8, "TLS setup", err);
2748
+ logAndSwallow(TAG9, "TLS setup", err);
2520
2749
  }
2521
2750
  } else {
2522
- logWarn(TAG8, "identity.crt/identity.tls.key not found \u2014 agent-api starting without TLS (plain HTTP)");
2751
+ logWarn(TAG9, "identity.crt/identity.tls.key not found \u2014 agent-api starting without TLS (plain HTTP)");
2523
2752
  }
2524
2753
  if (!hasTls) {
2525
2754
  this.server = createServer2((req, res) => this.handle(req, res));
@@ -2543,7 +2772,7 @@ var AgentApiServer = class {
2543
2772
  }
2544
2773
  }
2545
2774
  } catch (err) {
2546
- logAndSwallow(TAG8, "load agentRules", err);
2775
+ logAndSwallow(TAG9, "load agentRules", err);
2547
2776
  this.agentRules = "";
2548
2777
  }
2549
2778
  }
@@ -2570,10 +2799,10 @@ var AgentApiServer = class {
2570
2799
  if (result.ok) {
2571
2800
  this.peerWss.handleUpgrade(req, socket, head, (ws) => {
2572
2801
  this.peerWsConnections.set(name, ws);
2573
- logInfo(TAG8, `Peer WS connected: ${name}`);
2802
+ logInfo(TAG9, `Peer WS connected: ${name}`);
2574
2803
  ws.on("close", () => {
2575
2804
  this.peerWsConnections.delete(name);
2576
- logInfo(TAG8, `Peer WS disconnected: ${name}`);
2805
+ logInfo(TAG9, `Peer WS disconnected: ${name}`);
2577
2806
  });
2578
2807
  ws.on("error", () => {
2579
2808
  this.peerWsConnections.delete(name);
@@ -2620,7 +2849,7 @@ var AgentApiServer = class {
2620
2849
  try {
2621
2850
  const msg = JSON.parse(raw);
2622
2851
  if (msg.type === "request") {
2623
- this.handlePeerWsRequest(peerName, msg).catch((err) => logAndSwallow(TAG8, "ws-request", err));
2852
+ this.handlePeerWsRequest(peerName, msg).catch((err) => logAndSwallow(TAG9, "ws-request", err));
2624
2853
  }
2625
2854
  } catch {
2626
2855
  }
@@ -2630,7 +2859,7 @@ var AgentApiServer = class {
2630
2859
  if (!ws || ws.readyState !== ws.OPEN) return;
2631
2860
  let result = { error: "unknown method" };
2632
2861
  if (msg.method === "delegate") {
2633
- const { spin: spin2 } = await import("./spin-TI3TSVVT.js");
2862
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
2634
2863
  const p = msg.payload;
2635
2864
  const { cardId } = spin2.dispatch({ type: "W", goal: p.goal, title: p.goal.slice(0, 60), source: "peer", priority: p.priority ?? "MEDIUM" });
2636
2865
  result = { ok: true, taskId: cardId };
@@ -2661,7 +2890,7 @@ var AgentApiServer = class {
2661
2890
  this.idleTimer = null;
2662
2891
  }
2663
2892
  if (!this.agentSession) return;
2664
- logInfo(TAG8, "A2A idle timeout \u2014 saving transcript, closing log, killing session");
2893
+ logInfo(TAG9, "A2A idle timeout \u2014 saving transcript, closing log, killing session");
2665
2894
  try {
2666
2895
  const today = localDate();
2667
2896
  const dir = join6(this.workingDir, "memory", "working", today);
@@ -2669,9 +2898,9 @@ var AgentApiServer = class {
2669
2898
  const dest = join6(dir, "transcript_a2a.log");
2670
2899
  const transcript = this.agentSession.getMessages?.()?.map((m) => `[${m.role}] ${m.content}`).join("\n") ?? "";
2671
2900
  writeFileSync3(dest, transcript, "utf-8");
2672
- logInfo(TAG8, `A2A transcript saved to ${dest}`);
2901
+ logInfo(TAG9, `A2A transcript saved to ${dest}`);
2673
2902
  } catch (e) {
2674
- logWarn(TAG8, `A2A transcript save failed: ${e}`);
2903
+ logWarn(TAG9, `A2A transcript save failed: ${e}`);
2675
2904
  }
2676
2905
  this.log("SYSTEM", "Idle timeout \u2014 session closed");
2677
2906
  await this.agentSession.destroy();
@@ -2733,7 +2962,7 @@ var AgentApiServer = class {
2733
2962
  if (caller === null) return;
2734
2963
  this.guestName = caller;
2735
2964
  this.handleV1ChatCompletions(req, res, caller).catch((err) => {
2736
- logWarn(TAG8, `/v1/chat/completions error: ${err instanceof Error ? err.message : String(err)}`);
2965
+ logWarn(TAG9, `/v1/chat/completions error: ${err instanceof Error ? err.message : String(err)}`);
2737
2966
  if (!res.headersSent) {
2738
2967
  res.writeHead(500, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Internal server error", "server_error")));
2739
2968
  }
@@ -2743,7 +2972,7 @@ var AgentApiServer = class {
2743
2972
  if (url === "/v1/embeddings" && method === "POST") {
2744
2973
  if (this.requireBearer(req, res) === null) return;
2745
2974
  this.handleV1Embeddings(req, res).catch((err) => {
2746
- logWarn(TAG8, `/v1/embeddings error: ${err instanceof Error ? err.message : String(err)}`);
2975
+ logWarn(TAG9, `/v1/embeddings error: ${err instanceof Error ? err.message : String(err)}`);
2747
2976
  if (!res.headersSent) {
2748
2977
  res.writeHead(500, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Internal server error", "server_error")));
2749
2978
  }
@@ -2754,7 +2983,7 @@ var AgentApiServer = class {
2754
2983
  const caller = this.requireBearerRateLimited(req, res);
2755
2984
  if (caller === null) return;
2756
2985
  this.handleV1Tasks(req, res, caller).catch((err) => {
2757
- logWarn(TAG8, `/v1/tasks error: ${err instanceof Error ? err.message : String(err)}`);
2986
+ logWarn(TAG9, `/v1/tasks error: ${err instanceof Error ? err.message : String(err)}`);
2758
2987
  if (!res.headersSent) {
2759
2988
  res.writeHead(500, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Internal server error", "server_error")));
2760
2989
  }
@@ -2797,7 +3026,7 @@ var AgentApiServer = class {
2797
3026
  }
2798
3027
  async handleOrcRoute(url, method, req, res) {
2799
3028
  try {
2800
- const { getOrcTools } = await import("./orc-tools-4CHEFWSN.js");
3029
+ const { getOrcTools } = await import("./orc-tools-TOD4WHTM.js");
2801
3030
  if (url === "/v1/orc/spawn" && method === "POST") {
2802
3031
  const body = JSON.parse(await readBody(req));
2803
3032
  const tool = getOrcTools().find((t) => t.name === "spawn_worker");
@@ -2825,7 +3054,7 @@ var AgentApiServer = class {
2825
3054
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify({ ok: false, error: "peer and goal required" }));
2826
3055
  return;
2827
3056
  }
2828
- const { getPeerTransport } = await import("./peer-transport-I6JPLFZ2.js");
3057
+ const { getPeerTransport } = await import("./peer-transport-5VKK2I7P.js");
2829
3058
  const transport = getPeerTransport();
2830
3059
  const remoteId = await transport.delegateTask(peer, goal, { priority: "MEDIUM", context: title });
2831
3060
  res.writeHead(200, { "Content-Type": "application/json" }).end(JSON.stringify({ ok: true, result: `Delegated to ${peer} \u2014 remote card #${remoteId}` }));
@@ -2852,13 +3081,13 @@ var AgentApiServer = class {
2852
3081
  for (const [name, peer] of Object.entries(config.peers)) {
2853
3082
  const result = verifyJwt(token, peer.token, config.self.name);
2854
3083
  if (result.ok && result.payload.iss === name) {
2855
- logInfo(TAG8, `PEER_CALL iss=${result.payload.iss} aud=${result.payload.aud} verified`);
3084
+ logInfo(TAG9, `PEER_CALL iss=${result.payload.iss} aud=${result.payload.aud} verified`);
2856
3085
  return result.payload.iss;
2857
3086
  }
2858
3087
  }
2859
3088
  for (const [name, peer] of Object.entries(config.peers)) {
2860
3089
  if (token === peer.token) {
2861
- logInfo(TAG8, `PEER_CALL caller=${name} (raw token, no JWT)`);
3090
+ logInfo(TAG9, `PEER_CALL caller=${name} (raw token, no JWT)`);
2862
3091
  return name;
2863
3092
  }
2864
3093
  }
@@ -2891,7 +3120,7 @@ var AgentApiServer = class {
2891
3120
  if (!limit.allowed) {
2892
3121
  const retryAfter = Math.ceil((limit.retryAfterMs ?? 6e4) / 1e3);
2893
3122
  res.writeHead(429, { "Retry-After": String(retryAfter), "Content-Type": "application/json" }).end(JSON.stringify(openaiError(`Rate limit exceeded for ${caller}`, "rate_limit_error", "rate_limit")));
2894
- logWarn(TAG8, `Rate limited ${caller} \u2014 retry in ${retryAfter}s`);
3123
+ logWarn(TAG9, `Rate limited ${caller} \u2014 retry in ${retryAfter}s`);
2895
3124
  return;
2896
3125
  }
2897
3126
  const { setCurrentPeerHops } = await import("./peer-client-RGEU5HOK.js");
@@ -2900,7 +3129,7 @@ var AgentApiServer = class {
2900
3129
  try {
2901
3130
  body = JSON.parse(await readBody(req));
2902
3131
  } catch (err) {
2903
- logAndSwallow(TAG8, "JSON.parse chat completions body", err);
3132
+ logAndSwallow(TAG9, "JSON.parse chat completions body", err);
2904
3133
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Invalid JSON body", "invalid_request_error", "invalid_body")));
2905
3134
  setCurrentPeerHops(null);
2906
3135
  return;
@@ -2919,14 +3148,14 @@ var AgentApiServer = class {
2919
3148
  commsType = result2.valid ? "signed" : "sig-invalid";
2920
3149
  if (result2.valid) lastMsg.content = result2.text;
2921
3150
  } else if (peerEntry2?.mode === "signed" && !hasSigTag) {
2922
- logWarn(TAG8, `Rejected unsigned message from ${caller} (mode=signed)`);
3151
+ logWarn(TAG9, `Rejected unsigned message from ${caller} (mode=signed)`);
2923
3152
  res.writeHead(403, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Signature required", "authentication_error", "signature_missing")));
2924
3153
  setCurrentPeerHops(null);
2925
3154
  this.onPeerActivity?.(`\u{1F916} Agents: ${caller} \u2192 ${this.config.agentCodename} [rejected \u26A0\uFE0F no signature]`);
2926
3155
  return;
2927
3156
  }
2928
3157
  if (commsType === "sig-invalid" && peerEntry2?.mode === "signed") {
2929
- logWarn(TAG8, `Rejected invalid signature from ${caller}`);
3158
+ logWarn(TAG9, `Rejected invalid signature from ${caller}`);
2930
3159
  res.writeHead(403, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Invalid signature", "authentication_error", "signature_invalid")));
2931
3160
  setCurrentPeerHops(null);
2932
3161
  this.onPeerActivity?.(`\u{1F916} Agents: ${caller} \u2192 ${this.config.agentCodename} [rejected \u26A0\uFE0F invalid sig]`);
@@ -2934,7 +3163,7 @@ var AgentApiServer = class {
2934
3163
  }
2935
3164
  }
2936
3165
  if (lastMsg?.content && /\[NO-REPLY\]/i.test(lastMsg.content)) {
2937
- logInfo(TAG8, `Peer ${caller} sent [NO_REPLY] \u2014 returning empty completion`);
3166
+ logInfo(TAG9, `Peer ${caller} sent [NO_REPLY] \u2014 returning empty completion`);
2938
3167
  res.writeHead(200, { "Content-Type": "application/json" }).end(JSON.stringify({ id: "no-reply", object: "chat.completion", choices: [{ index: 0, message: { role: "assistant", content: "" }, finish_reason: "stop" }] }));
2939
3168
  setCurrentPeerHops(null);
2940
3169
  return;
@@ -2943,7 +3172,7 @@ var AgentApiServer = class {
2943
3172
  const { hasPending, popPendingPrompt } = await import("./pending-callback-NHFHL2JC.js");
2944
3173
  if (hasPending(caller)) {
2945
3174
  const pendingPrompt = popPendingPrompt(caller);
2946
- logInfo(TAG8, `Callback from ${caller} \u2014 returning pending prompt (${pendingPrompt?.length ?? 0} chars)`);
3175
+ logInfo(TAG9, `Callback from ${caller} \u2014 returning pending prompt (${pendingPrompt?.length ?? 0} chars)`);
2947
3176
  res.writeHead(200, { "Content-Type": "application/json" }).end(JSON.stringify({ id: "cb", object: "chat.completion", choices: [{ index: 0, message: { role: "assistant", content: pendingPrompt ?? "" }, finish_reason: "stop" }] }));
2948
3177
  setCurrentPeerHops(null);
2949
3178
  return;
@@ -2953,13 +3182,13 @@ var AgentApiServer = class {
2953
3182
  const { resolvePending } = await import("./pending-callback-NHFHL2JC.js");
2954
3183
  const answer = lastMsg.content.slice("[CB-RESPONSE]".length).trim();
2955
3184
  if (resolvePending(caller, answer)) {
2956
- logInfo(TAG8, `CB-RESPONSE from ${caller} \u2014 resolved pending (${answer.length} chars)`);
3185
+ logInfo(TAG9, `CB-RESPONSE from ${caller} \u2014 resolved pending (${answer.length} chars)`);
2957
3186
  }
2958
3187
  res.writeHead(200, { "Content-Type": "application/json" }).end(JSON.stringify({ id: "cb-ack", object: "chat.completion", choices: [{ index: 0, message: { role: "assistant", content: "" }, finish_reason: "stop" }] }));
2959
3188
  setCurrentPeerHops(null);
2960
3189
  return;
2961
3190
  }
2962
- logInfo(TAG8, `Peer call: ${caller} \u2192 ${this.config.agentCodename} [${commsType}]`);
3191
+ logInfo(TAG9, `Peer call: ${caller} \u2192 ${this.config.agentCodename} [${commsType}]`);
2963
3192
  const secLabel = `${this.tlsEnabled ? "tls" : "http"}+${commsType === "signed" ? "signed" : "jwt"}`;
2964
3193
  this.onPeerActivity?.(`\u{1F916} Agents: ${caller} \u2192 ${this.config.agentCodename} [${secLabel}]`);
2965
3194
  const { loadPeerConfig } = await import("./peer-config-TN55LFDC.js");
@@ -2999,7 +3228,7 @@ var AgentApiServer = class {
2999
3228
  try {
3000
3229
  session = await this.ensureAgentSession();
3001
3230
  } catch (err) {
3002
- logAndSwallow(TAG8, "ensureAgentSession", err);
3231
+ logAndSwallow(TAG9, "ensureAgentSession", err);
3003
3232
  res.writeHead(503, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Failed to spawn agent kiro-cli", "server_error", "spawn_failed")));
3004
3233
  setCurrentPeerHops(null);
3005
3234
  return;
@@ -3015,7 +3244,8 @@ var AgentApiServer = class {
3015
3244
  markRulesInjected: () => {
3016
3245
  this.rulesInjected = true;
3017
3246
  },
3018
- guestName: this.guestName
3247
+ guestName: this.guestName,
3248
+ sessionManager: this.sessionManager
3019
3249
  });
3020
3250
  const reqBody = body;
3021
3251
  const promptPreview = Array.isArray(reqBody.messages) && reqBody.messages.length > 0 ? String(reqBody.messages[reqBody.messages.length - 1]?.content ?? "").slice(0, 200) : "";
@@ -3038,7 +3268,7 @@ var AgentApiServer = class {
3038
3268
  try {
3039
3269
  body = JSON.parse(await readBody(req));
3040
3270
  } catch (err) {
3041
- logAndSwallow(TAG8, "JSON.parse embeddings body", err);
3271
+ logAndSwallow(TAG9, "JSON.parse embeddings body", err);
3042
3272
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Invalid JSON body", "invalid_request_error", "invalid_body")));
3043
3273
  return;
3044
3274
  }
@@ -3051,7 +3281,7 @@ var AgentApiServer = class {
3051
3281
  try {
3052
3282
  body = JSON.parse(await readBody(req));
3053
3283
  } catch (err) {
3054
- logAndSwallow(TAG8, "JSON.parse tasks body", err);
3284
+ logAndSwallow(TAG9, "JSON.parse tasks body", err);
3055
3285
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Invalid JSON body", "invalid_request_error", "invalid_body")));
3056
3286
  return;
3057
3287
  }
@@ -3060,7 +3290,7 @@ var AgentApiServer = class {
3060
3290
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Missing 'goal' field", "invalid_request_error", "missing_field")));
3061
3291
  return;
3062
3292
  }
3063
- const { spin: spin2 } = await import("./spin-TI3TSVVT.js");
3293
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
3064
3294
  const { cardId, sessionId } = spin2.dispatch({
3065
3295
  type: "O",
3066
3296
  goal: body.context ? `${goal}
@@ -3080,10 +3310,10 @@ Context: ${body.context}` : goal,
3080
3310
  const safeName = bn(art.name);
3081
3311
  writeFileSync3(join6(dir, safeName), Buffer.from(art.content, "base64"));
3082
3312
  }
3083
- logDebug(TAG8, `Wrote ${body.artifacts.length} artifact(s) to card#${cardId} workspace`);
3313
+ logDebug(TAG9, `Wrote ${body.artifacts.length} artifact(s) to card#${cardId} workspace`);
3084
3314
  }
3085
- logInfo(TAG8, `A2A task from ${caller}: card #${cardId} "${goal.slice(0, 60)}"${body.callback_peer ? ` (callback\u2192${body.callback_peer})` : ""}`);
3086
- logTrace(TAG8, `A2A task from ${caller} full goal: ${goal.slice(0, 500)}`);
3315
+ logInfo(TAG9, `A2A task from ${caller}: card #${cardId} "${goal.slice(0, 60)}"${body.callback_peer ? ` (callback\u2192${body.callback_peer})` : ""}`);
3316
+ logTrace(TAG9, `A2A task from ${caller} full goal: ${goal.slice(0, 500)}`);
3087
3317
  this.onPeerActivity?.(`\u{1F4CB} A2A task from ${caller}: "${goal.slice(0, 60)}" \u2192 card #${cardId}`);
3088
3318
  this.pushTraffic({
3089
3319
  ts: Date.now(),
@@ -3164,8 +3394,8 @@ Context: ${body.context}` : goal,
3164
3394
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Missing task_id or status", "invalid_request_error", "missing_field")));
3165
3395
  return;
3166
3396
  }
3167
- logDebug(TAG8, `\u2190 callback from ${caller}: task_id=${taskId} status=${body.status}`);
3168
- logTrace(TAG8, `\u2190 callback from ${caller} result: ${(body.result_summary ?? "").slice(0, 300)}`);
3397
+ logDebug(TAG9, `\u2190 callback from ${caller}: task_id=${taskId} status=${body.status}`);
3398
+ logTrace(TAG9, `\u2190 callback from ${caller} result: ${(body.result_summary ?? "").slice(0, 300)}`);
3169
3399
  const { kanbanList, kanbanComplete, kanbanFail } = (init_kanban_board(), __toCommonJS(kanban_board_exports));
3170
3400
  const remoteCards = kanbanList("running", "status").filter((c) => {
3171
3401
  if (c.type !== "remote") return false;
@@ -3177,7 +3407,7 @@ Context: ${body.context}` : goal,
3177
3407
  }
3178
3408
  });
3179
3409
  if (remoteCards.length === 0) {
3180
- logWarn(TAG8, `Callback from ${caller} for task_id=${taskId} \u2014 no matching local card`);
3410
+ logWarn(TAG9, `Callback from ${caller} for task_id=${taskId} \u2014 no matching local card`);
3181
3411
  res.writeHead(404, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("No matching local card", "not_found_error", "not_found")));
3182
3412
  return;
3183
3413
  }
@@ -3190,21 +3420,21 @@ Context: ${body.context}` : goal,
3190
3420
  const safeName = bn(art.name);
3191
3421
  writeFileSync3(join6(dir, safeName), Buffer.from(art.content, "base64"));
3192
3422
  }
3193
- logDebug(TAG8, `Wrote ${body.artifacts.length} result artifact(s) to local card#${card.id}`);
3423
+ logDebug(TAG9, `Wrote ${body.artifacts.length} result artifact(s) to local card#${card.id}`);
3194
3424
  }
3195
3425
  if (body.status === "done") {
3196
3426
  kanbanComplete(card.id, null, body.result_summary?.slice(0, 500) ?? "completed");
3197
- logInfo(TAG8, `PEER_CALLBACK ${caller}#${taskId} \u2192 local#${card.id} done (${(body.result_summary ?? "").length}ch)`);
3427
+ logInfo(TAG9, `PEER_CALLBACK ${caller}#${taskId} \u2192 local#${card.id} done (${(body.result_summary ?? "").length}ch)`);
3198
3428
  } else {
3199
3429
  kanbanFail(card.id, body.error ?? "remote task failed");
3200
- logInfo(TAG8, `PEER_CALLBACK ${caller}#${taskId} \u2192 local#${card.id} failed: ${(body.error ?? "").slice(0, 100)}`);
3430
+ logInfo(TAG9, `PEER_CALLBACK ${caller}#${taskId} \u2192 local#${card.id} failed: ${(body.error ?? "").slice(0, 100)}`);
3201
3431
  }
3202
3432
  if (body.tokens_used && typeof body.tokens_used === "number") {
3203
3433
  const { kanbanAddTokens } = (init_kanban_board(), __toCommonJS(kanban_board_exports));
3204
3434
  kanbanAddTokens(card.id, body.tokens_used);
3205
3435
  }
3206
3436
  try {
3207
- const { spin: spin2 } = await import("./spin-TI3TSVVT.js");
3437
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
3208
3438
  const meta = JSON.parse(card.notes ?? "{}");
3209
3439
  if (meta.remote_session_id) {
3210
3440
  const hollow = spin2.listAllSessions().find((s) => s.peer === caller && s.remoteSessionId === meta.remote_session_id);
@@ -3230,7 +3460,7 @@ Context: ${body.context}` : goal,
3230
3460
  // src/boot/phase-agent-api.ts
3231
3461
  init_log_and_swallow();
3232
3462
  init_logger();
3233
- var TAG9 = "agent_api";
3463
+ var TAG10 = "agent_api";
3234
3464
  async function phaseAgentApi(ctx) {
3235
3465
  const { config, memory, runtime, platforms, registry } = ctx;
3236
3466
  const agentConfig = loadAgentApiConfig(process.env);
@@ -3239,7 +3469,7 @@ async function phaseAgentApi(ctx) {
3239
3469
  sendNotification(ctx, msg);
3240
3470
  };
3241
3471
  setPeerActivityCallback(notifyPeer);
3242
- const { AgentApiAdapter } = await import("./agent-api-adapter-YAHKQMMZ.js");
3472
+ const { AgentApiAdapter } = await import("./agent-api-adapter-WRGEQ6DV.js");
3243
3473
  const a2aAdapter = new AgentApiAdapter();
3244
3474
  registry.register("agent-api", {
3245
3475
  configured: Boolean(agentConfig.port),
@@ -3250,6 +3480,7 @@ async function phaseAgentApi(ctx) {
3250
3480
  workingDir: config.transport.workingDir,
3251
3481
  memory,
3252
3482
  runtime,
3483
+ sessionManager: ctx.sessionManager,
3253
3484
  onPeerActivity: notifyPeer,
3254
3485
  a2aAdapter
3255
3486
  });
@@ -3283,7 +3514,7 @@ async function phaseAgentApi(ctx) {
3283
3514
  startGossipListener();
3284
3515
  }
3285
3516
  if (Object.keys(peerConfig.peers).length > 0) {
3286
- import("./peer-transport-I6JPLFZ2.js").then(({ initPeerTransport }) => initPeerTransport()).catch(() => {
3517
+ import("./peer-transport-5VKK2I7P.js").then(({ initPeerTransport }) => initPeerTransport()).catch(() => {
3287
3518
  });
3288
3519
  }
3289
3520
  if (Object.keys(peerConfig.peers).length > 0) {
@@ -3302,7 +3533,7 @@ async function phaseAgentApi(ctx) {
3302
3533
  try {
3303
3534
  resolve3(JSON.parse(data)?.choices?.[0]?.message?.content ?? "");
3304
3535
  } catch (err) {
3305
- logAndSwallow(TAG9, "JSON.parse agent-api response", err);
3536
+ logAndSwallow(TAG10, "JSON.parse agent-api response", err);
3306
3537
  resolve3("");
3307
3538
  }
3308
3539
  });
@@ -3544,7 +3775,7 @@ ${lines.join("\n")}`);
3544
3775
  }
3545
3776
  }
3546
3777
  if (ctx.telegramAdapter) {
3547
- const { spin: spin2 } = await import("./spin-TI3TSVVT.js");
3778
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
3548
3779
  spin2.setGreetingAdapter(ctx.telegramAdapter);
3549
3780
  }
3550
3781
  return bridge.waitForExit();
@@ -3648,6 +3879,11 @@ try {
3648
3879
  } catch {
3649
3880
  }
3650
3881
  process.on("uncaughtException", (err) => {
3882
+ const e = err;
3883
+ if (e.code === "ENOENT" && typeof e.syscall === "string" && e.syscall.startsWith("spawn")) {
3884
+ console.error(`[WARN] Suppressed spawn ENOENT (binary not found, bridge continues): ${e.syscall} \u2014 ${e.message}`);
3885
+ return;
3886
+ }
3651
3887
  console.error(`[FATAL] Uncaught exception: ${err.stack ?? err.message ?? err}`);
3652
3888
  process.exit(1);
3653
3889
  });