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.
- package/bundle/{_registry.generated-VN2OU54H.js → _registry.generated-YP5GLSG7.js} +8 -5
- package/bundle/{_registry.generated-VN2OU54H.js.map → _registry.generated-YP5GLSG7.js.map} +1 -1
- package/bundle/abtars-cli.js +4 -4
- package/bundle/abtars-task.js.map +2 -2
- package/bundle/abtars.js +374 -118
- package/bundle/abtars.js.map +4 -4
- package/bundle/{agent-api-adapter-PTJYZKQK.js → agent-api-adapter-WRGEQ6DV.js} +2 -2
- package/bundle/{agent-registry-OXFVXBOO.js → agent-registry-GHNG2PH3.js} +2 -2
- package/bundle/{bootstrap-XBTZIGKC.js → bootstrap-PZIDBPEJ.js} +2 -2
- package/bundle/{browser-EJNS35NT.js → browser-D3LZV7ZK.js} +2 -2
- package/bundle/{chunk-LGP6TYFI.js → chunk-374NCXFZ.js} +89 -2
- package/bundle/chunk-374NCXFZ.js.map +7 -0
- package/bundle/{chunk-44JSAOAU.js → chunk-75ATTOW4.js} +3 -3
- package/bundle/{chunk-AW2FTHQO.js → chunk-7JN2MMU7.js} +2 -2
- package/bundle/chunk-C7K6VZNY.js +186 -0
- package/bundle/chunk-C7K6VZNY.js.map +7 -0
- package/bundle/{chunk-V3DZFJZ2.js → chunk-CXXU3HAU.js} +2 -2
- package/bundle/{chunk-IRZOWJ5S.js → chunk-IHYKTDIP.js} +50 -28
- package/bundle/chunk-IHYKTDIP.js.map +7 -0
- package/bundle/{chunk-MGHNCO5V.js → chunk-LDUOOKQY.js} +4 -3
- package/bundle/chunk-LDUOOKQY.js.map +7 -0
- package/bundle/{chunk-AO32N2VB.js → chunk-M3JEX6L4.js} +270 -228
- package/bundle/chunk-M3JEX6L4.js.map +7 -0
- package/bundle/{chunk-7Z3HBPRY.js → chunk-N4EB6LA7.js} +2 -2
- package/bundle/{chunk-56SV72K4.js → chunk-P2K2K6XL.js} +15 -29
- package/bundle/chunk-P2K2K6XL.js.map +7 -0
- package/bundle/{chunk-5GCLBUBS.js → chunk-PU5HSKWH.js} +1 -1
- package/bundle/{chunk-NC72HN4Y.js → chunk-SMPHE3ZM.js} +188 -107
- package/bundle/chunk-SMPHE3ZM.js.map +7 -0
- package/bundle/{chunk-XGLBEDRG.js → chunk-UNM3OXHB.js} +5 -3
- package/bundle/chunk-UNM3OXHB.js.map +7 -0
- package/bundle/{chunk-7YQGRUXI.js → chunk-VXCETPZU.js} +40 -58
- package/bundle/chunk-VXCETPZU.js.map +7 -0
- package/bundle/{chunk-KTYGKPYM.js → chunk-W2R2HFOQ.js} +2 -2
- package/bundle/{chunk-PROPYS3P.js → chunk-YPAQEQSC.js} +2 -2
- package/bundle/{commands-BARN6XQ7.js → commands-OIISYHTD.js} +3 -3
- package/bundle/{delegation-tools-O7WLLYVP.js → delegation-tools-YATZFKYO.js} +4 -4
- package/bundle/{deploy-L6EASMTO.js → deploy-T6R45OZJ.js} +2 -2
- package/bundle/{direct-api-transport-LGYYBJNR.js → direct-api-transport-S2RDH2I7.js} +13 -9
- package/bundle/direct-api-transport-S2RDH2I7.js.map +7 -0
- package/bundle/{discord-adapter-6GRRMO4M.js → discord-adapter-UTXUWX3A.js} +3 -3
- package/bundle/{health-check-YKWFD2LZ.js → health-check-BUA36UAQ.js} +2 -2
- package/bundle/{health-check-YKWFD2LZ.js.map → health-check-BUA36UAQ.js.map} +1 -1
- package/bundle/{heartbeat-system-OATYKHRV.js → heartbeat-system-MVTRS4GP.js} +2 -2
- package/bundle/{heartbeat-tier3-JT422XQ4.js → heartbeat-tier3-6KH45CL6.js} +10 -10
- package/bundle/{install-C2WDC4WT.js → install-OS3CU7NF.js} +2 -2
- package/bundle/kanban-channel-IJ52OMNA.js +1 -1
- package/bundle/{message-pipeline-X6ENVZBZ.js → message-pipeline-AUIUNM5R.js} +3 -3
- package/bundle/meta.json +1568 -1545
- package/bundle/{orc-tools-A3G7WCSJ.js → orc-tools-TOD4WHTM.js} +2 -2
- package/bundle/{peer-transport-I6JPLFZ2.js → peer-transport-5VKK2I7P.js} +2 -2
- package/bundle/{phase-transport-R6L6EYAD.js → phase-transport-FS6NL4A5.js} +6 -5
- package/bundle/{reconciler-FHESO6OC.js → reconciler-NZ4O4BCP.js} +4 -4
- package/bundle/{skill-session-AXBDQSLQ.js → skill-session-VJXTKOKL.js} +2 -2
- package/bundle/{sleep-36XS6MHJ.js → sleep-BEWAUFCL.js} +5 -2
- package/bundle/{spin-IMW2MZOH.js → spin-E3ZDEDKT.js} +5 -5
- package/bundle/{spin-types-BLPYAETA.js → spin-types-OIE67MJK.js} +2 -2
- package/bundle/{system-status-FDVKSAFK.js → system-status-FAVNIUFJ.js} +3 -3
- package/bundle/{telegram-adapter-SIW2DMQX.js → telegram-adapter-4TX7QWKC.js} +12 -6
- package/bundle/{telegram-adapter-SIW2DMQX.js.map → telegram-adapter-4TX7QWKC.js.map} +2 -2
- package/bundle/{tool-registry-DDFUKQY7.js → tool-registry-7FK3OQGL.js} +8 -8
- package/bundle/{update-EZWBQTLI.js → update-CKFP6LBE.js} +3 -3
- package/package.json +1 -1
- package/scripts/abtars-watchdog.service +2 -1
- package/scripts/emergency-update.sh +53 -5
- package/templates/skills/skill-authoring/SKILL.md +6 -6
- package/bundle/chunk-56SV72K4.js.map +0 -7
- package/bundle/chunk-7YQGRUXI.js.map +0 -7
- package/bundle/chunk-AO32N2VB.js.map +0 -7
- package/bundle/chunk-IRZOWJ5S.js.map +0 -7
- package/bundle/chunk-LGP6TYFI.js.map +0 -7
- package/bundle/chunk-MGHNCO5V.js.map +0 -7
- package/bundle/chunk-NC72HN4Y.js.map +0 -7
- package/bundle/chunk-Q33GFBXL.js +0 -210
- package/bundle/chunk-Q33GFBXL.js.map +0 -7
- package/bundle/chunk-XGLBEDRG.js.map +0 -7
- package/bundle/chunk-Y76VUJSF.js +0 -75
- package/bundle/chunk-Y76VUJSF.js.map +0 -7
- package/bundle/direct-api-transport-LGYYBJNR.js.map +0 -7
- package/bundle/public/css/dashboard.css +0 -542
- package/bundle/public/index.html +0 -180
- package/bundle/public/js/app.js +0 -437
- package/bundle/public/memory-universe.js +0 -384
- package/bundle/subagent-runtime-HLCDLHK5.js +0 -14
- package/bundle/update-EZWBQTLI.js.map +0 -7
- /package/bundle/{agent-api-adapter-PTJYZKQK.js.map → agent-api-adapter-WRGEQ6DV.js.map} +0 -0
- /package/bundle/{agent-registry-OXFVXBOO.js.map → agent-registry-GHNG2PH3.js.map} +0 -0
- /package/bundle/{bootstrap-XBTZIGKC.js.map → bootstrap-PZIDBPEJ.js.map} +0 -0
- /package/bundle/{browser-EJNS35NT.js.map → browser-D3LZV7ZK.js.map} +0 -0
- /package/bundle/{chunk-44JSAOAU.js.map → chunk-75ATTOW4.js.map} +0 -0
- /package/bundle/{chunk-AW2FTHQO.js.map → chunk-7JN2MMU7.js.map} +0 -0
- /package/bundle/{chunk-V3DZFJZ2.js.map → chunk-CXXU3HAU.js.map} +0 -0
- /package/bundle/{chunk-7Z3HBPRY.js.map → chunk-N4EB6LA7.js.map} +0 -0
- /package/bundle/{chunk-5GCLBUBS.js.map → chunk-PU5HSKWH.js.map} +0 -0
- /package/bundle/{chunk-KTYGKPYM.js.map → chunk-W2R2HFOQ.js.map} +0 -0
- /package/bundle/{chunk-PROPYS3P.js.map → chunk-YPAQEQSC.js.map} +0 -0
- /package/bundle/{commands-BARN6XQ7.js.map → commands-OIISYHTD.js.map} +0 -0
- /package/bundle/{delegation-tools-O7WLLYVP.js.map → delegation-tools-YATZFKYO.js.map} +0 -0
- /package/bundle/{deploy-L6EASMTO.js.map → deploy-T6R45OZJ.js.map} +0 -0
- /package/bundle/{discord-adapter-6GRRMO4M.js.map → discord-adapter-UTXUWX3A.js.map} +0 -0
- /package/bundle/{heartbeat-system-OATYKHRV.js.map → heartbeat-system-MVTRS4GP.js.map} +0 -0
- /package/bundle/{heartbeat-tier3-JT422XQ4.js.map → heartbeat-tier3-6KH45CL6.js.map} +0 -0
- /package/bundle/{install-C2WDC4WT.js.map → install-OS3CU7NF.js.map} +0 -0
- /package/bundle/{message-pipeline-X6ENVZBZ.js.map → message-pipeline-AUIUNM5R.js.map} +0 -0
- /package/bundle/{orc-tools-A3G7WCSJ.js.map → orc-tools-TOD4WHTM.js.map} +0 -0
- /package/bundle/{peer-transport-I6JPLFZ2.js.map → peer-transport-5VKK2I7P.js.map} +0 -0
- /package/bundle/{phase-transport-R6L6EYAD.js.map → phase-transport-FS6NL4A5.js.map} +0 -0
- /package/bundle/{reconciler-FHESO6OC.js.map → reconciler-NZ4O4BCP.js.map} +0 -0
- /package/bundle/{skill-session-AXBDQSLQ.js.map → skill-session-VJXTKOKL.js.map} +0 -0
- /package/bundle/{sleep-36XS6MHJ.js.map → sleep-BEWAUFCL.js.map} +0 -0
- /package/bundle/{spin-IMW2MZOH.js.map → spin-E3ZDEDKT.js.map} +0 -0
- /package/bundle/{spin-types-BLPYAETA.js.map → spin-types-OIE67MJK.js.map} +0 -0
- /package/bundle/{system-status-FDVKSAFK.js.map → system-status-FAVNIUFJ.js.map} +0 -0
- /package/bundle/{subagent-runtime-HLCDLHK5.js.map → tool-registry-7FK3OQGL.js.map} +0 -0
- /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-
|
|
22
|
+
} from "./chunk-IHYKTDIP.js";
|
|
23
23
|
import {
|
|
24
24
|
loadNLMConfig
|
|
25
|
-
} from "./chunk-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
64
|
-
import "./chunk-
|
|
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-
|
|
65
|
+
import "./chunk-YPAQEQSC.js";
|
|
69
66
|
import {
|
|
70
67
|
init_spin,
|
|
71
68
|
spin
|
|
72
|
-
} from "./chunk-
|
|
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-
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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(
|
|
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-
|
|
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
|
-
|
|
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-
|
|
1433
|
-
const { killWakeInhibit } = await import("./commands-
|
|
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
|
|
1652
|
+
let nightSessionId;
|
|
1436
1653
|
const { getEnv: getEnv2 } = await import("./env-schema-4JXQUOH4.js");
|
|
1437
1654
|
const runtime = {
|
|
1438
1655
|
async complete(prompt) {
|
|
1439
|
-
|
|
1440
|
-
|
|
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: () =>
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
2398
|
-
|
|
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
|
|
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(
|
|
2746
|
+
logInfo(TAG9, "TLS 1.3 enabled for agent-api (self-signed cert)");
|
|
2498
2747
|
} catch (err) {
|
|
2499
|
-
logAndSwallow(
|
|
2748
|
+
logAndSwallow(TAG9, "TLS setup", err);
|
|
2500
2749
|
}
|
|
2501
2750
|
} else {
|
|
2502
|
-
logWarn(
|
|
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(
|
|
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(
|
|
2802
|
+
logInfo(TAG9, `Peer WS connected: ${name}`);
|
|
2554
2803
|
ws.on("close", () => {
|
|
2555
2804
|
this.peerWsConnections.delete(name);
|
|
2556
|
-
logInfo(
|
|
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(
|
|
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-
|
|
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(
|
|
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(
|
|
2901
|
+
logInfo(TAG9, `A2A transcript saved to ${dest}`);
|
|
2653
2902
|
} catch (e) {
|
|
2654
|
-
logWarn(
|
|
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(
|
|
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(
|
|
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(
|
|
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-
|
|
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-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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-
|
|
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(
|
|
3313
|
+
logDebug(TAG9, `Wrote ${body.artifacts.length} artifact(s) to card#${cardId} workspace`);
|
|
3064
3314
|
}
|
|
3065
|
-
logInfo(
|
|
3066
|
-
logTrace(
|
|
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(
|
|
3148
|
-
logTrace(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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-
|
|
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
|
|
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-
|
|
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-
|
|
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(
|
|
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-
|
|
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
|
});
|