chatroom-cli 1.57.0 → 1.57.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +641 -399
- package/dist/index.js.map +23 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29173,7 +29173,7 @@ function writeSpawnError(logPrefix, err, emitLogLine) {
|
|
|
29173
29173
|
emitLogLine?.(line);
|
|
29174
29174
|
console.error(`[${new Date().toISOString()}] ${logPrefix} spawn-error]`, err);
|
|
29175
29175
|
}
|
|
29176
|
-
var NO_SUBAGENT_DIRECTIVE2 = "NEVER spawn subagents. Follow the chatroom instructions strictly.", _sdkCache, _sdkLoadError, CURSOR_SDK_COMMAND = "cursor-sdk", DEFAULT_MODEL = "composer-2.5", AGENT_CREATE_TIMEOUT_MS = 60000, SEND_TIMEOUT_MS = 60000, RUN_WAIT_TIMEOUT_MS = 3600000, MODELS_LIST_TIMEOUT_MS =
|
|
29176
|
+
var NO_SUBAGENT_DIRECTIVE2 = "NEVER spawn subagents. Follow the chatroom instructions strictly.", _sdkCache, _sdkLoadError, CURSOR_SDK_COMMAND = "cursor-sdk", DEFAULT_MODEL = "composer-2.5", AGENT_CREATE_TIMEOUT_MS = 60000, SEND_TIMEOUT_MS = 60000, RUN_WAIT_TIMEOUT_MS = 3600000, MODELS_LIST_TIMEOUT_MS = 60000, RUN_CANCEL_TIMEOUT_MS = 5000, cachedSdkPackageVersion, CursorSdkAgentService;
|
|
29177
29177
|
var init_cursor_sdk_agent_service = __esm(() => {
|
|
29178
29178
|
init_esm();
|
|
29179
29179
|
init_base_cli_agent_service();
|
|
@@ -80624,19 +80624,51 @@ function isDaemonRunning() {
|
|
|
80624
80624
|
removePid();
|
|
80625
80625
|
return { running: false, pid: null };
|
|
80626
80626
|
}
|
|
80627
|
-
function
|
|
80628
|
-
const { running: running3
|
|
80627
|
+
function tryAcquireLock() {
|
|
80628
|
+
const { running: running3 } = isDaemonRunning();
|
|
80629
80629
|
if (running3) {
|
|
80630
|
-
console.error(`❌ Daemon already running for ${getConvexUrl()} (PID: ${pid})`);
|
|
80631
80630
|
return false;
|
|
80632
80631
|
}
|
|
80633
80632
|
writePid();
|
|
80634
80633
|
return true;
|
|
80635
80634
|
}
|
|
80635
|
+
function logWaitingForShutdown(pid) {
|
|
80636
|
+
console.error(`⏳ Waiting for previous daemon to shut down for ${getConvexUrl()} (PID: ${pid})...`);
|
|
80637
|
+
}
|
|
80638
|
+
function logDaemonAlreadyRunning(pid) {
|
|
80639
|
+
console.error(`❌ Daemon already running for ${getConvexUrl()} (PID: ${pid})`);
|
|
80640
|
+
}
|
|
80641
|
+
async function waitForLockOrTimeout(deadline, intervalMs, sleep5) {
|
|
80642
|
+
let loggedWait = false;
|
|
80643
|
+
while (Date.now() < deadline) {
|
|
80644
|
+
if (tryAcquireLock()) {
|
|
80645
|
+
return true;
|
|
80646
|
+
}
|
|
80647
|
+
const { pid } = isDaemonRunning();
|
|
80648
|
+
if (pid !== null && !loggedWait) {
|
|
80649
|
+
logWaitingForShutdown(pid);
|
|
80650
|
+
loggedWait = true;
|
|
80651
|
+
}
|
|
80652
|
+
await sleep5(intervalMs);
|
|
80653
|
+
}
|
|
80654
|
+
return false;
|
|
80655
|
+
}
|
|
80656
|
+
async function acquireLockWithRetry(options) {
|
|
80657
|
+
const intervalMs = options?.intervalMs ?? LOCK_RETRY_INTERVAL_MS;
|
|
80658
|
+
const maxWaitMs = options?.maxWaitMs ?? LOCK_RETRY_MAX_WAIT_MS;
|
|
80659
|
+
const sleep5 = options?.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
|
|
80660
|
+
const deadline = Date.now() + maxWaitMs;
|
|
80661
|
+
if (await waitForLockOrTimeout(deadline, intervalMs, sleep5)) {
|
|
80662
|
+
return true;
|
|
80663
|
+
}
|
|
80664
|
+
const { pid } = isDaemonRunning();
|
|
80665
|
+
logDaemonAlreadyRunning(pid);
|
|
80666
|
+
return false;
|
|
80667
|
+
}
|
|
80636
80668
|
function releaseLock() {
|
|
80637
80669
|
removePid();
|
|
80638
80670
|
}
|
|
80639
|
-
var CHATROOM_DIR4;
|
|
80671
|
+
var CHATROOM_DIR4, LOCK_RETRY_INTERVAL_MS = 500, LOCK_RETRY_MAX_WAIT_MS = 15000;
|
|
80640
80672
|
var init_pid = __esm(() => {
|
|
80641
80673
|
init_client2();
|
|
80642
80674
|
CHATROOM_DIR4 = join16(homedir6(), ".chatroom");
|
|
@@ -84918,6 +84950,315 @@ class TurnEndQueue {
|
|
|
84918
84950
|
}
|
|
84919
84951
|
}
|
|
84920
84952
|
|
|
84953
|
+
// src/commands/machine/daemon-start/native-delivery-ledger.ts
|
|
84954
|
+
class NativeDeliveryLedger {
|
|
84955
|
+
delivered = new Set;
|
|
84956
|
+
inFlight = new Set;
|
|
84957
|
+
deliveryKey(taskId, harnessSessionId) {
|
|
84958
|
+
return `${taskId}\x00${harnessSessionId}`;
|
|
84959
|
+
}
|
|
84960
|
+
isDelivered(taskId, harnessSessionId) {
|
|
84961
|
+
return this.delivered.has(this.deliveryKey(taskId, harnessSessionId));
|
|
84962
|
+
}
|
|
84963
|
+
tryAcquire(taskId, harnessSessionId) {
|
|
84964
|
+
const key = this.deliveryKey(taskId, harnessSessionId);
|
|
84965
|
+
if (this.delivered.has(key) || this.inFlight.has(key)) {
|
|
84966
|
+
return false;
|
|
84967
|
+
}
|
|
84968
|
+
this.inFlight.add(key);
|
|
84969
|
+
return true;
|
|
84970
|
+
}
|
|
84971
|
+
markDelivered(taskId, harnessSessionId) {
|
|
84972
|
+
const key = this.deliveryKey(taskId, harnessSessionId);
|
|
84973
|
+
this.inFlight.delete(key);
|
|
84974
|
+
this.delivered.add(key);
|
|
84975
|
+
}
|
|
84976
|
+
clearDelivery(taskId, harnessSessionId) {
|
|
84977
|
+
const key = this.deliveryKey(taskId, harnessSessionId);
|
|
84978
|
+
this.inFlight.delete(key);
|
|
84979
|
+
this.delivered.delete(key);
|
|
84980
|
+
}
|
|
84981
|
+
clearSession(harnessSessionId) {
|
|
84982
|
+
const suffix = `\x00${harnessSessionId}`;
|
|
84983
|
+
for (const key of [...this.delivered, ...this.inFlight]) {
|
|
84984
|
+
if (key.endsWith(suffix)) {
|
|
84985
|
+
this.delivered.delete(key);
|
|
84986
|
+
this.inFlight.delete(key);
|
|
84987
|
+
}
|
|
84988
|
+
}
|
|
84989
|
+
}
|
|
84990
|
+
}
|
|
84991
|
+
|
|
84992
|
+
// src/domain/native-integration/predicates.ts
|
|
84993
|
+
function isNativeInjectableAliveRunning(task) {
|
|
84994
|
+
const { agentConfig, status: status3 } = task;
|
|
84995
|
+
if (!isNativeHarness(agentConfig.agentHarness))
|
|
84996
|
+
return false;
|
|
84997
|
+
if (agentConfig.spawnedAgentPid == null || agentConfig.desiredState !== "running") {
|
|
84998
|
+
return false;
|
|
84999
|
+
}
|
|
85000
|
+
if (status3 === "pending")
|
|
85001
|
+
return true;
|
|
85002
|
+
if (status3 === "acknowledged") {
|
|
85003
|
+
const assignedTo = task.assignedTo?.toLowerCase();
|
|
85004
|
+
return assignedTo === agentConfig.role.toLowerCase();
|
|
85005
|
+
}
|
|
85006
|
+
return false;
|
|
85007
|
+
}
|
|
85008
|
+
function isInjectableNativeAction(action) {
|
|
85009
|
+
if (action == null)
|
|
85010
|
+
return true;
|
|
85011
|
+
return action === NATIVE_WAITING_ACTION;
|
|
85012
|
+
}
|
|
85013
|
+
function isNativeIdleAfterTaskComplete(participant) {
|
|
85014
|
+
return participant.lastSeenAction === NATIVE_TASK_INJECTED_ACTION && participant.lastStatus === "task.completed";
|
|
85015
|
+
}
|
|
85016
|
+
function isNativeAcknowledgedInjectionRetry(task) {
|
|
85017
|
+
if (task.status !== "acknowledged")
|
|
85018
|
+
return false;
|
|
85019
|
+
const assignedTo = task.assignedTo?.toLowerCase();
|
|
85020
|
+
if (assignedTo !== task.agentConfig.role.toLowerCase())
|
|
85021
|
+
return false;
|
|
85022
|
+
return task.participant?.lastSeenAction === NATIVE_TASK_INJECTED_ACTION;
|
|
85023
|
+
}
|
|
85024
|
+
function isStaleCliGetNextTaskWaiting(task) {
|
|
85025
|
+
const lastSeenAt = task.participant?.lastSeenAt ?? 0;
|
|
85026
|
+
return task.participant?.lastSeenAction === "get-next-task:started" && task.createdAt > lastSeenAt;
|
|
85027
|
+
}
|
|
85028
|
+
function isCliIdleNotListening(task, now, thresholdMs) {
|
|
85029
|
+
const lastSeenAt = task.participant?.lastSeenAt ?? 0;
|
|
85030
|
+
if (lastSeenAt === 0)
|
|
85031
|
+
return now - task.createdAt > thresholdMs;
|
|
85032
|
+
return now - lastSeenAt > thresholdMs;
|
|
85033
|
+
}
|
|
85034
|
+
var init_predicates = __esm(() => {
|
|
85035
|
+
init_types();
|
|
85036
|
+
init_participant();
|
|
85037
|
+
});
|
|
85038
|
+
|
|
85039
|
+
// src/infrastructure/services/remote-agents/spawn-prompt.ts
|
|
85040
|
+
function createSpawnPrompt(raw, opts) {
|
|
85041
|
+
if (opts?.nativeBootstrap) {
|
|
85042
|
+
return NATIVE_BOOTSTRAP_PROMPT;
|
|
85043
|
+
}
|
|
85044
|
+
const trimmed = raw?.trim();
|
|
85045
|
+
return trimmed && trimmed.length > 0 ? trimmed : DEFAULT_TRIGGER_PROMPT;
|
|
85046
|
+
}
|
|
85047
|
+
var DEFAULT_TRIGGER_PROMPT = "Please read your system prompt carefully and follow the Getting Started instructions.", NATIVE_BOOTSTRAP_PROMPT = "Focus on your role responsibilities. Complete each task via handoff.";
|
|
85048
|
+
|
|
85049
|
+
// src/domain/native-integration/spawn-policy.ts
|
|
85050
|
+
function shouldDeferInitialTurn(harness) {
|
|
85051
|
+
return isNativeHarness(harness);
|
|
85052
|
+
}
|
|
85053
|
+
function resolveNativeSpawnPolicy(harness, initMessage) {
|
|
85054
|
+
const deferInitialTurn = shouldDeferInitialTurn(harness);
|
|
85055
|
+
return {
|
|
85056
|
+
deferInitialTurn,
|
|
85057
|
+
prompt: createSpawnPrompt(initMessage, { nativeBootstrap: deferInitialTurn })
|
|
85058
|
+
};
|
|
85059
|
+
}
|
|
85060
|
+
var init_spawn_policy = __esm(() => {
|
|
85061
|
+
init_types();
|
|
85062
|
+
});
|
|
85063
|
+
|
|
85064
|
+
// src/domain/native-integration/index.ts
|
|
85065
|
+
var init_native_integration = __esm(() => {
|
|
85066
|
+
init_types();
|
|
85067
|
+
init_predicates();
|
|
85068
|
+
init_spawn_policy();
|
|
85069
|
+
});
|
|
85070
|
+
|
|
85071
|
+
// src/commands/machine/daemon-start/native-task-injector-logic.ts
|
|
85072
|
+
function shouldDeliverNativeTask(task, opts) {
|
|
85073
|
+
if (!isNativeInjectableAliveRunning(task))
|
|
85074
|
+
return false;
|
|
85075
|
+
if (!opts.harnessSessionId)
|
|
85076
|
+
return false;
|
|
85077
|
+
if (opts.ledger.isDelivered(task.taskId, opts.harnessSessionId))
|
|
85078
|
+
return false;
|
|
85079
|
+
return isInjectableNativeAction(task.participant?.lastSeenAction) || isNativeIdleAfterTaskComplete(task.participant ?? {}) || isNativeAcknowledgedInjectionRetry(task);
|
|
85080
|
+
}
|
|
85081
|
+
function buildNativeInjectionPrompt(params) {
|
|
85082
|
+
const { taskDeliveryOutput, compressMode } = params;
|
|
85083
|
+
if (compressMode === "new_session") {
|
|
85084
|
+
return [
|
|
85085
|
+
"⚠️ Context was compacted. Run `chatroom get-system-prompt` only if role instructions are missing.",
|
|
85086
|
+
"",
|
|
85087
|
+
taskDeliveryOutput
|
|
85088
|
+
].join(`
|
|
85089
|
+
`);
|
|
85090
|
+
}
|
|
85091
|
+
return taskDeliveryOutput;
|
|
85092
|
+
}
|
|
85093
|
+
var init_native_task_injector_logic = __esm(() => {
|
|
85094
|
+
init_predicates();
|
|
85095
|
+
init_native_integration();
|
|
85096
|
+
});
|
|
85097
|
+
|
|
85098
|
+
// ../../services/backend/src/domain/handoff/parse-compress-context.ts
|
|
85099
|
+
function findSectionIndex(content, headings) {
|
|
85100
|
+
const indices = headings.map((heading) => content.indexOf(heading)).filter((idx) => idx !== -1);
|
|
85101
|
+
return indices.length === 0 ? -1 : Math.min(...indices);
|
|
85102
|
+
}
|
|
85103
|
+
function normalizeMode(raw) {
|
|
85104
|
+
const value = raw.toLowerCase();
|
|
85105
|
+
if (value === "reset")
|
|
85106
|
+
return "new_session";
|
|
85107
|
+
if (value === "none")
|
|
85108
|
+
return value;
|
|
85109
|
+
return DEFAULT_MODE;
|
|
85110
|
+
}
|
|
85111
|
+
function extractSectionBody(content, sectionIdx) {
|
|
85112
|
+
const matchedHeading = SECTION_HEADINGS.find((h) => content.indexOf(h, sectionIdx) === sectionIdx) ?? SECTION_HEADINGS[0];
|
|
85113
|
+
const afterSection = content.slice(sectionIdx);
|
|
85114
|
+
const nextHeading = afterSection.slice(matchedHeading.length).search(/\n## /);
|
|
85115
|
+
return nextHeading === -1 ? afterSection : afterSection.slice(0, matchedHeading.length + nextHeading);
|
|
85116
|
+
}
|
|
85117
|
+
function parseCompressContext(handoffContent) {
|
|
85118
|
+
const sectionIdx = findSectionIndex(handoffContent, SECTION_HEADINGS);
|
|
85119
|
+
if (sectionIdx === -1)
|
|
85120
|
+
return DEFAULT_MODE;
|
|
85121
|
+
const match17 = extractSectionBody(handoffContent, sectionIdx).match(DATA_TAG);
|
|
85122
|
+
if (!match17)
|
|
85123
|
+
return DEFAULT_MODE;
|
|
85124
|
+
return normalizeMode(match17[1]);
|
|
85125
|
+
}
|
|
85126
|
+
function compressContextToWantResume(mode) {
|
|
85127
|
+
return mode === "none";
|
|
85128
|
+
}
|
|
85129
|
+
var SECTION_HEADINGS, DATA_TAG, DEFAULT_MODE = "new_session";
|
|
85130
|
+
var init_parse_compress_context = __esm(() => {
|
|
85131
|
+
SECTION_HEADINGS = ["## Session Management", "## Restart new context"];
|
|
85132
|
+
DATA_TAG = /\/\/\s*data:agent\.compress_context=(new_session|reset|none)\b/i;
|
|
85133
|
+
});
|
|
85134
|
+
|
|
85135
|
+
// src/commands/machine/daemon-start/native-task-injector.ts
|
|
85136
|
+
function runNativeInjectionEffect(task, harnessSessionId, deps, ledger) {
|
|
85137
|
+
return exports_Effect.gen(function* () {
|
|
85138
|
+
if (!shouldDeliverNativeTask(task, { ledger, harnessSessionId })) {
|
|
85139
|
+
return;
|
|
85140
|
+
}
|
|
85141
|
+
const { chatroomId, taskId, taskContent, agentConfig, status: status3 } = task;
|
|
85142
|
+
const { role } = agentConfig;
|
|
85143
|
+
if (!ledger.tryAcquire(taskId, harnessSessionId)) {
|
|
85144
|
+
return;
|
|
85145
|
+
}
|
|
85146
|
+
if (status3 === "pending") {
|
|
85147
|
+
const claimResult = yield* exports_Effect.tryPromise({
|
|
85148
|
+
try: () => deps.backend.mutation(api.tasks.claimTask, {
|
|
85149
|
+
sessionId: deps.sessionId,
|
|
85150
|
+
chatroomId,
|
|
85151
|
+
role,
|
|
85152
|
+
taskId
|
|
85153
|
+
}),
|
|
85154
|
+
catch: (err) => err
|
|
85155
|
+
}).pipe(exports_Effect.either);
|
|
85156
|
+
if (claimResult._tag === "Left") {
|
|
85157
|
+
ledger.clearDelivery(taskId, harnessSessionId);
|
|
85158
|
+
return yield* exports_Effect.fail(claimResult.left);
|
|
85159
|
+
}
|
|
85160
|
+
}
|
|
85161
|
+
const deliveryResult = yield* exports_Effect.tryPromise({
|
|
85162
|
+
try: () => deps.backend.query(api.messages.getTaskDeliveryPrompt, {
|
|
85163
|
+
sessionId: deps.sessionId,
|
|
85164
|
+
chatroomId,
|
|
85165
|
+
role,
|
|
85166
|
+
taskId,
|
|
85167
|
+
convexUrl: deps.convexUrl
|
|
85168
|
+
}),
|
|
85169
|
+
catch: (err) => err
|
|
85170
|
+
}).pipe(exports_Effect.either);
|
|
85171
|
+
if (deliveryResult._tag === "Left") {
|
|
85172
|
+
ledger.clearDelivery(taskId, harnessSessionId);
|
|
85173
|
+
return yield* exports_Effect.fail(deliveryResult.left);
|
|
85174
|
+
}
|
|
85175
|
+
const delivery = deliveryResult.right;
|
|
85176
|
+
const prompt = buildNativeInjectionPrompt({
|
|
85177
|
+
taskDeliveryOutput: delivery.fullCliOutput,
|
|
85178
|
+
compressMode: parseCompressContext(taskContent)
|
|
85179
|
+
});
|
|
85180
|
+
yield* exports_Effect.tryPromise({
|
|
85181
|
+
try: () => deps.backend.mutation(api.participants.join, {
|
|
85182
|
+
sessionId: deps.sessionId,
|
|
85183
|
+
chatroomId,
|
|
85184
|
+
role,
|
|
85185
|
+
action: NATIVE_TASK_INJECTED_ACTION,
|
|
85186
|
+
taskId
|
|
85187
|
+
}),
|
|
85188
|
+
catch: (err) => err
|
|
85189
|
+
}).pipe(exports_Effect.tapError(() => exports_Effect.sync(() => ledger.clearDelivery(taskId, harnessSessionId))));
|
|
85190
|
+
const resumeResult = yield* exports_Effect.tryPromise({
|
|
85191
|
+
try: () => deps.agentMgr.resumeTurnForSlot({ chatroomId, role, prompt }),
|
|
85192
|
+
catch: (err) => err
|
|
85193
|
+
}).pipe(exports_Effect.either);
|
|
85194
|
+
if (resumeResult._tag === "Left") {
|
|
85195
|
+
ledger.clearDelivery(taskId, harnessSessionId);
|
|
85196
|
+
console.warn(`[NativeTaskInjector] resumeTurn failed for ${role}@${chatroomId}: ${getErrorMessage(resumeResult.left)}`);
|
|
85197
|
+
return;
|
|
85198
|
+
}
|
|
85199
|
+
ledger.markDelivered(taskId, harnessSessionId);
|
|
85200
|
+
});
|
|
85201
|
+
}
|
|
85202
|
+
var init_native_task_injector = __esm(() => {
|
|
85203
|
+
init_participant();
|
|
85204
|
+
init_parse_compress_context();
|
|
85205
|
+
init_esm();
|
|
85206
|
+
init_native_task_injector_logic();
|
|
85207
|
+
init_api3();
|
|
85208
|
+
init_convex_error();
|
|
85209
|
+
});
|
|
85210
|
+
|
|
85211
|
+
// src/commands/machine/daemon-start/native-task-delivery-coordinator.ts
|
|
85212
|
+
class NativeTaskDeliveryCoordinator {
|
|
85213
|
+
ledger;
|
|
85214
|
+
constructor(ledger = new NativeDeliveryLedger) {
|
|
85215
|
+
this.ledger = ledger;
|
|
85216
|
+
}
|
|
85217
|
+
onSessionLost(params) {
|
|
85218
|
+
if (params.harnessSessionId) {
|
|
85219
|
+
this.ledger.clearSession(params.harnessSessionId);
|
|
85220
|
+
}
|
|
85221
|
+
}
|
|
85222
|
+
reconcileAssignedTasks(params) {
|
|
85223
|
+
const { tasks, runtime: runtime4, effectContext: effectContext2, agentMgr, sessionDeps } = params;
|
|
85224
|
+
for (const task of tasks) {
|
|
85225
|
+
const slot = agentMgr.getSlot(task.chatroomId, task.agentConfig.role);
|
|
85226
|
+
const harnessSessionId = slot?.harnessSessionId;
|
|
85227
|
+
if (!shouldDeliverNativeTask(task, {
|
|
85228
|
+
ledger: this.ledger,
|
|
85229
|
+
harnessSessionId
|
|
85230
|
+
})) {
|
|
85231
|
+
continue;
|
|
85232
|
+
}
|
|
85233
|
+
if (!harnessSessionId) {
|
|
85234
|
+
continue;
|
|
85235
|
+
}
|
|
85236
|
+
exports_Runtime.runFork(runtime4)(runNativeInjectionEffect(task, harnessSessionId, {
|
|
85237
|
+
sessionId: sessionDeps.sessionId,
|
|
85238
|
+
backend: sessionDeps.backend,
|
|
85239
|
+
agentMgr: {
|
|
85240
|
+
resumeTurnForSlot: (args2) => exports_Effect.runPromise(agentMgr.resumeTurnForSlot(args2))
|
|
85241
|
+
},
|
|
85242
|
+
convexUrl: sessionDeps.convexUrl
|
|
85243
|
+
}, this.ledger).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[NativeTaskDelivery] delivery failed for ${task.agentConfig.role}@${task.chatroomId}: ${getErrorMessage(err)}`)))));
|
|
85244
|
+
}
|
|
85245
|
+
}
|
|
85246
|
+
}
|
|
85247
|
+
function getNativeTaskDeliveryCoordinator() {
|
|
85248
|
+
coordinator ??= new NativeTaskDeliveryCoordinator;
|
|
85249
|
+
return coordinator;
|
|
85250
|
+
}
|
|
85251
|
+
function notifyNativeSessionLost(params) {
|
|
85252
|
+
getNativeTaskDeliveryCoordinator().onSessionLost(params);
|
|
85253
|
+
}
|
|
85254
|
+
var coordinator;
|
|
85255
|
+
var init_native_task_delivery_coordinator = __esm(() => {
|
|
85256
|
+
init_esm();
|
|
85257
|
+
init_native_task_injector_logic();
|
|
85258
|
+
init_native_task_injector();
|
|
85259
|
+
init_convex_error();
|
|
85260
|
+
});
|
|
85261
|
+
|
|
84921
85262
|
// src/domain/agent-lifecycle/entities/stop-reason.ts
|
|
84922
85263
|
function resolveStopReason(code2, signal) {
|
|
84923
85264
|
if (signal !== null)
|
|
@@ -85089,6 +85430,45 @@ var init_agent_lifecycle = __esm(() => {
|
|
|
85089
85430
|
init_restart_decision();
|
|
85090
85431
|
});
|
|
85091
85432
|
|
|
85433
|
+
// src/domain/agent-lifecycle/policies/cursor-sdk-run-error.ts
|
|
85434
|
+
function isCursorSdkRunErrorInLogs(logLines) {
|
|
85435
|
+
return logLines.some((line) => line.includes(" run-error]"));
|
|
85436
|
+
}
|
|
85437
|
+
function formatCursorSdkRunErrorMessage(logLines) {
|
|
85438
|
+
const line = [...logLines].reverse().find((l) => l.includes(" run-error]"));
|
|
85439
|
+
return line?.trim() ?? "Cursor SDK run failed";
|
|
85440
|
+
}
|
|
85441
|
+
|
|
85442
|
+
// src/commands/machine/daemon-start/native-harness-session-exit.ts
|
|
85443
|
+
function isNativeHarnessSessionDiscardedOnExit(ctx) {
|
|
85444
|
+
const { harness, harnessSessionId, stopReason, recentLogLines, supportsDaemonMemoryResume } = ctx;
|
|
85445
|
+
if (!harness || !harnessSessionId) {
|
|
85446
|
+
return false;
|
|
85447
|
+
}
|
|
85448
|
+
if (isCursorSdkRunErrorInLogs(recentLogLines ?? [])) {
|
|
85449
|
+
return true;
|
|
85450
|
+
}
|
|
85451
|
+
if (!supportsDaemonMemoryResume) {
|
|
85452
|
+
return true;
|
|
85453
|
+
}
|
|
85454
|
+
return !shouldRetainHarnessSessionForReconnect(stopReason);
|
|
85455
|
+
}
|
|
85456
|
+
function notifyNativeHarnessSessionLostOnExit(ctx) {
|
|
85457
|
+
if (!ctx.harness || !ctx.harnessSessionId || !getHarnessCapabilities(ctx.harness).supportsNativeIntegration || !isNativeHarnessSessionDiscardedOnExit(ctx)) {
|
|
85458
|
+
return;
|
|
85459
|
+
}
|
|
85460
|
+
notifyNativeSessionLost({
|
|
85461
|
+
chatroomId: ctx.chatroomId,
|
|
85462
|
+
role: ctx.role,
|
|
85463
|
+
harnessSessionId: ctx.harnessSessionId
|
|
85464
|
+
});
|
|
85465
|
+
}
|
|
85466
|
+
var init_native_harness_session_exit = __esm(() => {
|
|
85467
|
+
init_types();
|
|
85468
|
+
init_native_task_delivery_coordinator();
|
|
85469
|
+
init_agent_lifecycle();
|
|
85470
|
+
});
|
|
85471
|
+
|
|
85092
85472
|
// src/domain/agent-lifecycle/policies/classify-resume-storm-reason.ts
|
|
85093
85473
|
function classifyResumeStormReason(logLines) {
|
|
85094
85474
|
const blob = logLines.join(`
|
|
@@ -85209,15 +85589,6 @@ function appendRecentLogLine(slot, line) {
|
|
|
85209
85589
|
}
|
|
85210
85590
|
var RECENT_LOG_LINE_CAP2 = 100;
|
|
85211
85591
|
|
|
85212
|
-
// src/domain/agent-lifecycle/policies/cursor-sdk-run-error.ts
|
|
85213
|
-
function isCursorSdkRunErrorInLogs(logLines) {
|
|
85214
|
-
return logLines.some((line) => line.includes(" run-error]"));
|
|
85215
|
-
}
|
|
85216
|
-
function formatCursorSdkRunErrorMessage(logLines) {
|
|
85217
|
-
const line = [...logLines].reverse().find((l) => l.includes(" run-error]"));
|
|
85218
|
-
return line?.trim() ?? "Cursor SDK run failed";
|
|
85219
|
-
}
|
|
85220
|
-
|
|
85221
85592
|
// src/domain/agent-lifecycle/use-cases/handle-turn-completed.ts
|
|
85222
85593
|
async function handleTurnCompleted(deps, input, slot) {
|
|
85223
85594
|
if (slot?.resumeInFlight) {
|
|
@@ -85278,31 +85649,6 @@ var init_handle_turn_completed = __esm(() => {
|
|
|
85278
85649
|
init_terminal_provider_error();
|
|
85279
85650
|
});
|
|
85280
85651
|
|
|
85281
|
-
// src/infrastructure/services/remote-agents/spawn-prompt.ts
|
|
85282
|
-
function createSpawnPrompt(raw, opts) {
|
|
85283
|
-
if (opts?.nativeBootstrap) {
|
|
85284
|
-
return NATIVE_BOOTSTRAP_PROMPT;
|
|
85285
|
-
}
|
|
85286
|
-
const trimmed = raw?.trim();
|
|
85287
|
-
return trimmed && trimmed.length > 0 ? trimmed : DEFAULT_TRIGGER_PROMPT;
|
|
85288
|
-
}
|
|
85289
|
-
var DEFAULT_TRIGGER_PROMPT = "Please read your system prompt carefully and follow the Getting Started instructions.", NATIVE_BOOTSTRAP_PROMPT = "Focus on your role responsibilities. Complete each task via handoff.";
|
|
85290
|
-
|
|
85291
|
-
// src/domain/native-integration/spawn-policy.ts
|
|
85292
|
-
function shouldDeferInitialTurn(harness) {
|
|
85293
|
-
return isNativeHarness(harness);
|
|
85294
|
-
}
|
|
85295
|
-
function resolveNativeSpawnPolicy(harness, initMessage) {
|
|
85296
|
-
const deferInitialTurn = shouldDeferInitialTurn(harness);
|
|
85297
|
-
return {
|
|
85298
|
-
deferInitialTurn,
|
|
85299
|
-
prompt: createSpawnPrompt(initMessage, { nativeBootstrap: deferInitialTurn })
|
|
85300
|
-
};
|
|
85301
|
-
}
|
|
85302
|
-
var init_spawn_policy = __esm(() => {
|
|
85303
|
-
init_types();
|
|
85304
|
-
});
|
|
85305
|
-
|
|
85306
85652
|
// src/infrastructure/deps/process.ts
|
|
85307
85653
|
function isProcessAlive(kill, pid) {
|
|
85308
85654
|
try {
|
|
@@ -85921,6 +86267,15 @@ class AgentProcessManager {
|
|
|
85921
86267
|
}
|
|
85922
86268
|
const stopReason = resolveStopReason(opts.code, opts.signal);
|
|
85923
86269
|
const ctx = this.captureExitContext(slot, opts, stopReason);
|
|
86270
|
+
notifyNativeHarnessSessionLostOnExit({
|
|
86271
|
+
chatroomId: opts.chatroomId,
|
|
86272
|
+
role: opts.role,
|
|
86273
|
+
harness: ctx.harness,
|
|
86274
|
+
harnessSessionId: ctx.harnessSessionId,
|
|
86275
|
+
stopReason: ctx.stopReason,
|
|
86276
|
+
recentLogLines: ctx.recentLogLines,
|
|
86277
|
+
supportsDaemonMemoryResume: Boolean(ctx.harness && this.deps.agentServices.get(ctx.harness)?.resumeFromDaemonMemory)
|
|
86278
|
+
});
|
|
85924
86279
|
await this.preserveHarnessSessionOnExit(key, slot, ctx);
|
|
85925
86280
|
const lifecyclePromise = this.lifecycle.runPromise(exports_Effect.gen(function* () {
|
|
85926
86281
|
const svc = yield* AgentLifecycleService;
|
|
@@ -86021,11 +86376,11 @@ class AgentProcessManager {
|
|
|
86021
86376
|
}
|
|
86022
86377
|
this.maybeRestartAgent(opts, ctx);
|
|
86023
86378
|
}
|
|
86024
|
-
clearHarnessSessionAfterRunError(key,
|
|
86379
|
+
clearHarnessSessionAfterRunError(key, recentLogLines) {
|
|
86025
86380
|
if (!isCursorSdkRunErrorInLogs(recentLogLines)) {
|
|
86026
86381
|
return false;
|
|
86027
86382
|
}
|
|
86028
|
-
console.log(`[AgentProcessManager] cursor-sdk run-error — cold restarting ${
|
|
86383
|
+
console.log(`[AgentProcessManager] cursor-sdk run-error — cold restarting ${key}: ${formatCursorSdkRunErrorMessage(recentLogLines)}`);
|
|
86029
86384
|
this.clearLastHarnessSession(key);
|
|
86030
86385
|
return true;
|
|
86031
86386
|
}
|
|
@@ -86041,7 +86396,7 @@ class AgentProcessManager {
|
|
|
86041
86396
|
this.handlePermanentFailureForRestart(opts, recentLogLines, ctx.terminalProviderFailureHandled);
|
|
86042
86397
|
return;
|
|
86043
86398
|
}
|
|
86044
|
-
const coldRestartAfterRunError = this.clearHarnessSessionAfterRunError(key,
|
|
86399
|
+
const coldRestartAfterRunError = this.clearHarnessSessionAfterRunError(key, logs);
|
|
86045
86400
|
this.ensureRunning({
|
|
86046
86401
|
chatroomId: opts.chatroomId,
|
|
86047
86402
|
role: opts.role,
|
|
@@ -86050,6 +86405,10 @@ class AgentProcessManager {
|
|
|
86050
86405
|
workingDir,
|
|
86051
86406
|
reason: "platform.crash_recovery",
|
|
86052
86407
|
wantResume: coldRestartAfterRunError ? false : ctx.wantResume ?? true
|
|
86408
|
+
}).then((result) => {
|
|
86409
|
+
if (!result.success) {
|
|
86410
|
+
console.log(`[AgentProcessManager] ⚠️ Agent restart did not complete for ${opts.role}: ${result.error ?? "unknown"}`);
|
|
86411
|
+
}
|
|
86053
86412
|
}).catch((err) => {
|
|
86054
86413
|
console.log(` ⚠️ Failed to restart agent: ${err.message}`);
|
|
86055
86414
|
this.emitStartFailedEvent(opts.role, opts.chatroomId, err.message);
|
|
@@ -86739,6 +87098,7 @@ var init_agent_process_manager = __esm(() => {
|
|
|
86739
87098
|
init_turn_completed_backend();
|
|
86740
87099
|
init_api3();
|
|
86741
87100
|
init_orphan_tracker();
|
|
87101
|
+
init_native_harness_session_exit();
|
|
86742
87102
|
init_agent_lifecycle();
|
|
86743
87103
|
init_abort_resume_storm();
|
|
86744
87104
|
init_classify_resume_storm_reason();
|
|
@@ -86832,7 +87192,7 @@ var init_harness_spawning = __esm(() => {
|
|
|
86832
87192
|
});
|
|
86833
87193
|
|
|
86834
87194
|
// src/commands/machine/daemon-start/handlers/daemon-startup-log.ts
|
|
86835
|
-
var logStartupEffect = (
|
|
87195
|
+
var logStartupEffect = (cachedModels) => exports_Effect.gen(function* () {
|
|
86836
87196
|
const session2 = yield* DaemonSessionService;
|
|
86837
87197
|
yield* exports_Effect.sync(() => {
|
|
86838
87198
|
console.log(`[${formatTimestamp()}] \uD83D\uDE80 Daemon started`);
|
|
@@ -86840,7 +87200,7 @@ var logStartupEffect = (availableModels) => exports_Effect.gen(function* () {
|
|
|
86840
87200
|
console.log(` Machine ID: ${session2.machineId}`);
|
|
86841
87201
|
console.log(` Hostname: ${session2.config?.hostname ?? "unknown"}`);
|
|
86842
87202
|
console.log(` Available harnesses: ${session2.config?.availableHarnesses.join(", ") || "none"}`);
|
|
86843
|
-
console.log(` Available models: ${Object.keys(
|
|
87203
|
+
console.log(` Available models: ${Object.keys(cachedModels).length > 0 ? `${Object.values(cachedModels).flat().length} cached across ${Object.keys(cachedModels).join(", ")} (refreshing in background)` : "discovering in background"}`);
|
|
86844
87204
|
console.log(` PID: ${process.pid}`);
|
|
86845
87205
|
});
|
|
86846
87206
|
});
|
|
@@ -86852,6 +87212,23 @@ var init_daemon_startup_log = __esm(() => {
|
|
|
86852
87212
|
|
|
86853
87213
|
// src/commands/machine/daemon-start/init.ts
|
|
86854
87214
|
import { stat as stat3 } from "node:fs/promises";
|
|
87215
|
+
async function discoverModelsForHarness(harness, service3) {
|
|
87216
|
+
const installed2 = await service3.isInstalled();
|
|
87217
|
+
if (!installed2) {
|
|
87218
|
+
return { harness, models: [], installed: false };
|
|
87219
|
+
}
|
|
87220
|
+
try {
|
|
87221
|
+
const models = await service3.listModels();
|
|
87222
|
+
return { harness, models, installed: true };
|
|
87223
|
+
} catch (reason) {
|
|
87224
|
+
console.warn(JSON.stringify({
|
|
87225
|
+
event: "discover-models-error",
|
|
87226
|
+
harness,
|
|
87227
|
+
reason: getErrorMessage(reason)
|
|
87228
|
+
}));
|
|
87229
|
+
return { harness, models: [], installed: true };
|
|
87230
|
+
}
|
|
87231
|
+
}
|
|
86855
87232
|
async function discoverModels(agentServices) {
|
|
86856
87233
|
return exports_Effect.runPromise(discoverModelsEffect(agentServices));
|
|
86857
87234
|
}
|
|
@@ -86886,6 +87263,51 @@ function createDefaultDeps18() {
|
|
|
86886
87263
|
agentProcessManager: null
|
|
86887
87264
|
};
|
|
86888
87265
|
}
|
|
87266
|
+
function assembleDaemonSessionInit(args2) {
|
|
87267
|
+
const {
|
|
87268
|
+
client: client4,
|
|
87269
|
+
typedSessionId,
|
|
87270
|
+
machineId,
|
|
87271
|
+
config: config3,
|
|
87272
|
+
convexUrl,
|
|
87273
|
+
agentServices,
|
|
87274
|
+
cachedModels,
|
|
87275
|
+
deps
|
|
87276
|
+
} = args2;
|
|
87277
|
+
deps.backend.mutation = (endpoint, args3) => client4.mutation(endpoint, args3);
|
|
87278
|
+
deps.backend.query = (endpoint, args3) => client4.query(endpoint, args3);
|
|
87279
|
+
deps.agentProcessManager = new AgentProcessManager({
|
|
87280
|
+
agentServices,
|
|
87281
|
+
backend: deps.backend,
|
|
87282
|
+
sessionId: typedSessionId,
|
|
87283
|
+
machineId,
|
|
87284
|
+
processes: deps.processes,
|
|
87285
|
+
clock: deps.clock,
|
|
87286
|
+
fs: deps.fs,
|
|
87287
|
+
persistence: deps.machine,
|
|
87288
|
+
spawning: deps.spawning,
|
|
87289
|
+
crashLoop: new CrashLoopTracker,
|
|
87290
|
+
convexUrl
|
|
87291
|
+
});
|
|
87292
|
+
return {
|
|
87293
|
+
client: client4,
|
|
87294
|
+
sessionId: typedSessionId,
|
|
87295
|
+
machineId,
|
|
87296
|
+
config: config3,
|
|
87297
|
+
convexUrl,
|
|
87298
|
+
backend: deps.backend,
|
|
87299
|
+
fs: deps.fs,
|
|
87300
|
+
machine: deps.machine,
|
|
87301
|
+
spawning: deps.spawning,
|
|
87302
|
+
agentProcessManager: deps.agentProcessManager,
|
|
87303
|
+
events: new DaemonEventBus,
|
|
87304
|
+
agentServices,
|
|
87305
|
+
lastPushedGitState: new Map,
|
|
87306
|
+
lastPushedModels: Object.keys(cachedModels).length > 0 ? cachedModels : null,
|
|
87307
|
+
lastPushedHarnessFingerprint: harnessCapabilitiesFingerprint(config3.availableHarnesses, config3.harnessVersions),
|
|
87308
|
+
logger: console
|
|
87309
|
+
};
|
|
87310
|
+
}
|
|
86889
87311
|
|
|
86890
87312
|
class NetworkRetryError {
|
|
86891
87313
|
cause;
|
|
@@ -86900,21 +87322,11 @@ async function initDaemon() {
|
|
|
86900
87322
|
return exports_Effect.runPromise(initDaemonEffect);
|
|
86901
87323
|
}
|
|
86902
87324
|
var discoverModelsEffect = (agentServices) => exports_Effect.gen(function* () {
|
|
86903
|
-
const discoverOne = ([harness, service3]) => exports_Effect.promise(() => service3
|
|
86904
|
-
if (!
|
|
86905
|
-
return
|
|
87325
|
+
const discoverOne = ([harness, service3]) => exports_Effect.promise(() => discoverModelsForHarness(harness, service3)).pipe(exports_Effect.map((result) => {
|
|
87326
|
+
if (!result.installed) {
|
|
87327
|
+
return;
|
|
86906
87328
|
}
|
|
86907
|
-
return
|
|
86908
|
-
try: () => service3.listModels(),
|
|
86909
|
-
catch: (reason) => reason
|
|
86910
|
-
}).pipe(exports_Effect.map((models) => ({ harness, models })), exports_Effect.catchAll((reason) => {
|
|
86911
|
-
console.warn(JSON.stringify({
|
|
86912
|
-
event: "discover-models-error",
|
|
86913
|
-
harness,
|
|
86914
|
-
reason: getErrorMessage(reason)
|
|
86915
|
-
}));
|
|
86916
|
-
return exports_Effect.succeed({ harness, models: [] });
|
|
86917
|
-
}));
|
|
87329
|
+
return { harness: result.harness, models: result.models };
|
|
86918
87330
|
}));
|
|
86919
87331
|
const results = yield* exports_Effect.forEach(Array.from(agentServices.entries()), discoverOne, {
|
|
86920
87332
|
concurrency: "unbounded"
|
|
@@ -87011,21 +87423,28 @@ Run: chatroom auth login`);
|
|
|
87011
87423
|
return yield* exports_Effect.die(new Error("Machine config missing after ensureMachineRegistered — this should not happen"));
|
|
87012
87424
|
}
|
|
87013
87425
|
return config3;
|
|
87014
|
-
}),
|
|
87426
|
+
}), registerMachineEffect = (client4, sessionId, config3) => exports_Effect.catchAll(exports_Effect.tryPromise(() => client4.mutation(api.machines.register, {
|
|
87427
|
+
sessionId,
|
|
87428
|
+
machineId: config3.machineId,
|
|
87429
|
+
hostname: config3.hostname,
|
|
87430
|
+
os: config3.os,
|
|
87431
|
+
availableHarnesses: config3.availableHarnesses,
|
|
87432
|
+
harnessVersions: config3.harnessVersions
|
|
87433
|
+
})), (error) => exports_Effect.sync(() => {
|
|
87434
|
+
console.warn(`⚠️ Machine registration update failed: ${getErrorMessage(error)}`);
|
|
87435
|
+
})), fetchCachedMachineModelsEffect = (client4, sessionId, machineId) => exports_Effect.tryPromise({
|
|
87436
|
+
try: () => client4.query(api.machines.getMachineModels, { sessionId, machineId }),
|
|
87437
|
+
catch: (e) => e
|
|
87438
|
+
}).pipe(exports_Effect.map((result) => result?.availableModels ?? {}), exports_Effect.catchAll(() => exports_Effect.succeed({}))), connectOnceEffect = (client4, sessionId, convexUrl) => exports_Effect.gen(function* () {
|
|
87439
|
+
const typedSessionId = yield* validateSessionEffect(client4, sessionId, convexUrl);
|
|
87440
|
+
const config3 = yield* setupMachineEffect();
|
|
87015
87441
|
const { machineId } = config3;
|
|
87016
|
-
|
|
87017
|
-
|
|
87018
|
-
|
|
87019
|
-
|
|
87020
|
-
|
|
87021
|
-
|
|
87022
|
-
availableHarnesses: config3.availableHarnesses,
|
|
87023
|
-
harnessVersions: config3.harnessVersions,
|
|
87024
|
-
availableModels
|
|
87025
|
-
})), (error) => exports_Effect.sync(() => {
|
|
87026
|
-
console.warn(`⚠️ Machine registration update failed: ${getErrorMessage(error)}`);
|
|
87027
|
-
}));
|
|
87028
|
-
return availableModels;
|
|
87442
|
+
initHarnessRegistry();
|
|
87443
|
+
const agentServices = new Map(getAllHarnesses().map((s) => [s.id, s]));
|
|
87444
|
+
yield* registerMachineEffect(client4, typedSessionId, config3);
|
|
87445
|
+
const cachedModels = yield* fetchCachedMachineModelsEffect(client4, typedSessionId, machineId);
|
|
87446
|
+
yield* connectDaemonEffect(client4, typedSessionId, machineId);
|
|
87447
|
+
return { typedSessionId, config: config3, machineId, agentServices, cachedModels };
|
|
87029
87448
|
}), connectDaemonEffect = (client4, sessionId, machineId) => exports_Effect.tryPromise({
|
|
87030
87449
|
try: () => client4.mutation(api.machines.updateDaemonStatus, {
|
|
87031
87450
|
sessionId,
|
|
@@ -87070,14 +87489,7 @@ Run: chatroom auth login`);
|
|
|
87070
87489
|
const attemptRef = yield* exports_Ref.make(0);
|
|
87071
87490
|
const connectOnce = exports_Effect.gen(function* () {
|
|
87072
87491
|
yield* exports_Ref.update(attemptRef, (n) => n + 1);
|
|
87073
|
-
|
|
87074
|
-
const config3 = yield* setupMachineEffect();
|
|
87075
|
-
const { machineId } = config3;
|
|
87076
|
-
initHarnessRegistry();
|
|
87077
|
-
const agentServices = new Map(getAllHarnesses().map((s) => [s.id, s]));
|
|
87078
|
-
const availableModels = yield* registerCapabilitiesEffect(client4, typedSessionId, config3, agentServices);
|
|
87079
|
-
yield* connectDaemonEffect(client4, typedSessionId, machineId);
|
|
87080
|
-
return { typedSessionId, config: config3, machineId, agentServices, availableModels };
|
|
87492
|
+
return yield* connectOnceEffect(client4, sessionId, convexUrl);
|
|
87081
87493
|
}).pipe(exports_Effect.catchAll((error) => exports_Effect.flatMap(exports_Ref.get(attemptRef), (currentAttempt) => isNetworkError(error) ? exports_Effect.fail(new NetworkRetryError(error, currentAttempt)) : exports_Effect.die(error))));
|
|
87082
87494
|
const retrySchedule2 = exports_Schedule.fixed(exports_Duration.millis(CONNECTION_RETRY_INTERVAL_MS));
|
|
87083
87495
|
const connectWithRetry = connectOnce.pipe(exports_Effect.tapError((retryErr) => exports_Effect.gen(function* () {
|
|
@@ -87119,7 +87531,11 @@ var init_init2 = __esm(() => {
|
|
|
87119
87531
|
init_spawn_env();
|
|
87120
87532
|
AUTH_WAIT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
87121
87533
|
initDaemonEffect = exports_Effect.gen(function* () {
|
|
87122
|
-
|
|
87534
|
+
const lockAcquired = yield* exports_Effect.tryPromise({
|
|
87535
|
+
try: () => acquireLockWithRetry(),
|
|
87536
|
+
catch: (e) => e
|
|
87537
|
+
});
|
|
87538
|
+
if (!lockAcquired) {
|
|
87123
87539
|
return yield* exports_Effect.sync(() => {
|
|
87124
87540
|
process.exit(1);
|
|
87125
87541
|
});
|
|
@@ -87142,44 +87558,19 @@ var init_init2 = __esm(() => {
|
|
|
87142
87558
|
try: () => getConvexClient(),
|
|
87143
87559
|
catch: (e) => e
|
|
87144
87560
|
});
|
|
87145
|
-
const { typedSessionId, config: config3, machineId, agentServices,
|
|
87146
|
-
const
|
|
87147
|
-
deps.backend.mutation = (endpoint, args2) => client4.mutation(endpoint, args2);
|
|
87148
|
-
deps.backend.query = (endpoint, args2) => client4.query(endpoint, args2);
|
|
87149
|
-
deps.agentProcessManager = new AgentProcessManager({
|
|
87150
|
-
agentServices,
|
|
87151
|
-
backend: deps.backend,
|
|
87152
|
-
sessionId: typedSessionId,
|
|
87153
|
-
machineId,
|
|
87154
|
-
processes: deps.processes,
|
|
87155
|
-
clock: deps.clock,
|
|
87156
|
-
fs: deps.fs,
|
|
87157
|
-
persistence: deps.machine,
|
|
87158
|
-
spawning: deps.spawning,
|
|
87159
|
-
crashLoop: new CrashLoopTracker,
|
|
87160
|
-
convexUrl
|
|
87161
|
-
});
|
|
87162
|
-
const events = new DaemonEventBus;
|
|
87163
|
-
const init2 = {
|
|
87561
|
+
const { typedSessionId, config: config3, machineId, agentServices, cachedModels } = yield* connectWithRetryEffect(client4, sessionId, convexUrl);
|
|
87562
|
+
const init2 = assembleDaemonSessionInit({
|
|
87164
87563
|
client: client4,
|
|
87165
|
-
|
|
87564
|
+
typedSessionId,
|
|
87166
87565
|
machineId,
|
|
87167
87566
|
config: config3,
|
|
87168
87567
|
convexUrl,
|
|
87169
|
-
backend: deps.backend,
|
|
87170
|
-
fs: deps.fs,
|
|
87171
|
-
machine: deps.machine,
|
|
87172
|
-
spawning: deps.spawning,
|
|
87173
|
-
agentProcessManager: deps.agentProcessManager,
|
|
87174
|
-
events,
|
|
87175
87568
|
agentServices,
|
|
87176
|
-
|
|
87177
|
-
|
|
87178
|
-
|
|
87179
|
-
logger: console
|
|
87180
|
-
};
|
|
87569
|
+
cachedModels,
|
|
87570
|
+
deps: createDefaultDeps18()
|
|
87571
|
+
});
|
|
87181
87572
|
yield* registerEventListenersEffect().pipe(exports_Effect.provide(daemonSessionToLayers(init2)));
|
|
87182
|
-
yield* logStartupEffect(
|
|
87573
|
+
yield* logStartupEffect(cachedModels).pipe(exports_Effect.provide(daemonSessionToLayers(init2)));
|
|
87183
87574
|
yield* recoverStateEffect(init2);
|
|
87184
87575
|
return init2;
|
|
87185
87576
|
});
|
|
@@ -87229,7 +87620,70 @@ function logRefreshOutcome(diff8, totalCount) {
|
|
|
87229
87620
|
const summary5 = totalCount > 0 ? `${totalCount} models` : "none discovered";
|
|
87230
87621
|
console.log(`[${formatTimestamp()}] \uD83D\uDD04 Model refresh pushed: ${summary5}`);
|
|
87231
87622
|
}
|
|
87232
|
-
|
|
87623
|
+
function logPushOutcome(modelDiff, totalCount, options) {
|
|
87624
|
+
if (options?.logPrefix) {
|
|
87625
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDD04 ${options.logPrefix}: ${totalCount > 0 ? `${totalCount} models` : "none discovered"}`);
|
|
87626
|
+
return;
|
|
87627
|
+
}
|
|
87628
|
+
logRefreshOutcome(modelDiff, totalCount);
|
|
87629
|
+
}
|
|
87630
|
+
var pushModelsSnapshotMutationEffect = (models, modelDiff, nextHarnessFingerprint, ctxConfig, options) => exports_Effect.gen(function* () {
|
|
87631
|
+
const session2 = yield* DaemonSessionService;
|
|
87632
|
+
yield* exports_Effect.tryPromise({
|
|
87633
|
+
try: async () => session2.backend.mutation(api.machines.refreshCapabilities, {
|
|
87634
|
+
sessionId: session2.sessionId,
|
|
87635
|
+
machineId: session2.machineId,
|
|
87636
|
+
availableHarnesses: ctxConfig.availableHarnesses,
|
|
87637
|
+
harnessVersions: ctxConfig.harnessVersions,
|
|
87638
|
+
availableModels: models
|
|
87639
|
+
}),
|
|
87640
|
+
catch: (e) => e
|
|
87641
|
+
});
|
|
87642
|
+
const totalCount = Object.values(models).flat().length;
|
|
87643
|
+
logPushOutcome(modelDiff, totalCount, options);
|
|
87644
|
+
return {
|
|
87645
|
+
kind: "pushed",
|
|
87646
|
+
snapshot: {
|
|
87647
|
+
lastPushedModels: models,
|
|
87648
|
+
lastPushedHarnessFingerprint: nextHarnessFingerprint
|
|
87649
|
+
}
|
|
87650
|
+
};
|
|
87651
|
+
}), pushModelsSnapshotIfChangedEffect = (models, options) => exports_Effect.gen(function* () {
|
|
87652
|
+
const session2 = yield* DaemonSessionService;
|
|
87653
|
+
const mutable = yield* DaemonMutableStateService;
|
|
87654
|
+
if (!session2.config) {
|
|
87655
|
+
return { kind: "skipped_no_changes" };
|
|
87656
|
+
}
|
|
87657
|
+
const lastPushedModels = yield* exports_Ref.get(mutable.lastPushedModels);
|
|
87658
|
+
const lastPushedHarnessFingerprint = yield* exports_Ref.get(mutable.lastPushedHarnessFingerprint);
|
|
87659
|
+
const modelDiff = diffModels(lastPushedModels, models);
|
|
87660
|
+
const nextHarnessFingerprint = harnessCapabilitiesFingerprint(session2.config.availableHarnesses, session2.config.harnessVersions);
|
|
87661
|
+
if (!modelDiff.hasChanges && !harnessFingerprintChanged(lastPushedHarnessFingerprint, nextHarnessFingerprint)) {
|
|
87662
|
+
return { kind: "skipped_no_changes" };
|
|
87663
|
+
}
|
|
87664
|
+
return yield* pushModelsSnapshotMutationEffect(models, modelDiff, nextHarnessFingerprint, session2.config, options);
|
|
87665
|
+
}).pipe(exports_Effect.catchAll((error) => exports_Effect.sync(() => {
|
|
87666
|
+
const message = getErrorMessage(error);
|
|
87667
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Model refresh failed: ${message}`);
|
|
87668
|
+
return { kind: "failed", message };
|
|
87669
|
+
}))), refreshModelsEffect, discoverAndPushHarnessModelsEffect = (harness, service3) => exports_Effect.gen(function* () {
|
|
87670
|
+
const mutable = yield* DaemonMutableStateService;
|
|
87671
|
+
const result = yield* exports_Effect.promise(() => discoverModelsForHarness(harness, service3));
|
|
87672
|
+
const current = (yield* exports_Ref.get(mutable.lastPushedModels)) ?? {};
|
|
87673
|
+
const next4 = { ...current };
|
|
87674
|
+
if (result.installed) {
|
|
87675
|
+
next4[harness] = result.models;
|
|
87676
|
+
} else {
|
|
87677
|
+
delete next4[harness];
|
|
87678
|
+
}
|
|
87679
|
+
const pushOutcome = yield* pushModelsSnapshotIfChangedEffect(next4, {
|
|
87680
|
+
logPrefix: `${harness} models updated`
|
|
87681
|
+
});
|
|
87682
|
+
if (pushOutcome.kind === "pushed") {
|
|
87683
|
+
yield* exports_Ref.set(mutable.lastPushedModels, pushOutcome.snapshot.lastPushedModels);
|
|
87684
|
+
yield* exports_Ref.set(mutable.lastPushedHarnessFingerprint, pushOutcome.snapshot.lastPushedHarnessFingerprint);
|
|
87685
|
+
}
|
|
87686
|
+
}), startBackgroundModelDiscoveryEffect;
|
|
87233
87687
|
var init_models_refresh = __esm(() => {
|
|
87234
87688
|
init_esm();
|
|
87235
87689
|
init_daemon_services();
|
|
@@ -87244,8 +87698,6 @@ var init_models_refresh = __esm(() => {
|
|
|
87244
87698
|
return { kind: "noop" };
|
|
87245
87699
|
}
|
|
87246
87700
|
const ctxConfig = session2.config;
|
|
87247
|
-
const lastPushedModels = yield* exports_Ref.get(mutable.lastPushedModels);
|
|
87248
|
-
const lastPushedHarnessFingerprint = yield* exports_Ref.get(mutable.lastPushedHarnessFingerprint);
|
|
87249
87701
|
const outcome = yield* exports_Effect.gen(function* () {
|
|
87250
87702
|
const models = yield* exports_Effect.tryPromise({
|
|
87251
87703
|
try: async () => discoverModels(session2.agentServices),
|
|
@@ -87257,31 +87709,7 @@ var init_models_refresh = __esm(() => {
|
|
|
87257
87709
|
});
|
|
87258
87710
|
ctxConfig.availableHarnesses = freshConfig.availableHarnesses;
|
|
87259
87711
|
ctxConfig.harnessVersions = freshConfig.harnessVersions;
|
|
87260
|
-
|
|
87261
|
-
const nextHarnessFingerprint = harnessCapabilitiesFingerprint(ctxConfig.availableHarnesses, ctxConfig.harnessVersions);
|
|
87262
|
-
const fingerprintChanged = harnessFingerprintChanged(lastPushedHarnessFingerprint, nextHarnessFingerprint);
|
|
87263
|
-
if (!modelDiff.hasChanges && !fingerprintChanged) {
|
|
87264
|
-
return { kind: "skipped_no_changes" };
|
|
87265
|
-
}
|
|
87266
|
-
const totalCount = Object.values(models).flat().length;
|
|
87267
|
-
yield* exports_Effect.tryPromise({
|
|
87268
|
-
try: async () => session2.backend.mutation(api.machines.refreshCapabilities, {
|
|
87269
|
-
sessionId: session2.sessionId,
|
|
87270
|
-
machineId: session2.machineId,
|
|
87271
|
-
availableHarnesses: ctxConfig.availableHarnesses,
|
|
87272
|
-
harnessVersions: ctxConfig.harnessVersions,
|
|
87273
|
-
availableModels: models
|
|
87274
|
-
}),
|
|
87275
|
-
catch: (e) => e
|
|
87276
|
-
});
|
|
87277
|
-
logRefreshOutcome(modelDiff, totalCount);
|
|
87278
|
-
return {
|
|
87279
|
-
kind: "pushed",
|
|
87280
|
-
snapshot: {
|
|
87281
|
-
lastPushedModels: models,
|
|
87282
|
-
lastPushedHarnessFingerprint: nextHarnessFingerprint
|
|
87283
|
-
}
|
|
87284
|
-
};
|
|
87712
|
+
return yield* pushModelsSnapshotIfChangedEffect(models);
|
|
87285
87713
|
}).pipe(exports_Effect.catchAll((error) => exports_Effect.sync(() => {
|
|
87286
87714
|
const message = getErrorMessage(error);
|
|
87287
87715
|
console.warn(`[${formatTimestamp()}] ⚠️ Model refresh failed: ${message}`);
|
|
@@ -87290,9 +87718,22 @@ var init_models_refresh = __esm(() => {
|
|
|
87290
87718
|
if (outcome.kind === "pushed") {
|
|
87291
87719
|
yield* exports_Ref.set(mutable.lastPushedModels, outcome.snapshot.lastPushedModels);
|
|
87292
87720
|
yield* exports_Ref.set(mutable.lastPushedHarnessFingerprint, outcome.snapshot.lastPushedHarnessFingerprint);
|
|
87721
|
+
return {
|
|
87722
|
+
kind: "pushed",
|
|
87723
|
+
snapshot: outcome.snapshot
|
|
87724
|
+
};
|
|
87725
|
+
}
|
|
87726
|
+
if (outcome.kind === "skipped_no_changes") {
|
|
87727
|
+
return { kind: "skipped_no_changes" };
|
|
87293
87728
|
}
|
|
87294
87729
|
return outcome;
|
|
87295
87730
|
});
|
|
87731
|
+
startBackgroundModelDiscoveryEffect = exports_Effect.gen(function* () {
|
|
87732
|
+
const session2 = yield* DaemonSessionService;
|
|
87733
|
+
if (!session2.config)
|
|
87734
|
+
return;
|
|
87735
|
+
yield* exports_Effect.forEach(Array.from(session2.agentServices.entries()), ([harness, service3]) => discoverAndPushHarnessModelsEffect(harness, service3), { concurrency: "unbounded" });
|
|
87736
|
+
});
|
|
87296
87737
|
});
|
|
87297
87738
|
|
|
87298
87739
|
// src/commands/machine/daemon-start/observed-sync.ts
|
|
@@ -87489,225 +87930,6 @@ var init_observed_sync = __esm(() => {
|
|
|
87489
87930
|
init_convex_error();
|
|
87490
87931
|
});
|
|
87491
87932
|
|
|
87492
|
-
// ../../services/backend/src/domain/handoff/parse-compress-context.ts
|
|
87493
|
-
function findSectionIndex(content, headings) {
|
|
87494
|
-
const indices = headings.map((heading) => content.indexOf(heading)).filter((idx) => idx !== -1);
|
|
87495
|
-
return indices.length === 0 ? -1 : Math.min(...indices);
|
|
87496
|
-
}
|
|
87497
|
-
function normalizeMode(raw) {
|
|
87498
|
-
const value = raw.toLowerCase();
|
|
87499
|
-
if (value === "reset")
|
|
87500
|
-
return "new_session";
|
|
87501
|
-
if (value === "none")
|
|
87502
|
-
return value;
|
|
87503
|
-
return DEFAULT_MODE;
|
|
87504
|
-
}
|
|
87505
|
-
function extractSectionBody(content, sectionIdx) {
|
|
87506
|
-
const matchedHeading = SECTION_HEADINGS.find((h) => content.indexOf(h, sectionIdx) === sectionIdx) ?? SECTION_HEADINGS[0];
|
|
87507
|
-
const afterSection = content.slice(sectionIdx);
|
|
87508
|
-
const nextHeading = afterSection.slice(matchedHeading.length).search(/\n## /);
|
|
87509
|
-
return nextHeading === -1 ? afterSection : afterSection.slice(0, matchedHeading.length + nextHeading);
|
|
87510
|
-
}
|
|
87511
|
-
function parseCompressContext(handoffContent) {
|
|
87512
|
-
const sectionIdx = findSectionIndex(handoffContent, SECTION_HEADINGS);
|
|
87513
|
-
if (sectionIdx === -1)
|
|
87514
|
-
return DEFAULT_MODE;
|
|
87515
|
-
const match17 = extractSectionBody(handoffContent, sectionIdx).match(DATA_TAG);
|
|
87516
|
-
if (!match17)
|
|
87517
|
-
return DEFAULT_MODE;
|
|
87518
|
-
return normalizeMode(match17[1]);
|
|
87519
|
-
}
|
|
87520
|
-
function compressContextToWantResume(mode) {
|
|
87521
|
-
return mode === "none";
|
|
87522
|
-
}
|
|
87523
|
-
var SECTION_HEADINGS, DATA_TAG, DEFAULT_MODE = "new_session";
|
|
87524
|
-
var init_parse_compress_context = __esm(() => {
|
|
87525
|
-
SECTION_HEADINGS = ["## Session Management", "## Restart new context"];
|
|
87526
|
-
DATA_TAG = /\/\/\s*data:agent\.compress_context=(new_session|reset|none)\b/i;
|
|
87527
|
-
});
|
|
87528
|
-
|
|
87529
|
-
// src/domain/native-integration/predicates.ts
|
|
87530
|
-
function isNativePendingAliveRunning(task) {
|
|
87531
|
-
const { agentConfig, status: status3 } = task;
|
|
87532
|
-
return isNativeHarness(agentConfig.agentHarness) && status3 === "pending" && agentConfig.spawnedAgentPid != null && agentConfig.desiredState === "running";
|
|
87533
|
-
}
|
|
87534
|
-
function isNativeInjectableAliveRunning(task) {
|
|
87535
|
-
const { agentConfig, status: status3 } = task;
|
|
87536
|
-
if (!isNativeHarness(agentConfig.agentHarness))
|
|
87537
|
-
return false;
|
|
87538
|
-
if (agentConfig.spawnedAgentPid == null || agentConfig.desiredState !== "running") {
|
|
87539
|
-
return false;
|
|
87540
|
-
}
|
|
87541
|
-
if (status3 === "pending")
|
|
87542
|
-
return true;
|
|
87543
|
-
if (status3 === "acknowledged") {
|
|
87544
|
-
const assignedTo = task.assignedTo?.toLowerCase();
|
|
87545
|
-
return assignedTo === agentConfig.role.toLowerCase();
|
|
87546
|
-
}
|
|
87547
|
-
return false;
|
|
87548
|
-
}
|
|
87549
|
-
function isInjectableNativeAction(action) {
|
|
87550
|
-
if (action == null)
|
|
87551
|
-
return true;
|
|
87552
|
-
return action === NATIVE_WAITING_ACTION;
|
|
87553
|
-
}
|
|
87554
|
-
function isNativeIdleAfterTaskComplete(participant) {
|
|
87555
|
-
return participant.lastSeenAction === NATIVE_TASK_INJECTED_ACTION && participant.lastStatus === "task.completed";
|
|
87556
|
-
}
|
|
87557
|
-
function isNativeAcknowledgedInjectionRetry(task) {
|
|
87558
|
-
if (task.status !== "acknowledged")
|
|
87559
|
-
return false;
|
|
87560
|
-
const assignedTo = task.assignedTo?.toLowerCase();
|
|
87561
|
-
if (assignedTo !== task.agentConfig.role.toLowerCase())
|
|
87562
|
-
return false;
|
|
87563
|
-
return task.participant?.lastSeenAction === NATIVE_TASK_INJECTED_ACTION;
|
|
87564
|
-
}
|
|
87565
|
-
function isStaleCliGetNextTaskWaiting(task) {
|
|
87566
|
-
const lastSeenAt = task.participant?.lastSeenAt ?? 0;
|
|
87567
|
-
return task.participant?.lastSeenAction === "get-next-task:started" && task.createdAt > lastSeenAt;
|
|
87568
|
-
}
|
|
87569
|
-
function isCliIdleNotListening(task, now, thresholdMs) {
|
|
87570
|
-
const lastSeenAt = task.participant?.lastSeenAt ?? 0;
|
|
87571
|
-
if (lastSeenAt === 0)
|
|
87572
|
-
return now - task.createdAt > thresholdMs;
|
|
87573
|
-
return now - lastSeenAt > thresholdMs;
|
|
87574
|
-
}
|
|
87575
|
-
var init_predicates = __esm(() => {
|
|
87576
|
-
init_types();
|
|
87577
|
-
init_participant();
|
|
87578
|
-
});
|
|
87579
|
-
|
|
87580
|
-
// src/domain/native-integration/index.ts
|
|
87581
|
-
var init_native_integration = __esm(() => {
|
|
87582
|
-
init_types();
|
|
87583
|
-
init_predicates();
|
|
87584
|
-
init_spawn_policy();
|
|
87585
|
-
});
|
|
87586
|
-
|
|
87587
|
-
// src/commands/machine/daemon-start/native-task-injector-logic.ts
|
|
87588
|
-
function shouldInjectNativeTask(task, opts) {
|
|
87589
|
-
if (!isNativeInjectableAliveRunning(task))
|
|
87590
|
-
return false;
|
|
87591
|
-
if (opts?.alreadyInjectedTaskIds?.has(task.taskId))
|
|
87592
|
-
return false;
|
|
87593
|
-
return isInjectableNativeAction(task.participant?.lastSeenAction) || isNativeIdleAfterTaskComplete(task.participant ?? {}) || isNativeAcknowledgedInjectionRetry(task);
|
|
87594
|
-
}
|
|
87595
|
-
function buildNativeInjectionPrompt(params) {
|
|
87596
|
-
const { taskDeliveryOutput, compressMode } = params;
|
|
87597
|
-
if (compressMode === "new_session") {
|
|
87598
|
-
return [
|
|
87599
|
-
"⚠️ Context was compacted. Run `chatroom get-system-prompt` only if role instructions are missing.",
|
|
87600
|
-
"",
|
|
87601
|
-
taskDeliveryOutput
|
|
87602
|
-
].join(`
|
|
87603
|
-
`);
|
|
87604
|
-
}
|
|
87605
|
-
return taskDeliveryOutput;
|
|
87606
|
-
}
|
|
87607
|
-
|
|
87608
|
-
class NativeInjectionDedup {
|
|
87609
|
-
injected = new Set;
|
|
87610
|
-
inFlight = new Set;
|
|
87611
|
-
tryAcquire(taskId) {
|
|
87612
|
-
if (this.has(taskId) || this.inFlight.has(taskId)) {
|
|
87613
|
-
return false;
|
|
87614
|
-
}
|
|
87615
|
-
this.inFlight.add(taskId);
|
|
87616
|
-
return true;
|
|
87617
|
-
}
|
|
87618
|
-
markInjected(taskId) {
|
|
87619
|
-
this.inFlight.delete(taskId);
|
|
87620
|
-
this.injected.add(taskId);
|
|
87621
|
-
}
|
|
87622
|
-
has(taskId) {
|
|
87623
|
-
return this.injected.has(taskId);
|
|
87624
|
-
}
|
|
87625
|
-
clear(taskId) {
|
|
87626
|
-
this.inFlight.delete(taskId);
|
|
87627
|
-
this.injected.delete(taskId);
|
|
87628
|
-
}
|
|
87629
|
-
}
|
|
87630
|
-
var init_native_task_injector_logic = __esm(() => {
|
|
87631
|
-
init_predicates();
|
|
87632
|
-
init_native_integration();
|
|
87633
|
-
});
|
|
87634
|
-
|
|
87635
|
-
// src/commands/machine/daemon-start/native-task-injector.ts
|
|
87636
|
-
function runNativeInjectionEffect(task, deps, dedup) {
|
|
87637
|
-
return exports_Effect.gen(function* () {
|
|
87638
|
-
if (!shouldInjectNativeTask(task, { alreadyInjectedTaskIds: dedup })) {
|
|
87639
|
-
return;
|
|
87640
|
-
}
|
|
87641
|
-
const { chatroomId, taskId, taskContent, agentConfig, status: status3 } = task;
|
|
87642
|
-
const { role } = agentConfig;
|
|
87643
|
-
if (!dedup.tryAcquire(taskId)) {
|
|
87644
|
-
return;
|
|
87645
|
-
}
|
|
87646
|
-
if (status3 === "pending") {
|
|
87647
|
-
const claimResult = yield* exports_Effect.tryPromise({
|
|
87648
|
-
try: () => deps.backend.mutation(api.tasks.claimTask, {
|
|
87649
|
-
sessionId: deps.sessionId,
|
|
87650
|
-
chatroomId,
|
|
87651
|
-
role,
|
|
87652
|
-
taskId
|
|
87653
|
-
}),
|
|
87654
|
-
catch: (err) => err
|
|
87655
|
-
}).pipe(exports_Effect.either);
|
|
87656
|
-
if (claimResult._tag === "Left") {
|
|
87657
|
-
dedup.clear(taskId);
|
|
87658
|
-
return yield* exports_Effect.fail(claimResult.left);
|
|
87659
|
-
}
|
|
87660
|
-
}
|
|
87661
|
-
const deliveryResult = yield* exports_Effect.tryPromise({
|
|
87662
|
-
try: () => deps.backend.query(api.messages.getTaskDeliveryPrompt, {
|
|
87663
|
-
sessionId: deps.sessionId,
|
|
87664
|
-
chatroomId,
|
|
87665
|
-
role,
|
|
87666
|
-
taskId,
|
|
87667
|
-
convexUrl: deps.convexUrl
|
|
87668
|
-
}),
|
|
87669
|
-
catch: (err) => err
|
|
87670
|
-
}).pipe(exports_Effect.either);
|
|
87671
|
-
if (deliveryResult._tag === "Left") {
|
|
87672
|
-
dedup.clear(taskId);
|
|
87673
|
-
return yield* exports_Effect.fail(deliveryResult.left);
|
|
87674
|
-
}
|
|
87675
|
-
const delivery = deliveryResult.right;
|
|
87676
|
-
const prompt = buildNativeInjectionPrompt({
|
|
87677
|
-
taskDeliveryOutput: delivery.fullCliOutput,
|
|
87678
|
-
compressMode: parseCompressContext(taskContent)
|
|
87679
|
-
});
|
|
87680
|
-
yield* exports_Effect.tryPromise({
|
|
87681
|
-
try: () => deps.backend.mutation(api.participants.join, {
|
|
87682
|
-
sessionId: deps.sessionId,
|
|
87683
|
-
chatroomId,
|
|
87684
|
-
role,
|
|
87685
|
-
action: NATIVE_TASK_INJECTED_ACTION,
|
|
87686
|
-
taskId
|
|
87687
|
-
}),
|
|
87688
|
-
catch: (err) => err
|
|
87689
|
-
}).pipe(exports_Effect.tapError(() => exports_Effect.sync(() => dedup.clear(taskId))));
|
|
87690
|
-
const resumeResult = yield* exports_Effect.tryPromise({
|
|
87691
|
-
try: () => deps.agentMgr.resumeTurnForSlot({ chatroomId, role, prompt }),
|
|
87692
|
-
catch: (err) => err
|
|
87693
|
-
}).pipe(exports_Effect.either);
|
|
87694
|
-
if (resumeResult._tag === "Left") {
|
|
87695
|
-
dedup.clear(taskId);
|
|
87696
|
-
console.warn(`[NativeTaskInjector] resumeTurn failed for ${role}@${chatroomId}: ${getErrorMessage(resumeResult.left)}`);
|
|
87697
|
-
return;
|
|
87698
|
-
}
|
|
87699
|
-
dedup.markInjected(taskId);
|
|
87700
|
-
});
|
|
87701
|
-
}
|
|
87702
|
-
var init_native_task_injector = __esm(() => {
|
|
87703
|
-
init_participant();
|
|
87704
|
-
init_parse_compress_context();
|
|
87705
|
-
init_esm();
|
|
87706
|
-
init_native_task_injector_logic();
|
|
87707
|
-
init_api3();
|
|
87708
|
-
init_convex_error();
|
|
87709
|
-
});
|
|
87710
|
-
|
|
87711
87933
|
// src/commands/machine/daemon-start/task-monitor-logic.ts
|
|
87712
87934
|
function isPendingAliveRunningTask(task) {
|
|
87713
87935
|
const { agentConfig, status: status3 } = task;
|
|
@@ -87722,18 +87944,38 @@ function isSlotUnavailableForPid(slot, pid, isPidAlive) {
|
|
|
87722
87944
|
}
|
|
87723
87945
|
return !isPidAlive(pid);
|
|
87724
87946
|
}
|
|
87725
|
-
function
|
|
87726
|
-
|
|
87727
|
-
|
|
87728
|
-
|
|
87729
|
-
|
|
87730
|
-
|
|
87947
|
+
function isNativeRevivableTaskStatus(task) {
|
|
87948
|
+
const { status: status3 } = task;
|
|
87949
|
+
if (status3 === "pending") {
|
|
87950
|
+
return task.agentConfig.spawnedAgentPid != null;
|
|
87951
|
+
}
|
|
87952
|
+
if (status3 === "acknowledged") {
|
|
87953
|
+
return task.assignedTo?.toLowerCase() === task.agentConfig.role.toLowerCase();
|
|
87954
|
+
}
|
|
87955
|
+
return false;
|
|
87956
|
+
}
|
|
87957
|
+
function isNativeAgentSlotDown(task, health) {
|
|
87731
87958
|
const slot = health.getSlot(task.chatroomId, task.agentConfig.role);
|
|
87959
|
+
if (slot?.state === "spawning")
|
|
87960
|
+
return false;
|
|
87961
|
+
const pid = task.agentConfig.spawnedAgentPid ?? slot?.pid;
|
|
87962
|
+
if (pid == null) {
|
|
87963
|
+
return slot?.state !== "running";
|
|
87964
|
+
}
|
|
87732
87965
|
return isSlotUnavailableForPid(slot, pid, health.isPidAlive);
|
|
87733
87966
|
}
|
|
87967
|
+
function isNativeActiveTaskAgentDown(task, health) {
|
|
87968
|
+
if (!isNativeHarness(task.agentConfig.agentHarness))
|
|
87969
|
+
return false;
|
|
87970
|
+
if (task.agentConfig.desiredState !== "running")
|
|
87971
|
+
return false;
|
|
87972
|
+
if (!isNativeRevivableTaskStatus(task))
|
|
87973
|
+
return false;
|
|
87974
|
+
return isNativeAgentSlotDown(task, health);
|
|
87975
|
+
}
|
|
87734
87976
|
function listNativeTasksNeedingRevive(tasks, health, now, cooldown) {
|
|
87735
87977
|
return tasks.filter((task) => {
|
|
87736
|
-
if (!
|
|
87978
|
+
if (!isNativeActiveTaskAgentDown(task, health))
|
|
87737
87979
|
return false;
|
|
87738
87980
|
const { chatroomId, agentConfig } = task;
|
|
87739
87981
|
if (!agentConfig.workingDir)
|
|
@@ -87799,16 +88041,6 @@ var init_task_monitor_logic = __esm(() => {
|
|
|
87799
88041
|
function resolveTaskWantResume(task) {
|
|
87800
88042
|
return compressContextToWantResume(parseCompressContext(task.taskContent ?? ""));
|
|
87801
88043
|
}
|
|
87802
|
-
function runNativeInjectionFork(task, runtime4, effectContext2, dedup, agentMgr, session2) {
|
|
87803
|
-
exports_Runtime.runFork(runtime4)(runNativeInjectionEffect(task, {
|
|
87804
|
-
sessionId: session2.sessionId,
|
|
87805
|
-
backend: session2.backend,
|
|
87806
|
-
agentMgr: {
|
|
87807
|
-
resumeTurnForSlot: (args2) => exports_Effect.runPromise(agentMgr.resumeTurnForSlot(args2))
|
|
87808
|
-
},
|
|
87809
|
-
convexUrl: session2.convexUrl
|
|
87810
|
-
}, dedup).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] native injection failed for ${task.agentConfig.role}@${task.chatroomId}: ${getErrorMessage(err)}`)))));
|
|
87811
|
-
}
|
|
87812
88044
|
function buildCliNudgeLogLine(task) {
|
|
87813
88045
|
const { chatroomId, agentConfig } = task;
|
|
87814
88046
|
const { role } = agentConfig;
|
|
@@ -87817,13 +88049,25 @@ function buildCliNudgeLogLine(task) {
|
|
|
87817
88049
|
const wantResume = resolveTaskWantResume(task);
|
|
87818
88050
|
return `[TaskMonitor] nudging ${role}@${chatroomId} — pending task ${task.taskId}, lastSeenAction=${lastSeenAction}, compress_context=${compressMode}, wantResume=${wantResume}`;
|
|
87819
88051
|
}
|
|
87820
|
-
function
|
|
88052
|
+
function resolveTaskRunnerContext(task) {
|
|
87821
88053
|
const { chatroomId, agentConfig } = task;
|
|
87822
88054
|
const { role } = agentConfig;
|
|
87823
88055
|
const workingDir = agentConfig.workingDir;
|
|
87824
88056
|
if (!workingDir)
|
|
87825
88057
|
return;
|
|
87826
|
-
|
|
88058
|
+
return {
|
|
88059
|
+
chatroomId,
|
|
88060
|
+
agentConfig,
|
|
88061
|
+
role,
|
|
88062
|
+
workingDir,
|
|
88063
|
+
wantResume: resolveTaskWantResume(task)
|
|
88064
|
+
};
|
|
88065
|
+
}
|
|
88066
|
+
function executeCliNudge(task, runtime4, effectContext2, agentMgr) {
|
|
88067
|
+
const ctx = resolveTaskRunnerContext(task);
|
|
88068
|
+
if (!ctx)
|
|
88069
|
+
return;
|
|
88070
|
+
const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
|
|
87827
88071
|
exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
|
|
87828
88072
|
yield* agentMgr.stop({ chatroomId, role, reason: "platform.task_monitor_nudge" });
|
|
87829
88073
|
yield* agentMgr.ensureRunning({
|
|
@@ -87838,12 +88082,10 @@ function executeCliNudge(task, runtime4, effectContext2, agentMgr) {
|
|
|
87838
88082
|
}).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] nudge failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
|
|
87839
88083
|
}
|
|
87840
88084
|
function runNativeReviveEffect(task, runtime4, effectContext2, agentMgr) {
|
|
87841
|
-
const
|
|
87842
|
-
|
|
87843
|
-
const workingDir = agentConfig.workingDir;
|
|
87844
|
-
if (!workingDir)
|
|
88085
|
+
const ctx = resolveTaskRunnerContext(task);
|
|
88086
|
+
if (!ctx)
|
|
87845
88087
|
return;
|
|
87846
|
-
const wantResume =
|
|
88088
|
+
const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
|
|
87847
88089
|
console.log(`[TaskMonitor] native revive ${role}@${chatroomId} — backend PID stale or missing locally for pending task ${task.taskId}`);
|
|
87848
88090
|
exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
|
|
87849
88091
|
yield* agentMgr.ensureRunning({
|
|
@@ -87871,21 +88113,20 @@ function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, effectCo
|
|
|
87871
88113
|
runNativeReviveEffect(task, runtime4, effectContext2, agentMgr);
|
|
87872
88114
|
}
|
|
87873
88115
|
}
|
|
87874
|
-
function
|
|
87875
|
-
for (const task of tasks) {
|
|
87876
|
-
if (shouldInjectNativeTask(task, { alreadyInjectedTaskIds: dedup })) {
|
|
87877
|
-
runNativeInjectionFork(task, runtime4, effectContext2, dedup, agentMgr, sessionDeps);
|
|
87878
|
-
}
|
|
87879
|
-
}
|
|
87880
|
-
}
|
|
87881
|
-
function processTasksUpdate(tasks, runtime4, effectContext2, dedup, cooldown, agentMgr, sessionDeps) {
|
|
88116
|
+
function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, agentMgr, sessionDeps) {
|
|
87882
88117
|
const now = Date.now();
|
|
87883
88118
|
const localHealth = {
|
|
87884
88119
|
getSlot: (chatroomId, role) => agentMgr.getSlot(chatroomId, role),
|
|
87885
88120
|
isPidAlive: (pid) => isProcessAlive((p) => process.kill(p, 0), pid)
|
|
87886
88121
|
};
|
|
87887
88122
|
reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr);
|
|
87888
|
-
|
|
88123
|
+
getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
|
|
88124
|
+
tasks,
|
|
88125
|
+
runtime: runtime4,
|
|
88126
|
+
effectContext: effectContext2,
|
|
88127
|
+
agentMgr,
|
|
88128
|
+
sessionDeps
|
|
88129
|
+
});
|
|
87889
88130
|
nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr);
|
|
87890
88131
|
}
|
|
87891
88132
|
var startTaskMonitorSubscriptionEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
@@ -87895,7 +88136,6 @@ var startTaskMonitorSubscriptionEffect = (wsClient2) => exports_Effect.gen(funct
|
|
|
87895
88136
|
const runtime4 = yield* exports_Effect.runtime();
|
|
87896
88137
|
console.log(`[${formatTimestamp()}] \uD83D\uDCCB Starting task-monitor subscription (reactive)`);
|
|
87897
88138
|
const cooldown = new NudgeCooldown;
|
|
87898
|
-
const dedup = new NativeInjectionDedup;
|
|
87899
88139
|
let stopped = false;
|
|
87900
88140
|
const sessionDeps = {
|
|
87901
88141
|
sessionId: session2.sessionId,
|
|
@@ -87908,7 +88148,7 @@ var startTaskMonitorSubscriptionEffect = (wsClient2) => exports_Effect.gen(funct
|
|
|
87908
88148
|
const onTasksUpdate = (result) => {
|
|
87909
88149
|
if (stopped || !result?.tasks?.length)
|
|
87910
88150
|
return;
|
|
87911
|
-
processTasksUpdate(result.tasks, runtime4, effectContext2,
|
|
88151
|
+
processTasksUpdate(result.tasks, runtime4, effectContext2, cooldown, agentMgr, sessionDeps);
|
|
87912
88152
|
};
|
|
87913
88153
|
const unsubscribe = wsClient2.onUpdate(api.machines.getAssignedTasks, { sessionId: session2.sessionId, machineId: session2.machineId }, onTasksUpdate, (err) => console.warn(`[${formatTimestamp()}] Task-monitor subscription error: ${getErrorMessage(err)}`));
|
|
87914
88154
|
return {
|
|
@@ -87923,8 +88163,7 @@ var init_task_monitor = __esm(() => {
|
|
|
87923
88163
|
init_parse_compress_context();
|
|
87924
88164
|
init_esm();
|
|
87925
88165
|
init_daemon_services();
|
|
87926
|
-
|
|
87927
|
-
init_native_task_injector();
|
|
88166
|
+
init_native_task_delivery_coordinator();
|
|
87928
88167
|
init_task_monitor_logic();
|
|
87929
88168
|
init_api3();
|
|
87930
88169
|
init_convex_error();
|
|
@@ -88362,13 +88601,16 @@ Listening for commands...`);
|
|
|
88362
88601
|
// src/commands/machine/daemon-start/index.ts
|
|
88363
88602
|
async function daemonStart() {
|
|
88364
88603
|
const init2 = await initDaemon();
|
|
88365
|
-
|
|
88604
|
+
const layers = daemonSessionToLayers(init2);
|
|
88605
|
+
exports_Effect.runFork(startBackgroundModelDiscoveryEffect.pipe(exports_Effect.provide(layers)));
|
|
88606
|
+
await exports_Effect.runPromise(startCommandLoopEffect.pipe(exports_Effect.provide(layers)));
|
|
88366
88607
|
}
|
|
88367
88608
|
var init_daemon_start = __esm(() => {
|
|
88368
88609
|
init_esm();
|
|
88369
88610
|
init_command_loop();
|
|
88370
88611
|
init_daemon_layers();
|
|
88371
88612
|
init_init2();
|
|
88613
|
+
init_models_refresh();
|
|
88372
88614
|
});
|
|
88373
88615
|
|
|
88374
88616
|
// src/commands/machine/daemon-stop.ts
|
|
@@ -89423,4 +89665,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
89423
89665
|
});
|
|
89424
89666
|
program2.parse();
|
|
89425
89667
|
|
|
89426
|
-
//# debugId=
|
|
89668
|
+
//# debugId=CFDE8D88B080E55664756E2164756E21
|