abtars 0.3.4-alpha.6 → 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 (115) hide show
  1. package/bundle/{_registry.generated-VN2OU54H.js → _registry.generated-YP5GLSG7.js} +8 -5
  2. package/bundle/{_registry.generated-VN2OU54H.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 +374 -118
  6. package/bundle/abtars.js.map +4 -4
  7. package/bundle/{agent-api-adapter-PTJYZKQK.js → agent-api-adapter-WRGEQ6DV.js} +2 -2
  8. package/bundle/{agent-registry-OXFVXBOO.js → agent-registry-GHNG2PH3.js} +2 -2
  9. package/bundle/{bootstrap-XBTZIGKC.js → bootstrap-PZIDBPEJ.js} +2 -2
  10. package/bundle/{browser-EJNS35NT.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-44JSAOAU.js → chunk-75ATTOW4.js} +3 -3
  14. package/bundle/{chunk-AW2FTHQO.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-V3DZFJZ2.js → chunk-CXXU3HAU.js} +2 -2
  18. package/bundle/{chunk-IRZOWJ5S.js → chunk-IHYKTDIP.js} +50 -28
  19. package/bundle/chunk-IHYKTDIP.js.map +7 -0
  20. package/bundle/{chunk-MGHNCO5V.js → chunk-LDUOOKQY.js} +4 -3
  21. package/bundle/chunk-LDUOOKQY.js.map +7 -0
  22. package/bundle/{chunk-AO32N2VB.js → chunk-M3JEX6L4.js} +270 -228
  23. package/bundle/chunk-M3JEX6L4.js.map +7 -0
  24. package/bundle/{chunk-7Z3HBPRY.js → chunk-N4EB6LA7.js} +2 -2
  25. package/bundle/{chunk-56SV72K4.js → chunk-P2K2K6XL.js} +15 -29
  26. package/bundle/chunk-P2K2K6XL.js.map +7 -0
  27. package/bundle/{chunk-5GCLBUBS.js → chunk-PU5HSKWH.js} +1 -1
  28. package/bundle/{chunk-NC72HN4Y.js → chunk-SMPHE3ZM.js} +188 -107
  29. package/bundle/chunk-SMPHE3ZM.js.map +7 -0
  30. package/bundle/{chunk-XGLBEDRG.js → chunk-UNM3OXHB.js} +5 -3
  31. package/bundle/chunk-UNM3OXHB.js.map +7 -0
  32. package/bundle/{chunk-7YQGRUXI.js → chunk-VXCETPZU.js} +40 -58
  33. package/bundle/chunk-VXCETPZU.js.map +7 -0
  34. package/bundle/{chunk-KTYGKPYM.js → chunk-W2R2HFOQ.js} +2 -2
  35. package/bundle/{chunk-PROPYS3P.js → chunk-YPAQEQSC.js} +2 -2
  36. package/bundle/{commands-BARN6XQ7.js → commands-OIISYHTD.js} +3 -3
  37. package/bundle/{delegation-tools-O7WLLYVP.js → delegation-tools-YATZFKYO.js} +4 -4
  38. package/bundle/{deploy-L6EASMTO.js → deploy-T6R45OZJ.js} +2 -2
  39. package/bundle/{direct-api-transport-LGYYBJNR.js → direct-api-transport-S2RDH2I7.js} +13 -9
  40. package/bundle/direct-api-transport-S2RDH2I7.js.map +7 -0
  41. package/bundle/{discord-adapter-6GRRMO4M.js → discord-adapter-UTXUWX3A.js} +3 -3
  42. package/bundle/{health-check-YKWFD2LZ.js → health-check-BUA36UAQ.js} +2 -2
  43. package/bundle/{health-check-YKWFD2LZ.js.map → health-check-BUA36UAQ.js.map} +1 -1
  44. package/bundle/{heartbeat-system-OATYKHRV.js → heartbeat-system-MVTRS4GP.js} +2 -2
  45. package/bundle/{heartbeat-tier3-JT422XQ4.js → heartbeat-tier3-6KH45CL6.js} +10 -10
  46. package/bundle/{install-C2WDC4WT.js → install-OS3CU7NF.js} +2 -2
  47. package/bundle/kanban-channel-IJ52OMNA.js +1 -1
  48. package/bundle/{message-pipeline-X6ENVZBZ.js → message-pipeline-AUIUNM5R.js} +3 -3
  49. package/bundle/meta.json +1568 -1545
  50. package/bundle/{orc-tools-A3G7WCSJ.js → orc-tools-TOD4WHTM.js} +2 -2
  51. package/bundle/{peer-transport-I6JPLFZ2.js → peer-transport-5VKK2I7P.js} +2 -2
  52. package/bundle/{phase-transport-R6L6EYAD.js → phase-transport-FS6NL4A5.js} +6 -5
  53. package/bundle/{reconciler-FHESO6OC.js → reconciler-NZ4O4BCP.js} +4 -4
  54. package/bundle/{skill-session-AXBDQSLQ.js → skill-session-VJXTKOKL.js} +2 -2
  55. package/bundle/{sleep-36XS6MHJ.js → sleep-BEWAUFCL.js} +5 -2
  56. package/bundle/{spin-IMW2MZOH.js → spin-E3ZDEDKT.js} +5 -5
  57. package/bundle/{spin-types-BLPYAETA.js → spin-types-OIE67MJK.js} +2 -2
  58. package/bundle/{system-status-FDVKSAFK.js → system-status-FAVNIUFJ.js} +3 -3
  59. package/bundle/{telegram-adapter-SIW2DMQX.js → telegram-adapter-4TX7QWKC.js} +12 -6
  60. package/bundle/{telegram-adapter-SIW2DMQX.js.map → telegram-adapter-4TX7QWKC.js.map} +2 -2
  61. package/bundle/{tool-registry-DDFUKQY7.js → tool-registry-7FK3OQGL.js} +8 -8
  62. package/bundle/{update-EZWBQTLI.js → update-CKFP6LBE.js} +3 -3
  63. package/package.json +1 -1
  64. package/scripts/abtars-watchdog.service +2 -1
  65. package/scripts/emergency-update.sh +53 -5
  66. package/templates/skills/skill-authoring/SKILL.md +6 -6
  67. package/bundle/chunk-56SV72K4.js.map +0 -7
  68. package/bundle/chunk-7YQGRUXI.js.map +0 -7
  69. package/bundle/chunk-AO32N2VB.js.map +0 -7
  70. package/bundle/chunk-IRZOWJ5S.js.map +0 -7
  71. package/bundle/chunk-LGP6TYFI.js.map +0 -7
  72. package/bundle/chunk-MGHNCO5V.js.map +0 -7
  73. package/bundle/chunk-NC72HN4Y.js.map +0 -7
  74. package/bundle/chunk-Q33GFBXL.js +0 -210
  75. package/bundle/chunk-Q33GFBXL.js.map +0 -7
  76. package/bundle/chunk-XGLBEDRG.js.map +0 -7
  77. package/bundle/chunk-Y76VUJSF.js +0 -75
  78. package/bundle/chunk-Y76VUJSF.js.map +0 -7
  79. package/bundle/direct-api-transport-LGYYBJNR.js.map +0 -7
  80. package/bundle/public/css/dashboard.css +0 -542
  81. package/bundle/public/index.html +0 -180
  82. package/bundle/public/js/app.js +0 -437
  83. package/bundle/public/memory-universe.js +0 -384
  84. package/bundle/subagent-runtime-HLCDLHK5.js +0 -14
  85. package/bundle/update-EZWBQTLI.js.map +0 -7
  86. /package/bundle/{agent-api-adapter-PTJYZKQK.js.map → agent-api-adapter-WRGEQ6DV.js.map} +0 -0
  87. /package/bundle/{agent-registry-OXFVXBOO.js.map → agent-registry-GHNG2PH3.js.map} +0 -0
  88. /package/bundle/{bootstrap-XBTZIGKC.js.map → bootstrap-PZIDBPEJ.js.map} +0 -0
  89. /package/bundle/{browser-EJNS35NT.js.map → browser-D3LZV7ZK.js.map} +0 -0
  90. /package/bundle/{chunk-44JSAOAU.js.map → chunk-75ATTOW4.js.map} +0 -0
  91. /package/bundle/{chunk-AW2FTHQO.js.map → chunk-7JN2MMU7.js.map} +0 -0
  92. /package/bundle/{chunk-V3DZFJZ2.js.map → chunk-CXXU3HAU.js.map} +0 -0
  93. /package/bundle/{chunk-7Z3HBPRY.js.map → chunk-N4EB6LA7.js.map} +0 -0
  94. /package/bundle/{chunk-5GCLBUBS.js.map → chunk-PU5HSKWH.js.map} +0 -0
  95. /package/bundle/{chunk-KTYGKPYM.js.map → chunk-W2R2HFOQ.js.map} +0 -0
  96. /package/bundle/{chunk-PROPYS3P.js.map → chunk-YPAQEQSC.js.map} +0 -0
  97. /package/bundle/{commands-BARN6XQ7.js.map → commands-OIISYHTD.js.map} +0 -0
  98. /package/bundle/{delegation-tools-O7WLLYVP.js.map → delegation-tools-YATZFKYO.js.map} +0 -0
  99. /package/bundle/{deploy-L6EASMTO.js.map → deploy-T6R45OZJ.js.map} +0 -0
  100. /package/bundle/{discord-adapter-6GRRMO4M.js.map → discord-adapter-UTXUWX3A.js.map} +0 -0
  101. /package/bundle/{heartbeat-system-OATYKHRV.js.map → heartbeat-system-MVTRS4GP.js.map} +0 -0
  102. /package/bundle/{heartbeat-tier3-JT422XQ4.js.map → heartbeat-tier3-6KH45CL6.js.map} +0 -0
  103. /package/bundle/{install-C2WDC4WT.js.map → install-OS3CU7NF.js.map} +0 -0
  104. /package/bundle/{message-pipeline-X6ENVZBZ.js.map → message-pipeline-AUIUNM5R.js.map} +0 -0
  105. /package/bundle/{orc-tools-A3G7WCSJ.js.map → orc-tools-TOD4WHTM.js.map} +0 -0
  106. /package/bundle/{peer-transport-I6JPLFZ2.js.map → peer-transport-5VKK2I7P.js.map} +0 -0
  107. /package/bundle/{phase-transport-R6L6EYAD.js.map → phase-transport-FS6NL4A5.js.map} +0 -0
  108. /package/bundle/{reconciler-FHESO6OC.js.map → reconciler-NZ4O4BCP.js.map} +0 -0
  109. /package/bundle/{skill-session-AXBDQSLQ.js.map → skill-session-VJXTKOKL.js.map} +0 -0
  110. /package/bundle/{sleep-36XS6MHJ.js.map → sleep-BEWAUFCL.js.map} +0 -0
  111. /package/bundle/{spin-IMW2MZOH.js.map → spin-E3ZDEDKT.js.map} +0 -0
  112. /package/bundle/{spin-types-BLPYAETA.js.map → spin-types-OIE67MJK.js.map} +0 -0
  113. /package/bundle/{system-status-FDVKSAFK.js.map → system-status-FAVNIUFJ.js.map} +0 -0
  114. /package/bundle/{subagent-runtime-HLCDLHK5.js.map → tool-registry-7FK3OQGL.js.map} +0 -0
  115. /package/bundle/{tool-registry-DDFUKQY7.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-IRZOWJ5S.js";
22
+ } from "./chunk-IHYKTDIP.js";
23
23
  import {
24
24
  loadNLMConfig
25
- } from "./chunk-NC72HN4Y.js";
25
+ } from "./chunk-SMPHE3ZM.js";
26
26
  import "./chunk-63A7ZRIH.js";
27
27
  import "./chunk-OKAQICWY.js";
28
28
  import {
@@ -31,13 +31,13 @@ import {
31
31
  init_heartbeat_system,
32
32
  init_platform_detect,
33
33
  setHeartbeatInstance
34
- } from "./chunk-MGHNCO5V.js";
34
+ } from "./chunk-LDUOOKQY.js";
35
35
  import {
36
36
  sendNotification
37
37
  } from "./chunk-7BSQ5UQO.js";
38
38
  import {
39
39
  phaseTransport
40
- } from "./chunk-7YQGRUXI.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-V3DZFJZ2.js";
48
+ import "./chunk-CXXU3HAU.js";
49
49
  import "./chunk-5QUTMUIK.js";
50
- import {
51
- SubagentRuntime
52
- } from "./chunk-Q33GFBXL.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-56SV72K4.js";
64
- import "./chunk-AW2FTHQO.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-PROPYS3P.js";
65
+ import "./chunk-YPAQEQSC.js";
69
66
  import {
70
67
  init_spin,
71
68
  spin
72
- } from "./chunk-AO32N2VB.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,6 +1256,30 @@ 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})`);
1259
+ const { setMemoryBackend } = await import("./tool-registry-7FK3OQGL.js");
1260
+ const mm = ctx.memory;
1261
+ const backend = {
1262
+ initialize: async () => {
1263
+ },
1264
+ close: () => {
1265
+ },
1266
+ instantStore: (p) => mm.editor.instantStore(p),
1267
+ editMemory: (p) => mm.editor.editMemory(p),
1268
+ reclassifyMemory: (id, level, uo) => {
1269
+ mm.editor.reclassifyMemory(id, level, uo);
1270
+ return Promise.resolve();
1271
+ },
1272
+ adjustRelevance: (id, delta) => {
1273
+ mm.editor.adjustRelevance(id, delta);
1274
+ return Promise.resolve();
1275
+ },
1276
+ mergeMemories: (a, b) => mm.editor.mergeMemories(a, b),
1277
+ cascadeDelete: (ids, uid) => mm.editor.cascadeDelete(ids, uid),
1278
+ recall: (p) => mm.recallSearch(p),
1279
+ rebuildFtsIndexes: () => mm.rebuildFtsIndexes()
1280
+ };
1281
+ setMemoryBackend(backend);
1282
+ logInfo("main", "\u{1F9E0} In-process memory wired to tool registry (shared handle)");
1062
1283
  return "ran";
1063
1284
  } catch (err) {
1064
1285
  logWarn("main", `\u26A0\uFE0F Memory init failed: ${err instanceof Error ? err.message : String(err)}. Running without persistent memory.`);
@@ -1147,7 +1368,7 @@ async function phasePlatformsConnect(ctx) {
1147
1368
  registry.register("telegram", {
1148
1369
  configured: Boolean(config.telegram.botToken && config.telegram.allowedUserIds.size > 0),
1149
1370
  async create() {
1150
- const { TelegramAdapter } = await import("./telegram-adapter-SIW2DMQX.js");
1371
+ const { TelegramAdapter } = await import("./telegram-adapter-4TX7QWKC.js");
1151
1372
  const adapter = new TelegramAdapter(
1152
1373
  { botToken: config.telegram.botToken, allowedUserIds: config.telegram.allowedUserIds, pollTimeoutS: config.telegram.pollTimeoutS },
1153
1374
  { pipeline: { handleInbound: (msg) => recovery.handle(msg, adapter) }, conversationBuffer: ctx.conversationBuffer, transport: null, memory: null, sessionManager: ctx.sessionManager, actionGate: ctx.actionGate }
@@ -1179,7 +1400,7 @@ async function phasePlatformsConnect(ctx) {
1179
1400
  if (!config.discord.appId || !isValidSnowflake(config.discord.appId)) {
1180
1401
  throw new Error("DISCORD_APP_ID missing or invalid \u2014 Discord disabled");
1181
1402
  }
1182
- const { DiscordAdapter } = await import("./discord-adapter-6GRRMO4M.js");
1403
+ const { DiscordAdapter } = await import("./discord-adapter-UTXUWX3A.js");
1183
1404
  const adapter = new DiscordAdapter(
1184
1405
  { botToken: config.discord.botToken, appId: config.discord.appId, allowedUserIds: config.discord.allowedUserIds },
1185
1406
  { pipeline: { handleInbound: (msg) => recovery.handle(msg, adapter) }, transport: null, memory: null, conversationBuffer: ctx.conversationBuffer }
@@ -1257,13 +1478,13 @@ async function phaseCapabilities(ctx) {
1257
1478
  let loaded = [];
1258
1479
  let staticCaps;
1259
1480
  try {
1260
- ({ capabilities: staticCaps } = await import("./_registry.generated-VN2OU54H.js"));
1481
+ ({ capabilities: staticCaps } = await import("./_registry.generated-YP5GLSG7.js"));
1261
1482
  } catch (err) {
1262
1483
  logError("capabilities", `Registry import failed: ${err instanceof Error ? err.message : String(err)}. Loading individually.`);
1263
1484
  staticCaps = [];
1264
1485
  const individualCaps = [
1265
1486
  { name: "hotskills", load: () => import("./hotskills-FWX4QI7V.js") },
1266
- { name: "browser", load: () => import("./browser-EJNS35NT.js") }
1487
+ { name: "browser", load: () => import("./browser-D3LZV7ZK.js") }
1267
1488
  ];
1268
1489
  for (const { name, load } of individualCaps) {
1269
1490
  if (disabled.has(name)) continue;
@@ -1355,7 +1576,7 @@ function startInProcWatchdog(opts) {
1355
1576
  }
1356
1577
 
1357
1578
  // src/boot/phase-heartbeat.ts
1358
- var TAG3 = "heartbeat";
1579
+ var TAG4 = "heartbeat";
1359
1580
  async function phaseHeartbeat(ctx) {
1360
1581
  const { init: initSkillStats } = await import("./skill-stats-JORH5DGM.js");
1361
1582
  initSkillStats();
@@ -1389,7 +1610,7 @@ async function phaseHeartbeat(ctx) {
1389
1610
  heartbeat.registerTask(createSkillStatsFlushTask());
1390
1611
  heartbeat.registerTask(createSkillReloadTask());
1391
1612
  heartbeat.registerTask(createUpdateCheckTask((msg) => {
1392
- 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));
1393
1614
  }));
1394
1615
  heartbeat.registerTask({
1395
1616
  name: "restart-check",
@@ -1401,16 +1622,12 @@ async function phaseHeartbeat(ctx) {
1401
1622
  }
1402
1623
  }
1403
1624
  });
1404
- const { spin: spin2 } = await import("./spin-IMW2MZOH.js");
1625
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
1405
1626
  const masterUser = loadUsers().users.find((u) => u.role === "master");
1406
1627
  const masterUserId = masterUser?.userId ?? "master";
1407
1628
  ctx.sendSystemMessage = async (prompt) => {
1408
1629
  try {
1409
- const response = await spin2.inject(masterUserId, `[SYSTEM] ${prompt}`, { deliver: true });
1410
- if (response) {
1411
- const { sendNotification: sendNotification2 } = await import("./notification-BFSIEECG.js");
1412
- sendNotification2(ctx, response);
1413
- }
1630
+ await spin2.injectGreeting(masterUserId, `[SYSTEM] ${prompt}`);
1414
1631
  } catch (err) {
1415
1632
  logWarn("main", `System message failed: ${err instanceof Error ? err.message : String(err)}`);
1416
1633
  }
@@ -1423,21 +1640,29 @@ async function phaseHeartbeat(ctx) {
1423
1640
  // src/boot/phase-sleep.ts
1424
1641
  init_logger();
1425
1642
  async function phaseSleep(ctx) {
1426
- const { memoryConfig, memory, sendSystemMessage } = ctx;
1643
+ const { memoryConfig, memory, sendSystemMessage, sessionManager } = ctx;
1427
1644
  if (!sendSystemMessage) {
1428
1645
  ctx.phaseHealth.set(phaseSleep.name, { status: "skipped", error: "no sendSystemMessage" });
1429
1646
  logWarn("boot", `${phaseSleep.name}: skipping \u2014 heartbeat not available`);
1430
1647
  return "skipped";
1431
1648
  }
1432
- const { createSleepHandle } = await import("./sleep-36XS6MHJ.js");
1433
- const { killWakeInhibit } = await import("./commands-BARN6XQ7.js");
1649
+ const { createSleepHandle } = await import("./sleep-BEWAUFCL.js");
1650
+ const { killWakeInhibit } = await import("./commands-OIISYHTD.js");
1434
1651
  const SLEEP_HOUR = parseInt(readEnvWithDefault("BED_TIME", "2", "bedtime hour").split(":")[0] ?? "2", 10);
1435
- let subagent = null;
1652
+ let nightSessionId;
1436
1653
  const { getEnv: getEnv2 } = await import("./env-schema-4JXQUOH4.js");
1437
1654
  const runtime = {
1438
1655
  async complete(prompt) {
1439
- if (!subagent) subagent = new SubagentRuntime();
1440
- 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 ?? "";
1441
1666
  }
1442
1667
  };
1443
1668
  ctx.sleepHandle = createSleepHandle({
@@ -1445,10 +1670,21 @@ async function phaseSleep(ctx) {
1445
1670
  sleepAuditDir: ctx.sleepAuditDir,
1446
1671
  memoryEnabled: memoryConfig.memoryEnabled,
1447
1672
  runtime,
1448
- 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
+ },
1449
1681
  getLastMsgTs: () => memory?.getLastMessageTimestamp(true) ?? 0,
1450
1682
  sendSystemMessage,
1451
- killWakeInhibit
1683
+ killWakeInhibit,
1684
+ allocateSleepSession: (name) => {
1685
+ const s = sessionManager.allocateDreamySession(name);
1686
+ nightSessionId = s.id;
1687
+ }
1452
1688
  });
1453
1689
  return "ran";
1454
1690
  }
@@ -1620,7 +1856,7 @@ var AuthGate = class {
1620
1856
 
1621
1857
  // src/components/memory-search-controller.ts
1622
1858
  init_logger();
1623
- var TAG4 = "memory-search-ctrl";
1859
+ var TAG5 = "memory-search-ctrl";
1624
1860
  var VALID_STAGES = /* @__PURE__ */ new Set(["Sf", "Ss", "Se", "S6"]);
1625
1861
  var MemorySearchController = class {
1626
1862
  deps;
@@ -1633,7 +1869,7 @@ var MemorySearchController = class {
1633
1869
  return { status: 200, body: { userIds } };
1634
1870
  } catch (err) {
1635
1871
  const msg = err instanceof Error ? err.message : String(err);
1636
- logWarn(TAG4, `listChats failed: ${msg}`);
1872
+ logWarn(TAG5, `listChats failed: ${msg}`);
1637
1873
  return { status: 500, body: { error: msg } };
1638
1874
  }
1639
1875
  }
@@ -1643,7 +1879,7 @@ var MemorySearchController = class {
1643
1879
  return { status: 200, body: { memories } };
1644
1880
  } catch (err) {
1645
1881
  const msg = err instanceof Error ? err.message : String(err);
1646
- logWarn(TAG4, `listAll failed: ${msg}`);
1882
+ logWarn(TAG5, `listAll failed: ${msg}`);
1647
1883
  return { status: 500, body: { error: msg } };
1648
1884
  }
1649
1885
  }
@@ -1673,7 +1909,7 @@ var MemorySearchController = class {
1673
1909
  return { status: 200, body: response };
1674
1910
  } catch (err) {
1675
1911
  const msg = err instanceof Error ? err.message : String(err);
1676
- logWarn(TAG4, `search failed: ${msg}`);
1912
+ logWarn(TAG5, `search failed: ${msg}`);
1677
1913
  return { status: 500, body: { error: msg } };
1678
1914
  }
1679
1915
  }
@@ -1809,7 +2045,7 @@ var StatusBroadcaster = class {
1809
2045
 
1810
2046
  // src/components/dashboard/dashboard-server.ts
1811
2047
  init_logger();
1812
- var TAG5 = "dashboard-server";
2048
+ var TAG6 = "dashboard-server";
1813
2049
  var DashboardServer = class {
1814
2050
  deps;
1815
2051
  _broadcaster;
@@ -1841,7 +2077,7 @@ var DashboardServer = class {
1841
2077
  reject(err);
1842
2078
  });
1843
2079
  this.server.listen(config.webPort, config.webHost, () => {
1844
- logInfo(TAG5, `Dashboard listening on ${config.webHost}:${config.webPort}`);
2080
+ logInfo(TAG6, `Dashboard listening on ${config.webHost}:${config.webPort}`);
1845
2081
  resolve3();
1846
2082
  });
1847
2083
  });
@@ -2025,25 +2261,25 @@ var DashboardServer = class {
2025
2261
  }
2026
2262
  const token = this.deps.authGate.extractToken(req);
2027
2263
  if (!token || !this.deps.authGate.validate(token)) {
2028
- 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}`);
2029
2265
  socket.write(
2030
2266
  "HTTP/1.1 401 Unauthorized\r\nContent-Type: application/json\r\n\r\n" + JSON.stringify({ error: "Unauthorized" })
2031
2267
  );
2032
2268
  socket.destroy();
2033
2269
  return;
2034
2270
  }
2035
- logInfo(TAG5, `WebSocket client authenticated from ${req.socket.remoteAddress}`);
2271
+ logInfo(TAG6, `WebSocket client authenticated from ${req.socket.remoteAddress}`);
2036
2272
  this.wss.handleUpgrade(req, socket, head, (ws) => {
2037
2273
  this.wss.emit("connection", ws, req);
2038
2274
  this._broadcaster.addClient(ws);
2039
- logInfo(TAG5, "WebSocket client connected");
2275
+ logInfo(TAG6, "WebSocket client connected");
2040
2276
  });
2041
2277
  }
2042
2278
  // ── Helpers ───────────────────────────────────────────────────────────
2043
2279
  /** Send an error response, logging the error. */
2044
2280
  sendError(res, status, err) {
2045
2281
  const message = err instanceof Error ? err.message : String(err);
2046
- logError(TAG5, `Request error: ${message}`);
2282
+ logError(TAG6, `Request error: ${message}`);
2047
2283
  if (!res.headersSent) {
2048
2284
  res.writeHead(status, { "Content-Type": "application/json" });
2049
2285
  res.end(JSON.stringify({ error: message }));
@@ -2095,7 +2331,7 @@ function loadAgentApiConfig(env) {
2095
2331
  }
2096
2332
 
2097
2333
  // src/boot/phase-dashboard.ts
2098
- var TAG6 = "dashboard";
2334
+ var TAG7 = "dashboard";
2099
2335
  async function phaseDashboard(ctx) {
2100
2336
  const { platforms, memory, transport, registry, heartbeat, nlmConfig } = ctx;
2101
2337
  if (!platforms.web) return "skipped";
@@ -2106,9 +2342,9 @@ async function phaseDashboard(ctx) {
2106
2342
  }
2107
2343
  const dashConfig = loadDashboardConfig(process.env);
2108
2344
  if (!dashConfig.webAuthToken) {
2109
- const { randomBytes } = await import("node:crypto");
2345
+ const { randomBytes: randomBytes2 } = await import("node:crypto");
2110
2346
  const { readFile, writeFile } = await import("node:fs/promises");
2111
- const token = randomBytes(32).toString("hex");
2347
+ const token = randomBytes2(32).toString("hex");
2112
2348
  dashConfig.webAuthToken = token;
2113
2349
  process.env["WEB_AUTH"] = token;
2114
2350
  const envPath = join5(process.cwd(), "config", ".env");
@@ -2133,7 +2369,7 @@ WEB_AUTH=${token}
2133
2369
  try {
2134
2370
  return loadAgentApiConfig(process.env);
2135
2371
  } catch (err) {
2136
- logAndSwallow(TAG6, "loadAgentApiConfig", err);
2372
+ logAndSwallow(TAG7, "loadAgentApiConfig", err);
2137
2373
  return null;
2138
2374
  }
2139
2375
  })() : null;
@@ -2215,11 +2451,11 @@ WEB_AUTH=${token}
2215
2451
  }
2216
2452
  }
2217
2453
  if (!bound) {
2218
- 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`);
2219
2455
  return "skipped";
2220
2456
  }
2221
2457
  ctx.dashboardServer = dashboardServer;
2222
- 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}`);
2223
2459
  logInfo("main", `Web dashboard on ${dashConfig.webHost}:${dashConfig.webPort}${customModule ? ` (custom: ${customModule})` : ""}`);
2224
2460
  return "ran";
2225
2461
  }
@@ -2271,7 +2507,7 @@ function bufferedStreamBody(content, opts) {
2271
2507
 
2272
2508
  // src/components/openai-compat-routes.ts
2273
2509
  init_logger();
2274
- var TAG7 = "openai-compat";
2510
+ var TAG8 = "openai-compat";
2275
2511
  function handleModels() {
2276
2512
  return {
2277
2513
  status: 200,
@@ -2355,7 +2591,7 @@ async function handleChatCompletions(rawBody, req, deps) {
2355
2591
  const stream = body.stream === true;
2356
2592
  const model = body.model;
2357
2593
  if (body.tools || body.tool_choice) {
2358
- 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`);
2359
2595
  }
2360
2596
  const flat = flattenMessages(messages);
2361
2597
  for (let i = 0; i < flat.allContents.length; i++) {
@@ -2364,7 +2600,7 @@ async function handleChatCompletions(rawBody, req, deps) {
2364
2600
  const scan = abmind().scanForInjection(content);
2365
2601
  if (!scan.safe) {
2366
2602
  const top = scan.flags[0];
2367
- 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}`);
2368
2604
  const refusal = buildChatResponse({
2369
2605
  model,
2370
2606
  content: "I can't process that request \u2014 it triggered the injection guard. Please rephrase."
@@ -2394,8 +2630,19 @@ ${fullPrompt}`;
2394
2630
  const effectiveSessionKey = isPeer ? `${Math.floor(Date.now() / 1e3)}_P_01` : sessionKey;
2395
2631
  const now = Date.now();
2396
2632
  if (!isPeer) deps.memory?.recordMessage({ role: "user", content: flat.prompt, timestamp: now, userId: "master", sessionId: effectiveSessionKey });
2397
- logInfo(TAG7, `/v1/chat/completions guest=${deps.guestName} session=${effectiveSessionKey} promptLen=${flat.prompt.length} stream=${stream}`);
2398
- 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
+ }
2399
2646
  if (!isPeer) deps.memory?.recordMessage({ role: "assistant", content: reply, timestamp: Date.now(), userId: "master", sessionId: effectiveSessionKey });
2400
2647
  if (stream) {
2401
2648
  return {
@@ -2431,7 +2678,7 @@ function writeResult(res, result) {
2431
2678
  }
2432
2679
 
2433
2680
  // src/components/agent-api-server.ts
2434
- var TAG8 = "agent-api";
2681
+ var TAG9 = "agent-api";
2435
2682
  var MAX_TRAFFIC_LOG = 50;
2436
2683
  var IDLE_TIMEOUT_MS = 10 * 60 * 1e3;
2437
2684
  function normalizeIp(raw) {
@@ -2468,6 +2715,7 @@ var AgentApiServer = class {
2468
2715
  agentSession = null;
2469
2716
  idleTimer = null;
2470
2717
  runtime;
2718
+ sessionManager;
2471
2719
  guestName = "GUEST";
2472
2720
  onPeerActivity;
2473
2721
  tlsEnabled = false;
@@ -2479,6 +2727,7 @@ var AgentApiServer = class {
2479
2727
  this.workingDir = deps.workingDir;
2480
2728
  this.memory = deps.memory;
2481
2729
  this.runtime = deps.runtime;
2730
+ this.sessionManager = deps.sessionManager;
2482
2731
  this.onPeerActivity = deps.onPeerActivity;
2483
2732
  this.a2aAdapter = deps.a2aAdapter;
2484
2733
  const configDir = join6(abtarsHome(), "config");
@@ -2494,12 +2743,12 @@ var AgentApiServer = class {
2494
2743
  }, (req, res) => this.handle(req, res));
2495
2744
  hasTls = true;
2496
2745
  this.tlsEnabled = true;
2497
- 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)");
2498
2747
  } catch (err) {
2499
- logAndSwallow(TAG8, "TLS setup", err);
2748
+ logAndSwallow(TAG9, "TLS setup", err);
2500
2749
  }
2501
2750
  } else {
2502
- 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)");
2503
2752
  }
2504
2753
  if (!hasTls) {
2505
2754
  this.server = createServer2((req, res) => this.handle(req, res));
@@ -2523,7 +2772,7 @@ var AgentApiServer = class {
2523
2772
  }
2524
2773
  }
2525
2774
  } catch (err) {
2526
- logAndSwallow(TAG8, "load agentRules", err);
2775
+ logAndSwallow(TAG9, "load agentRules", err);
2527
2776
  this.agentRules = "";
2528
2777
  }
2529
2778
  }
@@ -2550,10 +2799,10 @@ var AgentApiServer = class {
2550
2799
  if (result.ok) {
2551
2800
  this.peerWss.handleUpgrade(req, socket, head, (ws) => {
2552
2801
  this.peerWsConnections.set(name, ws);
2553
- logInfo(TAG8, `Peer WS connected: ${name}`);
2802
+ logInfo(TAG9, `Peer WS connected: ${name}`);
2554
2803
  ws.on("close", () => {
2555
2804
  this.peerWsConnections.delete(name);
2556
- logInfo(TAG8, `Peer WS disconnected: ${name}`);
2805
+ logInfo(TAG9, `Peer WS disconnected: ${name}`);
2557
2806
  });
2558
2807
  ws.on("error", () => {
2559
2808
  this.peerWsConnections.delete(name);
@@ -2600,7 +2849,7 @@ var AgentApiServer = class {
2600
2849
  try {
2601
2850
  const msg = JSON.parse(raw);
2602
2851
  if (msg.type === "request") {
2603
- this.handlePeerWsRequest(peerName, msg).catch((err) => logAndSwallow(TAG8, "ws-request", err));
2852
+ this.handlePeerWsRequest(peerName, msg).catch((err) => logAndSwallow(TAG9, "ws-request", err));
2604
2853
  }
2605
2854
  } catch {
2606
2855
  }
@@ -2610,7 +2859,7 @@ var AgentApiServer = class {
2610
2859
  if (!ws || ws.readyState !== ws.OPEN) return;
2611
2860
  let result = { error: "unknown method" };
2612
2861
  if (msg.method === "delegate") {
2613
- const { spin: spin2 } = await import("./spin-IMW2MZOH.js");
2862
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
2614
2863
  const p = msg.payload;
2615
2864
  const { cardId } = spin2.dispatch({ type: "W", goal: p.goal, title: p.goal.slice(0, 60), source: "peer", priority: p.priority ?? "MEDIUM" });
2616
2865
  result = { ok: true, taskId: cardId };
@@ -2641,7 +2890,7 @@ var AgentApiServer = class {
2641
2890
  this.idleTimer = null;
2642
2891
  }
2643
2892
  if (!this.agentSession) return;
2644
- 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");
2645
2894
  try {
2646
2895
  const today = localDate();
2647
2896
  const dir = join6(this.workingDir, "memory", "working", today);
@@ -2649,9 +2898,9 @@ var AgentApiServer = class {
2649
2898
  const dest = join6(dir, "transcript_a2a.log");
2650
2899
  const transcript = this.agentSession.getMessages?.()?.map((m) => `[${m.role}] ${m.content}`).join("\n") ?? "";
2651
2900
  writeFileSync3(dest, transcript, "utf-8");
2652
- logInfo(TAG8, `A2A transcript saved to ${dest}`);
2901
+ logInfo(TAG9, `A2A transcript saved to ${dest}`);
2653
2902
  } catch (e) {
2654
- logWarn(TAG8, `A2A transcript save failed: ${e}`);
2903
+ logWarn(TAG9, `A2A transcript save failed: ${e}`);
2655
2904
  }
2656
2905
  this.log("SYSTEM", "Idle timeout \u2014 session closed");
2657
2906
  await this.agentSession.destroy();
@@ -2713,7 +2962,7 @@ var AgentApiServer = class {
2713
2962
  if (caller === null) return;
2714
2963
  this.guestName = caller;
2715
2964
  this.handleV1ChatCompletions(req, res, caller).catch((err) => {
2716
- 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)}`);
2717
2966
  if (!res.headersSent) {
2718
2967
  res.writeHead(500, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Internal server error", "server_error")));
2719
2968
  }
@@ -2723,7 +2972,7 @@ var AgentApiServer = class {
2723
2972
  if (url === "/v1/embeddings" && method === "POST") {
2724
2973
  if (this.requireBearer(req, res) === null) return;
2725
2974
  this.handleV1Embeddings(req, res).catch((err) => {
2726
- 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)}`);
2727
2976
  if (!res.headersSent) {
2728
2977
  res.writeHead(500, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Internal server error", "server_error")));
2729
2978
  }
@@ -2734,7 +2983,7 @@ var AgentApiServer = class {
2734
2983
  const caller = this.requireBearerRateLimited(req, res);
2735
2984
  if (caller === null) return;
2736
2985
  this.handleV1Tasks(req, res, caller).catch((err) => {
2737
- 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)}`);
2738
2987
  if (!res.headersSent) {
2739
2988
  res.writeHead(500, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Internal server error", "server_error")));
2740
2989
  }
@@ -2777,7 +3026,7 @@ var AgentApiServer = class {
2777
3026
  }
2778
3027
  async handleOrcRoute(url, method, req, res) {
2779
3028
  try {
2780
- const { getOrcTools } = await import("./orc-tools-A3G7WCSJ.js");
3029
+ const { getOrcTools } = await import("./orc-tools-TOD4WHTM.js");
2781
3030
  if (url === "/v1/orc/spawn" && method === "POST") {
2782
3031
  const body = JSON.parse(await readBody(req));
2783
3032
  const tool = getOrcTools().find((t) => t.name === "spawn_worker");
@@ -2805,7 +3054,7 @@ var AgentApiServer = class {
2805
3054
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify({ ok: false, error: "peer and goal required" }));
2806
3055
  return;
2807
3056
  }
2808
- const { getPeerTransport } = await import("./peer-transport-I6JPLFZ2.js");
3057
+ const { getPeerTransport } = await import("./peer-transport-5VKK2I7P.js");
2809
3058
  const transport = getPeerTransport();
2810
3059
  const remoteId = await transport.delegateTask(peer, goal, { priority: "MEDIUM", context: title });
2811
3060
  res.writeHead(200, { "Content-Type": "application/json" }).end(JSON.stringify({ ok: true, result: `Delegated to ${peer} \u2014 remote card #${remoteId}` }));
@@ -2832,13 +3081,13 @@ var AgentApiServer = class {
2832
3081
  for (const [name, peer] of Object.entries(config.peers)) {
2833
3082
  const result = verifyJwt(token, peer.token, config.self.name);
2834
3083
  if (result.ok && result.payload.iss === name) {
2835
- 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`);
2836
3085
  return result.payload.iss;
2837
3086
  }
2838
3087
  }
2839
3088
  for (const [name, peer] of Object.entries(config.peers)) {
2840
3089
  if (token === peer.token) {
2841
- logInfo(TAG8, `PEER_CALL caller=${name} (raw token, no JWT)`);
3090
+ logInfo(TAG9, `PEER_CALL caller=${name} (raw token, no JWT)`);
2842
3091
  return name;
2843
3092
  }
2844
3093
  }
@@ -2871,7 +3120,7 @@ var AgentApiServer = class {
2871
3120
  if (!limit.allowed) {
2872
3121
  const retryAfter = Math.ceil((limit.retryAfterMs ?? 6e4) / 1e3);
2873
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")));
2874
- logWarn(TAG8, `Rate limited ${caller} \u2014 retry in ${retryAfter}s`);
3123
+ logWarn(TAG9, `Rate limited ${caller} \u2014 retry in ${retryAfter}s`);
2875
3124
  return;
2876
3125
  }
2877
3126
  const { setCurrentPeerHops } = await import("./peer-client-RGEU5HOK.js");
@@ -2880,7 +3129,7 @@ var AgentApiServer = class {
2880
3129
  try {
2881
3130
  body = JSON.parse(await readBody(req));
2882
3131
  } catch (err) {
2883
- logAndSwallow(TAG8, "JSON.parse chat completions body", err);
3132
+ logAndSwallow(TAG9, "JSON.parse chat completions body", err);
2884
3133
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Invalid JSON body", "invalid_request_error", "invalid_body")));
2885
3134
  setCurrentPeerHops(null);
2886
3135
  return;
@@ -2899,14 +3148,14 @@ var AgentApiServer = class {
2899
3148
  commsType = result2.valid ? "signed" : "sig-invalid";
2900
3149
  if (result2.valid) lastMsg.content = result2.text;
2901
3150
  } else if (peerEntry2?.mode === "signed" && !hasSigTag) {
2902
- logWarn(TAG8, `Rejected unsigned message from ${caller} (mode=signed)`);
3151
+ logWarn(TAG9, `Rejected unsigned message from ${caller} (mode=signed)`);
2903
3152
  res.writeHead(403, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Signature required", "authentication_error", "signature_missing")));
2904
3153
  setCurrentPeerHops(null);
2905
3154
  this.onPeerActivity?.(`\u{1F916} Agents: ${caller} \u2192 ${this.config.agentCodename} [rejected \u26A0\uFE0F no signature]`);
2906
3155
  return;
2907
3156
  }
2908
3157
  if (commsType === "sig-invalid" && peerEntry2?.mode === "signed") {
2909
- logWarn(TAG8, `Rejected invalid signature from ${caller}`);
3158
+ logWarn(TAG9, `Rejected invalid signature from ${caller}`);
2910
3159
  res.writeHead(403, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Invalid signature", "authentication_error", "signature_invalid")));
2911
3160
  setCurrentPeerHops(null);
2912
3161
  this.onPeerActivity?.(`\u{1F916} Agents: ${caller} \u2192 ${this.config.agentCodename} [rejected \u26A0\uFE0F invalid sig]`);
@@ -2914,7 +3163,7 @@ var AgentApiServer = class {
2914
3163
  }
2915
3164
  }
2916
3165
  if (lastMsg?.content && /\[NO-REPLY\]/i.test(lastMsg.content)) {
2917
- logInfo(TAG8, `Peer ${caller} sent [NO_REPLY] \u2014 returning empty completion`);
3166
+ logInfo(TAG9, `Peer ${caller} sent [NO_REPLY] \u2014 returning empty completion`);
2918
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" }] }));
2919
3168
  setCurrentPeerHops(null);
2920
3169
  return;
@@ -2923,7 +3172,7 @@ var AgentApiServer = class {
2923
3172
  const { hasPending, popPendingPrompt } = await import("./pending-callback-NHFHL2JC.js");
2924
3173
  if (hasPending(caller)) {
2925
3174
  const pendingPrompt = popPendingPrompt(caller);
2926
- 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)`);
2927
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" }] }));
2928
3177
  setCurrentPeerHops(null);
2929
3178
  return;
@@ -2933,13 +3182,13 @@ var AgentApiServer = class {
2933
3182
  const { resolvePending } = await import("./pending-callback-NHFHL2JC.js");
2934
3183
  const answer = lastMsg.content.slice("[CB-RESPONSE]".length).trim();
2935
3184
  if (resolvePending(caller, answer)) {
2936
- 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)`);
2937
3186
  }
2938
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" }] }));
2939
3188
  setCurrentPeerHops(null);
2940
3189
  return;
2941
3190
  }
2942
- logInfo(TAG8, `Peer call: ${caller} \u2192 ${this.config.agentCodename} [${commsType}]`);
3191
+ logInfo(TAG9, `Peer call: ${caller} \u2192 ${this.config.agentCodename} [${commsType}]`);
2943
3192
  const secLabel = `${this.tlsEnabled ? "tls" : "http"}+${commsType === "signed" ? "signed" : "jwt"}`;
2944
3193
  this.onPeerActivity?.(`\u{1F916} Agents: ${caller} \u2192 ${this.config.agentCodename} [${secLabel}]`);
2945
3194
  const { loadPeerConfig } = await import("./peer-config-TN55LFDC.js");
@@ -2979,7 +3228,7 @@ var AgentApiServer = class {
2979
3228
  try {
2980
3229
  session = await this.ensureAgentSession();
2981
3230
  } catch (err) {
2982
- logAndSwallow(TAG8, "ensureAgentSession", err);
3231
+ logAndSwallow(TAG9, "ensureAgentSession", err);
2983
3232
  res.writeHead(503, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Failed to spawn agent kiro-cli", "server_error", "spawn_failed")));
2984
3233
  setCurrentPeerHops(null);
2985
3234
  return;
@@ -2995,7 +3244,8 @@ var AgentApiServer = class {
2995
3244
  markRulesInjected: () => {
2996
3245
  this.rulesInjected = true;
2997
3246
  },
2998
- guestName: this.guestName
3247
+ guestName: this.guestName,
3248
+ sessionManager: this.sessionManager
2999
3249
  });
3000
3250
  const reqBody = body;
3001
3251
  const promptPreview = Array.isArray(reqBody.messages) && reqBody.messages.length > 0 ? String(reqBody.messages[reqBody.messages.length - 1]?.content ?? "").slice(0, 200) : "";
@@ -3018,7 +3268,7 @@ var AgentApiServer = class {
3018
3268
  try {
3019
3269
  body = JSON.parse(await readBody(req));
3020
3270
  } catch (err) {
3021
- logAndSwallow(TAG8, "JSON.parse embeddings body", err);
3271
+ logAndSwallow(TAG9, "JSON.parse embeddings body", err);
3022
3272
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Invalid JSON body", "invalid_request_error", "invalid_body")));
3023
3273
  return;
3024
3274
  }
@@ -3031,7 +3281,7 @@ var AgentApiServer = class {
3031
3281
  try {
3032
3282
  body = JSON.parse(await readBody(req));
3033
3283
  } catch (err) {
3034
- logAndSwallow(TAG8, "JSON.parse tasks body", err);
3284
+ logAndSwallow(TAG9, "JSON.parse tasks body", err);
3035
3285
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Invalid JSON body", "invalid_request_error", "invalid_body")));
3036
3286
  return;
3037
3287
  }
@@ -3040,7 +3290,7 @@ var AgentApiServer = class {
3040
3290
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Missing 'goal' field", "invalid_request_error", "missing_field")));
3041
3291
  return;
3042
3292
  }
3043
- const { spin: spin2 } = await import("./spin-IMW2MZOH.js");
3293
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
3044
3294
  const { cardId, sessionId } = spin2.dispatch({
3045
3295
  type: "O",
3046
3296
  goal: body.context ? `${goal}
@@ -3060,10 +3310,10 @@ Context: ${body.context}` : goal,
3060
3310
  const safeName = bn(art.name);
3061
3311
  writeFileSync3(join6(dir, safeName), Buffer.from(art.content, "base64"));
3062
3312
  }
3063
- 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`);
3064
3314
  }
3065
- logInfo(TAG8, `A2A task from ${caller}: card #${cardId} "${goal.slice(0, 60)}"${body.callback_peer ? ` (callback\u2192${body.callback_peer})` : ""}`);
3066
- 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)}`);
3067
3317
  this.onPeerActivity?.(`\u{1F4CB} A2A task from ${caller}: "${goal.slice(0, 60)}" \u2192 card #${cardId}`);
3068
3318
  this.pushTraffic({
3069
3319
  ts: Date.now(),
@@ -3144,8 +3394,8 @@ Context: ${body.context}` : goal,
3144
3394
  res.writeHead(400, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("Missing task_id or status", "invalid_request_error", "missing_field")));
3145
3395
  return;
3146
3396
  }
3147
- logDebug(TAG8, `\u2190 callback from ${caller}: task_id=${taskId} status=${body.status}`);
3148
- 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)}`);
3149
3399
  const { kanbanList, kanbanComplete, kanbanFail } = (init_kanban_board(), __toCommonJS(kanban_board_exports));
3150
3400
  const remoteCards = kanbanList("running", "status").filter((c) => {
3151
3401
  if (c.type !== "remote") return false;
@@ -3157,7 +3407,7 @@ Context: ${body.context}` : goal,
3157
3407
  }
3158
3408
  });
3159
3409
  if (remoteCards.length === 0) {
3160
- 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`);
3161
3411
  res.writeHead(404, { "Content-Type": "application/json" }).end(JSON.stringify(openaiError("No matching local card", "not_found_error", "not_found")));
3162
3412
  return;
3163
3413
  }
@@ -3170,21 +3420,21 @@ Context: ${body.context}` : goal,
3170
3420
  const safeName = bn(art.name);
3171
3421
  writeFileSync3(join6(dir, safeName), Buffer.from(art.content, "base64"));
3172
3422
  }
3173
- 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}`);
3174
3424
  }
3175
3425
  if (body.status === "done") {
3176
3426
  kanbanComplete(card.id, null, body.result_summary?.slice(0, 500) ?? "completed");
3177
- 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)`);
3178
3428
  } else {
3179
3429
  kanbanFail(card.id, body.error ?? "remote task failed");
3180
- 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)}`);
3181
3431
  }
3182
3432
  if (body.tokens_used && typeof body.tokens_used === "number") {
3183
3433
  const { kanbanAddTokens } = (init_kanban_board(), __toCommonJS(kanban_board_exports));
3184
3434
  kanbanAddTokens(card.id, body.tokens_used);
3185
3435
  }
3186
3436
  try {
3187
- const { spin: spin2 } = await import("./spin-IMW2MZOH.js");
3437
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
3188
3438
  const meta = JSON.parse(card.notes ?? "{}");
3189
3439
  if (meta.remote_session_id) {
3190
3440
  const hollow = spin2.listAllSessions().find((s) => s.peer === caller && s.remoteSessionId === meta.remote_session_id);
@@ -3210,7 +3460,7 @@ Context: ${body.context}` : goal,
3210
3460
  // src/boot/phase-agent-api.ts
3211
3461
  init_log_and_swallow();
3212
3462
  init_logger();
3213
- var TAG9 = "agent_api";
3463
+ var TAG10 = "agent_api";
3214
3464
  async function phaseAgentApi(ctx) {
3215
3465
  const { config, memory, runtime, platforms, registry } = ctx;
3216
3466
  const agentConfig = loadAgentApiConfig(process.env);
@@ -3219,7 +3469,7 @@ async function phaseAgentApi(ctx) {
3219
3469
  sendNotification(ctx, msg);
3220
3470
  };
3221
3471
  setPeerActivityCallback(notifyPeer);
3222
- const { AgentApiAdapter } = await import("./agent-api-adapter-PTJYZKQK.js");
3472
+ const { AgentApiAdapter } = await import("./agent-api-adapter-WRGEQ6DV.js");
3223
3473
  const a2aAdapter = new AgentApiAdapter();
3224
3474
  registry.register("agent-api", {
3225
3475
  configured: Boolean(agentConfig.port),
@@ -3230,6 +3480,7 @@ async function phaseAgentApi(ctx) {
3230
3480
  workingDir: config.transport.workingDir,
3231
3481
  memory,
3232
3482
  runtime,
3483
+ sessionManager: ctx.sessionManager,
3233
3484
  onPeerActivity: notifyPeer,
3234
3485
  a2aAdapter
3235
3486
  });
@@ -3263,7 +3514,7 @@ async function phaseAgentApi(ctx) {
3263
3514
  startGossipListener();
3264
3515
  }
3265
3516
  if (Object.keys(peerConfig.peers).length > 0) {
3266
- import("./peer-transport-I6JPLFZ2.js").then(({ initPeerTransport }) => initPeerTransport()).catch(() => {
3517
+ import("./peer-transport-5VKK2I7P.js").then(({ initPeerTransport }) => initPeerTransport()).catch(() => {
3267
3518
  });
3268
3519
  }
3269
3520
  if (Object.keys(peerConfig.peers).length > 0) {
@@ -3282,7 +3533,7 @@ async function phaseAgentApi(ctx) {
3282
3533
  try {
3283
3534
  resolve3(JSON.parse(data)?.choices?.[0]?.message?.content ?? "");
3284
3535
  } catch (err) {
3285
- logAndSwallow(TAG9, "JSON.parse agent-api response", err);
3536
+ logAndSwallow(TAG10, "JSON.parse agent-api response", err);
3286
3537
  resolve3("");
3287
3538
  }
3288
3539
  });
@@ -3524,7 +3775,7 @@ ${lines.join("\n")}`);
3524
3775
  }
3525
3776
  }
3526
3777
  if (ctx.telegramAdapter) {
3527
- const { spin: spin2 } = await import("./spin-IMW2MZOH.js");
3778
+ const { spin: spin2 } = await import("./spin-E3ZDEDKT.js");
3528
3779
  spin2.setGreetingAdapter(ctx.telegramAdapter);
3529
3780
  }
3530
3781
  return bridge.waitForExit();
@@ -3628,6 +3879,11 @@ try {
3628
3879
  } catch {
3629
3880
  }
3630
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
+ }
3631
3887
  console.error(`[FATAL] Uncaught exception: ${err.stack ?? err.message ?? err}`);
3632
3888
  process.exit(1);
3633
3889
  });