chatroom-cli 1.98.5 → 1.98.6
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 +610 -733
- package/dist/index.js.map +27 -30
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -83544,7 +83544,9 @@ var DaemonMachineService, DaemonMachineServiceLive = (ops) => exports_Layer.succ
|
|
|
83544
83544
|
clearStuckStoppingSlot: (chatroomId, role) => exports_Effect.promise(() => mgr.clearStuckStoppingSlot(chatroomId, role)),
|
|
83545
83545
|
whenTurnEndsIdle: () => exports_Effect.promise(() => mgr.whenTurnEndsIdle()),
|
|
83546
83546
|
resumeTurnForSlot: (args2) => exports_Effect.promise(() => mgr.resumeTurnForSlot(args2)),
|
|
83547
|
-
setLastInFlightTask: (chatroomId, role, taskId) => exports_Effect.sync(() => mgr.setLastInFlightTask(chatroomId, role, taskId))
|
|
83547
|
+
setLastInFlightTask: (chatroomId, role, taskId) => exports_Effect.sync(() => mgr.setLastInFlightTask(chatroomId, role, taskId)),
|
|
83548
|
+
clearLastInFlightTaskIfMatches: (chatroomId, role, taskId) => exports_Effect.sync(() => mgr.clearLastInFlightTaskIfMatches(chatroomId, role, taskId)),
|
|
83549
|
+
reconcileNativeTurnPhaseIdle: (chatroomId, role) => exports_Effect.sync(() => mgr.reconcileNativeTurnPhaseIdle(chatroomId, role))
|
|
83548
83550
|
}), DaemonSessionService, DaemonMutableStateService;
|
|
83549
83551
|
var init_daemon_services = __esm(() => {
|
|
83550
83552
|
init_esm();
|
|
@@ -98686,40 +98688,18 @@ var init_convex_id = __esm(() => {
|
|
|
98686
98688
|
init_zod();
|
|
98687
98689
|
});
|
|
98688
98690
|
|
|
98689
|
-
// ../../services/backend/src/domain/usecase/machine/assigned-task-
|
|
98690
|
-
function
|
|
98691
|
-
return
|
|
98691
|
+
// ../../services/backend/src/domain/usecase/machine/assigned-task-snapshot-contract.ts
|
|
98692
|
+
function parseAssignedTaskSnapshotRow(raw) {
|
|
98693
|
+
return assignedTaskSnapshotRowSchema.parse(raw);
|
|
98692
98694
|
}
|
|
98693
|
-
function
|
|
98694
|
-
const full = assignedTaskPresenceSignalSchema.safeParse(raw);
|
|
98695
|
-
if (full.success)
|
|
98696
|
-
return full.data;
|
|
98697
|
-
const delta = assignedTaskPresenceDeltaSchema.safeParse(raw);
|
|
98698
|
-
if (delta.success) {
|
|
98699
|
-
const presenceUpdatedAt = Number(delta.data.presenceKey.split(":")[0]);
|
|
98700
|
-
const resolvedAt = Number.isFinite(presenceUpdatedAt) ? presenceUpdatedAt : 0;
|
|
98701
|
-
return {
|
|
98702
|
-
taskId: delta.data.taskId,
|
|
98703
|
-
chatroomId: "",
|
|
98704
|
-
role: delta.data.role,
|
|
98705
|
-
lastSeenAt: resolvedAt,
|
|
98706
|
-
presenceUpdatedAt: resolvedAt,
|
|
98707
|
-
presenceKey: delta.data.presenceKey
|
|
98708
|
-
};
|
|
98709
|
-
}
|
|
98710
|
-
return assignedTaskPresenceSignalSchema.parse(raw);
|
|
98711
|
-
}
|
|
98712
|
-
function parseAssignedTaskMonitorRow(raw) {
|
|
98713
|
-
return assignedTaskMonitorRowSchema.parse(raw);
|
|
98714
|
-
}
|
|
98715
|
-
function parseAssignedTaskMonitorRows(raw) {
|
|
98695
|
+
function parseAssignedTaskSnapshotRows(raw) {
|
|
98716
98696
|
if (!Array.isArray(raw)) {
|
|
98717
98697
|
throw new Error("Expected hydrate tasks array");
|
|
98718
98698
|
}
|
|
98719
|
-
return raw.map((row) =>
|
|
98699
|
+
return raw.map((row) => parseAssignedTaskSnapshotRow(row));
|
|
98720
98700
|
}
|
|
98721
|
-
var ACTIVE_TASK_STATUSES, activeTaskStatusSchema, ASSIGNED_TASK_SIGNAL_TYPES, assignedTaskSignalTypeSchema, SESSION_AUGMENTATION_MODES, sessionAugmentationSchema, AGENT_DESIRED_STATES, agentDesiredStateSchema, AGENT_CIRCUIT_STATES, agentCircuitStateSchema, chatroomTaskIdSchema, chatroomRoomIdSchema, assignedTaskAgentConfigSchema, assignedTaskParticipantSchema, assignedTaskSignalBootstrapFields, assignedTaskSignalSchema, assignedTaskPresenceSignalSchema, assignedTaskPresenceDeltaSchema,
|
|
98722
|
-
var
|
|
98701
|
+
var ACTIVE_TASK_STATUSES, activeTaskStatusSchema, ASSIGNED_TASK_SIGNAL_TYPES, assignedTaskSignalTypeSchema, SESSION_AUGMENTATION_MODES, sessionAugmentationSchema, AGENT_DESIRED_STATES, agentDesiredStateSchema, AGENT_CIRCUIT_STATES, agentCircuitStateSchema, chatroomTaskIdSchema, chatroomRoomIdSchema, assignedTaskAgentConfigSchema, assignedTaskParticipantSchema, assignedTaskSignalBootstrapFields, assignedTaskSignalSchema, assignedTaskPresenceSignalSchema, assignedTaskPresenceDeltaSchema, assignedTaskSnapshotRowSchema;
|
|
98702
|
+
var init_assigned_task_snapshot_contract = __esm(() => {
|
|
98723
98703
|
init_zod();
|
|
98724
98704
|
init_convex_id();
|
|
98725
98705
|
ACTIVE_TASK_STATUSES = ["pending", "acknowledged", "in_progress"];
|
|
@@ -98782,7 +98762,7 @@ var init_assigned_task_monitor_contract = __esm(() => {
|
|
|
98782
98762
|
role: exports_external.string(),
|
|
98783
98763
|
presenceKey: exports_external.string()
|
|
98784
98764
|
});
|
|
98785
|
-
|
|
98765
|
+
assignedTaskSnapshotRowSchema = exports_external.object({
|
|
98786
98766
|
taskId: chatroomTaskIdSchema,
|
|
98787
98767
|
chatroomId: chatroomRoomIdSchema,
|
|
98788
98768
|
status: activeTaskStatusSchema,
|
|
@@ -98943,6 +98923,19 @@ function getNativeDeliverySession() {
|
|
|
98943
98923
|
}
|
|
98944
98924
|
var registered = null;
|
|
98945
98925
|
|
|
98926
|
+
// src/daemon/entry/native-delivery/native-stale-turn-phase.ts
|
|
98927
|
+
function isStaleTurnInFlightWhileWaiting(task, slot) {
|
|
98928
|
+
if (!slot || isTurnPhaseIdle(slot.nativeTurnPhase ?? "idle"))
|
|
98929
|
+
return false;
|
|
98930
|
+
if (task.status !== "pending")
|
|
98931
|
+
return false;
|
|
98932
|
+
return task.participant?.lastSeenAction === NATIVE_WAITING_ACTION;
|
|
98933
|
+
}
|
|
98934
|
+
var init_native_stale_turn_phase = __esm(() => {
|
|
98935
|
+
init_participant();
|
|
98936
|
+
init_check_agent_slot();
|
|
98937
|
+
});
|
|
98938
|
+
|
|
98946
98939
|
// src/daemon/domain/native-integration/predicates.ts
|
|
98947
98940
|
function isStaleCliGetNextTaskWaiting(task) {
|
|
98948
98941
|
const lastSeenAt = task.participant?.lastSeenAt ?? 0;
|
|
@@ -99002,8 +98995,21 @@ function explainNativeDeliveryBlock(task, opts) {
|
|
|
99002
98995
|
return `acknowledged_wrong_role (assignedTo=${assignedTo ?? "none"}, role=${role})`;
|
|
99003
98996
|
}
|
|
99004
98997
|
}
|
|
98998
|
+
const inFlightBlock = explainInFlightDeliveryBlock(task, opts.slot);
|
|
98999
|
+
if (inFlightBlock)
|
|
99000
|
+
return inFlightBlock;
|
|
99005
99001
|
return explainAgentReadyForNativeDeliveryBlock(task, opts.slot);
|
|
99006
99002
|
}
|
|
99003
|
+
function explainInFlightDeliveryBlock(task, slot) {
|
|
99004
|
+
if (!slot?.lastInFlightTaskId || slot.lastInFlightTaskId !== task.taskId)
|
|
99005
|
+
return null;
|
|
99006
|
+
if (task.status === "pending")
|
|
99007
|
+
return null;
|
|
99008
|
+
if (task.status === "acknowledged") {
|
|
99009
|
+
return "already_delivered_to_slot (lastInFlightTaskId match, status=acknowledged)";
|
|
99010
|
+
}
|
|
99011
|
+
return null;
|
|
99012
|
+
}
|
|
99007
99013
|
function explainLedgerDeliveryBlock(taskId, harnessSessionId, ledger) {
|
|
99008
99014
|
if (ledger.isDelivered(taskId, harnessSessionId)) {
|
|
99009
99015
|
return "already_delivered_this_session";
|
|
@@ -99403,28 +99409,21 @@ function mapAssignedTaskSnapshotList(rows) {
|
|
|
99403
99409
|
return rows.map(mapAssignedTaskSnapshot);
|
|
99404
99410
|
}
|
|
99405
99411
|
|
|
99406
|
-
// src/infrastructure/
|
|
99407
|
-
function
|
|
99408
|
-
|
|
99409
|
-
|
|
99410
|
-
|
|
99411
|
-
|
|
99412
|
-
|
|
99413
|
-
hasSnapshot = false;
|
|
99414
|
-
}
|
|
99415
|
-
function hasAssignedTaskSnapshot() {
|
|
99416
|
-
return hasSnapshot;
|
|
99417
|
-
}
|
|
99418
|
-
function listAssignedTaskSnapshots() {
|
|
99419
|
-
return [...rows];
|
|
99412
|
+
// src/daemon/infrastructure/inbox/fetch-machine-assigned-task-snapshots.ts
|
|
99413
|
+
async function fetchMachineAssignedTaskSnapshots(sessionDeps, machineId) {
|
|
99414
|
+
const result = await sessionDeps.backend.query(api.machines.listMachineAssignedTaskSnapshots, {
|
|
99415
|
+
sessionId: sessionDeps.sessionId,
|
|
99416
|
+
machineId
|
|
99417
|
+
});
|
|
99418
|
+
return mapAssignedTaskSnapshotList(parseAssignedTaskSnapshotRows(result?.tasks ?? []));
|
|
99420
99419
|
}
|
|
99421
|
-
function
|
|
99420
|
+
function filterSnapshotsForRole(snapshots, chatroomId, role) {
|
|
99422
99421
|
const roleLower = role.toLowerCase();
|
|
99423
|
-
return
|
|
99422
|
+
return snapshots.filter((row) => row.chatroomId === chatroomId && row.agentConfig.role.toLowerCase() === roleLower);
|
|
99424
99423
|
}
|
|
99425
|
-
var
|
|
99426
|
-
|
|
99427
|
-
|
|
99424
|
+
var init_fetch_machine_assigned_task_snapshots = __esm(() => {
|
|
99425
|
+
init_assigned_task_snapshot_contract();
|
|
99426
|
+
init_api3();
|
|
99428
99427
|
});
|
|
99429
99428
|
|
|
99430
99429
|
// src/daemon/entry/restart-orchestrator-in-flight.ts
|
|
@@ -99518,18 +99517,22 @@ class NativeTaskDeliveryCoordinator {
|
|
|
99518
99517
|
if (!session2)
|
|
99519
99518
|
return;
|
|
99520
99519
|
const { runtime: runtime4, effectContext: effectContext2, agentMgr, sessionDeps, machineId } = session2;
|
|
99521
|
-
|
|
99522
|
-
|
|
99523
|
-
|
|
99524
|
-
|
|
99525
|
-
|
|
99526
|
-
|
|
99527
|
-
|
|
99528
|
-
|
|
99529
|
-
|
|
99530
|
-
|
|
99531
|
-
|
|
99532
|
-
|
|
99520
|
+
fetchMachineAssignedTaskSnapshots(sessionDeps, machineId).then((all8) => {
|
|
99521
|
+
const tasks = filterSnapshotsForRole(all8, chatroomId, role);
|
|
99522
|
+
if (tasks.length === 0) {
|
|
99523
|
+
logNativeDeliveryNoTasks(role, chatroomId);
|
|
99524
|
+
return;
|
|
99525
|
+
}
|
|
99526
|
+
this.reconcileAssignedTasks({
|
|
99527
|
+
tasks,
|
|
99528
|
+
runtime: runtime4,
|
|
99529
|
+
effectContext: effectContext2,
|
|
99530
|
+
agentMgr,
|
|
99531
|
+
sessionDeps,
|
|
99532
|
+
machineId
|
|
99533
|
+
});
|
|
99534
|
+
}).catch((err) => {
|
|
99535
|
+
console.warn(`[NativeTaskDelivery] rehydrate failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`);
|
|
99533
99536
|
});
|
|
99534
99537
|
}
|
|
99535
99538
|
reconcileAssignedTasks(params) {
|
|
@@ -99549,7 +99552,18 @@ class NativeTaskDeliveryCoordinator {
|
|
|
99549
99552
|
for (const row of pendingFirst) {
|
|
99550
99553
|
const { role } = row.agentConfig;
|
|
99551
99554
|
const slot = agentMgr.getSlot(row.chatroomId, role);
|
|
99552
|
-
|
|
99555
|
+
if (row.status === "pending" && slot?.lastInFlightTaskId === row.taskId) {
|
|
99556
|
+
exports_Effect.runSync(agentMgr.clearLastInFlightTaskIfMatches(row.chatroomId, role, row.taskId));
|
|
99557
|
+
}
|
|
99558
|
+
if (isStaleTurnInFlightWhileWaiting(row, slot)) {
|
|
99559
|
+
if (agentMgr.reconcileNativeTurnPhaseIdle) {
|
|
99560
|
+
exports_Effect.runSync(agentMgr.reconcileNativeTurnPhaseIdle(row.chatroomId, role));
|
|
99561
|
+
}
|
|
99562
|
+
logNativeDeliveryFallback("stale-turn-phase", role, row.chatroomId, row.taskId);
|
|
99563
|
+
}
|
|
99564
|
+
const blockReason = explainNativeDeliveryBlock(row, {
|
|
99565
|
+
slot: agentMgr.getSlot(row.chatroomId, role)
|
|
99566
|
+
});
|
|
99553
99567
|
if (blockReason) {
|
|
99554
99568
|
if (isDeliverableTaskStatus(row.status)) {
|
|
99555
99569
|
logNativeDeliverySkip(role, row.chatroomId, row.taskId, blockReason);
|
|
@@ -99638,12 +99652,13 @@ function notifyNativeTurnIdle(params) {
|
|
|
99638
99652
|
var coordinator;
|
|
99639
99653
|
var init_native_task_delivery_coordinator = __esm(() => {
|
|
99640
99654
|
init_esm();
|
|
99655
|
+
init_native_stale_turn_phase();
|
|
99641
99656
|
init_native_task_injector_logic();
|
|
99642
99657
|
init_native_task_injector();
|
|
99643
99658
|
init_api3();
|
|
99644
99659
|
init_assigned_task();
|
|
99645
|
-
init_assigned_task_snapshot_store();
|
|
99646
99660
|
init_convex_error();
|
|
99661
|
+
init_fetch_machine_assigned_task_snapshots();
|
|
99647
99662
|
init_restart_orchestrator_in_flight();
|
|
99648
99663
|
});
|
|
99649
99664
|
|
|
@@ -99718,7 +99733,7 @@ async function listDeliverableSnapshots(deps, event) {
|
|
|
99718
99733
|
machineId: deps.session.machineId
|
|
99719
99734
|
});
|
|
99720
99735
|
const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
|
|
99721
|
-
return mapAssignedTaskSnapshotList(
|
|
99736
|
+
return mapAssignedTaskSnapshotList(parseAssignedTaskSnapshotRows(result.tasks ?? [])).filter((t) => t.chatroomId === event.chatroomId && t.agentConfig.role.toLowerCase() === event.role.toLowerCase() && isDeliverableTaskStatus(t.status) && isAgentReadyForNativeDelivery(t, slot)).sort((a, b) => a.createdAt - b.createdAt);
|
|
99722
99737
|
}
|
|
99723
99738
|
async function deliverOneTask(deps, event, snapshot) {
|
|
99724
99739
|
const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
|
|
@@ -99740,6 +99755,11 @@ async function deliverOneTask(deps, event, snapshot) {
|
|
|
99740
99755
|
console.warn(`[RestartOrchestrator] skip task ${snapshot.taskId} — ${ledgerBlock}`);
|
|
99741
99756
|
return false;
|
|
99742
99757
|
}
|
|
99758
|
+
const deliveryBlock = explainNativeDeliveryBlock(snapshot, { slot });
|
|
99759
|
+
if (deliveryBlock) {
|
|
99760
|
+
console.warn(`[RestartOrchestrator] skip task ${snapshot.taskId} — ${deliveryBlock}`);
|
|
99761
|
+
return false;
|
|
99762
|
+
}
|
|
99743
99763
|
if (!ledger.tryAcquire(snapshot.taskId, harnessSessionId)) {
|
|
99744
99764
|
console.warn(`[RestartOrchestrator] skip task ${snapshot.taskId} — delivery_ledger_busy`);
|
|
99745
99765
|
return false;
|
|
@@ -99843,7 +99863,7 @@ var init_restart_orchestrator = __esm(() => {
|
|
|
99843
99863
|
init_reliability();
|
|
99844
99864
|
init_participant();
|
|
99845
99865
|
init_build_agent_restart_event();
|
|
99846
|
-
|
|
99866
|
+
init_assigned_task_snapshot_contract();
|
|
99847
99867
|
init_esm();
|
|
99848
99868
|
init_api3();
|
|
99849
99869
|
init_native_ready_invariant();
|
|
@@ -101527,6 +101547,7 @@ class AgentProcessManager {
|
|
|
101527
101547
|
}
|
|
101528
101548
|
if (slot) {
|
|
101529
101549
|
setNativeTurnPhase(slot, defaultNativeTurnPhase());
|
|
101550
|
+
this.clearLastInFlightTask(opts.chatroomId, opts.role);
|
|
101530
101551
|
}
|
|
101531
101552
|
notifyNativeTurnIdle({ chatroomId: opts.chatroomId, role: opts.role });
|
|
101532
101553
|
console.log(`[AgentProcessManager] ✅ Native agent_end handled for ${opts.role}`);
|
|
@@ -101542,6 +101563,9 @@ class AgentProcessManager {
|
|
|
101542
101563
|
}
|
|
101543
101564
|
const stopReason = resolveStopReason(opts.code, opts.signal);
|
|
101544
101565
|
const ctx = this.captureExitContext(slot, opts, stopReason);
|
|
101566
|
+
if (slot.harness && getHarnessCapabilities(slot.harness).supportsNativeIntegration) {
|
|
101567
|
+
setNativeTurnPhase(slot, defaultNativeTurnPhase());
|
|
101568
|
+
}
|
|
101545
101569
|
this.maybeEmitProviderUnavailable(opts.chatroomId, opts.role, slot);
|
|
101546
101570
|
notifyNativeHarnessSessionLostOnExit({
|
|
101547
101571
|
chatroomId: opts.chatroomId,
|
|
@@ -101843,6 +101867,21 @@ class AgentProcessManager {
|
|
|
101843
101867
|
const slot = this.getOrCreateSlot(agentKey3(chatroomId, role));
|
|
101844
101868
|
slot.lastInFlightTaskId = taskId;
|
|
101845
101869
|
}
|
|
101870
|
+
clearLastInFlightTaskIfMatches(chatroomId, role, taskId) {
|
|
101871
|
+
const slot = this.slots.get(agentKey3(chatroomId, role));
|
|
101872
|
+
if (slot?.lastInFlightTaskId === taskId)
|
|
101873
|
+
slot.lastInFlightTaskId = undefined;
|
|
101874
|
+
}
|
|
101875
|
+
reconcileNativeTurnPhaseIdle(chatroomId, role) {
|
|
101876
|
+
const slot = this.getSlot(chatroomId, role);
|
|
101877
|
+
if (slot)
|
|
101878
|
+
setNativeTurnPhase(slot, defaultNativeTurnPhase());
|
|
101879
|
+
}
|
|
101880
|
+
clearLastInFlightTask(chatroomId, role) {
|
|
101881
|
+
const slot = this.slots.get(agentKey3(chatroomId, role));
|
|
101882
|
+
if (slot)
|
|
101883
|
+
slot.lastInFlightTaskId = undefined;
|
|
101884
|
+
}
|
|
101846
101885
|
listActive() {
|
|
101847
101886
|
const result = [];
|
|
101848
101887
|
for (const [key, slot] of this.slots) {
|
|
@@ -102512,6 +102551,9 @@ class AgentProcessManager {
|
|
|
102512
102551
|
setNativeTurnPhase(slot, defaultNativeTurnPhase());
|
|
102513
102552
|
}
|
|
102514
102553
|
await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.agentHarness);
|
|
102554
|
+
if (getHarnessCapabilities(opts.agentHarness).supportsNativeIntegration) {
|
|
102555
|
+
getNativeTaskDeliveryCoordinator().tryInjectNextForRole(opts.chatroomId, opts.role);
|
|
102556
|
+
}
|
|
102515
102557
|
}
|
|
102516
102558
|
async emitNativeWaiting(chatroomId, role, harness) {
|
|
102517
102559
|
return emitNativeWaitingAfterSpawn({
|
|
@@ -114159,27 +114201,27 @@ function createFifoBatchedOutbox(o) {
|
|
|
114159
114201
|
return running3;
|
|
114160
114202
|
running3 = (async () => {
|
|
114161
114203
|
while (true) {
|
|
114162
|
-
const
|
|
114163
|
-
if (!
|
|
114204
|
+
const rows = o.store.claimNextBatch(o.deliveryKey, o.batchSize);
|
|
114205
|
+
if (!rows.length)
|
|
114164
114206
|
break;
|
|
114165
114207
|
try {
|
|
114166
|
-
const results = await o.send(
|
|
114208
|
+
const results = await o.send(rows.map((r) => o.deserialize(r.payloadJson)));
|
|
114167
114209
|
let hasRetry = false;
|
|
114168
114210
|
for (let i2 = 0;i2 < results.length; i2++) {
|
|
114169
|
-
const item = o.deserialize(
|
|
114211
|
+
const item = o.deserialize(rows[i2].payloadJson);
|
|
114170
114212
|
const outcome = o.classifyOutcome?.(results[i2], item) ?? { kind: "success" };
|
|
114171
114213
|
if (outcome.kind === "retry") {
|
|
114172
|
-
o.store.updatePayload(
|
|
114173
|
-
o.store.markPending(
|
|
114214
|
+
o.store.updatePayload(rows[i2].id, o.serialize(outcome.item));
|
|
114215
|
+
o.store.markPending(rows[i2].id);
|
|
114174
114216
|
hasRetry = true;
|
|
114175
114217
|
continue;
|
|
114176
114218
|
}
|
|
114177
|
-
o.store.markDone(
|
|
114178
|
-
waiters.get(
|
|
114179
|
-
waiters.delete(
|
|
114219
|
+
o.store.markDone(rows[i2].id);
|
|
114220
|
+
waiters.get(rows[i2].id)?.resolve(results[i2]);
|
|
114221
|
+
waiters.delete(rows[i2].id);
|
|
114180
114222
|
}
|
|
114181
|
-
for (let i2 = results.length;i2 <
|
|
114182
|
-
o.store.markPending(
|
|
114223
|
+
for (let i2 = results.length;i2 < rows.length; i2++)
|
|
114224
|
+
o.store.markPending(rows[i2].id);
|
|
114183
114225
|
if (hasRetry) {
|
|
114184
114226
|
scheduleRetry();
|
|
114185
114227
|
break;
|
|
@@ -114187,7 +114229,7 @@ function createFifoBatchedOutbox(o) {
|
|
|
114187
114229
|
retryAttempt = 0;
|
|
114188
114230
|
} catch (e) {
|
|
114189
114231
|
o.onError?.(e);
|
|
114190
|
-
for (const r of
|
|
114232
|
+
for (const r of rows)
|
|
114191
114233
|
o.store.markPendingRetry(r.id, e);
|
|
114192
114234
|
scheduleRetry();
|
|
114193
114235
|
break;
|
|
@@ -115715,20 +115757,7 @@ var init_command_run_subscription = __esm(() => {
|
|
|
115715
115757
|
dispatchedStop = new Set;
|
|
115716
115758
|
});
|
|
115717
115759
|
|
|
115718
|
-
// src/daemon/entry/
|
|
115719
|
-
function registerAssignedTaskMonitorHandler(h) {
|
|
115720
|
-
handler6 = h;
|
|
115721
|
-
}
|
|
115722
|
-
function unregisterAssignedTaskMonitorHandler() {
|
|
115723
|
-
handler6 = undefined;
|
|
115724
|
-
}
|
|
115725
|
-
async function dispatchAssignedTaskMonitorEvent(event) {
|
|
115726
|
-
if (handler6)
|
|
115727
|
-
await handler6(event);
|
|
115728
|
-
}
|
|
115729
|
-
var handler6;
|
|
115730
|
-
|
|
115731
|
-
// src/daemon/entry/task-monitor/task-monitor-logic.ts
|
|
115760
|
+
// src/daemon/entry/task-delivery/task-delivery-logic.ts
|
|
115732
115761
|
function isPendingAliveRunningTask(task) {
|
|
115733
115762
|
const { agentConfig, status: status3 } = task;
|
|
115734
115763
|
return status3 === "pending" && agentConfig.spawnedAgentPid != null && isAgentDesiredRunning(agentConfig.desiredState);
|
|
@@ -115787,9 +115816,29 @@ function listNativeTasksNeedingRevive(tasks, health, now, cooldown) {
|
|
|
115787
115816
|
const { chatroomId, agentConfig } = task;
|
|
115788
115817
|
if (!agentConfig.workingDir)
|
|
115789
115818
|
return false;
|
|
115790
|
-
if (!cooldown.
|
|
115819
|
+
if (!cooldown.canAttempt(chatroomId, agentConfig.role, "revive", now))
|
|
115791
115820
|
return false;
|
|
115792
|
-
cooldown.
|
|
115821
|
+
cooldown.recordAttempt(chatroomId, agentConfig.role, "revive", now);
|
|
115822
|
+
return true;
|
|
115823
|
+
});
|
|
115824
|
+
}
|
|
115825
|
+
function isNativePendingTaskNeedingWake(task) {
|
|
115826
|
+
if (!isNativeHarness(task.agentConfig.agentHarness))
|
|
115827
|
+
return false;
|
|
115828
|
+
if (task.status !== "pending")
|
|
115829
|
+
return false;
|
|
115830
|
+
if (isAgentDesiredRunning(task.agentConfig.desiredState))
|
|
115831
|
+
return false;
|
|
115832
|
+
return Boolean(task.agentConfig.workingDir);
|
|
115833
|
+
}
|
|
115834
|
+
function listNativePendingTasksNeedingWake(tasks, cooldown, now) {
|
|
115835
|
+
return tasks.filter((task) => {
|
|
115836
|
+
if (!isNativePendingTaskNeedingWake(task))
|
|
115837
|
+
return false;
|
|
115838
|
+
const { chatroomId, agentConfig } = task;
|
|
115839
|
+
if (!cooldown.canAttempt(chatroomId, agentConfig.role, "wake", now))
|
|
115840
|
+
return false;
|
|
115841
|
+
cooldown.recordAttempt(chatroomId, agentConfig.role, "wake", now);
|
|
115793
115842
|
return true;
|
|
115794
115843
|
});
|
|
115795
115844
|
}
|
|
@@ -115813,23 +115862,20 @@ function shouldNudgeNativePendingTask(task, now, pendingIdleThresholdMs, slot) {
|
|
|
115813
115862
|
const idleSince = lastSeenAt > 0 ? now - lastSeenAt : now - task.createdAt;
|
|
115814
115863
|
return idleSince > pendingIdleThresholdMs;
|
|
115815
115864
|
}
|
|
115816
|
-
function shouldEscalateNativeNudgeToRestart(chatroomId, role, failures3) {
|
|
115817
|
-
return failures3 >= NATIVE_NUDGE_ESCALATION_THRESHOLD;
|
|
115818
|
-
}
|
|
115819
115865
|
|
|
115820
|
-
class
|
|
115866
|
+
class RecoveryCooldown {
|
|
115821
115867
|
cooldownMs;
|
|
115822
|
-
|
|
115868
|
+
lastAttemptAt = new Map;
|
|
115823
115869
|
constructor(cooldownMs = NUDGE_COOLDOWN_MS) {
|
|
115824
115870
|
this.cooldownMs = cooldownMs;
|
|
115825
115871
|
}
|
|
115826
|
-
|
|
115827
|
-
const key = `${chatroomId}:${role}`;
|
|
115828
|
-
const last2 = this.
|
|
115872
|
+
canAttempt(chatroomId, role, kind, now) {
|
|
115873
|
+
const key = `${kind}:${chatroomId}:${role}`;
|
|
115874
|
+
const last2 = this.lastAttemptAt.get(key);
|
|
115829
115875
|
return last2 === undefined || now - last2 >= this.cooldownMs;
|
|
115830
115876
|
}
|
|
115831
|
-
|
|
115832
|
-
this.
|
|
115877
|
+
recordAttempt(chatroomId, role, kind, now) {
|
|
115878
|
+
this.lastAttemptAt.set(`${kind}:${chatroomId}:${role}`, now);
|
|
115833
115879
|
}
|
|
115834
115880
|
}
|
|
115835
115881
|
function isTaskReadyForNudge(task, now, cooldown, getSlot) {
|
|
@@ -115841,7 +115887,7 @@ function isTaskReadyForNudge(task, now, cooldown, getSlot) {
|
|
|
115841
115887
|
return false;
|
|
115842
115888
|
}
|
|
115843
115889
|
const { chatroomId, agentConfig } = task;
|
|
115844
|
-
if (!cooldown.
|
|
115890
|
+
if (!cooldown.canAttempt(chatroomId, agentConfig.role, "nudge", now))
|
|
115845
115891
|
return false;
|
|
115846
115892
|
if (!agentConfig.workingDir)
|
|
115847
115893
|
return false;
|
|
@@ -115851,12 +115897,12 @@ function listTasksReadyForNudge(tasks, now, cooldown, getSlot) {
|
|
|
115851
115897
|
return tasks.filter((task) => {
|
|
115852
115898
|
if (!isTaskReadyForNudge(task, now, cooldown, getSlot))
|
|
115853
115899
|
return false;
|
|
115854
|
-
cooldown.
|
|
115900
|
+
cooldown.recordAttempt(task.chatroomId, task.agentConfig.role, "nudge", now);
|
|
115855
115901
|
return true;
|
|
115856
115902
|
});
|
|
115857
115903
|
}
|
|
115858
|
-
var PENDING_IDLE_NUDGE_MS = 15000, NUDGE_COOLDOWN_MS = 60000
|
|
115859
|
-
var
|
|
115904
|
+
var PENDING_IDLE_NUDGE_MS = 15000, NUDGE_COOLDOWN_MS = 60000;
|
|
115905
|
+
var init_task_delivery_logic = __esm(() => {
|
|
115860
115906
|
init_assigned_task();
|
|
115861
115907
|
init_check_agent_slot();
|
|
115862
115908
|
init_predicates();
|
|
@@ -115865,7 +115911,7 @@ var init_task_monitor_logic = __esm(() => {
|
|
|
115865
115911
|
init_native_task_injector_logic();
|
|
115866
115912
|
});
|
|
115867
115913
|
|
|
115868
|
-
// src/daemon/entry/task-
|
|
115914
|
+
// src/daemon/entry/native-delivery/task-delivery-processor.ts
|
|
115869
115915
|
function resolveTaskWantResume(task) {
|
|
115870
115916
|
return sessionAugmentationToWantResume(resolveSessionAugmentationForTask({ content: task.taskContent ?? "", startInNewSession: task.startInNewSession }, task.agentConfig.role));
|
|
115871
115917
|
}
|
|
@@ -115955,6 +116001,24 @@ function runNativeReviveEffect(task, runtime4, effectContext2, agentMgr) {
|
|
|
115955
116001
|
});
|
|
115956
116002
|
}).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] native revive failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
|
|
115957
116003
|
}
|
|
116004
|
+
function runNativeWakeEffect(task, runtime4, effectContext2, agentMgr) {
|
|
116005
|
+
const ctx = resolveTaskRunnerContextFromFull(task);
|
|
116006
|
+
if (!ctx)
|
|
116007
|
+
return;
|
|
116008
|
+
const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
|
|
116009
|
+
console.log(`[TaskMonitor] native wake ${role}@${chatroomId} — desiredState=stopped with pending task ${task.taskId}`);
|
|
116010
|
+
exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
|
|
116011
|
+
yield* agentMgr.ensureRunning({
|
|
116012
|
+
chatroomId,
|
|
116013
|
+
role,
|
|
116014
|
+
agentHarness: agentConfig.agentHarness,
|
|
116015
|
+
model: agentConfig.model,
|
|
116016
|
+
workingDir,
|
|
116017
|
+
reason: "platform.pending_task_wake",
|
|
116018
|
+
wantResume
|
|
116019
|
+
});
|
|
116020
|
+
}).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] native wake failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
|
|
116021
|
+
}
|
|
115958
116022
|
async function fetchTaskForAction(sessionDeps, machineId, snapshotRow) {
|
|
115959
116023
|
const result = await sessionDeps.backend.query(api.machines.getAssignedTaskForAction, {
|
|
115960
116024
|
sessionId: sessionDeps.sessionId,
|
|
@@ -115976,43 +116040,9 @@ async function clearStuckStoppingSlotIfNeeded(agentMgr, chatroomId, role) {
|
|
|
115976
116040
|
}
|
|
115977
116041
|
async function nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
115978
116042
|
const getSlot = (chatroomId, role) => agentMgr.getSlot(chatroomId, role);
|
|
115979
|
-
|
|
116043
|
+
const cliTasks = tasks.filter((task) => !isNativeHarness(task.agentConfig.agentHarness));
|
|
116044
|
+
for (const row of listTasksReadyForNudge(cliTasks, now, cooldown, getSlot)) {
|
|
115980
116045
|
await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
|
|
115981
|
-
if (isNativeHarness(row.agentConfig.agentHarness)) {
|
|
115982
|
-
const { chatroomId, agentConfig } = row;
|
|
115983
|
-
const { role } = agentConfig;
|
|
115984
|
-
if (!isTeamAgentRole(role))
|
|
115985
|
-
continue;
|
|
115986
|
-
const deliveryState = getRoleDeliveryState();
|
|
115987
|
-
const failures3 = deliveryState.recordNativeNudgeFailure(chatroomId, role);
|
|
115988
|
-
if (shouldEscalateNativeNudgeToRestart(chatroomId, role, failures3)) {
|
|
115989
|
-
const full2 = await fetchTaskForAction(sessionDeps, machineId, row);
|
|
115990
|
-
if (!full2)
|
|
115991
|
-
continue;
|
|
115992
|
-
console.log(`[TaskMonitor] native nudge escalate restart ${role}@${chatroomId} — pending task ${row.taskId}`);
|
|
115993
|
-
runCliNudgeEffect(full2, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
|
|
115994
|
-
deliveryState.clearNativeNudgeFailures(chatroomId, role);
|
|
115995
|
-
continue;
|
|
115996
|
-
}
|
|
115997
|
-
resetRoleDeliveryState(chatroomId, role);
|
|
115998
|
-
await sessionDeps.backend.mutation(api.participants.join, {
|
|
115999
|
-
sessionId: sessionDeps.sessionId,
|
|
116000
|
-
chatroomId,
|
|
116001
|
-
role,
|
|
116002
|
-
action: NATIVE_WAITING_ACTION
|
|
116003
|
-
});
|
|
116004
|
-
console.log(`[TaskMonitor] native light nudge ${role}@${chatroomId} — redeliver pending task ${row.taskId}`);
|
|
116005
|
-
logNativeDeliveryFallback("native-light-nudge", role, chatroomId, row.taskId);
|
|
116006
|
-
getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
|
|
116007
|
-
tasks: [row],
|
|
116008
|
-
runtime: runtime4,
|
|
116009
|
-
effectContext: effectContext2,
|
|
116010
|
-
agentMgr,
|
|
116011
|
-
sessionDeps,
|
|
116012
|
-
machineId
|
|
116013
|
-
});
|
|
116014
|
-
continue;
|
|
116015
|
-
}
|
|
116016
116046
|
const full = await fetchTaskForAction(sessionDeps, machineId, row);
|
|
116017
116047
|
if (!full)
|
|
116018
116048
|
continue;
|
|
@@ -116030,7 +116060,19 @@ async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, ef
|
|
|
116030
116060
|
runNativeReviveEffect(full, runtime4, effectContext2, agentMgr);
|
|
116031
116061
|
}
|
|
116032
116062
|
}
|
|
116033
|
-
async function
|
|
116063
|
+
async function wakeStoppedAgentsForPendingTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
116064
|
+
for (const row of listNativePendingTasksNeedingWake(tasks, cooldown, now)) {
|
|
116065
|
+
if (isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role))
|
|
116066
|
+
continue;
|
|
116067
|
+
await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
|
|
116068
|
+
const full = await fetchTaskForAction(sessionDeps, machineId, row);
|
|
116069
|
+
if (!full)
|
|
116070
|
+
continue;
|
|
116071
|
+
runNativeWakeEffect(full, runtime4, effectContext2, agentMgr);
|
|
116072
|
+
}
|
|
116073
|
+
}
|
|
116074
|
+
async function processTasksUpdate(runtime4, effectContext2, cooldown, agentMgr, sessionDeps, machineId, _pass, options) {
|
|
116075
|
+
const tasks = options?.snapshots ? [...options.snapshots] : await fetchMachineAssignedTaskSnapshots(sessionDeps, machineId);
|
|
116034
116076
|
const filteredTasks = filterSnapshotsExcludingRestartInFlight(tasks);
|
|
116035
116077
|
if (filteredTasks.length === 0)
|
|
116036
116078
|
return;
|
|
@@ -116039,10 +116081,11 @@ async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, age
|
|
|
116039
116081
|
getSlot: (chatroomId, role) => agentMgr.getSlot(chatroomId, role),
|
|
116040
116082
|
isPidAlive: (pid) => isProcessAlive((p) => process.kill(p, 0), pid)
|
|
116041
116083
|
};
|
|
116084
|
+
await wakeStoppedAgentsForPendingTasks(filteredTasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
|
|
116042
116085
|
await reviveNativeTasks(filteredTasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
|
|
116043
116086
|
if (filteredTasks.length > 0) {
|
|
116044
116087
|
const first = filteredTasks[0];
|
|
116045
|
-
logNativeDeliveryFallback(
|
|
116088
|
+
logNativeDeliveryFallback(_pass, first.agentConfig.role, first.chatroomId, first.taskId);
|
|
116046
116089
|
}
|
|
116047
116090
|
getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
|
|
116048
116091
|
tasks: filteredTasks,
|
|
@@ -116054,60 +116097,317 @@ async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, age
|
|
|
116054
116097
|
});
|
|
116055
116098
|
await nudgeStuckTasks(filteredTasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
|
|
116056
116099
|
}
|
|
116057
|
-
|
|
116058
|
-
|
|
116059
|
-
|
|
116060
|
-
|
|
116061
|
-
|
|
116062
|
-
|
|
116063
|
-
|
|
116064
|
-
|
|
116065
|
-
|
|
116100
|
+
var init_task_delivery_processor = __esm(() => {
|
|
116101
|
+
init_parse_session_augmentation();
|
|
116102
|
+
init_esm();
|
|
116103
|
+
init_native_task_delivery_coordinator();
|
|
116104
|
+
init_native_task_injector_logic();
|
|
116105
|
+
init_api3();
|
|
116106
|
+
init_convex_error();
|
|
116107
|
+
init_fetch_machine_assigned_task_snapshots();
|
|
116108
|
+
init_restart_orchestrator_in_flight();
|
|
116109
|
+
init_task_delivery_logic();
|
|
116110
|
+
});
|
|
116111
|
+
|
|
116112
|
+
// src/daemon/infrastructure/inbox/store/schema.ts
|
|
116113
|
+
var SCHEMA_VERSION = 1, MIGRATIONS;
|
|
116114
|
+
var init_schema = __esm(() => {
|
|
116115
|
+
MIGRATIONS = [
|
|
116116
|
+
`CREATE TABLE IF NOT EXISTS schema_meta (
|
|
116117
|
+
key TEXT PRIMARY KEY,
|
|
116118
|
+
value TEXT NOT NULL
|
|
116119
|
+
)`,
|
|
116120
|
+
`CREATE TABLE IF NOT EXISTS inbox_state (
|
|
116121
|
+
inbox_type TEXT NOT NULL,
|
|
116122
|
+
scope_key TEXT NOT NULL,
|
|
116123
|
+
state_json TEXT NOT NULL,
|
|
116124
|
+
created_at INTEGER NOT NULL,
|
|
116125
|
+
updated_at INTEGER NOT NULL,
|
|
116126
|
+
PRIMARY KEY (inbox_type, scope_key)
|
|
116127
|
+
)`,
|
|
116128
|
+
`CREATE INDEX IF NOT EXISTS idx_inbox_state_type_updated
|
|
116129
|
+
ON inbox_state(inbox_type, updated_at DESC)`,
|
|
116130
|
+
`CREATE INDEX IF NOT EXISTS idx_inbox_state_updated
|
|
116131
|
+
ON inbox_state(updated_at DESC)`
|
|
116132
|
+
];
|
|
116133
|
+
});
|
|
116134
|
+
|
|
116135
|
+
// src/daemon/infrastructure/inbox/store/open-database.ts
|
|
116136
|
+
import { mkdirSync as mkdirSync8 } from "node:fs";
|
|
116137
|
+
import { dirname as dirname15 } from "node:path";
|
|
116138
|
+
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
116139
|
+
function openDatabase(dbPath) {
|
|
116140
|
+
mkdirSync8(dirname15(dbPath), { recursive: true });
|
|
116141
|
+
const db = new DatabaseSync3(dbPath);
|
|
116142
|
+
for (const sql of MIGRATIONS) {
|
|
116143
|
+
db.exec(sql);
|
|
116144
|
+
}
|
|
116145
|
+
db.prepare(`INSERT INTO schema_meta(key, value) VALUES('version', ?)
|
|
116146
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(String(SCHEMA_VERSION));
|
|
116147
|
+
return db;
|
|
116066
116148
|
}
|
|
116067
|
-
|
|
116068
|
-
|
|
116069
|
-
|
|
116070
|
-
|
|
116071
|
-
|
|
116072
|
-
|
|
116149
|
+
var init_open_database = __esm(() => {
|
|
116150
|
+
init_schema();
|
|
116151
|
+
});
|
|
116152
|
+
|
|
116153
|
+
// src/daemon/infrastructure/inbox/store/state-store.ts
|
|
116154
|
+
function assertKeyPart(value, name) {
|
|
116155
|
+
if (value.trim().length === 0) {
|
|
116156
|
+
throw new Error(`${name} cannot be empty`);
|
|
116157
|
+
}
|
|
116158
|
+
}
|
|
116159
|
+
function encodeState(state) {
|
|
116160
|
+
const encoded = JSON.stringify(state);
|
|
116161
|
+
if (encoded === undefined) {
|
|
116162
|
+
throw new Error("Inbox state must be JSON serializable");
|
|
116163
|
+
}
|
|
116164
|
+
return encoded;
|
|
116165
|
+
}
|
|
116166
|
+
function decodeRow(row) {
|
|
116167
|
+
return {
|
|
116168
|
+
inboxType: row.inbox_type,
|
|
116169
|
+
scopeKey: row.scope_key,
|
|
116170
|
+
state: JSON.parse(row.state_json),
|
|
116171
|
+
createdAt: row.created_at,
|
|
116172
|
+
updatedAt: row.updated_at
|
|
116173
|
+
};
|
|
116174
|
+
}
|
|
116175
|
+
function buildQuery(options) {
|
|
116176
|
+
const clauses = [];
|
|
116177
|
+
const params = [];
|
|
116178
|
+
if (options.inboxType !== undefined) {
|
|
116179
|
+
clauses.push("inbox_type = ?");
|
|
116180
|
+
params.push(options.inboxType);
|
|
116181
|
+
}
|
|
116182
|
+
if (options.scopeKey !== undefined) {
|
|
116183
|
+
clauses.push("scope_key = ?");
|
|
116184
|
+
params.push(options.scopeKey);
|
|
116185
|
+
}
|
|
116186
|
+
if (options.scopePrefix !== undefined) {
|
|
116187
|
+
clauses.push("scope_key LIKE ?");
|
|
116188
|
+
params.push(`${options.scopePrefix}%`);
|
|
116189
|
+
}
|
|
116190
|
+
if (options.updatedAfter !== undefined) {
|
|
116191
|
+
clauses.push("updated_at > ?");
|
|
116192
|
+
params.push(options.updatedAfter);
|
|
116193
|
+
}
|
|
116194
|
+
const where = clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
116195
|
+
const limit = Math.min(Math.max(options.limit ?? MAX_QUERY_LIMIT, 1), MAX_QUERY_LIMIT);
|
|
116196
|
+
return {
|
|
116197
|
+
sql: `SELECT inbox_type, scope_key, state_json, created_at, updated_at
|
|
116198
|
+
FROM inbox_state ${where}
|
|
116199
|
+
ORDER BY updated_at DESC, inbox_type ASC, scope_key ASC
|
|
116200
|
+
LIMIT ?`,
|
|
116201
|
+
params: [...params, limit]
|
|
116202
|
+
};
|
|
116203
|
+
}
|
|
116204
|
+
function getInboxState(db, key) {
|
|
116205
|
+
assertKeyPart(key.inboxType, "inboxType");
|
|
116206
|
+
assertKeyPart(key.scopeKey, "scopeKey");
|
|
116207
|
+
const row = db.prepare(`SELECT inbox_type, scope_key, state_json, created_at, updated_at
|
|
116208
|
+
FROM inbox_state
|
|
116209
|
+
WHERE inbox_type = ? AND scope_key = ?`).get(key.inboxType, key.scopeKey);
|
|
116210
|
+
return row ? decodeRow(row) : null;
|
|
116211
|
+
}
|
|
116212
|
+
function saveInboxState(db, key, state, updatedAt = Date.now()) {
|
|
116213
|
+
assertKeyPart(key.inboxType, "inboxType");
|
|
116214
|
+
assertKeyPart(key.scopeKey, "scopeKey");
|
|
116215
|
+
const stateJson = encodeState(state);
|
|
116216
|
+
db.prepare(`INSERT INTO inbox_state(inbox_type, scope_key, state_json, created_at, updated_at)
|
|
116217
|
+
VALUES(?, ?, ?, ?, ?)
|
|
116218
|
+
ON CONFLICT(inbox_type, scope_key) DO UPDATE SET
|
|
116219
|
+
state_json = excluded.state_json,
|
|
116220
|
+
updated_at = excluded.updated_at`).run(key.inboxType, key.scopeKey, stateJson, updatedAt, updatedAt);
|
|
116221
|
+
}
|
|
116222
|
+
function queryInboxState(db, options = {}) {
|
|
116223
|
+
const { sql, params } = buildQuery(options);
|
|
116224
|
+
return db.prepare(sql).all(...params).map((row) => decodeRow(row));
|
|
116225
|
+
}
|
|
116226
|
+
function deleteInboxState(db, key) {
|
|
116227
|
+
assertKeyPart(key.inboxType, "inboxType");
|
|
116228
|
+
assertKeyPart(key.scopeKey, "scopeKey");
|
|
116229
|
+
db.prepare("DELETE FROM inbox_state WHERE inbox_type = ? AND scope_key = ?").run(key.inboxType, key.scopeKey);
|
|
116230
|
+
}
|
|
116231
|
+
var MAX_QUERY_LIMIT = 1000;
|
|
116232
|
+
|
|
116233
|
+
// src/daemon/infrastructure/inbox/store/inbox-state-store.ts
|
|
116234
|
+
function createInboxStateStore(dbPath) {
|
|
116235
|
+
const db = openDatabase(dbPath);
|
|
116236
|
+
return {
|
|
116237
|
+
get: (key) => getInboxState(db, key),
|
|
116238
|
+
save: (key, state, updatedAt) => saveInboxState(db, key, state, updatedAt),
|
|
116239
|
+
query: (options) => queryInboxState(db, options),
|
|
116240
|
+
delete: (key) => deleteInboxState(db, key),
|
|
116241
|
+
close: () => db.close()
|
|
116242
|
+
};
|
|
116243
|
+
}
|
|
116244
|
+
var init_inbox_state_store = __esm(() => {
|
|
116245
|
+
init_open_database();
|
|
116246
|
+
});
|
|
116247
|
+
|
|
116248
|
+
// src/daemon/infrastructure/inbox/store/inbox-db-path.ts
|
|
116249
|
+
import { homedir as homedir10 } from "node:os";
|
|
116250
|
+
import { join as join26 } from "node:path";
|
|
116251
|
+
function resolveInboxDbPath(machineId) {
|
|
116252
|
+
return join26(homedir10(), ".chatroom", "daemon", machineId, "inboxes.sqlite");
|
|
116253
|
+
}
|
|
116254
|
+
var init_inbox_db_path = () => {};
|
|
116255
|
+
|
|
116256
|
+
// src/daemon/infrastructure/inbox/index.ts
|
|
116257
|
+
var init_inbox = __esm(() => {
|
|
116258
|
+
init_inbox_state_store();
|
|
116259
|
+
init_inbox_db_path();
|
|
116260
|
+
});
|
|
116261
|
+
|
|
116262
|
+
// src/daemon/infrastructure/inbox/task-inbox-delivery.ts
|
|
116263
|
+
async function handleTaskInboxUpdate(update6, deps) {
|
|
116264
|
+
if (update6.snapshots.length === 0)
|
|
116073
116265
|
return;
|
|
116074
|
-
|
|
116075
|
-
logNativeDeliveryFallback("periodic-reconcile", first.agentConfig.role, first.chatroomId, first.taskId);
|
|
116076
|
-
getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
|
|
116077
|
-
tasks: deliverable,
|
|
116078
|
-
runtime: runtime4,
|
|
116079
|
-
effectContext: effectContext2,
|
|
116080
|
-
agentMgr,
|
|
116081
|
-
sessionDeps,
|
|
116082
|
-
machineId
|
|
116083
|
-
});
|
|
116266
|
+
await processTasksUpdate(deps.runtime, deps.effectContext, deps.cooldown, deps.agentMgr, deps.sessionDeps, deps.machineId, "inbox-signal");
|
|
116084
116267
|
}
|
|
116085
|
-
|
|
116086
|
-
|
|
116087
|
-
|
|
116268
|
+
var init_task_inbox_delivery = __esm(() => {
|
|
116269
|
+
init_task_delivery_processor();
|
|
116270
|
+
});
|
|
116271
|
+
|
|
116272
|
+
// src/daemon/infrastructure/inbox/task.ts
|
|
116273
|
+
function taskSignalCursorAt(timestamp) {
|
|
116274
|
+
return `${String(Math.max(0, Math.floor(timestamp))).padStart(16, "0")}:`;
|
|
116275
|
+
}
|
|
116276
|
+
function abortError() {
|
|
116277
|
+
const error51 = new Error("Task inbox stopped");
|
|
116278
|
+
error51.name = "AbortError";
|
|
116279
|
+
return error51;
|
|
116280
|
+
}
|
|
116281
|
+
function throwIfAborted(signal) {
|
|
116282
|
+
if (signal?.aborted)
|
|
116283
|
+
throw abortError();
|
|
116284
|
+
}
|
|
116285
|
+
function waitForTaskSignalPage(options, afterSignalKey) {
|
|
116286
|
+
return new Promise((resolve8, reject) => {
|
|
116287
|
+
let unsubscribe;
|
|
116288
|
+
let settled = false;
|
|
116289
|
+
const cleanup = () => {
|
|
116290
|
+
unsubscribe?.();
|
|
116291
|
+
unsubscribe = undefined;
|
|
116292
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
116293
|
+
};
|
|
116294
|
+
const settle2 = (fn2) => {
|
|
116295
|
+
if (settled)
|
|
116296
|
+
return;
|
|
116297
|
+
settled = true;
|
|
116298
|
+
cleanup();
|
|
116299
|
+
fn2();
|
|
116300
|
+
};
|
|
116301
|
+
const onAbort = () => {
|
|
116302
|
+
settle2(() => reject(abortError()));
|
|
116303
|
+
};
|
|
116304
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
116305
|
+
try {
|
|
116306
|
+
throwIfAborted(options.signal);
|
|
116307
|
+
} catch (error51) {
|
|
116308
|
+
settle2(() => reject(error51));
|
|
116088
116309
|
return;
|
|
116089
|
-
|
|
116090
|
-
|
|
116091
|
-
|
|
116092
|
-
|
|
116310
|
+
}
|
|
116311
|
+
unsubscribe = options.client.onUpdate(api.messageList.subscribeTaskStatusSignalsSince, {
|
|
116312
|
+
sessionId: options.sessionId,
|
|
116313
|
+
machineId: options.machineId,
|
|
116314
|
+
afterKey: afterSignalKey,
|
|
116315
|
+
limit: options.signalPageLimit ?? DEFAULT_SIGNAL_PAGE_LIMIT
|
|
116316
|
+
}, (result) => {
|
|
116317
|
+
if (!result || typeof result !== "object")
|
|
116318
|
+
return;
|
|
116319
|
+
const page = result;
|
|
116320
|
+
const items = page.items;
|
|
116321
|
+
const highKey = page.highKey;
|
|
116322
|
+
if (!items?.length || !highKey)
|
|
116323
|
+
return;
|
|
116324
|
+
settle2(() => resolve8({
|
|
116325
|
+
items,
|
|
116326
|
+
afterSignalKey,
|
|
116327
|
+
highSignalKey: highKey
|
|
116328
|
+
}));
|
|
116329
|
+
}, (error51) => {
|
|
116330
|
+
settle2(() => reject(error51));
|
|
116331
|
+
});
|
|
116093
116332
|
});
|
|
116094
116333
|
}
|
|
116095
|
-
function
|
|
116096
|
-
|
|
116097
|
-
|
|
116334
|
+
async function* createTaskSignalIterator(options) {
|
|
116335
|
+
let afterSignalKey = options.initialAfterSignalKey ?? taskSignalCursorAt(options.serviceStartedAt ?? Date.now());
|
|
116336
|
+
while (!options.signal?.aborted) {
|
|
116337
|
+
const page = await waitForTaskSignalPage(options, afterSignalKey);
|
|
116338
|
+
yield page;
|
|
116339
|
+
afterSignalKey = page.highSignalKey;
|
|
116340
|
+
}
|
|
116341
|
+
}
|
|
116342
|
+
async function fetchSnapshotsForSignalPage(options, page) {
|
|
116343
|
+
const snapshots = [];
|
|
116344
|
+
let afterSignalKey = page.afterSignalKey;
|
|
116345
|
+
while (true) {
|
|
116346
|
+
throwIfAborted(options.signal);
|
|
116347
|
+
const result = await options.client.query(api.tasks.listTasksForMachineSignalRange, {
|
|
116348
|
+
sessionId: options.sessionId,
|
|
116349
|
+
machineId: options.machineId,
|
|
116350
|
+
afterSignalKey,
|
|
116351
|
+
throughSignalKey: page.highSignalKey,
|
|
116352
|
+
limit: options.taskPageLimit ?? DEFAULT_TASK_PAGE_LIMIT
|
|
116353
|
+
});
|
|
116354
|
+
snapshots.push(...result.snapshots);
|
|
116355
|
+
if (!result.hasMore || !result.nextSignalKey)
|
|
116356
|
+
break;
|
|
116357
|
+
afterSignalKey = result.nextSignalKey;
|
|
116358
|
+
}
|
|
116359
|
+
return snapshots;
|
|
116360
|
+
}
|
|
116361
|
+
async function runTaskInbox(options, onUpdate) {
|
|
116362
|
+
for await (const page of createTaskSignalIterator(options)) {
|
|
116363
|
+
const snapshots = await fetchSnapshotsForSignalPage(options, page);
|
|
116364
|
+
await onUpdate({
|
|
116365
|
+
signals: page.items,
|
|
116366
|
+
snapshots,
|
|
116367
|
+
afterSignalKey: page.afterSignalKey,
|
|
116368
|
+
throughSignalKey: page.highSignalKey
|
|
116369
|
+
});
|
|
116370
|
+
}
|
|
116371
|
+
}
|
|
116372
|
+
var DEFAULT_SIGNAL_PAGE_LIMIT = 100, DEFAULT_TASK_PAGE_LIMIT = 500;
|
|
116373
|
+
var init_task = __esm(() => {
|
|
116374
|
+
init_api3();
|
|
116375
|
+
});
|
|
116376
|
+
|
|
116377
|
+
// src/daemon/entry/task-inbox-runtime.ts
|
|
116378
|
+
async function bootstrapMachineAssignedTaskSnapshots(deps) {
|
|
116379
|
+
await deps.sessionDeps.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
|
|
116380
|
+
sessionId: deps.sessionDeps.sessionId,
|
|
116381
|
+
machineId: deps.machineId
|
|
116382
|
+
});
|
|
116383
|
+
const tasks = await fetchMachineAssignedTaskSnapshots(deps.sessionDeps, deps.machineId);
|
|
116384
|
+
if (!tasks.length)
|
|
116098
116385
|
return;
|
|
116099
|
-
|
|
116100
|
-
|
|
116386
|
+
await processTasksUpdate(deps.runtime, deps.effectContext, deps.cooldown, deps.agentMgr, deps.sessionDeps, deps.machineId, "bootstrap", { snapshots: tasks });
|
|
116387
|
+
}
|
|
116388
|
+
function isAbortError(error51) {
|
|
116389
|
+
return error51 instanceof Error && error51.name === "AbortError";
|
|
116390
|
+
}
|
|
116391
|
+
async function runInboxLoopWithRestart(options, onUpdate, isStopped) {
|
|
116392
|
+
let backoffMs = INBOX_RESTART_INITIAL_MS;
|
|
116393
|
+
while (!isStopped()) {
|
|
116394
|
+
try {
|
|
116395
|
+
await runTaskInbox(options, onUpdate);
|
|
116396
|
+
return;
|
|
116397
|
+
} catch (error51) {
|
|
116398
|
+
if (isStopped() || isAbortError(error51))
|
|
116399
|
+
return;
|
|
116400
|
+
console.warn(`[TaskInbox] loop error, restarting in ${backoffMs}ms:`, error51);
|
|
116401
|
+
await new Promise((resolve8) => setTimeout(resolve8, backoffMs));
|
|
116402
|
+
backoffMs = Math.min(backoffMs * 2, INBOX_RESTART_MAX_MS);
|
|
116403
|
+
}
|
|
116404
|
+
}
|
|
116101
116405
|
}
|
|
116102
|
-
var
|
|
116406
|
+
var INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startTaskInboxEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
116103
116407
|
const session2 = yield* DaemonSessionService;
|
|
116104
116408
|
const agentMgr = yield* DaemonAgentProcessManagerService;
|
|
116105
116409
|
const effectContext2 = yield* exports_Effect.context();
|
|
116106
116410
|
const runtime4 = yield* exports_Effect.runtime();
|
|
116107
|
-
console.log(`[${formatTimestamp()}] \uD83D\uDCCB Starting task-monitor (incremental subscribe)`);
|
|
116108
|
-
const cooldown = new NudgeCooldown;
|
|
116109
|
-
let stopped = false;
|
|
116110
|
-
let monitorPassInFlight = false;
|
|
116111
116411
|
const sessionDeps = {
|
|
116112
116412
|
sessionId: session2.sessionId,
|
|
116113
116413
|
convexUrl: session2.convexUrl,
|
|
@@ -116118,6 +116418,14 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
|
116118
116418
|
query: (fn2, args2) => session2.backend.query(fn2, args2)
|
|
116119
116419
|
}
|
|
116120
116420
|
};
|
|
116421
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCEC Starting task-inbox (machine-scoped signals)`);
|
|
116422
|
+
const inboxStore = createInboxStateStore(resolveInboxDbPath(session2.machineId));
|
|
116423
|
+
const persisted = inboxStore.get({
|
|
116424
|
+
inboxType: "task",
|
|
116425
|
+
scopeKey: session2.machineId
|
|
116426
|
+
});
|
|
116427
|
+
const abort = new AbortController;
|
|
116428
|
+
let stopped = false;
|
|
116121
116429
|
registerNativeDeliverySession({
|
|
116122
116430
|
runtime: runtime4,
|
|
116123
116431
|
effectContext: effectContext2,
|
|
@@ -116125,61 +116433,64 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
|
116125
116433
|
sessionDeps,
|
|
116126
116434
|
machineId: session2.machineId
|
|
116127
116435
|
});
|
|
116128
|
-
const
|
|
116129
|
-
const
|
|
116130
|
-
|
|
116131
|
-
|
|
116132
|
-
|
|
116133
|
-
|
|
116134
|
-
|
|
116135
|
-
|
|
116436
|
+
const cooldown = new RecoveryCooldown;
|
|
116437
|
+
const inboxOptions = {
|
|
116438
|
+
client: wsClient2,
|
|
116439
|
+
sessionId: session2.sessionId,
|
|
116440
|
+
machineId: session2.machineId,
|
|
116441
|
+
serviceStartedAt: Date.now(),
|
|
116442
|
+
initialAfterSignalKey: persisted?.state.afterSignalKey,
|
|
116443
|
+
signal: abort.signal
|
|
116136
116444
|
};
|
|
116137
|
-
|
|
116138
|
-
|
|
116139
|
-
});
|
|
116140
|
-
const reconcileTimer = setInterval(() => {
|
|
116141
|
-
runLocalStoreReconcilePass({
|
|
116142
|
-
stopped,
|
|
116143
|
-
monitorPassInFlight,
|
|
116144
|
-
agentMgr,
|
|
116445
|
+
const inboxHandler = async (update6) => {
|
|
116446
|
+
await handleTaskInboxUpdate(update6, {
|
|
116145
116447
|
runtime: runtime4,
|
|
116146
116448
|
effectContext: effectContext2,
|
|
116449
|
+
cooldown,
|
|
116450
|
+
agentMgr,
|
|
116147
116451
|
sessionDeps,
|
|
116148
116452
|
machineId: session2.machineId
|
|
116149
116453
|
});
|
|
116454
|
+
inboxStore.save({ inboxType: "task", scopeKey: session2.machineId }, { afterSignalKey: update6.throughSignalKey });
|
|
116455
|
+
};
|
|
116456
|
+
const reconcileTimer = setInterval(() => {
|
|
116457
|
+
if (stopped)
|
|
116458
|
+
return;
|
|
116459
|
+
processTasksUpdate(runtime4, effectContext2, cooldown, agentMgr, sessionDeps, session2.machineId, "periodic-reconcile");
|
|
116150
116460
|
}, NATIVE_DELIVERY_RECONCILE_MS);
|
|
116151
|
-
yield* exports_Effect.tryPromise(() =>
|
|
116152
|
-
|
|
116461
|
+
yield* exports_Effect.tryPromise(() => bootstrapMachineAssignedTaskSnapshots({
|
|
116462
|
+
sessionDeps,
|
|
116463
|
+
runtime: runtime4,
|
|
116464
|
+
effectContext: effectContext2,
|
|
116465
|
+
cooldown,
|
|
116466
|
+
agentMgr,
|
|
116153
116467
|
machineId: session2.machineId
|
|
116154
|
-
})).pipe(exports_Effect.catchAll(() =>
|
|
116468
|
+
})).pipe(exports_Effect.catchAll((error51) => {
|
|
116469
|
+
console.warn("[TaskInbox] bootstrap failed:", error51);
|
|
116470
|
+
return exports_Effect.void;
|
|
116471
|
+
}));
|
|
116472
|
+
runInboxLoopWithRestart(inboxOptions, inboxHandler, () => stopped);
|
|
116155
116473
|
return {
|
|
116156
116474
|
stop() {
|
|
116157
116475
|
stopped = true;
|
|
116158
|
-
|
|
116159
|
-
unsubscribeSnapshotStore();
|
|
116160
|
-
clearAssignedTaskSnapshots();
|
|
116161
|
-
unregisterNativeDeliverySession();
|
|
116476
|
+
abort.abort();
|
|
116162
116477
|
clearInterval(reconcileTimer);
|
|
116163
|
-
|
|
116478
|
+
unregisterNativeDeliverySession();
|
|
116479
|
+
inboxStore.close();
|
|
116164
116480
|
}
|
|
116165
116481
|
};
|
|
116166
116482
|
});
|
|
116167
|
-
var
|
|
116483
|
+
var init_task_inbox_runtime = __esm(() => {
|
|
116168
116484
|
init_reliability();
|
|
116169
|
-
init_participant();
|
|
116170
|
-
init_parse_session_augmentation();
|
|
116171
|
-
init_assigned_task_monitor_contract();
|
|
116172
116485
|
init_esm();
|
|
116173
116486
|
init_daemon_services();
|
|
116174
|
-
init_native_ready_invariant();
|
|
116175
|
-
init_native_task_delivery_coordinator();
|
|
116176
|
-
init_native_task_injector_logic();
|
|
116177
|
-
init_restart_orchestrator_in_flight();
|
|
116178
|
-
init_task_monitor_logic();
|
|
116179
116487
|
init_api3();
|
|
116180
|
-
|
|
116181
|
-
|
|
116182
|
-
|
|
116488
|
+
init_task_delivery_processor();
|
|
116489
|
+
init_task_delivery_logic();
|
|
116490
|
+
init_fetch_machine_assigned_task_snapshots();
|
|
116491
|
+
init_inbox();
|
|
116492
|
+
init_task_inbox_delivery();
|
|
116493
|
+
init_task();
|
|
116183
116494
|
});
|
|
116184
116495
|
|
|
116185
116496
|
// src/daemon/entry/workspace-git/git-subscription.ts
|
|
@@ -116529,16 +116840,16 @@ var init_workspace_list_subscription = __esm(() => {
|
|
|
116529
116840
|
|
|
116530
116841
|
// src/daemon/entry/workspace-git-inbound-registry.ts
|
|
116531
116842
|
function registerWorkspaceGitInboundHandler(h) {
|
|
116532
|
-
|
|
116843
|
+
handler6 = h;
|
|
116533
116844
|
}
|
|
116534
116845
|
function unregisterWorkspaceGitInboundHandler() {
|
|
116535
|
-
|
|
116846
|
+
handler6 = undefined;
|
|
116536
116847
|
}
|
|
116537
116848
|
async function dispatchWorkspaceGitInboundEvent(event) {
|
|
116538
|
-
if (
|
|
116539
|
-
await
|
|
116849
|
+
if (handler6)
|
|
116850
|
+
await handler6(event);
|
|
116540
116851
|
}
|
|
116541
|
-
var
|
|
116852
|
+
var handler6;
|
|
116542
116853
|
|
|
116543
116854
|
// src/events/lifecycle/on-daemon-shutdown.ts
|
|
116544
116855
|
var onDaemonShutdownEffect;
|
|
@@ -116579,7 +116890,7 @@ function createDaemonRuntime(deps) {
|
|
|
116579
116890
|
let directHarnessWorkerHandle = null;
|
|
116580
116891
|
let agenticQueryWorkerHandle = null;
|
|
116581
116892
|
let enhancerWorkerHandle = null;
|
|
116582
|
-
let
|
|
116893
|
+
let taskInboxHandle = null;
|
|
116583
116894
|
const activeSessions = new Map;
|
|
116584
116895
|
const harnesses = new Map;
|
|
116585
116896
|
let signalCount = 0;
|
|
@@ -116614,7 +116925,7 @@ function createDaemonRuntime(deps) {
|
|
|
116614
116925
|
gitSubscriptionHandle?.stop();
|
|
116615
116926
|
fileTreeSubscriptionHandle?.stop();
|
|
116616
116927
|
workspaceListSubscriptionHandle?.stop();
|
|
116617
|
-
|
|
116928
|
+
taskInboxHandle?.stop();
|
|
116618
116929
|
logObserverSubscriptionHandle?.stop();
|
|
116619
116930
|
directHarnessWorkerHandle?.stop();
|
|
116620
116931
|
agenticQueryWorkerHandle?.stop();
|
|
@@ -116720,7 +117031,7 @@ function createDaemonRuntime(deps) {
|
|
|
116720
117031
|
break;
|
|
116721
117032
|
}
|
|
116722
117033
|
});
|
|
116723
|
-
|
|
117034
|
+
taskInboxHandle = yield* startTaskInboxEffect(deps.wsClient);
|
|
116724
117035
|
logObserverSubscriptionHandle = startLogObserverSubscription({ sessionId: session2.sessionId, machineId: session2.machineId }, deps.wsClient);
|
|
116725
117036
|
const commandRunRuntime = yield* exports_Effect.runtime();
|
|
116726
117037
|
if (featureFlags.directHarnessWorkers) {
|
|
@@ -116780,7 +117091,7 @@ var init_daemon_runtime = __esm(() => {
|
|
|
116780
117091
|
init_command_run_subscription();
|
|
116781
117092
|
init_log_observer_sync();
|
|
116782
117093
|
init_init_daemon();
|
|
116783
|
-
|
|
117094
|
+
init_task_inbox_runtime();
|
|
116784
117095
|
init_git_heartbeat();
|
|
116785
117096
|
init_git_subscription();
|
|
116786
117097
|
init_api3();
|
|
@@ -116808,24 +117119,6 @@ var init_agentic_query_bridge = __esm(() => {
|
|
|
116808
117119
|
init_process_agentic_query_prompt();
|
|
116809
117120
|
});
|
|
116810
117121
|
|
|
116811
|
-
// src/daemon/domain/usecase/deliver-assigned-task.ts
|
|
116812
|
-
async function deliverAssignedTaskInbound(deps, event) {
|
|
116813
|
-
await deps.dispatchInbound(event);
|
|
116814
|
-
}
|
|
116815
|
-
|
|
116816
|
-
// src/daemon/entry/bridge/assigned-task-bridge.ts
|
|
116817
|
-
function createDeliverAssignedTaskDeps() {
|
|
116818
|
-
return { dispatchInbound: dispatchAssignedTaskMonitorEvent };
|
|
116819
|
-
}
|
|
116820
|
-
function createAssignedTaskRouterDeps() {
|
|
116821
|
-
return {
|
|
116822
|
-
deliverInbound: async (event) => {
|
|
116823
|
-
await deliverAssignedTaskInbound(createDeliverAssignedTaskDeps(), event);
|
|
116824
|
-
}
|
|
116825
|
-
};
|
|
116826
|
-
}
|
|
116827
|
-
var init_assigned_task_bridge = () => {};
|
|
116828
|
-
|
|
116829
117122
|
// src/daemon/domain/usecase/handle-command-event.ts
|
|
116830
117123
|
async function handleCommandEvent(deps, event) {
|
|
116831
117124
|
await deps.dispatchInbound(event);
|
|
@@ -116943,7 +117236,6 @@ var init_workspace_git_bridge = () => {};
|
|
|
116943
117236
|
// src/daemon/entry/default-router-deps.ts
|
|
116944
117237
|
function createDefaultEventRouterDeps() {
|
|
116945
117238
|
return {
|
|
116946
|
-
assignedTask: createAssignedTaskRouterDeps(),
|
|
116947
117239
|
directHarness: createDirectHarnessRouterDeps(),
|
|
116948
117240
|
command: createCommandRouterDeps(),
|
|
116949
117241
|
workspaceGit: createWorkspaceGitRouterDeps(),
|
|
@@ -116954,7 +117246,6 @@ function createDefaultEventRouterDeps() {
|
|
|
116954
117246
|
}
|
|
116955
117247
|
var init_default_router_deps = __esm(() => {
|
|
116956
117248
|
init_agentic_query_bridge();
|
|
116957
|
-
init_assigned_task_bridge();
|
|
116958
117249
|
init_command_bridge();
|
|
116959
117250
|
init_direct_harness_bridge();
|
|
116960
117251
|
init_enhancer_bridge();
|
|
@@ -117335,10 +117626,10 @@ var init_deps = __esm(() => {
|
|
|
117335
117626
|
});
|
|
117336
117627
|
|
|
117337
117628
|
// src/daemon/entry/persistence-path.ts
|
|
117338
|
-
import { homedir as
|
|
117339
|
-
import { join as
|
|
117629
|
+
import { homedir as homedir11 } from "node:os";
|
|
117630
|
+
import { join as join27 } from "node:path";
|
|
117340
117631
|
function resolvePersistenceDbPath(machineId) {
|
|
117341
|
-
return
|
|
117632
|
+
return join27(homedir11(), ".chatroom", "daemon", machineId, "events.sqlite");
|
|
117342
117633
|
}
|
|
117343
117634
|
var init_persistence_path = () => {};
|
|
117344
117635
|
|
|
@@ -117349,13 +117640,6 @@ async function handleAgenticQueryInbound(deps, event) {
|
|
|
117349
117640
|
}
|
|
117350
117641
|
}
|
|
117351
117642
|
|
|
117352
|
-
// src/daemon/domain/usecase/handle-assigned-task-inbound.ts
|
|
117353
|
-
async function handleAssignedTaskInbound(deps, event) {
|
|
117354
|
-
if (deps.deliverInbound) {
|
|
117355
|
-
await deps.deliverInbound(event);
|
|
117356
|
-
}
|
|
117357
|
-
}
|
|
117358
|
-
|
|
117359
117643
|
// src/daemon/domain/usecase/handle-command-inbound.ts
|
|
117360
117644
|
async function handleCommandInbound(deps, event) {
|
|
117361
117645
|
if (deps.deliverInbound) {
|
|
@@ -117394,10 +117678,6 @@ async function handleWorkspaceGitInbound(deps, event) {
|
|
|
117394
117678
|
// src/daemon/entry/event-router.ts
|
|
117395
117679
|
async function routeInboundEvent(deps, event) {
|
|
117396
117680
|
switch (event.type) {
|
|
117397
|
-
case "assigned-task.signal":
|
|
117398
|
-
case "assigned-task.presence":
|
|
117399
|
-
await handleAssignedTaskInbound(deps.assignedTask, event);
|
|
117400
|
-
break;
|
|
117401
117681
|
case "direct-harness.session-opened":
|
|
117402
117682
|
case "direct-harness.prompt":
|
|
117403
117683
|
case "direct-harness.command":
|
|
@@ -117496,403 +117776,6 @@ var init_agentic_query_session = __esm(() => {
|
|
|
117496
117776
|
init_api3();
|
|
117497
117777
|
});
|
|
117498
117778
|
|
|
117499
|
-
// src/infrastructure/incremental-sync/layers.ts
|
|
117500
|
-
var IntervalClock, IntervalClockLive;
|
|
117501
|
-
var init_layers = __esm(() => {
|
|
117502
|
-
init_esm();
|
|
117503
|
-
IntervalClock = class IntervalClock extends exports_Context.Tag("IntervalClock")() {
|
|
117504
|
-
};
|
|
117505
|
-
IntervalClockLive = exports_Layer.succeed(IntervalClock, {
|
|
117506
|
-
sleep: (ms) => exports_Effect.promise(() => new Promise((resolve8) => setTimeout(resolve8, ms)))
|
|
117507
|
-
});
|
|
117508
|
-
});
|
|
117509
|
-
|
|
117510
|
-
// src/infrastructure/incremental-sync/message-buffer.ts
|
|
117511
|
-
class MessageBuffer {
|
|
117512
|
-
keyOf;
|
|
117513
|
-
queue = [];
|
|
117514
|
-
inBuffer = new Set;
|
|
117515
|
-
inFlight = new Map;
|
|
117516
|
-
recentlyAcked = new Map;
|
|
117517
|
-
dedupe;
|
|
117518
|
-
dedupeTtlMs;
|
|
117519
|
-
maxSize;
|
|
117520
|
-
constructor(config4, keyOf) {
|
|
117521
|
-
this.keyOf = keyOf;
|
|
117522
|
-
this.dedupe = config4.dedupe ?? true;
|
|
117523
|
-
this.dedupeTtlMs = config4.dedupeTtlMs ?? 0;
|
|
117524
|
-
this.maxSize = config4.maxSize;
|
|
117525
|
-
}
|
|
117526
|
-
enqueue(items) {
|
|
117527
|
-
this.pruneRecentlyAcked();
|
|
117528
|
-
let enqueued = 0;
|
|
117529
|
-
for (const item of items) {
|
|
117530
|
-
const key = this.keyOf(item);
|
|
117531
|
-
if (this.dedupe && this.shouldSkip(key)) {
|
|
117532
|
-
continue;
|
|
117533
|
-
}
|
|
117534
|
-
this.queue.push({ key, item });
|
|
117535
|
-
this.inBuffer.add(key);
|
|
117536
|
-
enqueued++;
|
|
117537
|
-
}
|
|
117538
|
-
if (enqueued > 0) {
|
|
117539
|
-
this.queue.sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
|
|
117540
|
-
}
|
|
117541
|
-
this.enforceMaxSize();
|
|
117542
|
-
return enqueued;
|
|
117543
|
-
}
|
|
117544
|
-
dequeue() {
|
|
117545
|
-
this.pruneRecentlyAcked();
|
|
117546
|
-
const next4 = this.queue.shift();
|
|
117547
|
-
if (!next4)
|
|
117548
|
-
return;
|
|
117549
|
-
this.inBuffer.delete(next4.key);
|
|
117550
|
-
this.inFlight.set(next4.key, next4.item);
|
|
117551
|
-
return next4.item;
|
|
117552
|
-
}
|
|
117553
|
-
ack(key) {
|
|
117554
|
-
this.inFlight.delete(key);
|
|
117555
|
-
if (this.dedupe) {
|
|
117556
|
-
this.recentlyAcked.set(key, Date.now());
|
|
117557
|
-
}
|
|
117558
|
-
}
|
|
117559
|
-
nack(key, requeue = false) {
|
|
117560
|
-
const item = this.inFlight.get(key);
|
|
117561
|
-
this.inFlight.delete(key);
|
|
117562
|
-
if (requeue && item !== undefined) {
|
|
117563
|
-
this.enqueue([item]);
|
|
117564
|
-
}
|
|
117565
|
-
}
|
|
117566
|
-
size() {
|
|
117567
|
-
return this.queue.length;
|
|
117568
|
-
}
|
|
117569
|
-
highKeyOf(items) {
|
|
117570
|
-
if (items.length === 0)
|
|
117571
|
-
return null;
|
|
117572
|
-
let high = null;
|
|
117573
|
-
for (const item of items) {
|
|
117574
|
-
const key = this.keyOf(item);
|
|
117575
|
-
if (high === null || key > high) {
|
|
117576
|
-
high = key;
|
|
117577
|
-
}
|
|
117578
|
-
}
|
|
117579
|
-
return high;
|
|
117580
|
-
}
|
|
117581
|
-
shouldSkip(key) {
|
|
117582
|
-
if (this.inBuffer.has(key) || this.inFlight.has(key)) {
|
|
117583
|
-
return true;
|
|
117584
|
-
}
|
|
117585
|
-
if (this.dedupeTtlMs > 0) {
|
|
117586
|
-
const ackedAt = this.recentlyAcked.get(key);
|
|
117587
|
-
if (ackedAt !== undefined && Date.now() - ackedAt < this.dedupeTtlMs) {
|
|
117588
|
-
return true;
|
|
117589
|
-
}
|
|
117590
|
-
} else if (this.recentlyAcked.has(key)) {
|
|
117591
|
-
return true;
|
|
117592
|
-
}
|
|
117593
|
-
return false;
|
|
117594
|
-
}
|
|
117595
|
-
pruneRecentlyAcked() {
|
|
117596
|
-
if (this.dedupeTtlMs <= 0)
|
|
117597
|
-
return;
|
|
117598
|
-
const now = Date.now();
|
|
117599
|
-
for (const [key, ackedAt] of this.recentlyAcked) {
|
|
117600
|
-
if (now - ackedAt >= this.dedupeTtlMs) {
|
|
117601
|
-
this.recentlyAcked.delete(key);
|
|
117602
|
-
}
|
|
117603
|
-
}
|
|
117604
|
-
}
|
|
117605
|
-
enforceMaxSize() {
|
|
117606
|
-
while (this.queue.length > this.maxSize) {
|
|
117607
|
-
const dropped = this.queue.shift();
|
|
117608
|
-
if (dropped) {
|
|
117609
|
-
this.inBuffer.delete(dropped.key);
|
|
117610
|
-
console.warn(`[incremental-sync] Buffer full — dropped oldest unacked item (key=${dropped.key})`);
|
|
117611
|
-
}
|
|
117612
|
-
}
|
|
117613
|
-
}
|
|
117614
|
-
}
|
|
117615
|
-
// src/infrastructure/incremental-sync/resolve-high-key.ts
|
|
117616
|
-
function resolveHighKey(def, buffer, page) {
|
|
117617
|
-
if (page.highKey !== null)
|
|
117618
|
-
return page.highKey;
|
|
117619
|
-
const fromItems = buffer.highKeyOf(page.items);
|
|
117620
|
-
if (fromItems !== null)
|
|
117621
|
-
return fromItems;
|
|
117622
|
-
if (def.itemToKey && page.items.length > 0) {
|
|
117623
|
-
let high = null;
|
|
117624
|
-
for (const item of page.items) {
|
|
117625
|
-
const key = def.itemToKey(item);
|
|
117626
|
-
if (high === null || key > high)
|
|
117627
|
-
high = key;
|
|
117628
|
-
}
|
|
117629
|
-
return high;
|
|
117630
|
-
}
|
|
117631
|
-
return null;
|
|
117632
|
-
}
|
|
117633
|
-
|
|
117634
|
-
// src/infrastructure/incremental-sync/subscribe-loop.ts
|
|
117635
|
-
function parseFeedItems(def, items, onError3) {
|
|
117636
|
-
if (!def.parseItem) {
|
|
117637
|
-
return items;
|
|
117638
|
-
}
|
|
117639
|
-
const parsed = [];
|
|
117640
|
-
for (const raw of items) {
|
|
117641
|
-
try {
|
|
117642
|
-
parsed.push(def.parseItem(raw));
|
|
117643
|
-
} catch (err) {
|
|
117644
|
-
onError3?.(err);
|
|
117645
|
-
}
|
|
117646
|
-
}
|
|
117647
|
-
return parsed;
|
|
117648
|
-
}
|
|
117649
|
-
function startSubscribeLoop(opts) {
|
|
117650
|
-
let afterKey = opts.initialAfterKey ?? null;
|
|
117651
|
-
let stopped = false;
|
|
117652
|
-
let unsubscribe;
|
|
117653
|
-
let drainInFlight = false;
|
|
117654
|
-
const subscribe = () => {
|
|
117655
|
-
if (stopped)
|
|
117656
|
-
return;
|
|
117657
|
-
unsubscribe?.();
|
|
117658
|
-
unsubscribe = opts.wsClient.onUpdate(opts.target.query, opts.target.buildArgs(opts.args, afterKey, opts.config.limit), (result) => {
|
|
117659
|
-
if (stopped)
|
|
117660
|
-
return;
|
|
117661
|
-
const page = opts.target.parsePage(result);
|
|
117662
|
-
drainPages(page);
|
|
117663
|
-
}, (err) => {
|
|
117664
|
-
opts.onError?.(err);
|
|
117665
|
-
});
|
|
117666
|
-
};
|
|
117667
|
-
const fetchPage = async (cursor) => {
|
|
117668
|
-
const result = await opts.wsClient.query(opts.target.query, opts.target.buildArgs(opts.args, cursor, opts.config.limit));
|
|
117669
|
-
return opts.target.parsePage(result);
|
|
117670
|
-
};
|
|
117671
|
-
const drainPages = async (initialPage) => {
|
|
117672
|
-
if (stopped || drainInFlight)
|
|
117673
|
-
return;
|
|
117674
|
-
drainInFlight = true;
|
|
117675
|
-
try {
|
|
117676
|
-
const cursorAtStart = afterKey;
|
|
117677
|
-
let page = initialPage;
|
|
117678
|
-
while (!stopped && page.items.length > 0) {
|
|
117679
|
-
const items = parseFeedItems(opts.def, page.items, opts.onError);
|
|
117680
|
-
if (items.length > 0) {
|
|
117681
|
-
opts.buffer.enqueue(items);
|
|
117682
|
-
}
|
|
117683
|
-
const nextKey = resolveHighKey(opts.def, opts.buffer, page);
|
|
117684
|
-
if (nextKey === null) {
|
|
117685
|
-
break;
|
|
117686
|
-
}
|
|
117687
|
-
afterKey = nextKey;
|
|
117688
|
-
if (!page.hasMore) {
|
|
117689
|
-
break;
|
|
117690
|
-
}
|
|
117691
|
-
page = await fetchPage(afterKey);
|
|
117692
|
-
}
|
|
117693
|
-
if (!stopped && afterKey !== cursorAtStart) {
|
|
117694
|
-
subscribe();
|
|
117695
|
-
}
|
|
117696
|
-
} catch (err) {
|
|
117697
|
-
opts.onError?.(err);
|
|
117698
|
-
} finally {
|
|
117699
|
-
drainInFlight = false;
|
|
117700
|
-
}
|
|
117701
|
-
};
|
|
117702
|
-
subscribe();
|
|
117703
|
-
return {
|
|
117704
|
-
stop: () => {
|
|
117705
|
-
stopped = true;
|
|
117706
|
-
unsubscribe?.();
|
|
117707
|
-
unsubscribe = undefined;
|
|
117708
|
-
},
|
|
117709
|
-
getAfterKey: () => afterKey
|
|
117710
|
-
};
|
|
117711
|
-
}
|
|
117712
|
-
var init_subscribe_loop = () => {};
|
|
117713
|
-
|
|
117714
|
-
// src/infrastructure/incremental-sync/feed-runtime.ts
|
|
117715
|
-
function runWorkerLoop(feedName, buffer, keyOf, onItem) {
|
|
117716
|
-
return exports_Effect.gen(function* () {
|
|
117717
|
-
while (true) {
|
|
117718
|
-
const item = buffer.dequeue();
|
|
117719
|
-
if (item === undefined) {
|
|
117720
|
-
yield* exports_Effect.sleep("10 millis");
|
|
117721
|
-
continue;
|
|
117722
|
-
}
|
|
117723
|
-
const key = keyOf(item);
|
|
117724
|
-
const ctx = {
|
|
117725
|
-
item,
|
|
117726
|
-
feedName,
|
|
117727
|
-
ack: () => buffer.ack(key),
|
|
117728
|
-
nack: (opts) => buffer.nack(key, opts?.requeue ?? false)
|
|
117729
|
-
};
|
|
117730
|
-
yield* onItem(ctx).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
117731
|
-
}
|
|
117732
|
-
});
|
|
117733
|
-
}
|
|
117734
|
-
var runIncrementalSubscribeLive = (opts) => exports_Effect.gen(function* () {
|
|
117735
|
-
const buffer = new MessageBuffer(opts.buffer, opts.def.itemKey);
|
|
117736
|
-
const subscribeHandle = startSubscribeLoop({
|
|
117737
|
-
wsClient: opts.wsClient,
|
|
117738
|
-
target: opts.target,
|
|
117739
|
-
args: opts.args,
|
|
117740
|
-
buffer,
|
|
117741
|
-
def: opts.def,
|
|
117742
|
-
config: opts.subscribe,
|
|
117743
|
-
initialAfterKey: opts.initialAfterKey ?? null,
|
|
117744
|
-
onError: opts.onError
|
|
117745
|
-
});
|
|
117746
|
-
const workerFiber = yield* exports_Effect.forkDaemon(runWorkerLoop(opts.def.name, buffer, opts.def.itemKey, opts.onItem));
|
|
117747
|
-
return {
|
|
117748
|
-
buffer,
|
|
117749
|
-
stop: () => exports_Effect.gen(function* () {
|
|
117750
|
-
subscribeHandle.stop();
|
|
117751
|
-
yield* exports_Fiber.interrupt(workerFiber);
|
|
117752
|
-
})
|
|
117753
|
-
};
|
|
117754
|
-
});
|
|
117755
|
-
var init_feed_runtime = __esm(() => {
|
|
117756
|
-
init_esm();
|
|
117757
|
-
init_layers();
|
|
117758
|
-
init_subscribe_loop();
|
|
117759
|
-
});
|
|
117760
|
-
|
|
117761
|
-
// src/infrastructure/incremental-sync/feeds/assigned-task-presence.ts
|
|
117762
|
-
var assignedTaskPresenceFeedDef, assignedTaskPresenceSubscribeTarget, ASSIGNED_TASK_PRESENCE_FEED_LIMIT = 50, ASSIGNED_TASK_PRESENCE_FEED_BUFFER;
|
|
117763
|
-
var init_assigned_task_presence = __esm(() => {
|
|
117764
|
-
init_assigned_task_monitor_contract();
|
|
117765
|
-
init_api3();
|
|
117766
|
-
assignedTaskPresenceFeedDef = {
|
|
117767
|
-
name: "assigned-task-presence",
|
|
117768
|
-
itemKey: (item) => item.presenceKey,
|
|
117769
|
-
parseItem: parseAssignedTaskPresenceSignal
|
|
117770
|
-
};
|
|
117771
|
-
assignedTaskPresenceSubscribeTarget = {
|
|
117772
|
-
query: api.machines.subscribeAssignedTaskPresenceSince,
|
|
117773
|
-
buildArgs: (args2, afterKey, limit) => ({
|
|
117774
|
-
sessionId: args2.sessionId,
|
|
117775
|
-
machineId: args2.machineId,
|
|
117776
|
-
afterPresenceKey: afterKey ?? undefined,
|
|
117777
|
-
limit
|
|
117778
|
-
}),
|
|
117779
|
-
parsePage: (result) => {
|
|
117780
|
-
const page = result;
|
|
117781
|
-
return {
|
|
117782
|
-
items: page.items,
|
|
117783
|
-
highKey: page.highPresenceKey,
|
|
117784
|
-
hasMore: page.hasMore
|
|
117785
|
-
};
|
|
117786
|
-
}
|
|
117787
|
-
};
|
|
117788
|
-
ASSIGNED_TASK_PRESENCE_FEED_BUFFER = {
|
|
117789
|
-
maxSize: 200,
|
|
117790
|
-
dedupe: true
|
|
117791
|
-
};
|
|
117792
|
-
});
|
|
117793
|
-
|
|
117794
|
-
// src/daemon/infrastructure/convex/subscribers/assigned-task-presence.ts
|
|
117795
|
-
function startAssignedTaskPresenceSubscriber(deps, onEvent) {
|
|
117796
|
-
let stopped = false;
|
|
117797
|
-
const startPromise = exports_Effect.runPromise(runIncrementalSubscribeLive({
|
|
117798
|
-
wsClient: deps.wsClient,
|
|
117799
|
-
def: assignedTaskPresenceFeedDef,
|
|
117800
|
-
target: assignedTaskPresenceSubscribeTarget,
|
|
117801
|
-
args: { sessionId: deps.sessionId, machineId: deps.machineId },
|
|
117802
|
-
buffer: ASSIGNED_TASK_PRESENCE_FEED_BUFFER,
|
|
117803
|
-
subscribe: { limit: ASSIGNED_TASK_PRESENCE_FEED_LIMIT },
|
|
117804
|
-
onItem: ({ item, ack }) => exports_Effect.sync(() => {
|
|
117805
|
-
if (stopped)
|
|
117806
|
-
return;
|
|
117807
|
-
ack();
|
|
117808
|
-
onEvent({ type: "assigned-task.presence", taskId: item.taskId, role: item.role });
|
|
117809
|
-
}),
|
|
117810
|
-
onError: (err) => {
|
|
117811
|
-
console.warn(`[daemon] assigned-task-presence subscriber error: ${String(err)}`);
|
|
117812
|
-
}
|
|
117813
|
-
}));
|
|
117814
|
-
let feedHandle;
|
|
117815
|
-
startPromise.then((handle) => {
|
|
117816
|
-
feedHandle = handle;
|
|
117817
|
-
});
|
|
117818
|
-
return {
|
|
117819
|
-
async stop() {
|
|
117820
|
-
stopped = true;
|
|
117821
|
-
const handle = feedHandle ?? await startPromise;
|
|
117822
|
-
await exports_Effect.runPromise(handle.stop());
|
|
117823
|
-
}
|
|
117824
|
-
};
|
|
117825
|
-
}
|
|
117826
|
-
var init_assigned_task_presence2 = __esm(() => {
|
|
117827
|
-
init_esm();
|
|
117828
|
-
init_feed_runtime();
|
|
117829
|
-
init_assigned_task_presence();
|
|
117830
|
-
});
|
|
117831
|
-
|
|
117832
|
-
// src/infrastructure/incremental-sync/feeds/assigned-task-signals.ts
|
|
117833
|
-
var assignedTaskSignalsFeedDef, assignedTaskSignalsSubscribeTarget, ASSIGNED_TASK_SIGNAL_FEED_LIMIT = 50, ASSIGNED_TASK_SIGNAL_FEED_BUFFER;
|
|
117834
|
-
var init_assigned_task_signals = __esm(() => {
|
|
117835
|
-
init_assigned_task_monitor_contract();
|
|
117836
|
-
init_api3();
|
|
117837
|
-
assignedTaskSignalsFeedDef = {
|
|
117838
|
-
name: "assigned-task-signals",
|
|
117839
|
-
itemKey: (item) => item.revisionKey,
|
|
117840
|
-
parseItem: parseAssignedTaskSignal
|
|
117841
|
-
};
|
|
117842
|
-
assignedTaskSignalsSubscribeTarget = {
|
|
117843
|
-
query: api.machines.subscribeAssignedTaskSignalsSince,
|
|
117844
|
-
buildArgs: (args2, afterKey, limit) => ({
|
|
117845
|
-
sessionId: args2.sessionId,
|
|
117846
|
-
machineId: args2.machineId,
|
|
117847
|
-
afterKey: afterKey ?? undefined,
|
|
117848
|
-
limit
|
|
117849
|
-
}),
|
|
117850
|
-
parsePage: (result) => result
|
|
117851
|
-
};
|
|
117852
|
-
ASSIGNED_TASK_SIGNAL_FEED_BUFFER = {
|
|
117853
|
-
maxSize: 200,
|
|
117854
|
-
dedupe: true
|
|
117855
|
-
};
|
|
117856
|
-
});
|
|
117857
|
-
|
|
117858
|
-
// src/daemon/infrastructure/convex/subscribers/assigned-task-signals.ts
|
|
117859
|
-
function startAssignedTaskSignalsSubscriber(deps, onEvent) {
|
|
117860
|
-
let stopped = false;
|
|
117861
|
-
const startPromise = exports_Effect.runPromise(runIncrementalSubscribeLive({
|
|
117862
|
-
wsClient: deps.wsClient,
|
|
117863
|
-
def: assignedTaskSignalsFeedDef,
|
|
117864
|
-
target: assignedTaskSignalsSubscribeTarget,
|
|
117865
|
-
args: { sessionId: deps.sessionId, machineId: deps.machineId },
|
|
117866
|
-
buffer: ASSIGNED_TASK_SIGNAL_FEED_BUFFER,
|
|
117867
|
-
subscribe: { limit: ASSIGNED_TASK_SIGNAL_FEED_LIMIT },
|
|
117868
|
-
onItem: ({ item, ack }) => exports_Effect.sync(() => {
|
|
117869
|
-
if (stopped)
|
|
117870
|
-
return;
|
|
117871
|
-
ack();
|
|
117872
|
-
onEvent({ type: "assigned-task.signal", taskId: item.taskId, role: item.role });
|
|
117873
|
-
}),
|
|
117874
|
-
onError: (err) => {
|
|
117875
|
-
console.warn(`[daemon] assigned-task-signals subscriber error: ${String(err)}`);
|
|
117876
|
-
}
|
|
117877
|
-
}));
|
|
117878
|
-
let feedHandle;
|
|
117879
|
-
startPromise.then((handle) => {
|
|
117880
|
-
feedHandle = handle;
|
|
117881
|
-
});
|
|
117882
|
-
return {
|
|
117883
|
-
async stop() {
|
|
117884
|
-
stopped = true;
|
|
117885
|
-
const handle = feedHandle ?? await startPromise;
|
|
117886
|
-
await exports_Effect.runPromise(handle.stop());
|
|
117887
|
-
}
|
|
117888
|
-
};
|
|
117889
|
-
}
|
|
117890
|
-
var init_assigned_task_signals2 = __esm(() => {
|
|
117891
|
-
init_esm();
|
|
117892
|
-
init_feed_runtime();
|
|
117893
|
-
init_assigned_task_signals();
|
|
117894
|
-
});
|
|
117895
|
-
|
|
117896
117779
|
// src/daemon/infrastructure/convex/subscribers/command-events.ts
|
|
117897
117780
|
function startCommandEventsSubscriber(deps, onEvent) {
|
|
117898
117781
|
const seen = new Set;
|
|
@@ -118304,8 +118187,6 @@ function startAllSubscribers(deps) {
|
|
|
118304
118187
|
const onEvent = (event) => {
|
|
118305
118188
|
routeInboundEvent(deps.router, event);
|
|
118306
118189
|
};
|
|
118307
|
-
const signals = startAssignedTaskSignalsSubscriber(deps, onEvent);
|
|
118308
|
-
const presence = startAssignedTaskPresenceSubscriber(deps, onEvent);
|
|
118309
118190
|
const session2 = startDirectHarnessSessionSubscriber(deps, onEvent);
|
|
118310
118191
|
const prompt = startDirectHarnessPromptSubscriber(deps, onEvent);
|
|
118311
118192
|
const directHarnessCommand = startDirectHarnessCommandSubscriber(deps, onEvent);
|
|
@@ -118323,8 +118204,6 @@ function startAllSubscribers(deps) {
|
|
|
118323
118204
|
return {
|
|
118324
118205
|
async stopAll() {
|
|
118325
118206
|
await Promise.all([
|
|
118326
|
-
signals.stop(),
|
|
118327
|
-
presence.stop(),
|
|
118328
118207
|
session2.stop(),
|
|
118329
118208
|
prompt.stop(),
|
|
118330
118209
|
directHarnessCommand.stop(),
|
|
@@ -118347,8 +118226,6 @@ var init_subscriber_registry = __esm(() => {
|
|
|
118347
118226
|
init_event_router();
|
|
118348
118227
|
init_agentic_query_prompt();
|
|
118349
118228
|
init_agentic_query_session();
|
|
118350
|
-
init_assigned_task_presence2();
|
|
118351
|
-
init_assigned_task_signals2();
|
|
118352
118229
|
init_command_events();
|
|
118353
118230
|
init_command_run();
|
|
118354
118231
|
init_direct_harness_command();
|
|
@@ -118378,19 +118255,19 @@ function resolveEnvSlug(convexUrl) {
|
|
|
118378
118255
|
}
|
|
118379
118256
|
|
|
118380
118257
|
// src/infrastructure/log-server/resolve-logs-db-path.ts
|
|
118381
|
-
import { homedir as
|
|
118382
|
-
import { join as
|
|
118258
|
+
import { homedir as homedir12 } from "node:os";
|
|
118259
|
+
import { join as join28 } from "node:path";
|
|
118383
118260
|
function resolveLogsDbPath(convexUrl) {
|
|
118384
|
-
return
|
|
118261
|
+
return join28(homedir12(), ".chatroom", resolveEnvSlug(convexUrl ?? getConvexUrl()), "logs.sqlite");
|
|
118385
118262
|
}
|
|
118386
118263
|
var init_resolve_logs_db_path = __esm(() => {
|
|
118387
118264
|
init_client2();
|
|
118388
118265
|
});
|
|
118389
118266
|
|
|
118390
118267
|
// src/infrastructure/log-server/log-schema.ts
|
|
118391
|
-
var
|
|
118268
|
+
var SCHEMA_VERSION2 = 2, MIGRATIONS2;
|
|
118392
118269
|
var init_log_schema = __esm(() => {
|
|
118393
|
-
|
|
118270
|
+
MIGRATIONS2 = [
|
|
118394
118271
|
`CREATE TABLE IF NOT EXISTS schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`,
|
|
118395
118272
|
`CREATE TABLE IF NOT EXISTS log_entries (
|
|
118396
118273
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -118414,18 +118291,18 @@ var init_log_schema = __esm(() => {
|
|
|
118414
118291
|
});
|
|
118415
118292
|
|
|
118416
118293
|
// src/infrastructure/log-server/open-log-database.ts
|
|
118417
|
-
import { mkdirSync as
|
|
118418
|
-
import { dirname as
|
|
118419
|
-
import { DatabaseSync as
|
|
118294
|
+
import { mkdirSync as mkdirSync9 } from "node:fs";
|
|
118295
|
+
import { dirname as dirname16 } from "node:path";
|
|
118296
|
+
import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
|
|
118420
118297
|
function openLogDatabase(dbPath) {
|
|
118421
|
-
|
|
118422
|
-
const db = new
|
|
118298
|
+
mkdirSync9(dirname16(dbPath), { recursive: true });
|
|
118299
|
+
const db = new DatabaseSync4(dbPath);
|
|
118423
118300
|
db.exec("PRAGMA journal_mode = WAL");
|
|
118424
118301
|
db.exec("PRAGMA busy_timeout = 5000");
|
|
118425
118302
|
db.exec("PRAGMA synchronous = NORMAL");
|
|
118426
|
-
for (const migration of
|
|
118303
|
+
for (const migration of MIGRATIONS2)
|
|
118427
118304
|
db.exec(migration);
|
|
118428
|
-
db.prepare(`INSERT INTO schema_meta(key,value) VALUES('version',?) ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(String(
|
|
118305
|
+
db.prepare(`INSERT INTO schema_meta(key,value) VALUES('version',?) ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(String(SCHEMA_VERSION2));
|
|
118429
118306
|
return db;
|
|
118430
118307
|
}
|
|
118431
118308
|
var init_open_log_database = __esm(() => {
|
|
@@ -118474,8 +118351,8 @@ function queryEventStream(db, input) {
|
|
|
118474
118351
|
...input.toTimestamp !== undefined ? [input.toTimestamp] : [],
|
|
118475
118352
|
clamp4(input.limit)
|
|
118476
118353
|
];
|
|
118477
|
-
const
|
|
118478
|
-
return
|
|
118354
|
+
const rows = db.prepare(`SELECT * FROM event_stream_entries WHERE 1=1 ${filters} ORDER BY id DESC LIMIT ?`).all(...values3);
|
|
118355
|
+
return rows.reverse().map((row) => ({
|
|
118479
118356
|
id: Number(row.id),
|
|
118480
118357
|
timestamp: Number(row.timestamp),
|
|
118481
118358
|
type: row.type,
|
|
@@ -118501,8 +118378,8 @@ function queryAfterId(db, afterId = 0, limit = 100, source, chatroomId, role, ha
|
|
|
118501
118378
|
...toTimestamp !== undefined ? [toTimestamp] : [],
|
|
118502
118379
|
clamp4(limit)
|
|
118503
118380
|
];
|
|
118504
|
-
const
|
|
118505
|
-
return
|
|
118381
|
+
const rows = db.prepare(`SELECT * FROM log_entries WHERE id > ? ${filters} ORDER BY id ASC LIMIT ?`).all(...values3);
|
|
118382
|
+
return rows.map(map19);
|
|
118506
118383
|
}
|
|
118507
118384
|
function queryHistory(db, beforeId, limit = 100, source, chatroomId, role, harness, fromTimestamp, toTimestamp) {
|
|
118508
118385
|
const filters = [
|
|
@@ -118524,8 +118401,8 @@ function queryHistory(db, beforeId, limit = 100, source, chatroomId, role, harne
|
|
|
118524
118401
|
...toTimestamp !== undefined ? [toTimestamp] : [],
|
|
118525
118402
|
clamp4(limit)
|
|
118526
118403
|
];
|
|
118527
|
-
const
|
|
118528
|
-
return
|
|
118404
|
+
const rows = db.prepare(`SELECT * FROM log_entries WHERE 1=1 ${filters} ORDER BY id DESC LIMIT ?`).all(...values3);
|
|
118405
|
+
return rows.map(map19).reverse();
|
|
118529
118406
|
}
|
|
118530
118407
|
function listLogDimensions(db, chatroomId, limit = 100) {
|
|
118531
118408
|
const clamped = clamp4(limit);
|
|
@@ -118614,9 +118491,9 @@ function appendOutboundEvent(db, event) {
|
|
|
118614
118491
|
}
|
|
118615
118492
|
|
|
118616
118493
|
// src/daemon/infrastructure/persistence/schema.ts
|
|
118617
|
-
var
|
|
118618
|
-
var
|
|
118619
|
-
|
|
118494
|
+
var SCHEMA_VERSION3 = 1, MIGRATIONS3;
|
|
118495
|
+
var init_schema2 = __esm(() => {
|
|
118496
|
+
MIGRATIONS3 = [
|
|
118620
118497
|
`CREATE TABLE IF NOT EXISTS schema_meta (
|
|
118621
118498
|
key TEXT PRIMARY KEY,
|
|
118622
118499
|
value TEXT NOT NULL
|
|
@@ -118645,21 +118522,21 @@ var init_schema = __esm(() => {
|
|
|
118645
118522
|
});
|
|
118646
118523
|
|
|
118647
118524
|
// src/daemon/infrastructure/persistence/open-database.ts
|
|
118648
|
-
import { mkdirSync as
|
|
118649
|
-
import { dirname as
|
|
118650
|
-
import { DatabaseSync as
|
|
118651
|
-
function
|
|
118652
|
-
|
|
118653
|
-
const db = new
|
|
118654
|
-
for (const sql of
|
|
118525
|
+
import { mkdirSync as mkdirSync10 } from "node:fs";
|
|
118526
|
+
import { dirname as dirname17 } from "node:path";
|
|
118527
|
+
import { DatabaseSync as DatabaseSync5 } from "node:sqlite";
|
|
118528
|
+
function openDatabase2(dbPath) {
|
|
118529
|
+
mkdirSync10(dirname17(dbPath), { recursive: true });
|
|
118530
|
+
const db = new DatabaseSync5(dbPath);
|
|
118531
|
+
for (const sql of MIGRATIONS3) {
|
|
118655
118532
|
db.exec(sql);
|
|
118656
118533
|
}
|
|
118657
118534
|
db.prepare(`INSERT INTO schema_meta(key, value) VALUES('version', ?)
|
|
118658
|
-
ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(String(
|
|
118535
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(String(SCHEMA_VERSION3));
|
|
118659
118536
|
return db;
|
|
118660
118537
|
}
|
|
118661
|
-
var
|
|
118662
|
-
|
|
118538
|
+
var init_open_database2 = __esm(() => {
|
|
118539
|
+
init_schema2();
|
|
118663
118540
|
});
|
|
118664
118541
|
|
|
118665
118542
|
// src/daemon/infrastructure/persistence/outbox.ts
|
|
@@ -118677,10 +118554,10 @@ function listPendingOutbox(db, limit = 100) {
|
|
|
118677
118554
|
// src/daemon/infrastructure/persistence/read-model.ts
|
|
118678
118555
|
function listHarnessStreamLines(db, opts = {}) {
|
|
118679
118556
|
const limit = opts.limit ?? 500;
|
|
118680
|
-
const
|
|
118557
|
+
const rows = db.prepare(`SELECT payload_json FROM outbound_events
|
|
118681
118558
|
WHERE event_type = 'harness.stream'
|
|
118682
118559
|
ORDER BY id DESC LIMIT ?`).all(limit);
|
|
118683
|
-
const parsed =
|
|
118560
|
+
const parsed = rows.map((row) => JSON.parse(row.payload_json)).filter((event) => event.type === "harness.stream");
|
|
118684
118561
|
if (!opts.harness)
|
|
118685
118562
|
return parsed.reverse();
|
|
118686
118563
|
return parsed.filter((e) => e.harness === opts.harness).reverse();
|
|
@@ -118688,7 +118565,7 @@ function listHarnessStreamLines(db, opts = {}) {
|
|
|
118688
118565
|
|
|
118689
118566
|
// src/daemon/infrastructure/persistence/persistence-store.ts
|
|
118690
118567
|
function createPersistenceStore(dbPath) {
|
|
118691
|
-
const db =
|
|
118568
|
+
const db = openDatabase2(dbPath);
|
|
118692
118569
|
return {
|
|
118693
118570
|
append(event) {
|
|
118694
118571
|
const eventId = appendOutboundEvent(db, event);
|
|
@@ -118702,7 +118579,7 @@ function createPersistenceStore(dbPath) {
|
|
|
118702
118579
|
};
|
|
118703
118580
|
}
|
|
118704
118581
|
var init_persistence_store = __esm(() => {
|
|
118705
|
-
|
|
118582
|
+
init_open_database2();
|
|
118706
118583
|
});
|
|
118707
118584
|
|
|
118708
118585
|
// src/daemon/infrastructure/persistence/index.ts
|
|
@@ -121435,9 +121312,9 @@ var require_event_target2 = __commonJS((exports, module) => {
|
|
|
121435
121312
|
}
|
|
121436
121313
|
Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true });
|
|
121437
121314
|
var EventTarget = {
|
|
121438
|
-
addEventListener(type,
|
|
121315
|
+
addEventListener(type, handler7, options = {}) {
|
|
121439
121316
|
for (const listener of this.listeners(type)) {
|
|
121440
|
-
if (!options[kForOnEventAttribute] && listener[kListener] ===
|
|
121317
|
+
if (!options[kForOnEventAttribute] && listener[kListener] === handler7 && !listener[kForOnEventAttribute]) {
|
|
121441
121318
|
return;
|
|
121442
121319
|
}
|
|
121443
121320
|
}
|
|
@@ -121448,7 +121325,7 @@ var require_event_target2 = __commonJS((exports, module) => {
|
|
|
121448
121325
|
data: isBinary ? data : data.toString()
|
|
121449
121326
|
});
|
|
121450
121327
|
event[kTarget] = this;
|
|
121451
|
-
callListener(
|
|
121328
|
+
callListener(handler7, this, event);
|
|
121452
121329
|
};
|
|
121453
121330
|
} else if (type === "close") {
|
|
121454
121331
|
wrapper = function onClose(code2, message) {
|
|
@@ -121458,7 +121335,7 @@ var require_event_target2 = __commonJS((exports, module) => {
|
|
|
121458
121335
|
wasClean: this._closeFrameReceived && this._closeFrameSent
|
|
121459
121336
|
});
|
|
121460
121337
|
event[kTarget] = this;
|
|
121461
|
-
callListener(
|
|
121338
|
+
callListener(handler7, this, event);
|
|
121462
121339
|
};
|
|
121463
121340
|
} else if (type === "error") {
|
|
121464
121341
|
wrapper = function onError3(error51) {
|
|
@@ -121467,28 +121344,28 @@ var require_event_target2 = __commonJS((exports, module) => {
|
|
|
121467
121344
|
message: error51.message
|
|
121468
121345
|
});
|
|
121469
121346
|
event[kTarget] = this;
|
|
121470
|
-
callListener(
|
|
121347
|
+
callListener(handler7, this, event);
|
|
121471
121348
|
};
|
|
121472
121349
|
} else if (type === "open") {
|
|
121473
121350
|
wrapper = function onOpen() {
|
|
121474
121351
|
const event = new Event2("open");
|
|
121475
121352
|
event[kTarget] = this;
|
|
121476
|
-
callListener(
|
|
121353
|
+
callListener(handler7, this, event);
|
|
121477
121354
|
};
|
|
121478
121355
|
} else {
|
|
121479
121356
|
return;
|
|
121480
121357
|
}
|
|
121481
121358
|
wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];
|
|
121482
|
-
wrapper[kListener] =
|
|
121359
|
+
wrapper[kListener] = handler7;
|
|
121483
121360
|
if (options.once) {
|
|
121484
121361
|
this.once(type, wrapper);
|
|
121485
121362
|
} else {
|
|
121486
121363
|
this.on(type, wrapper);
|
|
121487
121364
|
}
|
|
121488
121365
|
},
|
|
121489
|
-
removeEventListener(type,
|
|
121366
|
+
removeEventListener(type, handler7) {
|
|
121490
121367
|
for (const listener of this.listeners(type)) {
|
|
121491
|
-
if (listener[kListener] ===
|
|
121368
|
+
if (listener[kListener] === handler7 && !listener[kForOnEventAttribute]) {
|
|
121492
121369
|
this.removeListener(type, listener);
|
|
121493
121370
|
break;
|
|
121494
121371
|
}
|
|
@@ -122017,16 +121894,16 @@ var require_websocket2 = __commonJS((exports, module) => {
|
|
|
122017
121894
|
}
|
|
122018
121895
|
return null;
|
|
122019
121896
|
},
|
|
122020
|
-
set(
|
|
121897
|
+
set(handler7) {
|
|
122021
121898
|
for (const listener of this.listeners(method)) {
|
|
122022
121899
|
if (listener[kForOnEventAttribute]) {
|
|
122023
121900
|
this.removeListener(method, listener);
|
|
122024
121901
|
break;
|
|
122025
121902
|
}
|
|
122026
121903
|
}
|
|
122027
|
-
if (typeof
|
|
121904
|
+
if (typeof handler7 !== "function")
|
|
122028
121905
|
return;
|
|
122029
|
-
this.addEventListener(method,
|
|
121906
|
+
this.addEventListener(method, handler7, {
|
|
122030
121907
|
[kForOnEventAttribute]: true
|
|
122031
121908
|
});
|
|
122032
121909
|
}
|
|
@@ -132360,19 +132237,19 @@ function routeRequest(req, res, deps) {
|
|
|
132360
132237
|
|
|
132361
132238
|
// src/daemon/local-web/server/serve-static.ts
|
|
132362
132239
|
import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
|
|
132363
|
-
import { dirname as
|
|
132240
|
+
import { dirname as dirname18, join as join29 } from "node:path";
|
|
132364
132241
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
132365
132242
|
function clientDistCandidates(here) {
|
|
132366
132243
|
return [
|
|
132367
|
-
|
|
132368
|
-
|
|
132369
|
-
|
|
132244
|
+
join29(here, "client/build"),
|
|
132245
|
+
join29(here, "../client/build"),
|
|
132246
|
+
join29(here, "../src/daemon/local-web/client/build")
|
|
132370
132247
|
];
|
|
132371
132248
|
}
|
|
132372
|
-
function resolveClientDistDir(here =
|
|
132249
|
+
function resolveClientDistDir(here = dirname18(fileURLToPath7(import.meta.url))) {
|
|
132373
132250
|
const candidates = clientDistCandidates(here);
|
|
132374
132251
|
for (const dir of candidates) {
|
|
132375
|
-
if (existsSync10(
|
|
132252
|
+
if (existsSync10(join29(dir, "index.html")))
|
|
132376
132253
|
return dir;
|
|
132377
132254
|
}
|
|
132378
132255
|
return candidates[0];
|
|
@@ -132385,7 +132262,7 @@ function tryServeStatic(req, res, distDir) {
|
|
|
132385
132262
|
return false;
|
|
132386
132263
|
}
|
|
132387
132264
|
const safePath = pathname === "/" ? "/index.html" : pathname;
|
|
132388
|
-
const filePath =
|
|
132265
|
+
const filePath = join29(distDir, safePath);
|
|
132389
132266
|
if (!filePath.startsWith(distDir)) {
|
|
132390
132267
|
res.writeHead(403);
|
|
132391
132268
|
res.end();
|
|
@@ -132402,7 +132279,7 @@ function tryServeStatic(req, res, distDir) {
|
|
|
132402
132279
|
}
|
|
132403
132280
|
return true;
|
|
132404
132281
|
}
|
|
132405
|
-
const indexPath =
|
|
132282
|
+
const indexPath = join29(distDir, "index.html");
|
|
132406
132283
|
if (existsSync10(indexPath)) {
|
|
132407
132284
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
132408
132285
|
if (req.method === "HEAD") {
|
|
@@ -132984,7 +132861,7 @@ async function harnessStatus() {
|
|
|
132984
132861
|
};
|
|
132985
132862
|
const program2 = exports_Effect.forEach(services, detectOne, { concurrency: "unbounded" });
|
|
132986
132863
|
const results = await exports_Effect.runPromise(program2);
|
|
132987
|
-
const
|
|
132864
|
+
const rows = results.map(({ id: id3, displayName, result }) => {
|
|
132988
132865
|
if (isInstalled(result)) {
|
|
132989
132866
|
return { id: id3, displayName, status: "installed" };
|
|
132990
132867
|
}
|
|
@@ -132996,13 +132873,13 @@ async function harnessStatus() {
|
|
|
132996
132873
|
}
|
|
132997
132874
|
return { id: id3, displayName, status: "not-installed" };
|
|
132998
132875
|
});
|
|
132999
|
-
const idWidth = Math.max(4, ...
|
|
133000
|
-
const nameWidth = Math.max(11, ...
|
|
132876
|
+
const idWidth = Math.max(4, ...rows.map((r) => r.id.length));
|
|
132877
|
+
const nameWidth = Math.max(11, ...rows.map((r) => r.displayName.length));
|
|
133001
132878
|
const header = `${"ID".padEnd(idWidth)} ${"DISPLAY NAME".padEnd(nameWidth)} STATUS`;
|
|
133002
132879
|
const divider = `${"-".repeat(idWidth)} ${"-".repeat(nameWidth)} ------`;
|
|
133003
132880
|
console.log(header);
|
|
133004
132881
|
console.log(divider);
|
|
133005
|
-
for (const row of
|
|
132882
|
+
for (const row of rows) {
|
|
133006
132883
|
const statusIcon = row.status === "installed" ? "✅ installed" : row.status === "error" ? "⚠️ error" : "❌ not installed";
|
|
133007
132884
|
const line = `${row.id.padEnd(idWidth)} ${row.displayName.padEnd(nameWidth)} ${statusIcon}`;
|
|
133008
132885
|
console.log(line);
|
|
@@ -133011,8 +132888,8 @@ async function harnessStatus() {
|
|
|
133011
132888
|
}
|
|
133012
132889
|
}
|
|
133013
132890
|
console.log("");
|
|
133014
|
-
const installedCount =
|
|
133015
|
-
const totalCount =
|
|
132891
|
+
const installedCount = rows.filter((r) => r.status === "installed").length;
|
|
132892
|
+
const totalCount = rows.length;
|
|
133016
132893
|
console.log(`${installedCount}/${totalCount} harnesses available on this machine.`);
|
|
133017
132894
|
}
|
|
133018
132895
|
var init_harness_status = __esm(() => {
|
|
@@ -134133,4 +134010,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
134133
134010
|
});
|
|
134134
134011
|
program2.parse();
|
|
134135
134012
|
|
|
134136
|
-
//# debugId=
|
|
134013
|
+
//# debugId=654C294BE572C9D764756E2164756E21
|