chatroom-cli 1.110.1 → 1.111.0
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 +1108 -890
- package/dist/index.js.map +36 -35
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28278,6 +28278,64 @@ var init_agent_process_service = __esm(() => {
|
|
|
28278
28278
|
init_service();
|
|
28279
28279
|
});
|
|
28280
28280
|
|
|
28281
|
+
// src/daemon/services/agent-process-service/infrastructure/components/agent-task-state/infra/in-memory-active-task-state-store.ts
|
|
28282
|
+
function keyOf(key) {
|
|
28283
|
+
return `${key.chatroomId}:${key.role.toLowerCase()}`;
|
|
28284
|
+
}
|
|
28285
|
+
|
|
28286
|
+
class InMemoryActiveTaskStateStore {
|
|
28287
|
+
states = new Map;
|
|
28288
|
+
get(key) {
|
|
28289
|
+
const state = this.states.get(keyOf(key));
|
|
28290
|
+
return state ? { ...state } : undefined;
|
|
28291
|
+
}
|
|
28292
|
+
start(input) {
|
|
28293
|
+
const state = {
|
|
28294
|
+
chatroomId: input.chatroomId,
|
|
28295
|
+
role: input.role,
|
|
28296
|
+
taskId: input.taskId
|
|
28297
|
+
};
|
|
28298
|
+
this.states.set(keyOf(input), state);
|
|
28299
|
+
return { ...state };
|
|
28300
|
+
}
|
|
28301
|
+
clear(key) {
|
|
28302
|
+
return this.states.delete(keyOf(key));
|
|
28303
|
+
}
|
|
28304
|
+
clearAll() {
|
|
28305
|
+
const count3 = this.states.size;
|
|
28306
|
+
this.states.clear();
|
|
28307
|
+
return count3;
|
|
28308
|
+
}
|
|
28309
|
+
}
|
|
28310
|
+
|
|
28311
|
+
// src/daemon/services/agent-process-service/infrastructure/components/agent-task-state/usecase/agent-task-state-service.ts
|
|
28312
|
+
class DefaultAgentTaskStateService {
|
|
28313
|
+
deps;
|
|
28314
|
+
constructor(deps) {
|
|
28315
|
+
this.deps = deps;
|
|
28316
|
+
}
|
|
28317
|
+
get(key) {
|
|
28318
|
+
return this.deps.taskState.get(key);
|
|
28319
|
+
}
|
|
28320
|
+
start(input) {
|
|
28321
|
+
return this.deps.taskState.start(input);
|
|
28322
|
+
}
|
|
28323
|
+
clear(key) {
|
|
28324
|
+
return this.deps.taskState.clear(key);
|
|
28325
|
+
}
|
|
28326
|
+
clearAll() {
|
|
28327
|
+
return this.deps.taskState.clearAll();
|
|
28328
|
+
}
|
|
28329
|
+
}
|
|
28330
|
+
|
|
28331
|
+
// src/daemon/services/agent-process-service/infrastructure/components/agent-task-state/index.ts
|
|
28332
|
+
function createAgentTaskStateService() {
|
|
28333
|
+
return new DefaultAgentTaskStateService({
|
|
28334
|
+
taskState: new InMemoryActiveTaskStateStore
|
|
28335
|
+
});
|
|
28336
|
+
}
|
|
28337
|
+
var init_agent_task_state = () => {};
|
|
28338
|
+
|
|
28281
28339
|
// src/daemon/services/agent-process-service/domain/usecase/native-turn-phase.ts
|
|
28282
28340
|
function defaultNativeTurnPhase() {
|
|
28283
28341
|
return "idle";
|
|
@@ -30996,6 +31054,7 @@ var init_harness_activity_emitter = __esm(() => {
|
|
|
30996
31054
|
// src/daemon/services/agent-process-service/index.ts
|
|
30997
31055
|
var init_agent_process_service2 = __esm(() => {
|
|
30998
31056
|
init_agent_process_service();
|
|
31057
|
+
init_agent_task_state();
|
|
30999
31058
|
init_agent_process_command_bus();
|
|
31000
31059
|
init_service();
|
|
31001
31060
|
init_agent_process_manager();
|
|
@@ -31005,64 +31064,6 @@ var init_agent_process_service2 = __esm(() => {
|
|
|
31005
31064
|
init_orphan_process_tracker();
|
|
31006
31065
|
});
|
|
31007
31066
|
|
|
31008
|
-
// src/daemon/services/agent-process-service/infrastructure/components/agent-task-state/infra/in-memory-active-task-state-store.ts
|
|
31009
|
-
function keyOf(key) {
|
|
31010
|
-
return `${key.chatroomId}:${key.role.toLowerCase()}`;
|
|
31011
|
-
}
|
|
31012
|
-
|
|
31013
|
-
class InMemoryActiveTaskStateStore {
|
|
31014
|
-
states = new Map;
|
|
31015
|
-
get(key) {
|
|
31016
|
-
const state = this.states.get(keyOf(key));
|
|
31017
|
-
return state ? { ...state } : undefined;
|
|
31018
|
-
}
|
|
31019
|
-
start(input) {
|
|
31020
|
-
const state = {
|
|
31021
|
-
chatroomId: input.chatroomId,
|
|
31022
|
-
role: input.role,
|
|
31023
|
-
taskId: input.taskId
|
|
31024
|
-
};
|
|
31025
|
-
this.states.set(keyOf(input), state);
|
|
31026
|
-
return { ...state };
|
|
31027
|
-
}
|
|
31028
|
-
clear(key) {
|
|
31029
|
-
return this.states.delete(keyOf(key));
|
|
31030
|
-
}
|
|
31031
|
-
clearAll() {
|
|
31032
|
-
const count3 = this.states.size;
|
|
31033
|
-
this.states.clear();
|
|
31034
|
-
return count3;
|
|
31035
|
-
}
|
|
31036
|
-
}
|
|
31037
|
-
|
|
31038
|
-
// src/daemon/services/agent-process-service/infrastructure/components/agent-task-state/usecase/agent-task-state-service.ts
|
|
31039
|
-
class DefaultAgentTaskStateService {
|
|
31040
|
-
deps;
|
|
31041
|
-
constructor(deps) {
|
|
31042
|
-
this.deps = deps;
|
|
31043
|
-
}
|
|
31044
|
-
get(key) {
|
|
31045
|
-
return this.deps.taskState.get(key);
|
|
31046
|
-
}
|
|
31047
|
-
start(input) {
|
|
31048
|
-
return this.deps.taskState.start(input);
|
|
31049
|
-
}
|
|
31050
|
-
clear(key) {
|
|
31051
|
-
return this.deps.taskState.clear(key);
|
|
31052
|
-
}
|
|
31053
|
-
clearAll() {
|
|
31054
|
-
return this.deps.taskState.clearAll();
|
|
31055
|
-
}
|
|
31056
|
-
}
|
|
31057
|
-
|
|
31058
|
-
// src/daemon/services/agent-process-service/infrastructure/components/agent-task-state/index.ts
|
|
31059
|
-
function createAgentTaskStateService() {
|
|
31060
|
-
return new DefaultAgentTaskStateService({
|
|
31061
|
-
taskState: new InMemoryActiveTaskStateStore
|
|
31062
|
-
});
|
|
31063
|
-
}
|
|
31064
|
-
var init_agent_task_state = () => {};
|
|
31065
|
-
|
|
31066
31067
|
// src/daemon/services/agent-process-contracts.ts
|
|
31067
31068
|
var init_agent_process_contracts = __esm(() => {
|
|
31068
31069
|
init_agent_process_service2();
|
|
@@ -31786,6 +31787,595 @@ var init_native_task_injector = __esm(() => {
|
|
|
31786
31787
|
init_native_task_injector_logic();
|
|
31787
31788
|
});
|
|
31788
31789
|
|
|
31790
|
+
// src/daemon/services/task-service/service/native-delivery/native-delivery-log.ts
|
|
31791
|
+
function logNativeDeliveryDecision(source, role, chatroomId, decision, taskId, details) {
|
|
31792
|
+
const taskSuffix = taskId ? ` task=${taskId}` : "";
|
|
31793
|
+
const detailSuffix = details ? Object.entries(details).filter(([, value]) => value !== undefined).map(([key, value]) => `${key}=${value}`).join(" ") : "";
|
|
31794
|
+
console.log(`[NativeDelivery:decision] source=${source} role=${role} chatroom=${chatroomId}${taskSuffix} decision=${decision}${detailSuffix ? ` ${detailSuffix}` : ""}`);
|
|
31795
|
+
}
|
|
31796
|
+
function logNativeDeliveryTrigger(source, role, chatroomId, taskId) {
|
|
31797
|
+
const taskSuffix = taskId ? ` task ${taskId}` : "";
|
|
31798
|
+
console.log(`[NativeDelivery:trigger] source=${source} ${role}@${chatroomId}${taskSuffix}`);
|
|
31799
|
+
}
|
|
31800
|
+
function logNativeDeliverySkip(role, chatroomId, taskId, reason) {
|
|
31801
|
+
console.log(`[NativeDelivery:skip] ${role}@${chatroomId} task ${taskId} — ${reason}`);
|
|
31802
|
+
}
|
|
31803
|
+
function logNativeDeliveryMutexSkip(role, chatroomId, taskId) {
|
|
31804
|
+
console.log(`[NativeDelivery:skip] ${role}@${chatroomId} task ${taskId} — delivery_mutex_busy (another inject in flight)`);
|
|
31805
|
+
}
|
|
31806
|
+
function logNativeDeliveryInjecting(role, chatroomId, taskId) {
|
|
31807
|
+
console.log(`[NativeDelivery:inject] ${role}@${chatroomId} task ${taskId} — starting injection`);
|
|
31808
|
+
}
|
|
31809
|
+
|
|
31810
|
+
// src/daemon/services/task-service/service/native-delivery/delivery-decision.ts
|
|
31811
|
+
function taskSort(a, b) {
|
|
31812
|
+
const pendingOrder = Number(b.status === "pending") - Number(a.status === "pending");
|
|
31813
|
+
return pendingOrder || a.createdAt - b.createdAt;
|
|
31814
|
+
}
|
|
31815
|
+
function stableBlockReason(reason) {
|
|
31816
|
+
const reasons = [
|
|
31817
|
+
"not_native_harness",
|
|
31818
|
+
"task_status_not_deliverable",
|
|
31819
|
+
"acknowledged_wrong_role",
|
|
31820
|
+
"chatroom_stop_scope_active",
|
|
31821
|
+
"operational_stop_intent_active",
|
|
31822
|
+
"operational_circuit_open",
|
|
31823
|
+
"operational_state_not_running",
|
|
31824
|
+
"slot_missing",
|
|
31825
|
+
"slot_not_running",
|
|
31826
|
+
"slot_pid_missing",
|
|
31827
|
+
"spawned_pid_missing",
|
|
31828
|
+
"pid_mismatch",
|
|
31829
|
+
"harness_session_missing",
|
|
31830
|
+
"turn_not_idle",
|
|
31831
|
+
"working_dir_missing"
|
|
31832
|
+
];
|
|
31833
|
+
return reasons.find((candidate) => reason.startsWith(candidate)) ?? "working_dir_missing";
|
|
31834
|
+
}
|
|
31835
|
+
function decideNextDelivery(tasks, context5) {
|
|
31836
|
+
const assignedTasks = [...tasks].filter((candidate) => candidate.agentConfig.role.toLowerCase() === context5.role.toLowerCase()).sort(taskSort);
|
|
31837
|
+
const task = assignedTasks.find((candidate) => isDeliverableTaskStatus(candidate.status));
|
|
31838
|
+
if (!task) {
|
|
31839
|
+
if (assignedTasks.length > 0) {
|
|
31840
|
+
return {
|
|
31841
|
+
kind: "blocked",
|
|
31842
|
+
taskId: assignedTasks[0].taskId,
|
|
31843
|
+
reason: "task_status_not_deliverable"
|
|
31844
|
+
};
|
|
31845
|
+
}
|
|
31846
|
+
return { kind: "idle", reason: tasks.length > 0 ? "not_assigned" : "no_deliverable_task" };
|
|
31847
|
+
}
|
|
31848
|
+
if (context5.activeTaskId === task.taskId) {
|
|
31849
|
+
return { kind: "deduplicated", taskId: task.taskId, reason: "task_state_active" };
|
|
31850
|
+
}
|
|
31851
|
+
if (context5.deliveryInFlight) {
|
|
31852
|
+
return { kind: "deduplicated", taskId: task.taskId, reason: "delivery_in_flight" };
|
|
31853
|
+
}
|
|
31854
|
+
if (!context5.isNativeHarness(task.agentConfig.agentHarness)) {
|
|
31855
|
+
return { kind: "blocked", taskId: task.taskId, reason: "not_native_harness" };
|
|
31856
|
+
}
|
|
31857
|
+
if (context5.agentLifecycleInFlight) {
|
|
31858
|
+
return { kind: "wait", taskId: task.taskId, reason: "agent_start_in_flight" };
|
|
31859
|
+
}
|
|
31860
|
+
const blockReason = context5.explainNativeDeliveryBlock(task, {
|
|
31861
|
+
slot: context5.slot,
|
|
31862
|
+
operational: context5.operational
|
|
31863
|
+
});
|
|
31864
|
+
if (blockReason === null) {
|
|
31865
|
+
return {
|
|
31866
|
+
kind: "inject",
|
|
31867
|
+
taskId: task.taskId,
|
|
31868
|
+
harnessSessionId: context5.slot?.harnessSessionId
|
|
31869
|
+
};
|
|
31870
|
+
}
|
|
31871
|
+
if (isSlotSpawning(context5.slot?.state ?? "idle")) {
|
|
31872
|
+
return { kind: "wait", taskId: task.taskId, reason: "slot_spawning" };
|
|
31873
|
+
}
|
|
31874
|
+
if (isSlotStopping(context5.slot?.state ?? "idle")) {
|
|
31875
|
+
return { kind: "wait", taskId: task.taskId, reason: "slot_stopping" };
|
|
31876
|
+
}
|
|
31877
|
+
const coldSession = context5.snapshotRequestsNativeColdSession(task);
|
|
31878
|
+
const startAllowed = blockReason.startsWith("slot_missing") || blockReason.startsWith("slot_not_running");
|
|
31879
|
+
if (startAllowed && !coldSession && task.status === "pending" && isSlotIdle(context5.slot?.state ?? "idle") && task.agentConfig.workingDir) {
|
|
31880
|
+
return { kind: "start-agent", taskId: task.taskId };
|
|
31881
|
+
}
|
|
31882
|
+
if (blockReason.startsWith("harness_session_missing")) {
|
|
31883
|
+
return { kind: "wait", taskId: task.taskId, reason: "session_not_ready" };
|
|
31884
|
+
}
|
|
31885
|
+
return { kind: "blocked", taskId: task.taskId, reason: stableBlockReason(blockReason) };
|
|
31886
|
+
}
|
|
31887
|
+
var init_delivery_decision = __esm(() => {
|
|
31888
|
+
init_assigned_task();
|
|
31889
|
+
init_check_agent_slot();
|
|
31890
|
+
});
|
|
31891
|
+
|
|
31892
|
+
// src/infrastructure/mappers/map-assigned-task.ts
|
|
31893
|
+
function mapAssignedTaskSnapshot(row) {
|
|
31894
|
+
return {
|
|
31895
|
+
taskId: row.taskId,
|
|
31896
|
+
chatroomId: row.chatroomId,
|
|
31897
|
+
status: row.status,
|
|
31898
|
+
assignedTo: row.assignedTo,
|
|
31899
|
+
updatedAt: row.updatedAt,
|
|
31900
|
+
createdAt: row.createdAt,
|
|
31901
|
+
agentConfig: {
|
|
31902
|
+
role: row.agentConfig.role,
|
|
31903
|
+
machineId: row.agentConfig.machineId,
|
|
31904
|
+
agentHarness: row.agentConfig.agentHarness,
|
|
31905
|
+
model: row.agentConfig.model,
|
|
31906
|
+
workingDir: row.agentConfig.workingDir,
|
|
31907
|
+
spawnedAgentPid: row.agentConfig.spawnedAgentPid,
|
|
31908
|
+
desiredState: row.agentConfig.desiredState,
|
|
31909
|
+
circuitState: row.agentConfig.circuitState,
|
|
31910
|
+
configLifecycleRevision: row.agentConfig.configLifecycleRevision
|
|
31911
|
+
},
|
|
31912
|
+
participant: row.participant,
|
|
31913
|
+
requestsNativeColdSession: row.requestsNativeColdSession
|
|
31914
|
+
};
|
|
31915
|
+
}
|
|
31916
|
+
function mapAssignedTaskView(row) {
|
|
31917
|
+
return {
|
|
31918
|
+
...mapAssignedTaskSnapshot(row),
|
|
31919
|
+
taskContent: row.taskContent,
|
|
31920
|
+
taskEnvelope: row.taskEnvelope,
|
|
31921
|
+
startInNewSession: row.startInNewSession
|
|
31922
|
+
};
|
|
31923
|
+
}
|
|
31924
|
+
function mapAssignedTaskSnapshotList(rows) {
|
|
31925
|
+
return rows.map(mapAssignedTaskSnapshot);
|
|
31926
|
+
}
|
|
31927
|
+
|
|
31928
|
+
// src/daemon/entry/restart-orchestrator-in-flight.ts
|
|
31929
|
+
function roleKey(chatroomId, role) {
|
|
31930
|
+
return `${chatroomId}:${role.toLowerCase()}`;
|
|
31931
|
+
}
|
|
31932
|
+
function markRestartOrchestratorInFlight(chatroomId, role, correlationId) {
|
|
31933
|
+
inFlight.set(roleKey(chatroomId, role), correlationId);
|
|
31934
|
+
}
|
|
31935
|
+
function clearRestartOrchestratorInFlight(chatroomId, role, correlationId) {
|
|
31936
|
+
const key = roleKey(chatroomId, role);
|
|
31937
|
+
if (correlationId !== undefined && inFlight.get(key) !== correlationId)
|
|
31938
|
+
return;
|
|
31939
|
+
inFlight.delete(key);
|
|
31940
|
+
}
|
|
31941
|
+
function isRestartOrchestratorInFlight(chatroomId, role) {
|
|
31942
|
+
return inFlight.has(roleKey(chatroomId, role));
|
|
31943
|
+
}
|
|
31944
|
+
var inFlight;
|
|
31945
|
+
var init_restart_orchestrator_in_flight = __esm(() => {
|
|
31946
|
+
inFlight = new Map;
|
|
31947
|
+
});
|
|
31948
|
+
|
|
31949
|
+
// src/daemon/entry/role-delivery-state.ts
|
|
31950
|
+
function roleKey2(chatroomId, role) {
|
|
31951
|
+
return `${chatroomId}:${role.toLowerCase()}`;
|
|
31952
|
+
}
|
|
31953
|
+
|
|
31954
|
+
class RoleDeliveryState {
|
|
31955
|
+
generation = new Map;
|
|
31956
|
+
inFlight = new Set;
|
|
31957
|
+
nativeNudgeFailures = new Map;
|
|
31958
|
+
getGeneration(chatroomId, role) {
|
|
31959
|
+
return this.generation.get(roleKey2(chatroomId, role)) ?? 0;
|
|
31960
|
+
}
|
|
31961
|
+
resetDeliveryState(chatroomId, role) {
|
|
31962
|
+
const key = roleKey2(chatroomId, role);
|
|
31963
|
+
const next4 = (this.generation.get(key) ?? 0) + 1;
|
|
31964
|
+
this.generation.set(key, next4);
|
|
31965
|
+
this.inFlight.delete(key);
|
|
31966
|
+
this.nativeNudgeFailures.delete(key);
|
|
31967
|
+
return next4;
|
|
31968
|
+
}
|
|
31969
|
+
tryAcquireDelivery(chatroomId, role) {
|
|
31970
|
+
const key = roleKey2(chatroomId, role);
|
|
31971
|
+
if (this.inFlight.has(key))
|
|
31972
|
+
return false;
|
|
31973
|
+
this.inFlight.add(key);
|
|
31974
|
+
return true;
|
|
31975
|
+
}
|
|
31976
|
+
releaseDelivery(chatroomId, role) {
|
|
31977
|
+
this.inFlight.delete(roleKey2(chatroomId, role));
|
|
31978
|
+
}
|
|
31979
|
+
recordNativeNudgeFailure(chatroomId, role) {
|
|
31980
|
+
const key = roleKey2(chatroomId, role);
|
|
31981
|
+
const count3 = (this.nativeNudgeFailures.get(key) ?? 0) + 1;
|
|
31982
|
+
this.nativeNudgeFailures.set(key, count3);
|
|
31983
|
+
return count3;
|
|
31984
|
+
}
|
|
31985
|
+
clearNativeNudgeFailures(chatroomId, role) {
|
|
31986
|
+
this.nativeNudgeFailures.delete(roleKey2(chatroomId, role));
|
|
31987
|
+
}
|
|
31988
|
+
getNativeNudgeFailures(chatroomId, role) {
|
|
31989
|
+
return this.nativeNudgeFailures.get(roleKey2(chatroomId, role)) ?? 0;
|
|
31990
|
+
}
|
|
31991
|
+
}
|
|
31992
|
+
function getRoleDeliveryState() {
|
|
31993
|
+
shared ??= new RoleDeliveryState;
|
|
31994
|
+
return shared;
|
|
31995
|
+
}
|
|
31996
|
+
var shared;
|
|
31997
|
+
|
|
31998
|
+
// src/daemon/services/task-service/service/native-delivery/native-task-delivery-coordinator.ts
|
|
31999
|
+
class NativeTaskDeliveryCoordinator {
|
|
32000
|
+
resetRoleDeliveryState(chatroomId, role) {
|
|
32001
|
+
getRoleDeliveryState().resetDeliveryState(chatroomId, role);
|
|
32002
|
+
}
|
|
32003
|
+
async reconcileRoleTasks(params) {
|
|
32004
|
+
const tasks = params.tasks;
|
|
32005
|
+
if (tasks.length === 0)
|
|
32006
|
+
return;
|
|
32007
|
+
const {
|
|
32008
|
+
runtime: runtime4,
|
|
32009
|
+
effectContext: effectContext2,
|
|
32010
|
+
agentMgr,
|
|
32011
|
+
sessionDeps,
|
|
32012
|
+
operationalModel,
|
|
32013
|
+
isTaskActive,
|
|
32014
|
+
machineId,
|
|
32015
|
+
onTaskDelivered,
|
|
32016
|
+
executors
|
|
32017
|
+
} = params;
|
|
32018
|
+
const deliveryState = getRoleDeliveryState();
|
|
32019
|
+
const taskService = params.taskService;
|
|
32020
|
+
const groups = new Map;
|
|
32021
|
+
for (const task of tasks) {
|
|
32022
|
+
const key = `${task.chatroomId}:${task.agentConfig.role.toLowerCase()}`;
|
|
32023
|
+
const group = groups.get(key) ?? [];
|
|
32024
|
+
group.push(task);
|
|
32025
|
+
groups.set(key, group);
|
|
32026
|
+
}
|
|
32027
|
+
for (const roleTasks of groups.values()) {
|
|
32028
|
+
const sortedTasks = [...roleTasks].sort((a, b) => {
|
|
32029
|
+
if (a.status === "pending" && b.status !== "pending")
|
|
32030
|
+
return -1;
|
|
32031
|
+
if (b.status === "pending" && a.status !== "pending")
|
|
32032
|
+
return 1;
|
|
32033
|
+
return a.createdAt - b.createdAt;
|
|
32034
|
+
});
|
|
32035
|
+
const firstTask = sortedTasks[0];
|
|
32036
|
+
if (!firstTask)
|
|
32037
|
+
continue;
|
|
32038
|
+
const { role } = firstTask.agentConfig;
|
|
32039
|
+
const slot = agentMgr.getSlot(firstTask.chatroomId, role);
|
|
32040
|
+
const operational = operationalModel.get(firstTask.chatroomId, role);
|
|
32041
|
+
const activeTaskId = roleTasks.find((candidate) => isTaskActive({ chatroomId: candidate.chatroomId, role, taskId: candidate.taskId }))?.taskId;
|
|
32042
|
+
const decision = decideNextDelivery(roleTasks, {
|
|
32043
|
+
role,
|
|
32044
|
+
slot,
|
|
32045
|
+
operational,
|
|
32046
|
+
activeTaskId,
|
|
32047
|
+
deliveryInFlight: false,
|
|
32048
|
+
agentLifecycleInFlight: isRestartOrchestratorInFlight(firstTask.chatroomId, role),
|
|
32049
|
+
isNativeHarness: taskService.isNativeHarness,
|
|
32050
|
+
snapshotRequestsNativeColdSession: taskService.snapshotRequestsNativeColdSession,
|
|
32051
|
+
explainNativeDeliveryBlock: taskService.explainNativeDeliveryBlock
|
|
32052
|
+
});
|
|
32053
|
+
const attemptId = `${Date.now()}-${firstTask.taskId}`;
|
|
32054
|
+
const decisionReason = "reason" in decision ? decision.reason : undefined;
|
|
32055
|
+
logNativeDeliveryDecision(params.pass ?? "inbox-signal", role, firstTask.chatroomId, decision.kind === "blocked" || decision.kind === "wait" ? `${decision.kind}:${decision.reason}` : decision.kind, "taskId" in decision ? decision.taskId : undefined, {
|
|
32056
|
+
...decisionReason ? { reason: decisionReason } : {},
|
|
32057
|
+
attemptId,
|
|
32058
|
+
slotState: slot?.state ?? "missing",
|
|
32059
|
+
nativeTurnPhase: slot?.nativeTurnPhase ?? "unknown",
|
|
32060
|
+
harnessSessionPresent: Boolean(slot?.harnessSessionId),
|
|
32061
|
+
operationalState: operational?.operationalState ?? "missing"
|
|
32062
|
+
});
|
|
32063
|
+
const row = ("taskId" in decision ? sortedTasks.find((candidate) => candidate.taskId === decision.taskId) : firstTask) ?? firstTask;
|
|
32064
|
+
if (decision.kind === "idle" || decision.kind === "blocked" || decision.kind === "wait") {
|
|
32065
|
+
if (decision.kind === "blocked") {
|
|
32066
|
+
logNativeDeliverySkip(role, row.chatroomId, decision.taskId, decision.reason);
|
|
32067
|
+
}
|
|
32068
|
+
continue;
|
|
32069
|
+
}
|
|
32070
|
+
if (decision.kind === "deduplicated") {
|
|
32071
|
+
logNativeDeliverySkip(role, row.chatroomId, decision.taskId, decision.reason);
|
|
32072
|
+
continue;
|
|
32073
|
+
}
|
|
32074
|
+
if (decision.kind === "start-agent") {
|
|
32075
|
+
if (!row.agentConfig.workingDir || slot && !isSlotIdle(slot.state))
|
|
32076
|
+
continue;
|
|
32077
|
+
try {
|
|
32078
|
+
if (executors) {
|
|
32079
|
+
const startResult2 = await executors.startAgent(row, operational?.operationalState);
|
|
32080
|
+
console.log(`[NativeDelivery:execution] attempt=${attemptId} role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=start-agent result=${startResult2 && typeof startResult2 === "object" && "success" in startResult2 ? startResult2.success : "completed"}`);
|
|
32081
|
+
continue;
|
|
32082
|
+
}
|
|
32083
|
+
const startResult = await params.runSerializedForAgent({ chatroomId: row.chatroomId, role }, { timeoutMs: 120000 }, (ops, context5) => ops.startAgent({
|
|
32084
|
+
chatroomId: row.chatroomId,
|
|
32085
|
+
role,
|
|
32086
|
+
agentHarness: row.agentConfig.agentHarness,
|
|
32087
|
+
model: row.agentConfig.model ?? "",
|
|
32088
|
+
workingDir: row.agentConfig.workingDir,
|
|
32089
|
+
reason: operational?.operationalState === "running" ? AgentStartReasonEnum["platform.task_monitor_nudge"] : AgentStartReasonEnum["platform.pending_task_wake"],
|
|
32090
|
+
wantResume: false,
|
|
32091
|
+
lifecycleRevision: row.agentConfig.configLifecycleRevision,
|
|
32092
|
+
taskId: row.taskId
|
|
32093
|
+
}, context5.signal));
|
|
32094
|
+
console.log(`[NativeDelivery:execution] attempt=${attemptId} role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=start-agent result=${startResult && typeof startResult === "object" && "success" in startResult ? startResult.success : "completed"}`);
|
|
32095
|
+
} catch (error) {
|
|
32096
|
+
console.warn(`[NativeDelivery:failure] role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=start-agent error=${getErrorMessage(error)}`);
|
|
32097
|
+
}
|
|
32098
|
+
continue;
|
|
32099
|
+
}
|
|
32100
|
+
if (!deliveryState.tryAcquireDelivery(row.chatroomId, role)) {
|
|
32101
|
+
logNativeDeliveryMutexSkip(role, row.chatroomId, row.taskId);
|
|
32102
|
+
continue;
|
|
32103
|
+
}
|
|
32104
|
+
const harnessSessionId = decision.harnessSessionId;
|
|
32105
|
+
logNativeDeliveryInjecting(role, row.chatroomId, row.taskId);
|
|
32106
|
+
if (executors) {
|
|
32107
|
+
try {
|
|
32108
|
+
const result = await executors.injectTask(row, harnessSessionId);
|
|
32109
|
+
if (result.kind === "task-unavailable") {
|
|
32110
|
+
console.warn(`[NativeDelivery:execution] attempt=${attemptId} role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=inject result=task_hydration_missing`);
|
|
32111
|
+
} else if (result.delivered) {
|
|
32112
|
+
onTaskDelivered?.(result.delivered);
|
|
32113
|
+
deliveryState.clearNativeNudgeFailures(row.chatroomId, role);
|
|
32114
|
+
console.log(`[NativeDelivery:execution] attempt=${attemptId} role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=inject result=success`);
|
|
32115
|
+
}
|
|
32116
|
+
} catch (error) {
|
|
32117
|
+
console.warn(`[NativeDelivery:failure] role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=inject error=${getErrorMessage(error)}`);
|
|
32118
|
+
} finally {
|
|
32119
|
+
deliveryState.releaseDelivery(row.chatroomId, role);
|
|
32120
|
+
}
|
|
32121
|
+
continue;
|
|
32122
|
+
}
|
|
32123
|
+
await exports_Runtime.runPromise(runtime4)(exports_Effect.gen(function* () {
|
|
32124
|
+
const backend2 = yield* exports_Effect.tryPromise(() => sessionDeps.backend.query(api.machines.getAssignedTaskForAction, {
|
|
32125
|
+
sessionId: sessionDeps.sessionId,
|
|
32126
|
+
machineId,
|
|
32127
|
+
taskId: row.taskId,
|
|
32128
|
+
role: row.agentConfig.role
|
|
32129
|
+
}));
|
|
32130
|
+
if (!backend2) {
|
|
32131
|
+
console.warn(`[NativeDelivery:execution] attempt=${attemptId} role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=inject result=task_hydration_missing`);
|
|
32132
|
+
return;
|
|
32133
|
+
}
|
|
32134
|
+
const full = mapAssignedTaskView(backend2);
|
|
32135
|
+
yield* exports_Effect.tryPromise(() => taskService.deliverNativeTask(full, harnessSessionId, (delivered) => {
|
|
32136
|
+
onTaskDelivered?.(delivered);
|
|
32137
|
+
deliveryState.clearNativeNudgeFailures(delivered.chatroomId, delivered.role);
|
|
32138
|
+
console.log(`[NativeDelivery:execution] attempt=${attemptId} role=${delivered.role} chatroom=${delivered.chatroomId} task=${delivered.taskId} operation=inject result=success`);
|
|
32139
|
+
}));
|
|
32140
|
+
}).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[NativeDelivery:failure] role=${row.agentConfig.role} chatroom=${row.chatroomId} task=${row.taskId} operation=inject error=${getErrorMessage(err)}`))), exports_Effect.ensuring(exports_Effect.sync(() => {
|
|
32141
|
+
deliveryState.releaseDelivery(row.chatroomId, row.agentConfig.role);
|
|
32142
|
+
}))));
|
|
32143
|
+
}
|
|
32144
|
+
}
|
|
32145
|
+
}
|
|
32146
|
+
function getNativeTaskDeliveryCoordinator() {
|
|
32147
|
+
coordinator ??= new NativeTaskDeliveryCoordinator;
|
|
32148
|
+
return coordinator;
|
|
32149
|
+
}
|
|
32150
|
+
function resetRoleDeliveryState(chatroomId, role) {
|
|
32151
|
+
getRoleDeliveryState().resetDeliveryState(chatroomId, role);
|
|
32152
|
+
}
|
|
32153
|
+
var coordinator;
|
|
32154
|
+
var init_native_task_delivery_coordinator = __esm(() => {
|
|
32155
|
+
init_agent();
|
|
32156
|
+
init_esm();
|
|
32157
|
+
init_delivery_decision();
|
|
32158
|
+
init_api3();
|
|
32159
|
+
init_convex_error();
|
|
32160
|
+
init_check_agent_slot();
|
|
32161
|
+
init_restart_orchestrator_in_flight();
|
|
32162
|
+
});
|
|
32163
|
+
|
|
32164
|
+
// src/daemon/services/task-service/service/native-delivery/task-delivery-processor.ts
|
|
32165
|
+
async function processTasksUpdate(runtime4, effectContext2, agentMgr, runSerializedForAgent, taskService, sessionDeps, machineId, pass, lifecycleOutbox, operationalModel, isTaskActive, options) {
|
|
32166
|
+
const first = options.snapshots[0];
|
|
32167
|
+
if (!first)
|
|
32168
|
+
return;
|
|
32169
|
+
logNativeDeliveryTrigger(pass, first.agentConfig.role, first.chatroomId, first.taskId);
|
|
32170
|
+
const executors = {
|
|
32171
|
+
startAgent: (task, operationalState) => runSerializedForAgent({ chatroomId: task.chatroomId, role: task.agentConfig.role }, { timeoutMs: 120000 }, (ops, context5) => ops.startAgent({
|
|
32172
|
+
chatroomId: task.chatroomId,
|
|
32173
|
+
role: task.agentConfig.role,
|
|
32174
|
+
agentHarness: task.agentConfig.agentHarness,
|
|
32175
|
+
model: task.agentConfig.model ?? "",
|
|
32176
|
+
workingDir: task.agentConfig.workingDir,
|
|
32177
|
+
reason: operationalState === "running" ? AgentStartReasonEnum["platform.task_monitor_nudge"] : AgentStartReasonEnum["platform.pending_task_wake"],
|
|
32178
|
+
wantResume: false,
|
|
32179
|
+
lifecycleRevision: task.agentConfig.configLifecycleRevision,
|
|
32180
|
+
taskId: task.taskId
|
|
32181
|
+
}, context5.signal)),
|
|
32182
|
+
injectTask: async (task, harnessSessionId) => {
|
|
32183
|
+
const backend2 = await sessionDeps.backend.query(api.machines.getAssignedTaskForAction, {
|
|
32184
|
+
sessionId: sessionDeps.sessionId,
|
|
32185
|
+
machineId,
|
|
32186
|
+
taskId: task.taskId,
|
|
32187
|
+
role: task.agentConfig.role
|
|
32188
|
+
});
|
|
32189
|
+
if (!backend2)
|
|
32190
|
+
return { kind: "task-unavailable" };
|
|
32191
|
+
const full = mapAssignedTaskView(backend2);
|
|
32192
|
+
let delivered;
|
|
32193
|
+
await taskService.deliverNativeTask(full, harnessSessionId, (result) => {
|
|
32194
|
+
delivered = result;
|
|
32195
|
+
});
|
|
32196
|
+
return { kind: "delivered", ...delivered ? { delivered } : {} };
|
|
32197
|
+
}
|
|
32198
|
+
};
|
|
32199
|
+
await getNativeTaskDeliveryCoordinator().reconcileRoleTasks({
|
|
32200
|
+
tasks: [...options.snapshots],
|
|
32201
|
+
pass,
|
|
32202
|
+
runtime: runtime4,
|
|
32203
|
+
effectContext: effectContext2,
|
|
32204
|
+
agentMgr,
|
|
32205
|
+
runSerializedForAgent,
|
|
32206
|
+
taskService,
|
|
32207
|
+
sessionDeps,
|
|
32208
|
+
lifecycleOutbox,
|
|
32209
|
+
operationalModel,
|
|
32210
|
+
isTaskActive,
|
|
32211
|
+
machineId,
|
|
32212
|
+
onTaskDelivered: options.onTaskDelivered,
|
|
32213
|
+
executors
|
|
32214
|
+
});
|
|
32215
|
+
}
|
|
32216
|
+
var init_task_delivery_processor = __esm(() => {
|
|
32217
|
+
init_agent();
|
|
32218
|
+
init_native_task_delivery_coordinator();
|
|
32219
|
+
init_api3();
|
|
32220
|
+
});
|
|
32221
|
+
|
|
32222
|
+
// src/daemon/services/task-service/service/native-delivery/native-delivery-service.ts
|
|
32223
|
+
class NativeDeliveryService {
|
|
32224
|
+
deps;
|
|
32225
|
+
unsubscribeAgentTurnEnded;
|
|
32226
|
+
unsubscribeAgentStarted;
|
|
32227
|
+
unsubscribeAgentSessionLost;
|
|
32228
|
+
reconcileStates = new Map;
|
|
32229
|
+
unsubscribeTaskService;
|
|
32230
|
+
periodicReconcileTimer;
|
|
32231
|
+
periodicReconcileInFlight = false;
|
|
32232
|
+
constructor(deps) {
|
|
32233
|
+
this.deps = deps;
|
|
32234
|
+
this.unsubscribeAgentTurnEnded = deps.agentMgr.subscribeAgentTurnEnded((event) => this.handleAgentTurnEnded(event));
|
|
32235
|
+
this.unsubscribeAgentStarted = deps.agentMgr.subscribeAgentStarted((event) => this.handleAgentStarted(event));
|
|
32236
|
+
this.unsubscribeAgentSessionLost = deps.agentMgr.subscribeAgentSessionLost((event) => this.handleAgentSessionLost(event));
|
|
32237
|
+
this.unsubscribeTaskService = deps.taskService.subscribe?.((notification) => this.handleTaskServiceNotification(notification));
|
|
32238
|
+
}
|
|
32239
|
+
async handleAgentStarted(event) {
|
|
32240
|
+
await this.requestReconcile({
|
|
32241
|
+
chatroomId: event.chatroomId,
|
|
32242
|
+
role: event.role,
|
|
32243
|
+
source: "agent-started"
|
|
32244
|
+
});
|
|
32245
|
+
}
|
|
32246
|
+
handleAgentSessionLost(event) {
|
|
32247
|
+
getRoleDeliveryState().resetDeliveryState(event.chatroomId, event.role);
|
|
32248
|
+
this.deps.agentTaskState.clear({ chatroomId: event.chatroomId, role: event.role });
|
|
32249
|
+
this.requestReconcile({
|
|
32250
|
+
chatroomId: event.chatroomId,
|
|
32251
|
+
role: event.role,
|
|
32252
|
+
source: "operational-signal"
|
|
32253
|
+
}).catch((error) => {
|
|
32254
|
+
console.warn(`[NativeDelivery:failure] role=${event.role} chatroom=${event.chatroomId} operation=session-loss-reconcile error=${error instanceof Error ? error.message : String(error)}`);
|
|
32255
|
+
});
|
|
32256
|
+
}
|
|
32257
|
+
async handleAgentTurnEnded(event) {
|
|
32258
|
+
this.scheduleRoleDelivery(event.chatroomId, event.role);
|
|
32259
|
+
}
|
|
32260
|
+
scheduleRoleDelivery(chatroomId, role) {
|
|
32261
|
+
setTimeout(() => {
|
|
32262
|
+
this.requestReconcile({ chatroomId, role, source: "turn-ended" }).catch((error) => {
|
|
32263
|
+
console.warn(`[NativeDelivery] post-turn delivery failed for ${role}@${chatroomId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
32264
|
+
});
|
|
32265
|
+
}, 0);
|
|
32266
|
+
}
|
|
32267
|
+
dispose() {
|
|
32268
|
+
this.unsubscribeAgentTurnEnded();
|
|
32269
|
+
this.unsubscribeAgentStarted();
|
|
32270
|
+
this.unsubscribeAgentSessionLost();
|
|
32271
|
+
this.unsubscribeTaskService?.();
|
|
32272
|
+
this.unsubscribeTaskService = undefined;
|
|
32273
|
+
if (this.periodicReconcileTimer) {
|
|
32274
|
+
clearInterval(this.periodicReconcileTimer);
|
|
32275
|
+
this.periodicReconcileTimer = undefined;
|
|
32276
|
+
}
|
|
32277
|
+
}
|
|
32278
|
+
startPeriodicReconciliation(intervalMs = NATIVE_DELIVERY_RECONCILE_MS) {
|
|
32279
|
+
if (this.periodicReconcileTimer)
|
|
32280
|
+
return;
|
|
32281
|
+
this.periodicReconcileTimer = setInterval(() => {
|
|
32282
|
+
if (this.periodicReconcileInFlight)
|
|
32283
|
+
return;
|
|
32284
|
+
this.periodicReconcileInFlight = true;
|
|
32285
|
+
const roleKeys = new Set(this.deps.taskSnapshotState.listAll().map((snapshot) => `${snapshot.chatroomId}:${snapshot.agentConfig.role.toLowerCase()}`));
|
|
32286
|
+
Promise.all([...roleKeys].map((key) => {
|
|
32287
|
+
const separator = key.indexOf(":");
|
|
32288
|
+
return this.requestReconcile({
|
|
32289
|
+
chatroomId: key.slice(0, separator),
|
|
32290
|
+
role: key.slice(separator + 1),
|
|
32291
|
+
source: "periodic-reconcile"
|
|
32292
|
+
});
|
|
32293
|
+
})).catch((error) => {
|
|
32294
|
+
console.warn("[TaskService] local delivery reconciliation failed:", error);
|
|
32295
|
+
}).finally(() => {
|
|
32296
|
+
this.periodicReconcileInFlight = false;
|
|
32297
|
+
});
|
|
32298
|
+
}, intervalMs);
|
|
32299
|
+
this.periodicReconcileTimer.unref?.();
|
|
32300
|
+
}
|
|
32301
|
+
get agentTaskState() {
|
|
32302
|
+
return this.deps.agentTaskState;
|
|
32303
|
+
}
|
|
32304
|
+
async handleTaskInboxUpdate(update5) {
|
|
32305
|
+
await this.requestReconcileForSnapshots(update5.snapshots, "task-signal");
|
|
32306
|
+
}
|
|
32307
|
+
async handleTaskServiceNotification(notification) {
|
|
32308
|
+
if (notification.kind === "bootstrap") {
|
|
32309
|
+
await this.requestReconcileForSnapshots(notification.snapshots, "bootstrap");
|
|
32310
|
+
return;
|
|
32311
|
+
}
|
|
32312
|
+
await this.handleTaskInboxUpdate(notification.update);
|
|
32313
|
+
}
|
|
32314
|
+
async requestReconcile(params) {
|
|
32315
|
+
const key = `${params.chatroomId}:${params.role.toLowerCase()}`;
|
|
32316
|
+
const existing = this.reconcileStates.get(key);
|
|
32317
|
+
if (existing) {
|
|
32318
|
+
existing.pendingSource = params.source;
|
|
32319
|
+
await existing.promise;
|
|
32320
|
+
return;
|
|
32321
|
+
}
|
|
32322
|
+
const state = {
|
|
32323
|
+
pendingSource: undefined,
|
|
32324
|
+
promise: Promise.resolve()
|
|
32325
|
+
};
|
|
32326
|
+
state.promise = (async () => {
|
|
32327
|
+
try {
|
|
32328
|
+
do {
|
|
32329
|
+
const source = state.pendingSource ?? params.source;
|
|
32330
|
+
state.pendingSource = undefined;
|
|
32331
|
+
const snapshots = this.deps.taskSnapshotState.listForRole(params.chatroomId, params.role);
|
|
32332
|
+
if (snapshots.length === 0) {
|
|
32333
|
+
logNativeDeliveryDecision(source, params.role, params.chatroomId, "idle", undefined, {
|
|
32334
|
+
reason: "no_deliverable_task",
|
|
32335
|
+
attemptId: `${Date.now()}-${params.chatroomId}-${params.role}`
|
|
32336
|
+
});
|
|
32337
|
+
}
|
|
32338
|
+
await this.reconcileRole(source, snapshots, params.onTaskDelivered);
|
|
32339
|
+
} while (state.pendingSource !== undefined);
|
|
32340
|
+
} finally {
|
|
32341
|
+
if (this.reconcileStates.get(key) === state)
|
|
32342
|
+
this.reconcileStates.delete(key);
|
|
32343
|
+
}
|
|
32344
|
+
})();
|
|
32345
|
+
this.reconcileStates.set(key, state);
|
|
32346
|
+
await state.promise;
|
|
32347
|
+
}
|
|
32348
|
+
async requestReconcileForSnapshots(snapshots, source) {
|
|
32349
|
+
const roles = new Set(snapshots.map((snapshot) => `${snapshot.chatroomId}:${snapshot.agentConfig.role.toLowerCase()}`));
|
|
32350
|
+
await Promise.all([...roles].map((key) => {
|
|
32351
|
+
const separator = key.indexOf(":");
|
|
32352
|
+
return this.requestReconcile({
|
|
32353
|
+
chatroomId: key.slice(0, separator),
|
|
32354
|
+
role: key.slice(separator + 1),
|
|
32355
|
+
source
|
|
32356
|
+
});
|
|
32357
|
+
}));
|
|
32358
|
+
}
|
|
32359
|
+
async reconcileRole(pass, snapshots, onTaskDelivered) {
|
|
32360
|
+
if (snapshots.length === 0)
|
|
32361
|
+
return;
|
|
32362
|
+
await processTasksUpdate(this.deps.runtime, this.deps.effectContext, this.deps.agentMgr, this.deps.runSerializedForAgent, this.deps.taskService, this.deps.sessionDeps, this.deps.machineId, pass, this.deps.lifecycleOutbox, this.deps.agentOperationalReadModel, ({ chatroomId, role, taskId }) => this.deps.agentTaskState.get({ chatroomId, role })?.taskId === taskId, {
|
|
32363
|
+
snapshots,
|
|
32364
|
+
onTaskDelivered: (args2) => {
|
|
32365
|
+
this.recordTaskDelivered(args2);
|
|
32366
|
+
onTaskDelivered?.(args2);
|
|
32367
|
+
}
|
|
32368
|
+
});
|
|
32369
|
+
}
|
|
32370
|
+
recordTaskDelivered(args2) {
|
|
32371
|
+
this.deps.agentTaskState.start(args2);
|
|
32372
|
+
}
|
|
32373
|
+
}
|
|
32374
|
+
var NATIVE_DELIVERY_RECONCILE_MS = 1e4;
|
|
32375
|
+
var init_native_delivery_service = __esm(() => {
|
|
32376
|
+
init_task_delivery_processor();
|
|
32377
|
+
});
|
|
32378
|
+
|
|
31789
32379
|
// src/daemon/services/task-service/service/task-outbox.ts
|
|
31790
32380
|
class TaskOutbox {
|
|
31791
32381
|
sender;
|
|
@@ -46535,42 +47125,6 @@ var init_assigned_task_snapshot_contract = __esm(() => {
|
|
|
46535
47125
|
}));
|
|
46536
47126
|
});
|
|
46537
47127
|
|
|
46538
|
-
// src/infrastructure/mappers/map-assigned-task.ts
|
|
46539
|
-
function mapAssignedTaskSnapshot(row) {
|
|
46540
|
-
return {
|
|
46541
|
-
taskId: row.taskId,
|
|
46542
|
-
chatroomId: row.chatroomId,
|
|
46543
|
-
status: row.status,
|
|
46544
|
-
assignedTo: row.assignedTo,
|
|
46545
|
-
updatedAt: row.updatedAt,
|
|
46546
|
-
createdAt: row.createdAt,
|
|
46547
|
-
agentConfig: {
|
|
46548
|
-
role: row.agentConfig.role,
|
|
46549
|
-
machineId: row.agentConfig.machineId,
|
|
46550
|
-
agentHarness: row.agentConfig.agentHarness,
|
|
46551
|
-
model: row.agentConfig.model,
|
|
46552
|
-
workingDir: row.agentConfig.workingDir,
|
|
46553
|
-
spawnedAgentPid: row.agentConfig.spawnedAgentPid,
|
|
46554
|
-
desiredState: row.agentConfig.desiredState,
|
|
46555
|
-
circuitState: row.agentConfig.circuitState,
|
|
46556
|
-
configLifecycleRevision: row.agentConfig.configLifecycleRevision
|
|
46557
|
-
},
|
|
46558
|
-
participant: row.participant,
|
|
46559
|
-
requestsNativeColdSession: row.requestsNativeColdSession
|
|
46560
|
-
};
|
|
46561
|
-
}
|
|
46562
|
-
function mapAssignedTaskView(row) {
|
|
46563
|
-
return {
|
|
46564
|
-
...mapAssignedTaskSnapshot(row),
|
|
46565
|
-
taskContent: row.taskContent,
|
|
46566
|
-
taskEnvelope: row.taskEnvelope,
|
|
46567
|
-
startInNewSession: row.startInNewSession
|
|
46568
|
-
};
|
|
46569
|
-
}
|
|
46570
|
-
function mapAssignedTaskSnapshotList(rows) {
|
|
46571
|
-
return rows.map(mapAssignedTaskSnapshot);
|
|
46572
|
-
}
|
|
46573
|
-
|
|
46574
47128
|
// src/daemon/infrastructure/inbox/fetch-machine-assigned-task-snapshots.ts
|
|
46575
47129
|
async function fetchMachineAssignedTaskSnapshots(sessionDeps, machineId) {
|
|
46576
47130
|
const result = await sessionDeps.backend.query(api.machines.listMachineAssignedTaskSnapshots, {
|
|
@@ -47025,7 +47579,7 @@ function createTaskService(deps) {
|
|
|
47025
47579
|
roomControllers.set(chatroomId, controller);
|
|
47026
47580
|
runRoomInbox(chatroomId, cursor, controller);
|
|
47027
47581
|
};
|
|
47028
|
-
|
|
47582
|
+
const service4 = {
|
|
47029
47583
|
startTaskInbox: async (client2) => {
|
|
47030
47584
|
if (inboxClient)
|
|
47031
47585
|
return;
|
|
@@ -47075,11 +47629,22 @@ function createTaskService(deps) {
|
|
|
47075
47629
|
deliverNativeTask: (task, harnessSessionId, onTaskDelivered) => taskOutbox.enqueue({ task, harnessSessionId, onTaskDelivered }),
|
|
47076
47630
|
isNativeHarness,
|
|
47077
47631
|
snapshotRequestsNativeColdSession,
|
|
47078
|
-
explainNativeDeliveryBlock: (task, options) => explainNativeDeliveryBlock(task, options)
|
|
47632
|
+
explainNativeDeliveryBlock: (task, options) => explainNativeDeliveryBlock(task, options),
|
|
47633
|
+
createNativeDeliveryService: (deliveryDeps) => {
|
|
47634
|
+
const nativeDelivery = new NativeDeliveryService({
|
|
47635
|
+
...deliveryDeps,
|
|
47636
|
+
taskSnapshotState,
|
|
47637
|
+
taskService: service4
|
|
47638
|
+
});
|
|
47639
|
+
nativeDelivery.startPeriodicReconciliation();
|
|
47640
|
+
return nativeDelivery;
|
|
47641
|
+
}
|
|
47079
47642
|
};
|
|
47643
|
+
return service4;
|
|
47080
47644
|
}
|
|
47081
47645
|
var init_task_service = __esm(() => {
|
|
47082
47646
|
init_esm();
|
|
47647
|
+
init_native_delivery_service();
|
|
47083
47648
|
init_native_task_injector();
|
|
47084
47649
|
init_api3();
|
|
47085
47650
|
init_fetch_machine_assigned_task_snapshots();
|
|
@@ -47098,6 +47663,10 @@ var init_task_service2 = __esm(() => {
|
|
|
47098
47663
|
init_native_ready_invariant();
|
|
47099
47664
|
init_native_cold_session_delivery();
|
|
47100
47665
|
init_task_service();
|
|
47666
|
+
init_convex_native_task_delivery_gateway();
|
|
47667
|
+
init_daemon_audit_port();
|
|
47668
|
+
init_native_delivery_service();
|
|
47669
|
+
init_native_task_delivery_coordinator();
|
|
47101
47670
|
});
|
|
47102
47671
|
|
|
47103
47672
|
// src/daemon/services/service-interfaces.ts
|
|
@@ -47109,8 +47678,10 @@ __export(exports_service_interfaces, {
|
|
|
47109
47678
|
shouldDeliverNativeTask: () => shouldDeliverNativeTask,
|
|
47110
47679
|
setNativeTurnPhase: () => setNativeTurnPhase,
|
|
47111
47680
|
runRoleScopedStop: () => runRoleScopedStop,
|
|
47681
|
+
runNativeInjectionEffect: () => runNativeInjectionEffect,
|
|
47112
47682
|
runExactTargetsStop: () => runExactTargetsStop,
|
|
47113
47683
|
runConfirmedStop: () => runConfirmedStop,
|
|
47684
|
+
resetRoleDeliveryState: () => resetRoleDeliveryState,
|
|
47114
47685
|
resetChatroomScopeBarrierForTests: () => resetChatroomScopeBarrierForTests,
|
|
47115
47686
|
reapOrphanedProcessGroupsEffect: () => reapOrphanedProcessGroupsEffect,
|
|
47116
47687
|
reapOrphanedProcessGroups: () => reapOrphanedProcessGroups,
|
|
@@ -47130,6 +47701,8 @@ __export(exports_service_interfaces, {
|
|
|
47130
47701
|
createStopAgentTargetsDeps: () => createStopAgentTargetsDeps,
|
|
47131
47702
|
createStopAgentConfirmedDeps: () => createStopAgentConfirmedDeps,
|
|
47132
47703
|
createHarnessActivityEmitter: () => createHarnessActivityEmitter,
|
|
47704
|
+
createDaemonAuditPort: () => createDaemonAuditPort,
|
|
47705
|
+
createConvexNativeTaskDeliveryGateway: () => createConvexNativeTaskDeliveryGateway,
|
|
47133
47706
|
createChatroomScopeBarrier: () => createChatroomScopeBarrier,
|
|
47134
47707
|
createAgentTaskStateService: () => createAgentTaskStateService,
|
|
47135
47708
|
createAgentProcessService: () => createAgentProcessService,
|
|
@@ -47140,6 +47713,7 @@ __export(exports_service_interfaces, {
|
|
|
47140
47713
|
buildStopTargetDescriptor: () => buildStopTargetDescriptor,
|
|
47141
47714
|
buildNativeInjectionPrompt: () => buildNativeInjectionPrompt,
|
|
47142
47715
|
STOPPING_TIMEOUT_MS: () => STOPPING_TIMEOUT_MS,
|
|
47716
|
+
NativeDeliveryService: () => NativeDeliveryService,
|
|
47143
47717
|
InMemoryActiveTaskStateStore: () => InMemoryActiveTaskStateStore,
|
|
47144
47718
|
HARNESS_ACTIVITY_KINDS: () => HARNESS_ACTIVITY_KINDS,
|
|
47145
47719
|
DefaultAgentTaskStateService: () => DefaultAgentTaskStateService,
|
|
@@ -110113,6 +110687,346 @@ var init_command_sync_heartbeat = __esm(() => {
|
|
|
110113
110687
|
});
|
|
110114
110688
|
});
|
|
110115
110689
|
|
|
110690
|
+
// src/daemon/entry/refresh-models-outcome.ts
|
|
110691
|
+
function capabilitiesOutcomeToStatus(outcome) {
|
|
110692
|
+
switch (outcome.kind) {
|
|
110693
|
+
case "pushed":
|
|
110694
|
+
return { status: "completed" };
|
|
110695
|
+
case "skipped_no_changes":
|
|
110696
|
+
return { status: "skipped_no_changes" };
|
|
110697
|
+
case "failed":
|
|
110698
|
+
return { status: "failed", errorMessage: outcome.message };
|
|
110699
|
+
case "noop":
|
|
110700
|
+
return { status: "failed", errorMessage: "Daemon configuration unavailable" };
|
|
110701
|
+
default: {
|
|
110702
|
+
const _exhaustive = outcome;
|
|
110703
|
+
return _exhaustive;
|
|
110704
|
+
}
|
|
110705
|
+
}
|
|
110706
|
+
}
|
|
110707
|
+
var init_refresh_models_outcome = () => {};
|
|
110708
|
+
|
|
110709
|
+
// src/daemon/entry/resolve-local-web-port.ts
|
|
110710
|
+
function resolveDefaultLocalWebPort(convexUrl = getConvexUrl()) {
|
|
110711
|
+
return isProductionConvexUrl(convexUrl) ? PRODUCTION_LOCAL_WEB_PORT : NON_PRODUCTION_LOCAL_WEB_PORT;
|
|
110712
|
+
}
|
|
110713
|
+
function resolveLocalWebPort(env2 = process.env, convexUrl = getConvexUrl()) {
|
|
110714
|
+
const override = env2.CHATROOM_LOCAL_WEB_PORT;
|
|
110715
|
+
if (override !== undefined && override !== "") {
|
|
110716
|
+
return Number(override);
|
|
110717
|
+
}
|
|
110718
|
+
return resolveDefaultLocalWebPort(convexUrl);
|
|
110719
|
+
}
|
|
110720
|
+
var PRODUCTION_LOCAL_WEB_PORT = 18765, NON_PRODUCTION_LOCAL_WEB_PORT = 28765;
|
|
110721
|
+
var init_resolve_local_web_port = __esm(() => {
|
|
110722
|
+
init_env();
|
|
110723
|
+
init_client2();
|
|
110724
|
+
});
|
|
110725
|
+
|
|
110726
|
+
// src/daemon/infrastructure/git/git-writer.ts
|
|
110727
|
+
function classifyError2(errMessage) {
|
|
110728
|
+
return { status: "error", message: errMessage.trim() };
|
|
110729
|
+
}
|
|
110730
|
+
async function discardFile(workingDir, filePath) {
|
|
110731
|
+
const result = await runGit(["checkout", "--", filePath], workingDir);
|
|
110732
|
+
if ("error" in result) {
|
|
110733
|
+
return classifyError2(result.error.message);
|
|
110734
|
+
}
|
|
110735
|
+
return { status: "available" };
|
|
110736
|
+
}
|
|
110737
|
+
async function discardAllChanges(workingDir) {
|
|
110738
|
+
const checkoutResult = await runGit(["checkout", "--", "."], workingDir);
|
|
110739
|
+
if ("error" in checkoutResult) {
|
|
110740
|
+
return classifyError2(checkoutResult.error.message);
|
|
110741
|
+
}
|
|
110742
|
+
const cleanResult = await runGit(["clean", "-fd"], workingDir);
|
|
110743
|
+
if ("error" in cleanResult) {
|
|
110744
|
+
return classifyError2(cleanResult.error.message);
|
|
110745
|
+
}
|
|
110746
|
+
return { status: "available" };
|
|
110747
|
+
}
|
|
110748
|
+
async function gitPull(workingDir) {
|
|
110749
|
+
const result = await runGit(["pull"], workingDir);
|
|
110750
|
+
if ("error" in result) {
|
|
110751
|
+
const message = result.error.message;
|
|
110752
|
+
if (message.includes("no tracking branch")) {
|
|
110753
|
+
return {
|
|
110754
|
+
status: "error",
|
|
110755
|
+
message: "No tracking branch configured. Set upstream with `git push -u`."
|
|
110756
|
+
};
|
|
110757
|
+
}
|
|
110758
|
+
if (message.includes("conflict")) {
|
|
110759
|
+
return { status: "error", message: "Merge conflict detected. Resolve conflicts manually." };
|
|
110760
|
+
}
|
|
110761
|
+
if (message.includes("Authentication failed") || message.includes("could not read")) {
|
|
110762
|
+
return {
|
|
110763
|
+
status: "error",
|
|
110764
|
+
message: "Authentication failed. Run `gh auth status` to check your GitHub credentials."
|
|
110765
|
+
};
|
|
110766
|
+
}
|
|
110767
|
+
return classifyError2(message);
|
|
110768
|
+
}
|
|
110769
|
+
const stderr = result.stderr.trim();
|
|
110770
|
+
if (stderr && !stderr.includes("Already up to date")) {
|
|
110771
|
+
return { status: "available", message: stderr };
|
|
110772
|
+
}
|
|
110773
|
+
return { status: "available" };
|
|
110774
|
+
}
|
|
110775
|
+
async function gitPush(workingDir) {
|
|
110776
|
+
const result = await runGit(["push"], workingDir);
|
|
110777
|
+
if ("error" in result) {
|
|
110778
|
+
const message = result.error.message;
|
|
110779
|
+
if (message.includes("no upstream branch")) {
|
|
110780
|
+
return {
|
|
110781
|
+
status: "error",
|
|
110782
|
+
message: "No upstream branch configured. Set upstream with `git push -u`."
|
|
110783
|
+
};
|
|
110784
|
+
}
|
|
110785
|
+
if (message.includes("Authentication failed") || message.includes("could not read")) {
|
|
110786
|
+
return {
|
|
110787
|
+
status: "error",
|
|
110788
|
+
message: "Authentication failed. Run `gh auth status` to check your GitHub credentials."
|
|
110789
|
+
};
|
|
110790
|
+
}
|
|
110791
|
+
return classifyError2(message);
|
|
110792
|
+
}
|
|
110793
|
+
const stderr = result.stderr.trim();
|
|
110794
|
+
if (stderr && !stderr.includes("Everything up-to-date")) {
|
|
110795
|
+
return { status: "available", message: stderr };
|
|
110796
|
+
}
|
|
110797
|
+
return { status: "available" };
|
|
110798
|
+
}
|
|
110799
|
+
async function gitSync(workingDir) {
|
|
110800
|
+
const pullResult = await gitPull(workingDir);
|
|
110801
|
+
if (pullResult.status === "error") {
|
|
110802
|
+
return pullResult;
|
|
110803
|
+
}
|
|
110804
|
+
return gitPush(workingDir);
|
|
110805
|
+
}
|
|
110806
|
+
var init_git_writer = __esm(() => {
|
|
110807
|
+
init_run_command();
|
|
110808
|
+
});
|
|
110809
|
+
|
|
110810
|
+
// src/daemon/infrastructure/git/index.ts
|
|
110811
|
+
var init_git = __esm(() => {
|
|
110812
|
+
init_git_reader();
|
|
110813
|
+
init_git_writer();
|
|
110814
|
+
});
|
|
110815
|
+
|
|
110816
|
+
// src/infrastructure/local-actions/execute-local-action.ts
|
|
110817
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
110818
|
+
import { access as access3 } from "node:fs/promises";
|
|
110819
|
+
function escapeShellArg(arg) {
|
|
110820
|
+
return `"${arg.replace(/"/g, "\\\"")}"`;
|
|
110821
|
+
}
|
|
110822
|
+
function resolveWhichCommand(name) {
|
|
110823
|
+
return process.platform === "win32" ? `where ${name}` : `which ${name}`;
|
|
110824
|
+
}
|
|
110825
|
+
function isCliAvailable(cliName) {
|
|
110826
|
+
return new Promise((resolve5) => {
|
|
110827
|
+
const child = spawn5(resolveWhichCommand(cliName), [], DETACHED_SHELL_SPAWN_OPTIONS);
|
|
110828
|
+
child.on("error", () => resolve5(false));
|
|
110829
|
+
child.on("close", (code2) => resolve5(code2 === 0));
|
|
110830
|
+
child.unref();
|
|
110831
|
+
});
|
|
110832
|
+
}
|
|
110833
|
+
function execFireAndForget(command, logTag) {
|
|
110834
|
+
const child = spawn5(command, [], DETACHED_SHELL_SPAWN_OPTIONS);
|
|
110835
|
+
child.on("error", (err) => {
|
|
110836
|
+
console.warn(`[${logTag}] spawn failed: ${err.message}`);
|
|
110837
|
+
});
|
|
110838
|
+
child.unref();
|
|
110839
|
+
}
|
|
110840
|
+
function resolveOpenCommand(platform) {
|
|
110841
|
+
switch (platform) {
|
|
110842
|
+
case "darwin":
|
|
110843
|
+
return "open";
|
|
110844
|
+
case "win32":
|
|
110845
|
+
return "explorer";
|
|
110846
|
+
default:
|
|
110847
|
+
return "xdg-open";
|
|
110848
|
+
}
|
|
110849
|
+
}
|
|
110850
|
+
function resolveOpenUrlCommand(platform) {
|
|
110851
|
+
return platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
|
|
110852
|
+
}
|
|
110853
|
+
async function openVscode(workingDir) {
|
|
110854
|
+
const available = await isCliAvailable("code");
|
|
110855
|
+
if (!available) {
|
|
110856
|
+
return {
|
|
110857
|
+
success: false,
|
|
110858
|
+
error: "VS Code CLI (code) not found. Install via: VS Code → Cmd+Shift+P → 'Shell Command: Install code in PATH'"
|
|
110859
|
+
};
|
|
110860
|
+
}
|
|
110861
|
+
execFireAndForget(`code ${escapeShellArg(workingDir)}`, "open-vscode");
|
|
110862
|
+
return { success: true };
|
|
110863
|
+
}
|
|
110864
|
+
async function openFinder(workingDir) {
|
|
110865
|
+
const cmd = resolveOpenCommand(process.platform);
|
|
110866
|
+
execFireAndForget(`${cmd} ${escapeShellArg(workingDir)}`, "open-finder");
|
|
110867
|
+
return { success: true };
|
|
110868
|
+
}
|
|
110869
|
+
async function openCursor(workingDir) {
|
|
110870
|
+
const available = await isCliAvailable("cursor");
|
|
110871
|
+
if (!available) {
|
|
110872
|
+
return {
|
|
110873
|
+
success: false,
|
|
110874
|
+
error: "Cursor CLI (cursor) not found. Install via: Cursor → Cmd+Shift+P → 'Shell Command: Install cursor in PATH'"
|
|
110875
|
+
};
|
|
110876
|
+
}
|
|
110877
|
+
execFireAndForget(`cursor ${escapeShellArg(workingDir)}`, "open-cursor");
|
|
110878
|
+
return { success: true };
|
|
110879
|
+
}
|
|
110880
|
+
async function openGithubDesktop(workingDir) {
|
|
110881
|
+
const available = await isCliAvailable("github");
|
|
110882
|
+
if (!available) {
|
|
110883
|
+
return { success: false, error: "GitHub Desktop CLI not found" };
|
|
110884
|
+
}
|
|
110885
|
+
execFireAndForget(`github ${escapeShellArg(workingDir)}`, "open-github-desktop");
|
|
110886
|
+
return { success: true };
|
|
110887
|
+
}
|
|
110888
|
+
async function openDaemonLogs(_workingDir, options) {
|
|
110889
|
+
const params = new URLSearchParams;
|
|
110890
|
+
if (options?.chatroomId)
|
|
110891
|
+
params.set("chatroomId", options.chatroomId);
|
|
110892
|
+
const qs = params.toString();
|
|
110893
|
+
const url3 = `http://127.0.0.1:${resolveLocalWebPort()}/${qs ? `?${qs}` : ""}`;
|
|
110894
|
+
execFireAndForget(`${resolveOpenUrlCommand(process.platform)} ${escapeShellArg(url3)}`, "open-daemon-logs");
|
|
110895
|
+
return { success: true };
|
|
110896
|
+
}
|
|
110897
|
+
async function gitDiscardFileAction(workingDir) {
|
|
110898
|
+
const separatorIndex = workingDir.indexOf("::");
|
|
110899
|
+
if (separatorIndex === -1) {
|
|
110900
|
+
return {
|
|
110901
|
+
success: false,
|
|
110902
|
+
error: 'Invalid file path. Expected format: "/path/to/dir::/path/to/file"'
|
|
110903
|
+
};
|
|
110904
|
+
}
|
|
110905
|
+
const dir = workingDir.slice(0, separatorIndex);
|
|
110906
|
+
const filePath = workingDir.slice(separatorIndex + 2);
|
|
110907
|
+
const result = await discardFile(dir, filePath);
|
|
110908
|
+
if (result.status === "error") {
|
|
110909
|
+
return { success: false, error: result.message };
|
|
110910
|
+
}
|
|
110911
|
+
return { success: true };
|
|
110912
|
+
}
|
|
110913
|
+
async function gitDiscardAllAction(workingDir) {
|
|
110914
|
+
const result = await discardAllChanges(workingDir);
|
|
110915
|
+
if (result.status === "error") {
|
|
110916
|
+
return { success: false, error: result.message };
|
|
110917
|
+
}
|
|
110918
|
+
return { success: true };
|
|
110919
|
+
}
|
|
110920
|
+
async function gitPullAction(workingDir) {
|
|
110921
|
+
const result = await gitPull(workingDir);
|
|
110922
|
+
if (result.status === "error") {
|
|
110923
|
+
return { success: false, error: result.message };
|
|
110924
|
+
}
|
|
110925
|
+
return { success: true, message: result.message ?? "Pull successful" };
|
|
110926
|
+
}
|
|
110927
|
+
async function gitPushAction(workingDir) {
|
|
110928
|
+
const result = await gitPush(workingDir);
|
|
110929
|
+
if (result.status === "error") {
|
|
110930
|
+
return { success: false, error: result.message };
|
|
110931
|
+
}
|
|
110932
|
+
return { success: true, message: result.message ?? "Push successful" };
|
|
110933
|
+
}
|
|
110934
|
+
async function gitSyncAction(workingDir) {
|
|
110935
|
+
const result = await gitSync(workingDir);
|
|
110936
|
+
if (result.status === "error") {
|
|
110937
|
+
return { success: false, error: result.message };
|
|
110938
|
+
}
|
|
110939
|
+
return { success: true, message: result.message ?? "Sync successful" };
|
|
110940
|
+
}
|
|
110941
|
+
async function executeLocalAction(action, workingDir, options) {
|
|
110942
|
+
if (action === "open-daemon-logs")
|
|
110943
|
+
return openDaemonLogs(workingDir, options);
|
|
110944
|
+
try {
|
|
110945
|
+
await access3(workingDir);
|
|
110946
|
+
} catch {
|
|
110947
|
+
return { success: false, error: `Directory not found: ${workingDir}` };
|
|
110948
|
+
}
|
|
110949
|
+
const handler2 = actionHandlers[action];
|
|
110950
|
+
if (handler2)
|
|
110951
|
+
return handler2(workingDir);
|
|
110952
|
+
return { success: false, error: `Unknown action: ${action}` };
|
|
110953
|
+
}
|
|
110954
|
+
var DETACHED_SHELL_SPAWN_OPTIONS, actionHandlers;
|
|
110955
|
+
var init_execute_local_action = __esm(() => {
|
|
110956
|
+
init_resolve_local_web_port();
|
|
110957
|
+
init_git();
|
|
110958
|
+
DETACHED_SHELL_SPAWN_OPTIONS = {
|
|
110959
|
+
stdio: "ignore",
|
|
110960
|
+
detached: true,
|
|
110961
|
+
shell: true
|
|
110962
|
+
};
|
|
110963
|
+
actionHandlers = {
|
|
110964
|
+
"open-vscode": openVscode,
|
|
110965
|
+
"open-finder": openFinder,
|
|
110966
|
+
"open-cursor": openCursor,
|
|
110967
|
+
"open-github-desktop": openGithubDesktop,
|
|
110968
|
+
"open-daemon-logs": openDaemonLogs,
|
|
110969
|
+
"git-discard-file": gitDiscardFileAction,
|
|
110970
|
+
"git-discard-all": gitDiscardAllAction,
|
|
110971
|
+
"git-pull": gitPullAction,
|
|
110972
|
+
"git-push": gitPushAction,
|
|
110973
|
+
"git-sync": gitSyncAction
|
|
110974
|
+
};
|
|
110975
|
+
});
|
|
110976
|
+
|
|
110977
|
+
// src/infrastructure/local-actions/index.ts
|
|
110978
|
+
var init_local_actions = __esm(() => {
|
|
110979
|
+
init_execute_local_action();
|
|
110980
|
+
});
|
|
110981
|
+
|
|
110982
|
+
// src/infrastructure/local-actions/pick-folder.ts
|
|
110983
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
110984
|
+
function runPicker(command, args2) {
|
|
110985
|
+
try {
|
|
110986
|
+
const path3 = execFileSync2(command, args2, { encoding: "utf8", timeout: 300000 }).trim();
|
|
110987
|
+
if (!path3)
|
|
110988
|
+
return { success: false, error: "No folder selected" };
|
|
110989
|
+
return { success: true, path: path3 };
|
|
110990
|
+
} catch (error51) {
|
|
110991
|
+
const exitCode = typeof error51 === "object" && error51 !== null && "status" in error51 ? error51.status : null;
|
|
110992
|
+
if (exitCode === 1)
|
|
110993
|
+
return { success: false, error: "Cancelled", cancelled: true };
|
|
110994
|
+
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
110995
|
+
return { success: false, error: message };
|
|
110996
|
+
}
|
|
110997
|
+
}
|
|
110998
|
+
function pickFolderDialog() {
|
|
110999
|
+
switch (process.platform) {
|
|
111000
|
+
case "darwin":
|
|
111001
|
+
return runPicker("osascript", [
|
|
111002
|
+
"-e",
|
|
111003
|
+
'POSIX path of (choose folder with prompt "Select workspace folder")'
|
|
111004
|
+
]);
|
|
111005
|
+
case "win32":
|
|
111006
|
+
return runPicker("powershell", [
|
|
111007
|
+
"-NoProfile",
|
|
111008
|
+
"-Command",
|
|
111009
|
+
[
|
|
111010
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
111011
|
+
"$dialog = New-Object System.Windows.Forms.FolderBrowserDialog",
|
|
111012
|
+
'$dialog.Description = "Select workspace folder"',
|
|
111013
|
+
"if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {",
|
|
111014
|
+
" Write-Output $dialog.SelectedPath",
|
|
111015
|
+
" exit 0",
|
|
111016
|
+
"}",
|
|
111017
|
+
"exit 1"
|
|
111018
|
+
].join("; ")
|
|
111019
|
+
]);
|
|
111020
|
+
default:
|
|
111021
|
+
return runPicker("zenity", [
|
|
111022
|
+
"--file-selection",
|
|
111023
|
+
"--directory",
|
|
111024
|
+
"--title=Select workspace folder"
|
|
111025
|
+
]);
|
|
111026
|
+
}
|
|
111027
|
+
}
|
|
111028
|
+
var init_pick_folder = () => {};
|
|
111029
|
+
|
|
110116
111030
|
// src/daemon/domain/usecase/restart-agent.ts
|
|
110117
111031
|
async function restartAgent(deps, input) {
|
|
110118
111032
|
const now = deps.now?.() ?? Date.now();
|
|
@@ -110134,7 +111048,9 @@ async function restartAgent(deps, input) {
|
|
|
110134
111048
|
wantResume: input.wantResume,
|
|
110135
111049
|
...input.lifecycleRevision !== undefined ? { lifecycleRevision: input.lifecycleRevision } : {}
|
|
110136
111050
|
});
|
|
110137
|
-
} catch {
|
|
111051
|
+
} catch (error51) {
|
|
111052
|
+
log4(`[daemon] agent.restart failed (correlationId=${input.correlationId}) for role=${input.role}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
111053
|
+
}
|
|
110138
111054
|
}
|
|
110139
111055
|
|
|
110140
111056
|
// ../../services/backend/src/domain/usecase/agent/build-agent-restart-event.ts
|
|
@@ -110165,200 +111081,6 @@ var init_build_agent_restart_event = __esm(() => {
|
|
|
110165
111081
|
init_reliability();
|
|
110166
111082
|
});
|
|
110167
111083
|
|
|
110168
|
-
// src/daemon/infrastructure/agent-operational/fetch-machine-agent-operational-status.ts
|
|
110169
|
-
async function fetchMachineAgentOperationalStatus(sessionDeps, machineId) {
|
|
110170
|
-
const result = await sessionDeps.backend.query(api.machines.listMachineAgentOperationalStatus, {
|
|
110171
|
-
sessionId: sessionDeps.sessionId,
|
|
110172
|
-
machineId
|
|
110173
|
-
});
|
|
110174
|
-
return result;
|
|
110175
|
-
}
|
|
110176
|
-
var init_fetch_machine_agent_operational_status = __esm(() => {
|
|
110177
|
-
init_api3();
|
|
110178
|
-
});
|
|
110179
|
-
|
|
110180
|
-
// src/daemon/entry/native-delivery/native-delivery-log.ts
|
|
110181
|
-
function logNativeDeliveryTrigger(source, role, chatroomId, taskId) {
|
|
110182
|
-
const taskSuffix = taskId ? ` task ${taskId}` : "";
|
|
110183
|
-
console.log(`[NativeDelivery:trigger] source=${source} ${role}@${chatroomId}${taskSuffix}`);
|
|
110184
|
-
}
|
|
110185
|
-
function logNativeDeliveryFallback(reason, role, chatroomId, taskId) {
|
|
110186
|
-
const taskSuffix = taskId ? ` task ${taskId}` : "";
|
|
110187
|
-
console.log(`[NativeDelivery:fallback] source=${reason} ${role}@${chatroomId}${taskSuffix} — periodic recovery pass`);
|
|
110188
|
-
}
|
|
110189
|
-
function logNativeDeliverySkip(role, chatroomId, taskId, reason) {
|
|
110190
|
-
console.log(`[NativeDelivery:skip] ${role}@${chatroomId} task ${taskId} — ${reason}`);
|
|
110191
|
-
}
|
|
110192
|
-
function logNativeDeliveryMutexSkip(role, chatroomId, taskId) {
|
|
110193
|
-
console.log(`[NativeDelivery:skip] ${role}@${chatroomId} task ${taskId} — delivery_mutex_busy (another inject in flight)`);
|
|
110194
|
-
}
|
|
110195
|
-
function logNativeDeliveryInjecting(role, chatroomId, taskId) {
|
|
110196
|
-
console.log(`[NativeDelivery:inject] ${role}@${chatroomId} task ${taskId} — starting injection`);
|
|
110197
|
-
}
|
|
110198
|
-
|
|
110199
|
-
// src/daemon/entry/restart-orchestrator-in-flight.ts
|
|
110200
|
-
function roleKey(chatroomId, role) {
|
|
110201
|
-
return `${chatroomId}:${role.toLowerCase()}`;
|
|
110202
|
-
}
|
|
110203
|
-
function markRestartOrchestratorInFlight(chatroomId, role, correlationId) {
|
|
110204
|
-
inFlight.set(roleKey(chatroomId, role), correlationId);
|
|
110205
|
-
}
|
|
110206
|
-
function clearRestartOrchestratorInFlight(chatroomId, role, correlationId) {
|
|
110207
|
-
const key = roleKey(chatroomId, role);
|
|
110208
|
-
if (correlationId !== undefined && inFlight.get(key) !== correlationId)
|
|
110209
|
-
return;
|
|
110210
|
-
inFlight.delete(key);
|
|
110211
|
-
}
|
|
110212
|
-
function isRestartOrchestratorInFlight(chatroomId, role) {
|
|
110213
|
-
return inFlight.has(roleKey(chatroomId, role));
|
|
110214
|
-
}
|
|
110215
|
-
function filterSnapshotsExcludingRestartInFlight(snapshots) {
|
|
110216
|
-
return snapshots.filter((row) => !isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role));
|
|
110217
|
-
}
|
|
110218
|
-
var inFlight;
|
|
110219
|
-
var init_restart_orchestrator_in_flight = __esm(() => {
|
|
110220
|
-
inFlight = new Map;
|
|
110221
|
-
});
|
|
110222
|
-
|
|
110223
|
-
// src/daemon/entry/role-delivery-state.ts
|
|
110224
|
-
function roleKey2(chatroomId, role) {
|
|
110225
|
-
return `${chatroomId}:${role.toLowerCase()}`;
|
|
110226
|
-
}
|
|
110227
|
-
|
|
110228
|
-
class RoleDeliveryState {
|
|
110229
|
-
generation = new Map;
|
|
110230
|
-
inFlight = new Set;
|
|
110231
|
-
nativeNudgeFailures = new Map;
|
|
110232
|
-
getGeneration(chatroomId, role) {
|
|
110233
|
-
return this.generation.get(roleKey2(chatroomId, role)) ?? 0;
|
|
110234
|
-
}
|
|
110235
|
-
resetDeliveryState(chatroomId, role) {
|
|
110236
|
-
const key = roleKey2(chatroomId, role);
|
|
110237
|
-
const next4 = (this.generation.get(key) ?? 0) + 1;
|
|
110238
|
-
this.generation.set(key, next4);
|
|
110239
|
-
this.inFlight.delete(key);
|
|
110240
|
-
this.nativeNudgeFailures.delete(key);
|
|
110241
|
-
return next4;
|
|
110242
|
-
}
|
|
110243
|
-
tryAcquireDelivery(chatroomId, role) {
|
|
110244
|
-
const key = roleKey2(chatroomId, role);
|
|
110245
|
-
if (this.inFlight.has(key))
|
|
110246
|
-
return false;
|
|
110247
|
-
this.inFlight.add(key);
|
|
110248
|
-
return true;
|
|
110249
|
-
}
|
|
110250
|
-
releaseDelivery(chatroomId, role) {
|
|
110251
|
-
this.inFlight.delete(roleKey2(chatroomId, role));
|
|
110252
|
-
}
|
|
110253
|
-
recordNativeNudgeFailure(chatroomId, role) {
|
|
110254
|
-
const key = roleKey2(chatroomId, role);
|
|
110255
|
-
const count3 = (this.nativeNudgeFailures.get(key) ?? 0) + 1;
|
|
110256
|
-
this.nativeNudgeFailures.set(key, count3);
|
|
110257
|
-
return count3;
|
|
110258
|
-
}
|
|
110259
|
-
clearNativeNudgeFailures(chatroomId, role) {
|
|
110260
|
-
this.nativeNudgeFailures.delete(roleKey2(chatroomId, role));
|
|
110261
|
-
}
|
|
110262
|
-
getNativeNudgeFailures(chatroomId, role) {
|
|
110263
|
-
return this.nativeNudgeFailures.get(roleKey2(chatroomId, role)) ?? 0;
|
|
110264
|
-
}
|
|
110265
|
-
}
|
|
110266
|
-
function getRoleDeliveryState() {
|
|
110267
|
-
shared ??= new RoleDeliveryState;
|
|
110268
|
-
return shared;
|
|
110269
|
-
}
|
|
110270
|
-
var shared;
|
|
110271
|
-
|
|
110272
|
-
// src/daemon/entry/native-delivery/native-task-delivery-coordinator.ts
|
|
110273
|
-
class NativeTaskDeliveryCoordinator {
|
|
110274
|
-
resetRoleDeliveryState(chatroomId, role) {
|
|
110275
|
-
getRoleDeliveryState().resetDeliveryState(chatroomId, role);
|
|
110276
|
-
}
|
|
110277
|
-
async reconcileAssignedTasks(params) {
|
|
110278
|
-
const tasks = filterSnapshotsExcludingRestartInFlight(params.tasks);
|
|
110279
|
-
if (tasks.length === 0)
|
|
110280
|
-
return;
|
|
110281
|
-
const {
|
|
110282
|
-
runtime: runtime4,
|
|
110283
|
-
effectContext: effectContext2,
|
|
110284
|
-
agentMgr,
|
|
110285
|
-
sessionDeps,
|
|
110286
|
-
operationalModel,
|
|
110287
|
-
isTaskActive,
|
|
110288
|
-
machineId,
|
|
110289
|
-
onTaskDelivered
|
|
110290
|
-
} = params;
|
|
110291
|
-
const deliveryState = getRoleDeliveryState();
|
|
110292
|
-
const taskService = params.taskService;
|
|
110293
|
-
const pendingFirst = [...tasks].sort((a, b) => {
|
|
110294
|
-
if (a.status === "pending" && b.status !== "pending")
|
|
110295
|
-
return -1;
|
|
110296
|
-
if (b.status === "pending" && a.status !== "pending")
|
|
110297
|
-
return 1;
|
|
110298
|
-
return a.createdAt - b.createdAt;
|
|
110299
|
-
});
|
|
110300
|
-
for (const row of pendingFirst) {
|
|
110301
|
-
const { role } = row.agentConfig;
|
|
110302
|
-
const slot = agentMgr.getSlot(row.chatroomId, role);
|
|
110303
|
-
const blockReason = taskService.explainNativeDeliveryBlock(row, {
|
|
110304
|
-
slot,
|
|
110305
|
-
operational: operationalModel.get(row.chatroomId, role)
|
|
110306
|
-
});
|
|
110307
|
-
if (blockReason) {
|
|
110308
|
-
if (isDeliverableTaskStatus(row.status)) {
|
|
110309
|
-
logNativeDeliverySkip(role, row.chatroomId, row.taskId, blockReason);
|
|
110310
|
-
}
|
|
110311
|
-
continue;
|
|
110312
|
-
}
|
|
110313
|
-
if (isTaskActive({ chatroomId: row.chatroomId, role, taskId: row.taskId })) {
|
|
110314
|
-
logNativeDeliverySkip(role, row.chatroomId, row.taskId, "task_state_active");
|
|
110315
|
-
continue;
|
|
110316
|
-
}
|
|
110317
|
-
const harnessSessionId = slot?.harnessSessionId;
|
|
110318
|
-
if (!deliveryState.tryAcquireDelivery(row.chatroomId, role)) {
|
|
110319
|
-
logNativeDeliveryMutexSkip(role, row.chatroomId, row.taskId);
|
|
110320
|
-
continue;
|
|
110321
|
-
}
|
|
110322
|
-
logNativeDeliveryInjecting(role, row.chatroomId, row.taskId);
|
|
110323
|
-
await exports_Runtime.runPromise(runtime4)(exports_Effect.gen(function* () {
|
|
110324
|
-
const backend2 = yield* exports_Effect.tryPromise(() => sessionDeps.backend.query(api.machines.getAssignedTaskForAction, {
|
|
110325
|
-
sessionId: sessionDeps.sessionId,
|
|
110326
|
-
machineId,
|
|
110327
|
-
taskId: row.taskId,
|
|
110328
|
-
role: row.agentConfig.role
|
|
110329
|
-
}));
|
|
110330
|
-
if (!backend2) {
|
|
110331
|
-
console.warn(`[NativeDelivery:skip] ${role}@${row.chatroomId} task ${row.taskId} — task_hydrate_missing (deleted or not assigned)`);
|
|
110332
|
-
return;
|
|
110333
|
-
}
|
|
110334
|
-
const full = mapAssignedTaskView(backend2);
|
|
110335
|
-
yield* exports_Effect.tryPromise(() => taskService.deliverNativeTask(full, harnessSessionId, (delivered) => {
|
|
110336
|
-
onTaskDelivered?.(delivered);
|
|
110337
|
-
deliveryState.clearNativeNudgeFailures(delivered.chatroomId, delivered.role);
|
|
110338
|
-
}));
|
|
110339
|
-
}).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[NativeTaskDelivery] delivery failed for ${row.agentConfig.role}@${row.chatroomId}: ${getErrorMessage(err)}`))), exports_Effect.ensuring(exports_Effect.sync(() => {
|
|
110340
|
-
deliveryState.releaseDelivery(row.chatroomId, row.agentConfig.role);
|
|
110341
|
-
}))));
|
|
110342
|
-
break;
|
|
110343
|
-
}
|
|
110344
|
-
}
|
|
110345
|
-
}
|
|
110346
|
-
function getNativeTaskDeliveryCoordinator() {
|
|
110347
|
-
coordinator ??= new NativeTaskDeliveryCoordinator;
|
|
110348
|
-
return coordinator;
|
|
110349
|
-
}
|
|
110350
|
-
function resetRoleDeliveryState(chatroomId, role) {
|
|
110351
|
-
getRoleDeliveryState().resetDeliveryState(chatroomId, role);
|
|
110352
|
-
}
|
|
110353
|
-
var coordinator;
|
|
110354
|
-
var init_native_task_delivery_coordinator = __esm(() => {
|
|
110355
|
-
init_esm();
|
|
110356
|
-
init_api3();
|
|
110357
|
-
init_assigned_task();
|
|
110358
|
-
init_convex_error();
|
|
110359
|
-
init_restart_orchestrator_in_flight();
|
|
110360
|
-
});
|
|
110361
|
-
|
|
110362
111084
|
// src/daemon/entry/restart-orchestrator.ts
|
|
110363
111085
|
async function emitPhase(deps, event, phase, detail) {
|
|
110364
111086
|
const now = Date.now();
|
|
@@ -110399,31 +111121,22 @@ async function forceNativeWaiting(deps, event) {
|
|
|
110399
111121
|
action: NATIVE_WAITING_ACTION
|
|
110400
111122
|
});
|
|
110401
111123
|
}
|
|
110402
|
-
async function
|
|
111124
|
+
async function syncAssignedTaskSnapshots(deps) {
|
|
110403
111125
|
await deps.session.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
|
|
110404
111126
|
sessionId: deps.session.sessionId,
|
|
110405
111127
|
machineId: deps.session.machineId
|
|
110406
111128
|
});
|
|
110407
|
-
const result = await deps.session.backend.query(api.machines.listMachineAssignedTaskSnapshots, {
|
|
110408
|
-
sessionId: deps.session.sessionId,
|
|
110409
|
-
machineId: deps.session.machineId
|
|
110410
|
-
});
|
|
110411
|
-
const operationalRows = await fetchMachineAgentOperationalStatus({
|
|
110412
|
-
sessionId: deps.session.sessionId,
|
|
110413
|
-
machineId: deps.session.machineId,
|
|
110414
|
-
convexUrl: deps.session.convexUrl,
|
|
110415
|
-
logEvent: deps.session.logEvent,
|
|
110416
|
-
backend: deps.session.backend
|
|
110417
|
-
}, deps.session.machineId);
|
|
110418
|
-
const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
|
|
110419
|
-
const operational = operationalRows.find((row) => row.chatroomId === event.chatroomId && row.role.toLowerCase() === event.role.toLowerCase());
|
|
110420
|
-
return mapAssignedTaskSnapshotList(parseAssignedTaskSnapshotRows(result.tasks ?? [])).filter((t) => t.chatroomId === event.chatroomId && t.agentConfig.role.toLowerCase() === event.role.toLowerCase() && isDeliverableTaskStatus(t.status) && isAgentReadyForNativeDelivery(t, slot, operational)).sort((a, b) => a.createdAt - b.createdAt);
|
|
110421
111129
|
}
|
|
110422
111130
|
async function deliverPendingTasks(deps, event) {
|
|
110423
111131
|
const delivered = [];
|
|
110424
|
-
|
|
110425
|
-
await deps.nativeDelivery.
|
|
110426
|
-
|
|
111132
|
+
await syncAssignedTaskSnapshots(deps);
|
|
111133
|
+
await deps.nativeDelivery.requestReconcile({
|
|
111134
|
+
chatroomId: event.chatroomId,
|
|
111135
|
+
role: event.role,
|
|
111136
|
+
source: "restart-completed",
|
|
111137
|
+
onTaskDelivered: ({ taskId }) => {
|
|
111138
|
+
delivered.push(taskId);
|
|
111139
|
+
}
|
|
110427
111140
|
});
|
|
110428
111141
|
return delivered;
|
|
110429
111142
|
}
|
|
@@ -110479,15 +111192,11 @@ async function runRestartOrchestrator(deps, event) {
|
|
|
110479
111192
|
var init_restart_orchestrator = __esm(() => {
|
|
110480
111193
|
init_reliability();
|
|
110481
111194
|
init_build_agent_restart_event();
|
|
110482
|
-
init_assigned_task_snapshot_contract();
|
|
110483
|
-
init_fetch_machine_agent_operational_status();
|
|
110484
|
-
init_api3();
|
|
110485
|
-
init_service_interfaces();
|
|
110486
|
-
init_native_task_delivery_coordinator();
|
|
110487
111195
|
init_restart_orchestrator_in_flight();
|
|
111196
|
+
init_api3();
|
|
110488
111197
|
init_convex_error();
|
|
110489
|
-
init_assigned_task();
|
|
110490
111198
|
init_execution_kind();
|
|
111199
|
+
init_service_interfaces();
|
|
110491
111200
|
});
|
|
110492
111201
|
|
|
110493
111202
|
// src/daemon/entry/bridge/agent-control-bridge.ts
|
|
@@ -110814,346 +111523,6 @@ var init_manager = __esm(() => {
|
|
|
110814
111523
|
processManager = new ProcessManager;
|
|
110815
111524
|
});
|
|
110816
111525
|
|
|
110817
|
-
// src/daemon/entry/refresh-models-outcome.ts
|
|
110818
|
-
function capabilitiesOutcomeToStatus(outcome) {
|
|
110819
|
-
switch (outcome.kind) {
|
|
110820
|
-
case "pushed":
|
|
110821
|
-
return { status: "completed" };
|
|
110822
|
-
case "skipped_no_changes":
|
|
110823
|
-
return { status: "skipped_no_changes" };
|
|
110824
|
-
case "failed":
|
|
110825
|
-
return { status: "failed", errorMessage: outcome.message };
|
|
110826
|
-
case "noop":
|
|
110827
|
-
return { status: "failed", errorMessage: "Daemon configuration unavailable" };
|
|
110828
|
-
default: {
|
|
110829
|
-
const _exhaustive = outcome;
|
|
110830
|
-
return _exhaustive;
|
|
110831
|
-
}
|
|
110832
|
-
}
|
|
110833
|
-
}
|
|
110834
|
-
var init_refresh_models_outcome = () => {};
|
|
110835
|
-
|
|
110836
|
-
// src/daemon/entry/resolve-local-web-port.ts
|
|
110837
|
-
function resolveDefaultLocalWebPort(convexUrl = getConvexUrl()) {
|
|
110838
|
-
return isProductionConvexUrl(convexUrl) ? PRODUCTION_LOCAL_WEB_PORT : NON_PRODUCTION_LOCAL_WEB_PORT;
|
|
110839
|
-
}
|
|
110840
|
-
function resolveLocalWebPort(env2 = process.env, convexUrl = getConvexUrl()) {
|
|
110841
|
-
const override = env2.CHATROOM_LOCAL_WEB_PORT;
|
|
110842
|
-
if (override !== undefined && override !== "") {
|
|
110843
|
-
return Number(override);
|
|
110844
|
-
}
|
|
110845
|
-
return resolveDefaultLocalWebPort(convexUrl);
|
|
110846
|
-
}
|
|
110847
|
-
var PRODUCTION_LOCAL_WEB_PORT = 18765, NON_PRODUCTION_LOCAL_WEB_PORT = 28765;
|
|
110848
|
-
var init_resolve_local_web_port = __esm(() => {
|
|
110849
|
-
init_env();
|
|
110850
|
-
init_client2();
|
|
110851
|
-
});
|
|
110852
|
-
|
|
110853
|
-
// src/daemon/infrastructure/git/git-writer.ts
|
|
110854
|
-
function classifyError2(errMessage) {
|
|
110855
|
-
return { status: "error", message: errMessage.trim() };
|
|
110856
|
-
}
|
|
110857
|
-
async function discardFile(workingDir, filePath) {
|
|
110858
|
-
const result = await runGit(["checkout", "--", filePath], workingDir);
|
|
110859
|
-
if ("error" in result) {
|
|
110860
|
-
return classifyError2(result.error.message);
|
|
110861
|
-
}
|
|
110862
|
-
return { status: "available" };
|
|
110863
|
-
}
|
|
110864
|
-
async function discardAllChanges(workingDir) {
|
|
110865
|
-
const checkoutResult = await runGit(["checkout", "--", "."], workingDir);
|
|
110866
|
-
if ("error" in checkoutResult) {
|
|
110867
|
-
return classifyError2(checkoutResult.error.message);
|
|
110868
|
-
}
|
|
110869
|
-
const cleanResult = await runGit(["clean", "-fd"], workingDir);
|
|
110870
|
-
if ("error" in cleanResult) {
|
|
110871
|
-
return classifyError2(cleanResult.error.message);
|
|
110872
|
-
}
|
|
110873
|
-
return { status: "available" };
|
|
110874
|
-
}
|
|
110875
|
-
async function gitPull(workingDir) {
|
|
110876
|
-
const result = await runGit(["pull"], workingDir);
|
|
110877
|
-
if ("error" in result) {
|
|
110878
|
-
const message = result.error.message;
|
|
110879
|
-
if (message.includes("no tracking branch")) {
|
|
110880
|
-
return {
|
|
110881
|
-
status: "error",
|
|
110882
|
-
message: "No tracking branch configured. Set upstream with `git push -u`."
|
|
110883
|
-
};
|
|
110884
|
-
}
|
|
110885
|
-
if (message.includes("conflict")) {
|
|
110886
|
-
return { status: "error", message: "Merge conflict detected. Resolve conflicts manually." };
|
|
110887
|
-
}
|
|
110888
|
-
if (message.includes("Authentication failed") || message.includes("could not read")) {
|
|
110889
|
-
return {
|
|
110890
|
-
status: "error",
|
|
110891
|
-
message: "Authentication failed. Run `gh auth status` to check your GitHub credentials."
|
|
110892
|
-
};
|
|
110893
|
-
}
|
|
110894
|
-
return classifyError2(message);
|
|
110895
|
-
}
|
|
110896
|
-
const stderr = result.stderr.trim();
|
|
110897
|
-
if (stderr && !stderr.includes("Already up to date")) {
|
|
110898
|
-
return { status: "available", message: stderr };
|
|
110899
|
-
}
|
|
110900
|
-
return { status: "available" };
|
|
110901
|
-
}
|
|
110902
|
-
async function gitPush(workingDir) {
|
|
110903
|
-
const result = await runGit(["push"], workingDir);
|
|
110904
|
-
if ("error" in result) {
|
|
110905
|
-
const message = result.error.message;
|
|
110906
|
-
if (message.includes("no upstream branch")) {
|
|
110907
|
-
return {
|
|
110908
|
-
status: "error",
|
|
110909
|
-
message: "No upstream branch configured. Set upstream with `git push -u`."
|
|
110910
|
-
};
|
|
110911
|
-
}
|
|
110912
|
-
if (message.includes("Authentication failed") || message.includes("could not read")) {
|
|
110913
|
-
return {
|
|
110914
|
-
status: "error",
|
|
110915
|
-
message: "Authentication failed. Run `gh auth status` to check your GitHub credentials."
|
|
110916
|
-
};
|
|
110917
|
-
}
|
|
110918
|
-
return classifyError2(message);
|
|
110919
|
-
}
|
|
110920
|
-
const stderr = result.stderr.trim();
|
|
110921
|
-
if (stderr && !stderr.includes("Everything up-to-date")) {
|
|
110922
|
-
return { status: "available", message: stderr };
|
|
110923
|
-
}
|
|
110924
|
-
return { status: "available" };
|
|
110925
|
-
}
|
|
110926
|
-
async function gitSync(workingDir) {
|
|
110927
|
-
const pullResult = await gitPull(workingDir);
|
|
110928
|
-
if (pullResult.status === "error") {
|
|
110929
|
-
return pullResult;
|
|
110930
|
-
}
|
|
110931
|
-
return gitPush(workingDir);
|
|
110932
|
-
}
|
|
110933
|
-
var init_git_writer = __esm(() => {
|
|
110934
|
-
init_run_command();
|
|
110935
|
-
});
|
|
110936
|
-
|
|
110937
|
-
// src/daemon/infrastructure/git/index.ts
|
|
110938
|
-
var init_git = __esm(() => {
|
|
110939
|
-
init_git_reader();
|
|
110940
|
-
init_git_writer();
|
|
110941
|
-
});
|
|
110942
|
-
|
|
110943
|
-
// src/infrastructure/local-actions/execute-local-action.ts
|
|
110944
|
-
import { spawn as spawn5 } from "node:child_process";
|
|
110945
|
-
import { access as access3 } from "node:fs/promises";
|
|
110946
|
-
function escapeShellArg(arg) {
|
|
110947
|
-
return `"${arg.replace(/"/g, "\\\"")}"`;
|
|
110948
|
-
}
|
|
110949
|
-
function resolveWhichCommand(name) {
|
|
110950
|
-
return process.platform === "win32" ? `where ${name}` : `which ${name}`;
|
|
110951
|
-
}
|
|
110952
|
-
function isCliAvailable(cliName) {
|
|
110953
|
-
return new Promise((resolve5) => {
|
|
110954
|
-
const child = spawn5(resolveWhichCommand(cliName), [], DETACHED_SHELL_SPAWN_OPTIONS);
|
|
110955
|
-
child.on("error", () => resolve5(false));
|
|
110956
|
-
child.on("close", (code2) => resolve5(code2 === 0));
|
|
110957
|
-
child.unref();
|
|
110958
|
-
});
|
|
110959
|
-
}
|
|
110960
|
-
function execFireAndForget(command, logTag) {
|
|
110961
|
-
const child = spawn5(command, [], DETACHED_SHELL_SPAWN_OPTIONS);
|
|
110962
|
-
child.on("error", (err) => {
|
|
110963
|
-
console.warn(`[${logTag}] spawn failed: ${err.message}`);
|
|
110964
|
-
});
|
|
110965
|
-
child.unref();
|
|
110966
|
-
}
|
|
110967
|
-
function resolveOpenCommand(platform) {
|
|
110968
|
-
switch (platform) {
|
|
110969
|
-
case "darwin":
|
|
110970
|
-
return "open";
|
|
110971
|
-
case "win32":
|
|
110972
|
-
return "explorer";
|
|
110973
|
-
default:
|
|
110974
|
-
return "xdg-open";
|
|
110975
|
-
}
|
|
110976
|
-
}
|
|
110977
|
-
function resolveOpenUrlCommand(platform) {
|
|
110978
|
-
return platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
|
|
110979
|
-
}
|
|
110980
|
-
async function openVscode(workingDir) {
|
|
110981
|
-
const available = await isCliAvailable("code");
|
|
110982
|
-
if (!available) {
|
|
110983
|
-
return {
|
|
110984
|
-
success: false,
|
|
110985
|
-
error: "VS Code CLI (code) not found. Install via: VS Code → Cmd+Shift+P → 'Shell Command: Install code in PATH'"
|
|
110986
|
-
};
|
|
110987
|
-
}
|
|
110988
|
-
execFireAndForget(`code ${escapeShellArg(workingDir)}`, "open-vscode");
|
|
110989
|
-
return { success: true };
|
|
110990
|
-
}
|
|
110991
|
-
async function openFinder(workingDir) {
|
|
110992
|
-
const cmd = resolveOpenCommand(process.platform);
|
|
110993
|
-
execFireAndForget(`${cmd} ${escapeShellArg(workingDir)}`, "open-finder");
|
|
110994
|
-
return { success: true };
|
|
110995
|
-
}
|
|
110996
|
-
async function openCursor(workingDir) {
|
|
110997
|
-
const available = await isCliAvailable("cursor");
|
|
110998
|
-
if (!available) {
|
|
110999
|
-
return {
|
|
111000
|
-
success: false,
|
|
111001
|
-
error: "Cursor CLI (cursor) not found. Install via: Cursor → Cmd+Shift+P → 'Shell Command: Install cursor in PATH'"
|
|
111002
|
-
};
|
|
111003
|
-
}
|
|
111004
|
-
execFireAndForget(`cursor ${escapeShellArg(workingDir)}`, "open-cursor");
|
|
111005
|
-
return { success: true };
|
|
111006
|
-
}
|
|
111007
|
-
async function openGithubDesktop(workingDir) {
|
|
111008
|
-
const available = await isCliAvailable("github");
|
|
111009
|
-
if (!available) {
|
|
111010
|
-
return { success: false, error: "GitHub Desktop CLI not found" };
|
|
111011
|
-
}
|
|
111012
|
-
execFireAndForget(`github ${escapeShellArg(workingDir)}`, "open-github-desktop");
|
|
111013
|
-
return { success: true };
|
|
111014
|
-
}
|
|
111015
|
-
async function openDaemonLogs(_workingDir, options) {
|
|
111016
|
-
const params = new URLSearchParams;
|
|
111017
|
-
if (options?.chatroomId)
|
|
111018
|
-
params.set("chatroomId", options.chatroomId);
|
|
111019
|
-
const qs = params.toString();
|
|
111020
|
-
const url3 = `http://127.0.0.1:${resolveLocalWebPort()}/${qs ? `?${qs}` : ""}`;
|
|
111021
|
-
execFireAndForget(`${resolveOpenUrlCommand(process.platform)} ${escapeShellArg(url3)}`, "open-daemon-logs");
|
|
111022
|
-
return { success: true };
|
|
111023
|
-
}
|
|
111024
|
-
async function gitDiscardFileAction(workingDir) {
|
|
111025
|
-
const separatorIndex = workingDir.indexOf("::");
|
|
111026
|
-
if (separatorIndex === -1) {
|
|
111027
|
-
return {
|
|
111028
|
-
success: false,
|
|
111029
|
-
error: 'Invalid file path. Expected format: "/path/to/dir::/path/to/file"'
|
|
111030
|
-
};
|
|
111031
|
-
}
|
|
111032
|
-
const dir = workingDir.slice(0, separatorIndex);
|
|
111033
|
-
const filePath = workingDir.slice(separatorIndex + 2);
|
|
111034
|
-
const result = await discardFile(dir, filePath);
|
|
111035
|
-
if (result.status === "error") {
|
|
111036
|
-
return { success: false, error: result.message };
|
|
111037
|
-
}
|
|
111038
|
-
return { success: true };
|
|
111039
|
-
}
|
|
111040
|
-
async function gitDiscardAllAction(workingDir) {
|
|
111041
|
-
const result = await discardAllChanges(workingDir);
|
|
111042
|
-
if (result.status === "error") {
|
|
111043
|
-
return { success: false, error: result.message };
|
|
111044
|
-
}
|
|
111045
|
-
return { success: true };
|
|
111046
|
-
}
|
|
111047
|
-
async function gitPullAction(workingDir) {
|
|
111048
|
-
const result = await gitPull(workingDir);
|
|
111049
|
-
if (result.status === "error") {
|
|
111050
|
-
return { success: false, error: result.message };
|
|
111051
|
-
}
|
|
111052
|
-
return { success: true, message: result.message ?? "Pull successful" };
|
|
111053
|
-
}
|
|
111054
|
-
async function gitPushAction(workingDir) {
|
|
111055
|
-
const result = await gitPush(workingDir);
|
|
111056
|
-
if (result.status === "error") {
|
|
111057
|
-
return { success: false, error: result.message };
|
|
111058
|
-
}
|
|
111059
|
-
return { success: true, message: result.message ?? "Push successful" };
|
|
111060
|
-
}
|
|
111061
|
-
async function gitSyncAction(workingDir) {
|
|
111062
|
-
const result = await gitSync(workingDir);
|
|
111063
|
-
if (result.status === "error") {
|
|
111064
|
-
return { success: false, error: result.message };
|
|
111065
|
-
}
|
|
111066
|
-
return { success: true, message: result.message ?? "Sync successful" };
|
|
111067
|
-
}
|
|
111068
|
-
async function executeLocalAction(action, workingDir, options) {
|
|
111069
|
-
if (action === "open-daemon-logs")
|
|
111070
|
-
return openDaemonLogs(workingDir, options);
|
|
111071
|
-
try {
|
|
111072
|
-
await access3(workingDir);
|
|
111073
|
-
} catch {
|
|
111074
|
-
return { success: false, error: `Directory not found: ${workingDir}` };
|
|
111075
|
-
}
|
|
111076
|
-
const handler2 = actionHandlers[action];
|
|
111077
|
-
if (handler2)
|
|
111078
|
-
return handler2(workingDir);
|
|
111079
|
-
return { success: false, error: `Unknown action: ${action}` };
|
|
111080
|
-
}
|
|
111081
|
-
var DETACHED_SHELL_SPAWN_OPTIONS, actionHandlers;
|
|
111082
|
-
var init_execute_local_action = __esm(() => {
|
|
111083
|
-
init_resolve_local_web_port();
|
|
111084
|
-
init_git();
|
|
111085
|
-
DETACHED_SHELL_SPAWN_OPTIONS = {
|
|
111086
|
-
stdio: "ignore",
|
|
111087
|
-
detached: true,
|
|
111088
|
-
shell: true
|
|
111089
|
-
};
|
|
111090
|
-
actionHandlers = {
|
|
111091
|
-
"open-vscode": openVscode,
|
|
111092
|
-
"open-finder": openFinder,
|
|
111093
|
-
"open-cursor": openCursor,
|
|
111094
|
-
"open-github-desktop": openGithubDesktop,
|
|
111095
|
-
"open-daemon-logs": openDaemonLogs,
|
|
111096
|
-
"git-discard-file": gitDiscardFileAction,
|
|
111097
|
-
"git-discard-all": gitDiscardAllAction,
|
|
111098
|
-
"git-pull": gitPullAction,
|
|
111099
|
-
"git-push": gitPushAction,
|
|
111100
|
-
"git-sync": gitSyncAction
|
|
111101
|
-
};
|
|
111102
|
-
});
|
|
111103
|
-
|
|
111104
|
-
// src/infrastructure/local-actions/index.ts
|
|
111105
|
-
var init_local_actions = __esm(() => {
|
|
111106
|
-
init_execute_local_action();
|
|
111107
|
-
});
|
|
111108
|
-
|
|
111109
|
-
// src/infrastructure/local-actions/pick-folder.ts
|
|
111110
|
-
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
111111
|
-
function runPicker(command, args2) {
|
|
111112
|
-
try {
|
|
111113
|
-
const path3 = execFileSync2(command, args2, { encoding: "utf8", timeout: 300000 }).trim();
|
|
111114
|
-
if (!path3)
|
|
111115
|
-
return { success: false, error: "No folder selected" };
|
|
111116
|
-
return { success: true, path: path3 };
|
|
111117
|
-
} catch (error51) {
|
|
111118
|
-
const exitCode = typeof error51 === "object" && error51 !== null && "status" in error51 ? error51.status : null;
|
|
111119
|
-
if (exitCode === 1)
|
|
111120
|
-
return { success: false, error: "Cancelled", cancelled: true };
|
|
111121
|
-
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
111122
|
-
return { success: false, error: message };
|
|
111123
|
-
}
|
|
111124
|
-
}
|
|
111125
|
-
function pickFolderDialog() {
|
|
111126
|
-
switch (process.platform) {
|
|
111127
|
-
case "darwin":
|
|
111128
|
-
return runPicker("osascript", [
|
|
111129
|
-
"-e",
|
|
111130
|
-
'POSIX path of (choose folder with prompt "Select workspace folder")'
|
|
111131
|
-
]);
|
|
111132
|
-
case "win32":
|
|
111133
|
-
return runPicker("powershell", [
|
|
111134
|
-
"-NoProfile",
|
|
111135
|
-
"-Command",
|
|
111136
|
-
[
|
|
111137
|
-
"Add-Type -AssemblyName System.Windows.Forms",
|
|
111138
|
-
"$dialog = New-Object System.Windows.Forms.FolderBrowserDialog",
|
|
111139
|
-
'$dialog.Description = "Select workspace folder"',
|
|
111140
|
-
"if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {",
|
|
111141
|
-
" Write-Output $dialog.SelectedPath",
|
|
111142
|
-
" exit 0",
|
|
111143
|
-
"}",
|
|
111144
|
-
"exit 1"
|
|
111145
|
-
].join("; ")
|
|
111146
|
-
]);
|
|
111147
|
-
default:
|
|
111148
|
-
return runPicker("zenity", [
|
|
111149
|
-
"--file-selection",
|
|
111150
|
-
"--directory",
|
|
111151
|
-
"--title=Select workspace folder"
|
|
111152
|
-
]);
|
|
111153
|
-
}
|
|
111154
|
-
}
|
|
111155
|
-
var init_pick_folder = () => {};
|
|
111156
|
-
|
|
111157
111526
|
// src/daemon/domain/usecase/refresh-machine-capabilities.ts
|
|
111158
111527
|
async function refreshMachineCapabilities(deps) {
|
|
111159
111528
|
return deps.refresh.refresh();
|
|
@@ -111378,15 +111747,15 @@ var init_command_dispatch = __esm(() => {
|
|
|
111378
111747
|
init_command_event_types();
|
|
111379
111748
|
init_command_sync_heartbeat();
|
|
111380
111749
|
init_daemon_services();
|
|
111750
|
+
init_refresh_models_outcome();
|
|
111751
|
+
init_local_actions();
|
|
111752
|
+
init_pick_folder();
|
|
111381
111753
|
init_on_request_restart_agent();
|
|
111382
111754
|
init_on_request_start_agent();
|
|
111383
111755
|
init_on_request_stop_agent();
|
|
111384
111756
|
init_on_stop_scope_agent();
|
|
111385
111757
|
init_ping();
|
|
111386
111758
|
init_manager();
|
|
111387
|
-
init_refresh_models_outcome();
|
|
111388
|
-
init_local_actions();
|
|
111389
|
-
init_pick_folder();
|
|
111390
111759
|
init_convex_error();
|
|
111391
111760
|
GIT_PUSH_ACTIONS = new Set(["git-pull", "git-push", "git-sync", "git-discard-all"]);
|
|
111392
111761
|
commandEventHandlers = {
|
|
@@ -117624,197 +117993,6 @@ var init_command_run_subscription = __esm(() => {
|
|
|
117624
117993
|
dispatchedStop = new Set;
|
|
117625
117994
|
});
|
|
117626
117995
|
|
|
117627
|
-
// src/daemon/infrastructure/agent-operational/agent-operational-read-model.ts
|
|
117628
|
-
function isOperationalCircuitOpen2(row) {
|
|
117629
|
-
return row?.operationalState === "circuit_open";
|
|
117630
|
-
}
|
|
117631
|
-
function isOperationalStopIntentActive2(row) {
|
|
117632
|
-
return row?.stopState === "stopped" || row?.stopState === "stopping" || row?.stopState === "pending";
|
|
117633
|
-
}
|
|
117634
|
-
|
|
117635
|
-
class AgentOperationalReadModel {
|
|
117636
|
-
rows = new Map;
|
|
117637
|
-
replace(rows) {
|
|
117638
|
-
const changed = [];
|
|
117639
|
-
const nextKeys = new Set;
|
|
117640
|
-
for (const row of rows) {
|
|
117641
|
-
const key = roleKey3(row.chatroomId, row.role);
|
|
117642
|
-
nextKeys.add(key);
|
|
117643
|
-
const prev = this.rows.get(key);
|
|
117644
|
-
if (!prev || prev.revisionKey !== row.revisionKey)
|
|
117645
|
-
changed.push({ chatroomId: row.chatroomId, role: row.role });
|
|
117646
|
-
this.rows.set(key, row);
|
|
117647
|
-
}
|
|
117648
|
-
for (const [key, prev] of this.rows) {
|
|
117649
|
-
if (!nextKeys.has(key)) {
|
|
117650
|
-
changed.push({ chatroomId: prev.chatroomId, role: prev.role });
|
|
117651
|
-
this.rows.delete(key);
|
|
117652
|
-
}
|
|
117653
|
-
}
|
|
117654
|
-
return changed;
|
|
117655
|
-
}
|
|
117656
|
-
applySignalPage(rows, removed) {
|
|
117657
|
-
const changed = [];
|
|
117658
|
-
for (const row of rows) {
|
|
117659
|
-
const key = roleKey3(row.chatroomId, row.role);
|
|
117660
|
-
const prev = this.rows.get(key);
|
|
117661
|
-
if (!prev || prev.revisionKey !== row.revisionKey) {
|
|
117662
|
-
changed.push({ chatroomId: row.chatroomId, role: row.role });
|
|
117663
|
-
}
|
|
117664
|
-
this.rows.set(key, row);
|
|
117665
|
-
}
|
|
117666
|
-
for (const item of removed) {
|
|
117667
|
-
const key = roleKey3(item.chatroomId, item.role);
|
|
117668
|
-
if (this.rows.has(key))
|
|
117669
|
-
changed.push(item);
|
|
117670
|
-
this.rows.delete(key);
|
|
117671
|
-
}
|
|
117672
|
-
return changed;
|
|
117673
|
-
}
|
|
117674
|
-
get(chatroomId, role) {
|
|
117675
|
-
return this.rows.get(roleKey3(chatroomId, role));
|
|
117676
|
-
}
|
|
117677
|
-
}
|
|
117678
|
-
var roleKey3 = (chatroomId, role) => `${chatroomId}:${role.toLowerCase()}`;
|
|
117679
|
-
|
|
117680
|
-
// src/daemon/entry/native-delivery/task-delivery-processor.ts
|
|
117681
|
-
async function startPendingNativeAgents(tasks, agentMgr, runSerializedForAgent, taskService, operationalModel) {
|
|
117682
|
-
const started = new Set;
|
|
117683
|
-
await Promise.all(tasks.map(async (task) => {
|
|
117684
|
-
if (task.status !== "pending" || !taskService.isNativeHarness(task.agentConfig.agentHarness) || taskService.snapshotRequestsNativeColdSession(task) || !task.agentConfig.workingDir) {
|
|
117685
|
-
return;
|
|
117686
|
-
}
|
|
117687
|
-
const key = `${task.chatroomId}:${task.agentConfig.role.toLowerCase()}`;
|
|
117688
|
-
if (started.has(key))
|
|
117689
|
-
return;
|
|
117690
|
-
const slot = agentMgr.getSlot(task.chatroomId, task.agentConfig.role);
|
|
117691
|
-
if (slot && !isSlotIdle(slot.state))
|
|
117692
|
-
return;
|
|
117693
|
-
const operational = operationalModel?.get(task.chatroomId, task.agentConfig.role);
|
|
117694
|
-
if (isChatroomStopScopeActive(task.chatroomId))
|
|
117695
|
-
return;
|
|
117696
|
-
if (isOperationalCircuitOpen2(operational) || isOperationalStopIntentActive2(operational))
|
|
117697
|
-
return;
|
|
117698
|
-
started.add(key);
|
|
117699
|
-
try {
|
|
117700
|
-
await runSerializedForAgent({ chatroomId: task.chatroomId, role: task.agentConfig.role }, { timeoutMs: 120000 }, (ops, context5) => ops.startAgent({
|
|
117701
|
-
chatroomId: task.chatroomId,
|
|
117702
|
-
role: task.agentConfig.role,
|
|
117703
|
-
agentHarness: task.agentConfig.agentHarness,
|
|
117704
|
-
model: task.agentConfig.model,
|
|
117705
|
-
workingDir: task.agentConfig.workingDir,
|
|
117706
|
-
reason: operational?.operationalState === "running" ? AgentStartReasonEnum["platform.task_monitor_nudge"] : AgentStartReasonEnum["platform.pending_task_wake"],
|
|
117707
|
-
wantResume: false,
|
|
117708
|
-
lifecycleRevision: task.agentConfig.configLifecycleRevision,
|
|
117709
|
-
taskId: task.taskId
|
|
117710
|
-
}, context5.signal));
|
|
117711
|
-
} catch (error51) {
|
|
117712
|
-
console.warn(`[NativeDelivery] pending agent activation failed for ${task.agentConfig.role}@${task.chatroomId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
117713
|
-
}
|
|
117714
|
-
}));
|
|
117715
|
-
}
|
|
117716
|
-
async function processTasksUpdate(runtime4, effectContext2, agentMgr, runSerializedForAgent, taskService, sessionDeps, machineId, pass, lifecycleOutbox, operationalModel, isTaskActive, options) {
|
|
117717
|
-
const filteredTasks = filterSnapshotsExcludingRestartInFlight([...options.snapshots]);
|
|
117718
|
-
if (filteredTasks.length === 0)
|
|
117719
|
-
return;
|
|
117720
|
-
await startPendingNativeAgents(filteredTasks, agentMgr, runSerializedForAgent, taskService, operationalModel);
|
|
117721
|
-
const first = filteredTasks[0];
|
|
117722
|
-
if (pass === "periodic-reconcile") {
|
|
117723
|
-
logNativeDeliveryFallback(pass, first.agentConfig.role, first.chatroomId, first.taskId);
|
|
117724
|
-
} else {
|
|
117725
|
-
logNativeDeliveryTrigger(pass, first.agentConfig.role, first.chatroomId, first.taskId);
|
|
117726
|
-
}
|
|
117727
|
-
await getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
|
|
117728
|
-
tasks: filteredTasks,
|
|
117729
|
-
runtime: runtime4,
|
|
117730
|
-
effectContext: effectContext2,
|
|
117731
|
-
agentMgr,
|
|
117732
|
-
runSerializedForAgent,
|
|
117733
|
-
taskService,
|
|
117734
|
-
sessionDeps,
|
|
117735
|
-
lifecycleOutbox,
|
|
117736
|
-
operationalModel,
|
|
117737
|
-
isTaskActive,
|
|
117738
|
-
machineId,
|
|
117739
|
-
onTaskDelivered: options.onTaskDelivered
|
|
117740
|
-
});
|
|
117741
|
-
}
|
|
117742
|
-
var init_task_delivery_processor = __esm(() => {
|
|
117743
|
-
init_agent();
|
|
117744
|
-
init_native_task_delivery_coordinator();
|
|
117745
|
-
init_check_agent_slot();
|
|
117746
|
-
init_service_interfaces();
|
|
117747
|
-
init_restart_orchestrator_in_flight();
|
|
117748
|
-
});
|
|
117749
|
-
|
|
117750
|
-
// src/daemon/entry/native-delivery/native-delivery-service.ts
|
|
117751
|
-
class NativeDeliveryService {
|
|
117752
|
-
deps;
|
|
117753
|
-
unsubscribeAgentTurnEnded;
|
|
117754
|
-
unsubscribeAgentStarted;
|
|
117755
|
-
unsubscribeAgentSessionLost;
|
|
117756
|
-
constructor(deps) {
|
|
117757
|
-
this.deps = deps;
|
|
117758
|
-
this.unsubscribeAgentTurnEnded = deps.agentMgr.subscribeAgentTurnEnded((event) => this.handleAgentTurnEnded(event));
|
|
117759
|
-
this.unsubscribeAgentStarted = deps.agentMgr.subscribeAgentStarted((event) => this.handleAgentStarted(event));
|
|
117760
|
-
this.unsubscribeAgentSessionLost = deps.agentMgr.subscribeAgentSessionLost((event) => this.handleAgentSessionLost(event));
|
|
117761
|
-
}
|
|
117762
|
-
async handleAgentStarted(event) {
|
|
117763
|
-
const tasks = this.deps.taskSnapshotState.listForRole(event.chatroomId, event.role);
|
|
117764
|
-
await this.processSnapshots("operational-status", tasks);
|
|
117765
|
-
}
|
|
117766
|
-
handleAgentSessionLost(event) {
|
|
117767
|
-
getRoleDeliveryState().resetDeliveryState(event.chatroomId, event.role);
|
|
117768
|
-
this.deps.agentTaskState.clear({ chatroomId: event.chatroomId, role: event.role });
|
|
117769
|
-
}
|
|
117770
|
-
async handleAgentTurnEnded(event) {
|
|
117771
|
-
this.scheduleRoleDelivery(event.chatroomId, event.role);
|
|
117772
|
-
}
|
|
117773
|
-
scheduleRoleDelivery(chatroomId, role) {
|
|
117774
|
-
setTimeout(() => {
|
|
117775
|
-
const snapshots = this.deps.taskSnapshotState.listForRole(chatroomId, role);
|
|
117776
|
-
this.processSnapshots("operational-status", snapshots).catch((error51) => {
|
|
117777
|
-
console.warn(`[NativeDelivery] post-turn delivery failed for ${role}@${chatroomId}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
117778
|
-
});
|
|
117779
|
-
}, 0);
|
|
117780
|
-
}
|
|
117781
|
-
dispose() {
|
|
117782
|
-
this.unsubscribeAgentTurnEnded();
|
|
117783
|
-
this.unsubscribeAgentStarted();
|
|
117784
|
-
this.unsubscribeAgentSessionLost();
|
|
117785
|
-
}
|
|
117786
|
-
get agentTaskState() {
|
|
117787
|
-
return this.deps.agentTaskState;
|
|
117788
|
-
}
|
|
117789
|
-
async handleTaskInboxUpdate(update6) {
|
|
117790
|
-
await this.processSnapshots("inbox-signal", update6.snapshots);
|
|
117791
|
-
}
|
|
117792
|
-
async handleTaskServiceNotification(notification) {
|
|
117793
|
-
if (notification.kind === "bootstrap") {
|
|
117794
|
-
await this.processSnapshots("bootstrap", notification.snapshots);
|
|
117795
|
-
return;
|
|
117796
|
-
}
|
|
117797
|
-
await this.handleTaskInboxUpdate(notification.update);
|
|
117798
|
-
}
|
|
117799
|
-
async processSnapshots(pass, snapshots, onTaskDelivered) {
|
|
117800
|
-
if (snapshots.length === 0)
|
|
117801
|
-
return;
|
|
117802
|
-
await processTasksUpdate(this.deps.runtime, this.deps.effectContext, this.deps.agentMgr, this.deps.runSerializedForAgent, this.deps.taskService, this.deps.sessionDeps, this.deps.machineId, pass, this.deps.lifecycleOutbox, this.deps.agentOperationalReadModel, ({ chatroomId, role, taskId }) => this.deps.agentTaskState.get({ chatroomId, role })?.taskId === taskId, {
|
|
117803
|
-
snapshots,
|
|
117804
|
-
onTaskDelivered: (args2) => {
|
|
117805
|
-
this.recordTaskDelivered(args2);
|
|
117806
|
-
onTaskDelivered?.(args2);
|
|
117807
|
-
}
|
|
117808
|
-
});
|
|
117809
|
-
}
|
|
117810
|
-
recordTaskDelivered(args2) {
|
|
117811
|
-
this.deps.agentTaskState.start(args2);
|
|
117812
|
-
}
|
|
117813
|
-
}
|
|
117814
|
-
var init_native_delivery_service = __esm(() => {
|
|
117815
|
-
init_task_delivery_processor();
|
|
117816
|
-
});
|
|
117817
|
-
|
|
117818
117996
|
// src/daemon/entry/task-inbox-membership-registry.ts
|
|
117819
117997
|
function registerTaskInboxRoomMembershipRefresh(refresh) {
|
|
117820
117998
|
refreshRoomMembership = refresh;
|
|
@@ -117879,6 +118057,64 @@ var init_ack_machine_operational_signals = __esm(() => {
|
|
|
117879
118057
|
init_api3();
|
|
117880
118058
|
});
|
|
117881
118059
|
|
|
118060
|
+
// src/daemon/infrastructure/agent-operational/agent-operational-read-model.ts
|
|
118061
|
+
class AgentOperationalReadModel {
|
|
118062
|
+
rows = new Map;
|
|
118063
|
+
replace(rows) {
|
|
118064
|
+
const changed = [];
|
|
118065
|
+
const nextKeys = new Set;
|
|
118066
|
+
for (const row of rows) {
|
|
118067
|
+
const key = roleKey3(row.chatroomId, row.role);
|
|
118068
|
+
nextKeys.add(key);
|
|
118069
|
+
const prev = this.rows.get(key);
|
|
118070
|
+
if (!prev || prev.revisionKey !== row.revisionKey)
|
|
118071
|
+
changed.push({ chatroomId: row.chatroomId, role: row.role });
|
|
118072
|
+
this.rows.set(key, row);
|
|
118073
|
+
}
|
|
118074
|
+
for (const [key, prev] of this.rows) {
|
|
118075
|
+
if (!nextKeys.has(key)) {
|
|
118076
|
+
changed.push({ chatroomId: prev.chatroomId, role: prev.role });
|
|
118077
|
+
this.rows.delete(key);
|
|
118078
|
+
}
|
|
118079
|
+
}
|
|
118080
|
+
return changed;
|
|
118081
|
+
}
|
|
118082
|
+
applySignalPage(rows, removed) {
|
|
118083
|
+
const changed = [];
|
|
118084
|
+
for (const row of rows) {
|
|
118085
|
+
const key = roleKey3(row.chatroomId, row.role);
|
|
118086
|
+
const prev = this.rows.get(key);
|
|
118087
|
+
if (!prev || prev.revisionKey !== row.revisionKey) {
|
|
118088
|
+
changed.push({ chatroomId: row.chatroomId, role: row.role });
|
|
118089
|
+
}
|
|
118090
|
+
this.rows.set(key, row);
|
|
118091
|
+
}
|
|
118092
|
+
for (const item of removed) {
|
|
118093
|
+
const key = roleKey3(item.chatroomId, item.role);
|
|
118094
|
+
if (this.rows.has(key))
|
|
118095
|
+
changed.push(item);
|
|
118096
|
+
this.rows.delete(key);
|
|
118097
|
+
}
|
|
118098
|
+
return changed;
|
|
118099
|
+
}
|
|
118100
|
+
get(chatroomId, role) {
|
|
118101
|
+
return this.rows.get(roleKey3(chatroomId, role));
|
|
118102
|
+
}
|
|
118103
|
+
}
|
|
118104
|
+
var roleKey3 = (chatroomId, role) => `${chatroomId}:${role.toLowerCase()}`;
|
|
118105
|
+
|
|
118106
|
+
// src/daemon/infrastructure/agent-operational/fetch-machine-agent-operational-status.ts
|
|
118107
|
+
async function fetchMachineAgentOperationalStatus(sessionDeps, machineId) {
|
|
118108
|
+
const result = await sessionDeps.backend.query(api.machines.listMachineAgentOperationalStatus, {
|
|
118109
|
+
sessionId: sessionDeps.sessionId,
|
|
118110
|
+
machineId
|
|
118111
|
+
});
|
|
118112
|
+
return result;
|
|
118113
|
+
}
|
|
118114
|
+
var init_fetch_machine_agent_operational_status = __esm(() => {
|
|
118115
|
+
init_api3();
|
|
118116
|
+
});
|
|
118117
|
+
|
|
117882
118118
|
// src/daemon/infrastructure/agent-operational/operational-inbox.ts
|
|
117883
118119
|
function operationalSignalCursorAt(timestamp) {
|
|
117884
118120
|
return `${String(Math.max(0, Math.floor(timestamp))).padStart(16, "0")}:`;
|
|
@@ -118012,7 +118248,7 @@ async function runOperationalInboxLoopWithRestart(options, onUpdate, isStopped)
|
|
|
118012
118248
|
}
|
|
118013
118249
|
}
|
|
118014
118250
|
}
|
|
118015
|
-
var
|
|
118251
|
+
var INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startTaskInboxEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
118016
118252
|
const session2 = yield* DaemonSessionService;
|
|
118017
118253
|
const agentMgr = yield* DaemonAgentProcessManagerService;
|
|
118018
118254
|
const commandService = yield* DaemonAgentProcessManagerCommandService;
|
|
@@ -118037,31 +118273,25 @@ var NATIVE_DELIVERY_RECONCILE_MS = 1e4, INBOX_RESTART_INITIAL_MS = 1000, INBOX_R
|
|
|
118037
118273
|
const serviceStartedAt = Date.now();
|
|
118038
118274
|
const abort = new AbortController;
|
|
118039
118275
|
let stopped = false;
|
|
118040
|
-
const taskSnapshotState = session2.taskService.taskSnapshotState;
|
|
118041
118276
|
const agentOperationalReadModel = new AgentOperationalReadModel;
|
|
118042
118277
|
const agentTaskState = createAgentTaskStateService();
|
|
118043
|
-
const nativeDelivery =
|
|
118278
|
+
const nativeDelivery = session2.taskService.createNativeDeliveryService({
|
|
118044
118279
|
runtime: runtime4,
|
|
118045
118280
|
effectContext: effectContext2,
|
|
118046
118281
|
agentMgr,
|
|
118047
118282
|
runSerializedForAgent: commandService.runSerializedForAgent,
|
|
118048
118283
|
sessionDeps,
|
|
118049
118284
|
machineId: session2.machineId,
|
|
118050
|
-
taskSnapshotState,
|
|
118051
118285
|
agentTaskState,
|
|
118052
118286
|
agentOperationalReadModel,
|
|
118053
|
-
lifecycleOutbox
|
|
118054
|
-
taskService: session2.taskService
|
|
118287
|
+
lifecycleOutbox
|
|
118055
118288
|
});
|
|
118056
|
-
const unsubscribeTaskService = session2.taskService.subscribe((notification) => nativeDelivery.handleTaskServiceNotification(notification));
|
|
118057
118289
|
yield* exports_Effect.tryPromise(() => session2.taskService.startTaskInbox(wsClient2)).pipe(exports_Effect.catchAll((error51) => {
|
|
118058
118290
|
console.warn("[TaskInbox] service bootstrap failed:", error51);
|
|
118059
118291
|
return exports_Effect.void;
|
|
118060
118292
|
}));
|
|
118061
118293
|
const knownRoomIds = new Set;
|
|
118062
118294
|
const roomWatchers = new Map;
|
|
118063
|
-
let inboxUpdatesInFlight = 0;
|
|
118064
|
-
let reconcileInFlight = false;
|
|
118065
118295
|
const bootstrapSucceeded = yield* exports_Effect.tryPromise(async () => {
|
|
118066
118296
|
const rows = await fetchMachineAgentOperationalStatus(sessionDeps, session2.machineId);
|
|
118067
118297
|
agentOperationalReadModel.replace(rows);
|
|
@@ -118074,24 +118304,20 @@ var NATIVE_DELIVERY_RECONCILE_MS = 1e4, INBOX_RESTART_INITIAL_MS = 1000, INBOX_R
|
|
|
118074
118304
|
}));
|
|
118075
118305
|
const operationalHandler = async (update6) => {
|
|
118076
118306
|
const chatroomId = update6.chatroomId;
|
|
118077
|
-
|
|
118307
|
+
const changed = agentOperationalReadModel.applySignalPage(update6.rows, update6.removed);
|
|
118308
|
+
await Promise.all(changed.map(({ chatroomId: roomId, role }) => nativeDelivery.requestReconcile({
|
|
118309
|
+
chatroomId: roomId,
|
|
118310
|
+
role,
|
|
118311
|
+
source: "operational-signal"
|
|
118312
|
+
})));
|
|
118313
|
+
inboxStore.save({
|
|
118314
|
+
inboxType: "operational",
|
|
118315
|
+
scopeKey: roomScopeKey(session2.machineId, chatroomId)
|
|
118316
|
+
}, { afterSignalKey: update6.throughSignalKey });
|
|
118078
118317
|
try {
|
|
118079
|
-
|
|
118080
|
-
|
|
118081
|
-
|
|
118082
|
-
await nativeDelivery.processSnapshots("operational-status", snapshots);
|
|
118083
|
-
}
|
|
118084
|
-
inboxStore.save({
|
|
118085
|
-
inboxType: "operational",
|
|
118086
|
-
scopeKey: roomScopeKey(session2.machineId, chatroomId)
|
|
118087
|
-
}, { afterSignalKey: update6.throughSignalKey });
|
|
118088
|
-
try {
|
|
118089
|
-
await ackMachineOperationalSignals(sessionDeps, session2.machineId, chatroomId, update6.throughSignalKey);
|
|
118090
|
-
} catch (error51) {
|
|
118091
|
-
console.warn(`[OperationalInbox room=${chatroomId}] signal cleanup failed:`, error51);
|
|
118092
|
-
}
|
|
118093
|
-
} finally {
|
|
118094
|
-
inboxUpdatesInFlight -= 1;
|
|
118318
|
+
await ackMachineOperationalSignals(sessionDeps, session2.machineId, chatroomId, update6.throughSignalKey);
|
|
118319
|
+
} catch (error51) {
|
|
118320
|
+
console.warn(`[OperationalInbox room=${chatroomId}] signal cleanup failed:`, error51);
|
|
118095
118321
|
}
|
|
118096
118322
|
};
|
|
118097
118323
|
const ensureRoomInboxes = (chatroomId) => {
|
|
@@ -118179,16 +118405,6 @@ var NATIVE_DELIVERY_RECONCILE_MS = 1e4, INBOX_RESTART_INITIAL_MS = 1000, INBOX_R
|
|
|
118179
118405
|
console.warn("[OperationalInbox] initial watcher start failed:", error51);
|
|
118180
118406
|
return exports_Effect.void;
|
|
118181
118407
|
}));
|
|
118182
|
-
const reconcileTimer = setInterval(() => {
|
|
118183
|
-
if (stopped || inboxUpdatesInFlight > 0 || reconcileInFlight)
|
|
118184
|
-
return;
|
|
118185
|
-
reconcileInFlight = true;
|
|
118186
|
-
nativeDelivery.processSnapshots("periodic-reconcile", taskSnapshotState.listAll()).catch((error51) => {
|
|
118187
|
-
console.warn("[TaskInbox] local delivery reconciliation failed:", error51);
|
|
118188
|
-
}).finally(() => {
|
|
118189
|
-
reconcileInFlight = false;
|
|
118190
|
-
});
|
|
118191
|
-
}, NATIVE_DELIVERY_RECONCILE_MS);
|
|
118192
118408
|
return {
|
|
118193
118409
|
nativeDelivery,
|
|
118194
118410
|
stop() {
|
|
@@ -118197,9 +118413,7 @@ var NATIVE_DELIVERY_RECONCILE_MS = 1e4, INBOX_RESTART_INITIAL_MS = 1000, INBOX_R
|
|
|
118197
118413
|
for (const watcher of roomWatchers.values()) {
|
|
118198
118414
|
watcher.controller.abort();
|
|
118199
118415
|
}
|
|
118200
|
-
clearInterval(reconcileTimer);
|
|
118201
118416
|
unregisterTaskInboxRoomMembershipRefresh();
|
|
118202
|
-
unsubscribeTaskService();
|
|
118203
118417
|
session2.taskService.stopTaskInbox();
|
|
118204
118418
|
nativeDelivery.dispose();
|
|
118205
118419
|
nativeDelivery.agentTaskState.clearAll();
|
|
@@ -118211,7 +118425,6 @@ var init_task_inbox_runtime = __esm(() => {
|
|
|
118211
118425
|
init_esm();
|
|
118212
118426
|
init_daemon_services();
|
|
118213
118427
|
init_api3();
|
|
118214
|
-
init_native_delivery_service();
|
|
118215
118428
|
init_ack_machine_operational_signals();
|
|
118216
118429
|
init_fetch_machine_agent_operational_status();
|
|
118217
118430
|
init_operational_inbox();
|
|
@@ -118746,7 +118959,12 @@ Listening for commands...`);
|
|
|
118746
118959
|
registerCommandInboundHandler(async (event) => {
|
|
118747
118960
|
evictStaleDedupEntries(dedupTracker);
|
|
118748
118961
|
if (event.type === "command.received") {
|
|
118749
|
-
|
|
118962
|
+
const nativeDelivery = taskInboxHandle?.nativeDelivery;
|
|
118963
|
+
if (!nativeDelivery) {
|
|
118964
|
+
console.warn("[Daemon] command received before task inbox started");
|
|
118965
|
+
return;
|
|
118966
|
+
}
|
|
118967
|
+
await handleInboundCommandEvent(event.commandId, dedupTracker, effectContext2, session2, event.claimedCommand, nativeDelivery);
|
|
118750
118968
|
} else {
|
|
118751
118969
|
await drainActionableCommandRuns(session2, commandRunRuntime);
|
|
118752
118970
|
}
|
|
@@ -135550,4 +135768,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
135550
135768
|
});
|
|
135551
135769
|
program2.parse();
|
|
135552
135770
|
|
|
135553
|
-
//# debugId=
|
|
135771
|
+
//# debugId=F48EA5F0861EF1C964756E2164756E21
|