@drisp/cli 0.5.11 → 0.5.13
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/athena-gateway.js +248 -181
- package/dist/{chunk-2QMUBFZZ.js → chunk-BUNMENOT.js} +557 -446
- package/dist/cli.js +2 -2
- package/dist/dashboard-daemon.js +1 -1
- package/dist/hook-forwarder.js +5 -5
- package/package.json +1 -1
|
@@ -216,7 +216,6 @@ function cleanupStaleSockets(sockDir) {
|
|
|
216
216
|
|
|
217
217
|
// src/harnesses/claude/runtime/interactionRules.ts
|
|
218
218
|
var DEFAULT_TIMEOUT_MS = 4e3;
|
|
219
|
-
var PERMISSION_TIMEOUT_MS = 3e5;
|
|
220
219
|
var DEFAULT_HINTS = {
|
|
221
220
|
expectsDecision: false,
|
|
222
221
|
defaultTimeoutMs: DEFAULT_TIMEOUT_MS,
|
|
@@ -225,12 +224,12 @@ var DEFAULT_HINTS = {
|
|
|
225
224
|
var RULES = {
|
|
226
225
|
"permission.request": {
|
|
227
226
|
expectsDecision: true,
|
|
228
|
-
defaultTimeoutMs:
|
|
227
|
+
defaultTimeoutMs: null,
|
|
229
228
|
canBlock: true
|
|
230
229
|
},
|
|
231
230
|
"tool.pre": {
|
|
232
231
|
expectsDecision: true,
|
|
233
|
-
defaultTimeoutMs:
|
|
232
|
+
defaultTimeoutMs: null,
|
|
234
233
|
canBlock: true
|
|
235
234
|
},
|
|
236
235
|
"tool.post": {
|
|
@@ -390,7 +389,7 @@ var RULES = {
|
|
|
390
389
|
},
|
|
391
390
|
"elicitation.request": {
|
|
392
391
|
expectsDecision: true,
|
|
393
|
-
defaultTimeoutMs:
|
|
392
|
+
defaultTimeoutMs: null,
|
|
394
393
|
canBlock: true
|
|
395
394
|
},
|
|
396
395
|
"elicitation.result": {
|
|
@@ -5369,13 +5368,12 @@ function describeAction(a) {
|
|
|
5369
5368
|
}
|
|
5370
5369
|
|
|
5371
5370
|
// src/harnesses/codex/runtime/interactionRules.ts
|
|
5372
|
-
var APPROVAL_TIMEOUT_MS = 3e5;
|
|
5373
5371
|
var DEFAULT_TIMEOUT_MS2 = 4e3;
|
|
5374
5372
|
function getCodexInteractionHints(expectsDecision) {
|
|
5375
5373
|
if (expectsDecision) {
|
|
5376
5374
|
return {
|
|
5377
5375
|
expectsDecision: true,
|
|
5378
|
-
defaultTimeoutMs:
|
|
5376
|
+
defaultTimeoutMs: null,
|
|
5379
5377
|
canBlock: true
|
|
5380
5378
|
};
|
|
5381
5379
|
}
|
|
@@ -7860,7 +7858,8 @@ function createTranscriptReader() {
|
|
|
7860
7858
|
}
|
|
7861
7859
|
|
|
7862
7860
|
// src/core/feed/internals/runLifecycle.ts
|
|
7863
|
-
function createRunLifecycle() {
|
|
7861
|
+
function createRunLifecycle(boundary) {
|
|
7862
|
+
const { makeEvent, resetPerRunState } = boundary;
|
|
7864
7863
|
let currentSession = null;
|
|
7865
7864
|
let currentRun = null;
|
|
7866
7865
|
let seq = 0;
|
|
@@ -7869,17 +7868,79 @@ function createRunLifecycle() {
|
|
|
7869
7868
|
const sessId = currentSession?.session_id ?? "unknown";
|
|
7870
7869
|
return `${sessId}:R${runSeq}`;
|
|
7871
7870
|
}
|
|
7871
|
+
function allocateSeq() {
|
|
7872
|
+
return ++seq;
|
|
7873
|
+
}
|
|
7874
|
+
function getCurrentRun() {
|
|
7875
|
+
return currentRun;
|
|
7876
|
+
}
|
|
7877
|
+
function closeRun(ts, status) {
|
|
7878
|
+
if (!currentRun) return null;
|
|
7879
|
+
currentRun.status = status;
|
|
7880
|
+
currentRun.ended_at = ts;
|
|
7881
|
+
const closed = currentRun;
|
|
7882
|
+
currentRun = null;
|
|
7883
|
+
return closed;
|
|
7884
|
+
}
|
|
7885
|
+
function openNewRun(ts, sessionId, triggerType, promptPreview) {
|
|
7886
|
+
runSeq++;
|
|
7887
|
+
currentRun = {
|
|
7888
|
+
run_id: getRunId(),
|
|
7889
|
+
session_id: sessionId,
|
|
7890
|
+
started_at: ts,
|
|
7891
|
+
trigger: { type: triggerType, prompt_preview: promptPreview },
|
|
7892
|
+
status: "running",
|
|
7893
|
+
actors: { root_agent_id: "agent:root", subagent_ids: [] },
|
|
7894
|
+
counters: {
|
|
7895
|
+
tool_uses: 0,
|
|
7896
|
+
tool_failures: 0,
|
|
7897
|
+
permission_requests: 0,
|
|
7898
|
+
blocks: 0
|
|
7899
|
+
}
|
|
7900
|
+
};
|
|
7901
|
+
return currentRun;
|
|
7902
|
+
}
|
|
7903
|
+
function closeRunIntoEvent(runtimeEvent, status) {
|
|
7904
|
+
const closed = closeRun(runtimeEvent.timestamp, status);
|
|
7905
|
+
if (!closed) return null;
|
|
7906
|
+
return makeEvent(
|
|
7907
|
+
"run.end",
|
|
7908
|
+
"info",
|
|
7909
|
+
"system",
|
|
7910
|
+
{ status, counters: { ...closed.counters } },
|
|
7911
|
+
runtimeEvent
|
|
7912
|
+
);
|
|
7913
|
+
}
|
|
7914
|
+
function beginRun(runtimeEvent, triggerType = "other", promptPreview) {
|
|
7915
|
+
if (currentRun && triggerType === "other") return [];
|
|
7916
|
+
const results = [];
|
|
7917
|
+
const closeEvt = closeRunIntoEvent(runtimeEvent, "completed");
|
|
7918
|
+
if (closeEvt) results.push(closeEvt);
|
|
7919
|
+
resetPerRunState();
|
|
7920
|
+
openNewRun(
|
|
7921
|
+
runtimeEvent.timestamp,
|
|
7922
|
+
runtimeEvent.sessionId,
|
|
7923
|
+
triggerType,
|
|
7924
|
+
promptPreview
|
|
7925
|
+
);
|
|
7926
|
+
results.push(
|
|
7927
|
+
makeEvent(
|
|
7928
|
+
"run.start",
|
|
7929
|
+
"info",
|
|
7930
|
+
"system",
|
|
7931
|
+
{ trigger: { type: triggerType, prompt_preview: promptPreview } },
|
|
7932
|
+
runtimeEvent
|
|
7933
|
+
)
|
|
7934
|
+
);
|
|
7935
|
+
return results;
|
|
7936
|
+
}
|
|
7872
7937
|
return {
|
|
7873
|
-
allocateSeq
|
|
7874
|
-
return ++seq;
|
|
7875
|
-
},
|
|
7938
|
+
allocateSeq,
|
|
7876
7939
|
getRunId,
|
|
7877
7940
|
getSession() {
|
|
7878
7941
|
return currentSession;
|
|
7879
7942
|
},
|
|
7880
|
-
getCurrentRun
|
|
7881
|
-
return currentRun;
|
|
7882
|
-
},
|
|
7943
|
+
getCurrentRun,
|
|
7883
7944
|
setSession(session) {
|
|
7884
7945
|
currentSession = session;
|
|
7885
7946
|
},
|
|
@@ -7892,32 +7953,10 @@ function createRunLifecycle() {
|
|
|
7892
7953
|
incrementCounter(name) {
|
|
7893
7954
|
if (currentRun) currentRun.counters[name]++;
|
|
7894
7955
|
},
|
|
7895
|
-
closeRun
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
const closed = currentRun;
|
|
7900
|
-
currentRun = null;
|
|
7901
|
-
return closed;
|
|
7902
|
-
},
|
|
7903
|
-
openNewRun(ts, sessionId, triggerType, promptPreview) {
|
|
7904
|
-
runSeq++;
|
|
7905
|
-
currentRun = {
|
|
7906
|
-
run_id: getRunId(),
|
|
7907
|
-
session_id: sessionId,
|
|
7908
|
-
started_at: ts,
|
|
7909
|
-
trigger: { type: triggerType, prompt_preview: promptPreview },
|
|
7910
|
-
status: "running",
|
|
7911
|
-
actors: { root_agent_id: "agent:root", subagent_ids: [] },
|
|
7912
|
-
counters: {
|
|
7913
|
-
tool_uses: 0,
|
|
7914
|
-
tool_failures: 0,
|
|
7915
|
-
permission_requests: 0,
|
|
7916
|
-
blocks: 0
|
|
7917
|
-
}
|
|
7918
|
-
};
|
|
7919
|
-
return currentRun;
|
|
7920
|
-
},
|
|
7956
|
+
closeRun,
|
|
7957
|
+
openNewRun,
|
|
7958
|
+
closeRunIntoEvent,
|
|
7959
|
+
beginRun,
|
|
7921
7960
|
restoreFrom(bootstrap) {
|
|
7922
7961
|
for (const e of bootstrap.feedEvents) {
|
|
7923
7962
|
if (e.seq > seq) seq = e.seq;
|
|
@@ -8037,6 +8076,34 @@ function createToolCorrelation() {
|
|
|
8037
8076
|
};
|
|
8038
8077
|
}
|
|
8039
8078
|
|
|
8079
|
+
// src/core/feed/internals/projection.ts
|
|
8080
|
+
function readString(...values) {
|
|
8081
|
+
for (const value of values) {
|
|
8082
|
+
if (typeof value === "string") return value;
|
|
8083
|
+
}
|
|
8084
|
+
return void 0;
|
|
8085
|
+
}
|
|
8086
|
+
function readBoolean(...values) {
|
|
8087
|
+
for (const value of values) {
|
|
8088
|
+
if (typeof value === "boolean") return value;
|
|
8089
|
+
}
|
|
8090
|
+
return void 0;
|
|
8091
|
+
}
|
|
8092
|
+
function readObject(...values) {
|
|
8093
|
+
for (const value of values) {
|
|
8094
|
+
if (typeof value === "object" && value !== null) {
|
|
8095
|
+
return value;
|
|
8096
|
+
}
|
|
8097
|
+
}
|
|
8098
|
+
return {};
|
|
8099
|
+
}
|
|
8100
|
+
function readSuggestionArray(...values) {
|
|
8101
|
+
for (const value of values) {
|
|
8102
|
+
if (Array.isArray(value)) return value;
|
|
8103
|
+
}
|
|
8104
|
+
return void 0;
|
|
8105
|
+
}
|
|
8106
|
+
|
|
8040
8107
|
// src/core/feed/internals/agentMessageStream.ts
|
|
8041
8108
|
function normalizeAgentMessage(message) {
|
|
8042
8109
|
return message.replace(/\r\n/g, "\n").trimEnd();
|
|
@@ -8044,6 +8111,9 @@ function normalizeAgentMessage(message) {
|
|
|
8044
8111
|
function agentMessageKey(actorId, scope) {
|
|
8045
8112
|
return `${actorId}\0${scope}`;
|
|
8046
8113
|
}
|
|
8114
|
+
function isStopEvent(kind) {
|
|
8115
|
+
return kind === "stop.request" || kind === "subagent.stop";
|
|
8116
|
+
}
|
|
8047
8117
|
function createAgentMessageStream(eventBuilder, transcriptReader) {
|
|
8048
8118
|
const pendingMessages = /* @__PURE__ */ new Map();
|
|
8049
8119
|
const lastAgentMessageByActorScope = /* @__PURE__ */ new Map();
|
|
@@ -8070,6 +8140,25 @@ function createAgentMessageStream(eventBuilder, transcriptReader) {
|
|
|
8070
8140
|
lastAgentMessageByActorScope.set(key, normalized);
|
|
8071
8141
|
return event;
|
|
8072
8142
|
}
|
|
8143
|
+
function emitTranscriptMessages(transcriptPath, runtimeEvent, actorId, scope) {
|
|
8144
|
+
const msgs = transcriptReader.readNewAssistantMessages(transcriptPath);
|
|
8145
|
+
const out = [];
|
|
8146
|
+
for (const msg of msgs) {
|
|
8147
|
+
const ev = emit({
|
|
8148
|
+
runtimeEvent,
|
|
8149
|
+
actorId,
|
|
8150
|
+
scope,
|
|
8151
|
+
message: msg.text,
|
|
8152
|
+
source: "transcript",
|
|
8153
|
+
model: msg.model
|
|
8154
|
+
});
|
|
8155
|
+
if (ev) out.push(ev);
|
|
8156
|
+
}
|
|
8157
|
+
return out;
|
|
8158
|
+
}
|
|
8159
|
+
function drainTranscript(transcriptPath) {
|
|
8160
|
+
transcriptReader.readNewAssistantMessages(transcriptPath);
|
|
8161
|
+
}
|
|
8073
8162
|
return {
|
|
8074
8163
|
emit,
|
|
8075
8164
|
appendPendingDelta(itemId, delta, defaultActorId, defaultScope) {
|
|
@@ -8125,25 +8214,37 @@ function createAgentMessageStream(eventBuilder, transcriptReader) {
|
|
|
8125
8214
|
}
|
|
8126
8215
|
return out;
|
|
8127
8216
|
},
|
|
8128
|
-
emitTranscriptMessages
|
|
8129
|
-
|
|
8130
|
-
const
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
model: msg.model
|
|
8139
|
-
});
|
|
8140
|
-
if (ev) out.push(ev);
|
|
8141
|
-
}
|
|
8142
|
-
return out;
|
|
8217
|
+
emitTranscriptMessages,
|
|
8218
|
+
replayBeforeEvent(runtimeEvent, actorId, scope) {
|
|
8219
|
+
const transcriptPath = runtimeEvent.context.transcriptPath;
|
|
8220
|
+
if (!transcriptPath || isStopEvent(runtimeEvent.kind)) return [];
|
|
8221
|
+
return emitTranscriptMessages(
|
|
8222
|
+
transcriptPath,
|
|
8223
|
+
runtimeEvent,
|
|
8224
|
+
actorId,
|
|
8225
|
+
scope
|
|
8226
|
+
);
|
|
8143
8227
|
},
|
|
8144
|
-
|
|
8145
|
-
|
|
8228
|
+
emitStopFallback(runtimeEvent, opts) {
|
|
8229
|
+
const transcriptPath = runtimeEvent.context.transcriptPath;
|
|
8230
|
+
if (transcriptPath) drainTranscript(transcriptPath);
|
|
8231
|
+
if (opts.priorResults.some((r) => r.kind === "agent.message")) return [];
|
|
8232
|
+
const message = readString(
|
|
8233
|
+
runtimeEvent.data["last_assistant_message"]
|
|
8234
|
+
);
|
|
8235
|
+
if (!message) return [];
|
|
8236
|
+
const parent = opts.priorResults.find((r) => r.kind === opts.parentKind);
|
|
8237
|
+
const ev = emit({
|
|
8238
|
+
runtimeEvent,
|
|
8239
|
+
actorId: opts.actorId,
|
|
8240
|
+
scope: opts.scope,
|
|
8241
|
+
message,
|
|
8242
|
+
source: "hook",
|
|
8243
|
+
cause: parent ? { parent_event_id: parent.event_id } : void 0
|
|
8244
|
+
});
|
|
8245
|
+
return ev ? [ev] : [];
|
|
8146
8246
|
},
|
|
8247
|
+
drainTranscript,
|
|
8147
8248
|
appendReasoningSummary(itemId, index, chunk) {
|
|
8148
8249
|
const key = `${itemId ?? ""}:${index ?? 0}`;
|
|
8149
8250
|
const next = `${reasoningSummaryByKey.get(key) ?? ""}${chunk}`;
|
|
@@ -8242,6 +8343,129 @@ function createTaskLifecycleTracker() {
|
|
|
8242
8343
|
};
|
|
8243
8344
|
}
|
|
8244
8345
|
|
|
8346
|
+
// src/core/feed/internals/taskStateTracker.ts
|
|
8347
|
+
function extractTodoItems(toolInput) {
|
|
8348
|
+
const input = toolInput;
|
|
8349
|
+
return Array.isArray(input?.todos) ? input.todos : [];
|
|
8350
|
+
}
|
|
8351
|
+
function mapPlanStepStatus(status) {
|
|
8352
|
+
switch (status) {
|
|
8353
|
+
case "inProgress":
|
|
8354
|
+
return "in_progress";
|
|
8355
|
+
case "completed":
|
|
8356
|
+
return "completed";
|
|
8357
|
+
case void 0:
|
|
8358
|
+
default:
|
|
8359
|
+
return "pending";
|
|
8360
|
+
}
|
|
8361
|
+
}
|
|
8362
|
+
function createTaskStateTracker() {
|
|
8363
|
+
const rootPlan = createRootPlanTracker();
|
|
8364
|
+
const taskLifecycle = createTaskLifecycleTracker();
|
|
8365
|
+
function applyToolPre(input) {
|
|
8366
|
+
const { toolName, toolInput, actorId } = input;
|
|
8367
|
+
if (toolName === "TodoWrite" && actorId === "agent:root") {
|
|
8368
|
+
rootPlan.set(extractTodoItems(toolInput));
|
|
8369
|
+
}
|
|
8370
|
+
if (toolName === "TaskUpdate") {
|
|
8371
|
+
const taskId = readString(toolInput["taskId"], toolInput["task_id"]);
|
|
8372
|
+
const status = coerceTaskStatus(toolInput["status"]);
|
|
8373
|
+
if (taskId && status) {
|
|
8374
|
+
taskLifecycle.updateStatus({ taskId, status });
|
|
8375
|
+
}
|
|
8376
|
+
}
|
|
8377
|
+
}
|
|
8378
|
+
function applyToolPost(input) {
|
|
8379
|
+
const { toolName, toolInput, toolResponse } = input;
|
|
8380
|
+
if (toolName === "TaskCreate") {
|
|
8381
|
+
const response = readObject(toolResponse);
|
|
8382
|
+
const task = readObject(response["task"]);
|
|
8383
|
+
const taskId = readString(task["id"], task["task_id"]);
|
|
8384
|
+
const subject = readString(task["subject"], toolInput["subject"]);
|
|
8385
|
+
if (taskId && subject) {
|
|
8386
|
+
taskLifecycle.upsertCreated({
|
|
8387
|
+
taskId,
|
|
8388
|
+
subject,
|
|
8389
|
+
description: readString(toolInput["description"]),
|
|
8390
|
+
activeForm: readString(toolInput["activeForm"])
|
|
8391
|
+
});
|
|
8392
|
+
}
|
|
8393
|
+
}
|
|
8394
|
+
if (toolName === "TaskUpdate") {
|
|
8395
|
+
const response = readObject(toolResponse);
|
|
8396
|
+
const taskId = readString(
|
|
8397
|
+
response["taskId"],
|
|
8398
|
+
response["task_id"],
|
|
8399
|
+
toolInput["taskId"],
|
|
8400
|
+
toolInput["task_id"]
|
|
8401
|
+
);
|
|
8402
|
+
const status = coerceTaskStatus(
|
|
8403
|
+
readObject(response["statusChange"])["to"] ?? toolInput["status"]
|
|
8404
|
+
);
|
|
8405
|
+
if (taskId && status) {
|
|
8406
|
+
taskLifecycle.updateStatus({ taskId, status });
|
|
8407
|
+
}
|
|
8408
|
+
}
|
|
8409
|
+
}
|
|
8410
|
+
function applyTaskCreatedEvent(data) {
|
|
8411
|
+
const taskId = readString(data["task_id"]);
|
|
8412
|
+
const subject = readString(data["task_subject"]);
|
|
8413
|
+
const description = readString(data["task_description"]);
|
|
8414
|
+
if (taskId && subject) {
|
|
8415
|
+
taskLifecycle.upsertCreated({ taskId, subject, description });
|
|
8416
|
+
}
|
|
8417
|
+
}
|
|
8418
|
+
function applyTaskCompletedEvent(data) {
|
|
8419
|
+
const taskId = readString(data["task_id"]);
|
|
8420
|
+
const subject = readString(data["task_subject"]);
|
|
8421
|
+
if (taskId) {
|
|
8422
|
+
taskLifecycle.markCompleted({ taskId, subject });
|
|
8423
|
+
}
|
|
8424
|
+
}
|
|
8425
|
+
return {
|
|
8426
|
+
current() {
|
|
8427
|
+
return [...rootPlan.current(), ...taskLifecycle.current()];
|
|
8428
|
+
},
|
|
8429
|
+
applyToolPre,
|
|
8430
|
+
applyToolPost,
|
|
8431
|
+
applyPlanDelta(planSteps) {
|
|
8432
|
+
if (!Array.isArray(planSteps) || planSteps.length === 0) return false;
|
|
8433
|
+
const next = planSteps.map((step) => ({
|
|
8434
|
+
content: typeof step.step === "string" ? step.step : "",
|
|
8435
|
+
status: mapPlanStepStatus(step.status)
|
|
8436
|
+
}));
|
|
8437
|
+
if (!rootPlan.differs(next)) return false;
|
|
8438
|
+
rootPlan.set(next);
|
|
8439
|
+
return true;
|
|
8440
|
+
},
|
|
8441
|
+
applyTaskCreatedEvent,
|
|
8442
|
+
applyTaskCompletedEvent,
|
|
8443
|
+
restore(feedEvents) {
|
|
8444
|
+
for (const e of feedEvents) {
|
|
8445
|
+
if (e.kind === "tool.pre") {
|
|
8446
|
+
const data = e.data;
|
|
8447
|
+
applyToolPre({
|
|
8448
|
+
toolName: data.tool_name ?? "",
|
|
8449
|
+
toolInput: readObject(data.tool_input),
|
|
8450
|
+
actorId: e.actor_id
|
|
8451
|
+
});
|
|
8452
|
+
} else if (e.kind === "tool.post") {
|
|
8453
|
+
const data = e.data;
|
|
8454
|
+
applyToolPost({
|
|
8455
|
+
toolName: data.tool_name ?? "",
|
|
8456
|
+
toolInput: readObject(data.tool_input),
|
|
8457
|
+
toolResponse: data.tool_response
|
|
8458
|
+
});
|
|
8459
|
+
} else if (e.kind === "task.created") {
|
|
8460
|
+
applyTaskCreatedEvent(e.data);
|
|
8461
|
+
} else if (e.kind === "task.completed") {
|
|
8462
|
+
applyTaskCompletedEvent(e.data);
|
|
8463
|
+
}
|
|
8464
|
+
}
|
|
8465
|
+
}
|
|
8466
|
+
};
|
|
8467
|
+
}
|
|
8468
|
+
|
|
8245
8469
|
// src/core/feed/internals/subagentTracker.ts
|
|
8246
8470
|
function createSubagentTracker() {
|
|
8247
8471
|
const stack = [];
|
|
@@ -8284,44 +8508,57 @@ function createSubagentTracker() {
|
|
|
8284
8508
|
};
|
|
8285
8509
|
}
|
|
8286
8510
|
|
|
8287
|
-
// src/core/feed/internals/projection.ts
|
|
8288
|
-
function readString(...values) {
|
|
8289
|
-
for (const value of values) {
|
|
8290
|
-
if (typeof value === "string") return value;
|
|
8291
|
-
}
|
|
8292
|
-
return void 0;
|
|
8293
|
-
}
|
|
8294
|
-
function readBoolean(...values) {
|
|
8295
|
-
for (const value of values) {
|
|
8296
|
-
if (typeof value === "boolean") return value;
|
|
8297
|
-
}
|
|
8298
|
-
return void 0;
|
|
8299
|
-
}
|
|
8300
|
-
function readObject(...values) {
|
|
8301
|
-
for (const value of values) {
|
|
8302
|
-
if (typeof value === "object" && value !== null) {
|
|
8303
|
-
return value;
|
|
8304
|
-
}
|
|
8305
|
-
}
|
|
8306
|
-
return {};
|
|
8307
|
-
}
|
|
8308
|
-
function readSuggestionArray(...values) {
|
|
8309
|
-
for (const value of values) {
|
|
8310
|
-
if (Array.isArray(value)) return value;
|
|
8311
|
-
}
|
|
8312
|
-
return void 0;
|
|
8313
|
-
}
|
|
8314
|
-
|
|
8315
8511
|
// src/core/feed/todo.ts
|
|
8316
8512
|
function isSubagentTool(toolName) {
|
|
8317
8513
|
return toolName === "Task" || toolName === "Agent";
|
|
8318
8514
|
}
|
|
8319
8515
|
|
|
8320
|
-
// src/core/feed/internals/
|
|
8321
|
-
function
|
|
8322
|
-
const
|
|
8323
|
-
|
|
8516
|
+
// src/core/feed/internals/subagentLifecycle.ts
|
|
8517
|
+
function createSubagentLifecycle(args) {
|
|
8518
|
+
const { actors, runLifecycle } = args;
|
|
8519
|
+
const tracker = createSubagentTracker();
|
|
8520
|
+
const actorIdFor = (agentId) => `subagent:${agentId}`;
|
|
8521
|
+
return {
|
|
8522
|
+
observeToolInput(toolName, toolInput) {
|
|
8523
|
+
if (!isSubagentTool(toolName)) return;
|
|
8524
|
+
if (typeof toolInput["description"] === "string") {
|
|
8525
|
+
tracker.recordPendingDescription(toolInput["description"]);
|
|
8526
|
+
} else {
|
|
8527
|
+
tracker.clearPendingDescription();
|
|
8528
|
+
}
|
|
8529
|
+
},
|
|
8530
|
+
startSubagent({ agentId, agentType, fallbackDescription }) {
|
|
8531
|
+
const description = tracker.consumePendingDescription() ?? fallbackDescription;
|
|
8532
|
+
if (agentId) {
|
|
8533
|
+
actors.ensureSubagent(agentId, agentType ?? "unknown");
|
|
8534
|
+
const currentRun = runLifecycle.getCurrentRun();
|
|
8535
|
+
if (currentRun) currentRun.actors.subagent_ids.push(agentId);
|
|
8536
|
+
tracker.pushActor(actorIdFor(agentId));
|
|
8537
|
+
if (description) tracker.setDescription(agentId, description);
|
|
8538
|
+
}
|
|
8539
|
+
return { actorId: "agent:root", description: description ?? void 0 };
|
|
8540
|
+
},
|
|
8541
|
+
stopSubagent(agentId) {
|
|
8542
|
+
if (agentId) tracker.popActor(actorIdFor(agentId));
|
|
8543
|
+
return {
|
|
8544
|
+
actorId: actorIdFor(agentId ?? "unknown"),
|
|
8545
|
+
description: tracker.description(agentId ?? "")
|
|
8546
|
+
};
|
|
8547
|
+
},
|
|
8548
|
+
currentActor() {
|
|
8549
|
+
return tracker.peek() ?? "agent:root";
|
|
8550
|
+
},
|
|
8551
|
+
currentScope() {
|
|
8552
|
+
return tracker.currentScope();
|
|
8553
|
+
},
|
|
8554
|
+
actorIdFor,
|
|
8555
|
+
clear() {
|
|
8556
|
+
tracker.clear();
|
|
8557
|
+
}
|
|
8558
|
+
};
|
|
8324
8559
|
}
|
|
8560
|
+
|
|
8561
|
+
// src/core/feed/internals/toolProjection.ts
|
|
8325
8562
|
function resolveToolUseId(event, record) {
|
|
8326
8563
|
return event.toolUseId ?? record["tool_use_id"];
|
|
8327
8564
|
}
|
|
@@ -8337,8 +8574,7 @@ function createToolProjection(args) {
|
|
|
8337
8574
|
makeEvent,
|
|
8338
8575
|
runLifecycle,
|
|
8339
8576
|
toolCorrelation,
|
|
8340
|
-
|
|
8341
|
-
taskLifecycle,
|
|
8577
|
+
taskState,
|
|
8342
8578
|
subagents,
|
|
8343
8579
|
resolveToolActor
|
|
8344
8580
|
} = args;
|
|
@@ -8435,23 +8671,12 @@ function createToolProjection(args) {
|
|
|
8435
8671
|
webSearchStarted(event, data, toolUseId, preEvent.event_id)
|
|
8436
8672
|
);
|
|
8437
8673
|
}
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8444
|
-
if (taskId && status) {
|
|
8445
|
-
taskLifecycle.updateStatus({ taskId, status });
|
|
8446
|
-
}
|
|
8447
|
-
}
|
|
8448
|
-
if (isSubagentTool(toolName)) {
|
|
8449
|
-
if (typeof toolInput["description"] === "string") {
|
|
8450
|
-
subagents.recordPendingDescription(toolInput["description"]);
|
|
8451
|
-
} else {
|
|
8452
|
-
subagents.clearPendingDescription();
|
|
8453
|
-
}
|
|
8454
|
-
}
|
|
8674
|
+
taskState.applyToolPre({
|
|
8675
|
+
toolName,
|
|
8676
|
+
toolInput,
|
|
8677
|
+
actorId: preEvent.actor_id
|
|
8678
|
+
});
|
|
8679
|
+
subagents.observeToolInput(toolName, toolInput);
|
|
8455
8680
|
return results;
|
|
8456
8681
|
}
|
|
8457
8682
|
if (event.kind === "tool.post") {
|
|
@@ -8471,35 +8696,11 @@ function createToolProjection(args) {
|
|
|
8471
8696
|
toolUseCause(toolUseId, parentId)
|
|
8472
8697
|
);
|
|
8473
8698
|
results.push(postEvent);
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
if (taskId && subject) {
|
|
8480
|
-
taskLifecycle.upsertCreated({
|
|
8481
|
-
taskId,
|
|
8482
|
-
subject,
|
|
8483
|
-
description: readString(toolInput["description"]),
|
|
8484
|
-
activeForm: readString(toolInput["activeForm"])
|
|
8485
|
-
});
|
|
8486
|
-
}
|
|
8487
|
-
}
|
|
8488
|
-
if (toolName === "TaskUpdate") {
|
|
8489
|
-
const response = readObject(data["tool_response"]);
|
|
8490
|
-
const taskId = readString(
|
|
8491
|
-
response["taskId"],
|
|
8492
|
-
response["task_id"],
|
|
8493
|
-
toolInput["taskId"],
|
|
8494
|
-
toolInput["task_id"]
|
|
8495
|
-
);
|
|
8496
|
-
const status = coerceTaskStatus(
|
|
8497
|
-
readObject(response["statusChange"])["to"] ?? toolInput["status"]
|
|
8498
|
-
);
|
|
8499
|
-
if (taskId && status) {
|
|
8500
|
-
taskLifecycle.updateStatus({ taskId, status });
|
|
8501
|
-
}
|
|
8502
|
-
}
|
|
8699
|
+
taskState.applyToolPost({
|
|
8700
|
+
toolName,
|
|
8701
|
+
toolInput,
|
|
8702
|
+
toolResponse: data.tool_response
|
|
8703
|
+
});
|
|
8503
8704
|
if (toolName === "WebSearch") {
|
|
8504
8705
|
results.push(
|
|
8505
8706
|
webSearchCompleted(event, data, toolUseId, postEvent.event_id)
|
|
@@ -8940,29 +9141,27 @@ function createDecisionProjection(args) {
|
|
|
8940
9141
|
|
|
8941
9142
|
// src/core/feed/internals/subagentProjection.ts
|
|
8942
9143
|
function createSubagentProjection(args) {
|
|
8943
|
-
const { ensureRunArray, makeEvent,
|
|
9144
|
+
const { ensureRunArray, makeEvent, subagents } = args;
|
|
8944
9145
|
return {
|
|
8945
9146
|
mapSubagentEvent(event, data) {
|
|
8946
9147
|
const results = ensureRunArray(event);
|
|
8947
9148
|
const agentId = event.agentId ?? readString(data["agent_id"]);
|
|
8948
9149
|
const agentType = event.agentType ?? readString(data["agent_type"]);
|
|
8949
9150
|
if (event.kind === "subagent.start") {
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
}
|
|
8956
|
-
const description = subagents.consumePendingDescription() ?? readString(data["prompt"]);
|
|
9151
|
+
const { actorId: actorId2, description: description2 } = subagents.startSubagent({
|
|
9152
|
+
agentId,
|
|
9153
|
+
agentType,
|
|
9154
|
+
fallbackDescription: readString(data["prompt"])
|
|
9155
|
+
});
|
|
8957
9156
|
results.push(
|
|
8958
9157
|
makeEvent(
|
|
8959
9158
|
"subagent.start",
|
|
8960
9159
|
"info",
|
|
8961
|
-
|
|
9160
|
+
actorId2,
|
|
8962
9161
|
{
|
|
8963
9162
|
agent_id: agentId ?? "",
|
|
8964
9163
|
agent_type: agentType ?? "",
|
|
8965
|
-
description:
|
|
9164
|
+
description: description2 ?? void 0,
|
|
8966
9165
|
tool: readString(data["tool"]),
|
|
8967
9166
|
sender_thread_id: readString(data["sender_thread_id"]),
|
|
8968
9167
|
receiver_thread_id: readString(data["receiver_thread_id"]),
|
|
@@ -8972,23 +9171,21 @@ function createSubagentProjection(args) {
|
|
|
8972
9171
|
event
|
|
8973
9172
|
)
|
|
8974
9173
|
);
|
|
8975
|
-
if (agentId && description)
|
|
8976
|
-
subagents.setDescription(agentId, description);
|
|
8977
9174
|
return results;
|
|
8978
9175
|
}
|
|
8979
|
-
|
|
9176
|
+
const { actorId, description } = subagents.stopSubagent(agentId);
|
|
8980
9177
|
results.push(
|
|
8981
9178
|
makeEvent(
|
|
8982
9179
|
"subagent.stop",
|
|
8983
9180
|
"info",
|
|
8984
|
-
|
|
9181
|
+
actorId,
|
|
8985
9182
|
{
|
|
8986
9183
|
agent_id: agentId ?? "",
|
|
8987
9184
|
agent_type: agentType ?? "",
|
|
8988
9185
|
stop_hook_active: readBoolean(data["stop_hook_active"]) ?? false,
|
|
8989
9186
|
agent_transcript_path: readString(data["agent_transcript_path"]),
|
|
8990
9187
|
last_assistant_message: readString(data["last_assistant_message"]),
|
|
8991
|
-
description
|
|
9188
|
+
description,
|
|
8992
9189
|
tool: readString(data["tool"]),
|
|
8993
9190
|
status: readString(data["status"]),
|
|
8994
9191
|
sender_thread_id: readString(data["sender_thread_id"]),
|
|
@@ -9169,17 +9366,6 @@ function createFileConfigProjection(args) {
|
|
|
9169
9366
|
}
|
|
9170
9367
|
|
|
9171
9368
|
// src/core/feed/internals/runSessionProjection.ts
|
|
9172
|
-
function mapPlanStepStatus(status) {
|
|
9173
|
-
switch (status) {
|
|
9174
|
-
case "inProgress":
|
|
9175
|
-
return "in_progress";
|
|
9176
|
-
case "completed":
|
|
9177
|
-
return "completed";
|
|
9178
|
-
case void 0:
|
|
9179
|
-
default:
|
|
9180
|
-
return "pending";
|
|
9181
|
-
}
|
|
9182
|
-
}
|
|
9183
9369
|
function createRunSessionProjection(args) {
|
|
9184
9370
|
const {
|
|
9185
9371
|
ensureRunArray,
|
|
@@ -9187,7 +9373,7 @@ function createRunSessionProjection(args) {
|
|
|
9187
9373
|
closeRunIntoEvent,
|
|
9188
9374
|
runLifecycle,
|
|
9189
9375
|
agentMessageStream,
|
|
9190
|
-
|
|
9376
|
+
taskState,
|
|
9191
9377
|
resolveToolActor,
|
|
9192
9378
|
currentScope
|
|
9193
9379
|
} = args;
|
|
@@ -9338,28 +9524,19 @@ function createRunSessionProjection(args) {
|
|
|
9338
9524
|
}
|
|
9339
9525
|
if (event.kind === "plan.delta") {
|
|
9340
9526
|
const planSteps = data["plan"];
|
|
9341
|
-
if (
|
|
9342
|
-
|
|
9343
|
-
(
|
|
9344
|
-
|
|
9345
|
-
|
|
9346
|
-
|
|
9527
|
+
if (taskState.applyPlanDelta(planSteps)) {
|
|
9528
|
+
results.push(
|
|
9529
|
+
makeEvent(
|
|
9530
|
+
"todo.update",
|
|
9531
|
+
"info",
|
|
9532
|
+
"system",
|
|
9533
|
+
{
|
|
9534
|
+
todo_id: "plan",
|
|
9535
|
+
patch: { status: "doing" }
|
|
9536
|
+
},
|
|
9537
|
+
event
|
|
9538
|
+
)
|
|
9347
9539
|
);
|
|
9348
|
-
if (rootPlan.differs(next)) {
|
|
9349
|
-
rootPlan.set(next);
|
|
9350
|
-
results.push(
|
|
9351
|
-
makeEvent(
|
|
9352
|
-
"todo.update",
|
|
9353
|
-
"info",
|
|
9354
|
-
"system",
|
|
9355
|
-
{
|
|
9356
|
-
todo_id: "plan",
|
|
9357
|
-
patch: { status: "doing" }
|
|
9358
|
-
},
|
|
9359
|
-
event
|
|
9360
|
-
)
|
|
9361
|
-
);
|
|
9362
|
-
}
|
|
9363
9540
|
}
|
|
9364
9541
|
results.push(
|
|
9365
9542
|
makeEvent(
|
|
@@ -9431,7 +9608,7 @@ function createRunSessionProjection(args) {
|
|
|
9431
9608
|
|
|
9432
9609
|
// src/core/feed/internals/statusProjection.ts
|
|
9433
9610
|
function createStatusProjection(args) {
|
|
9434
|
-
const { ensureRunArray, makeEvent,
|
|
9611
|
+
const { ensureRunArray, makeEvent, taskState } = args;
|
|
9435
9612
|
return {
|
|
9436
9613
|
mapStatusEvent(event, data) {
|
|
9437
9614
|
const results = ensureRunArray(event);
|
|
@@ -9454,13 +9631,7 @@ function createStatusProjection(args) {
|
|
|
9454
9631
|
const taskId = readString(data["task_id"]) ?? "";
|
|
9455
9632
|
const subject = readString(data["task_subject"]) ?? "";
|
|
9456
9633
|
const description = readString(data["task_description"]);
|
|
9457
|
-
|
|
9458
|
-
taskLifecycle.upsertCreated({
|
|
9459
|
-
taskId,
|
|
9460
|
-
subject,
|
|
9461
|
-
description
|
|
9462
|
-
});
|
|
9463
|
-
}
|
|
9634
|
+
taskState.applyTaskCreatedEvent(data);
|
|
9464
9635
|
results.push(
|
|
9465
9636
|
makeEvent(
|
|
9466
9637
|
"task.created",
|
|
@@ -9481,7 +9652,7 @@ function createStatusProjection(args) {
|
|
|
9481
9652
|
if (event.kind === "task.completed") {
|
|
9482
9653
|
const taskId = readString(data["task_id"]) ?? "";
|
|
9483
9654
|
const subject = readString(data["task_subject"]);
|
|
9484
|
-
|
|
9655
|
+
taskState.applyTaskCompletedEvent(data);
|
|
9485
9656
|
results.push(
|
|
9486
9657
|
makeEvent(
|
|
9487
9658
|
"task.completed",
|
|
@@ -9551,14 +9722,21 @@ var STATUS_EVENT_KINDS = /* @__PURE__ */ new Set([
|
|
|
9551
9722
|
"task.created"
|
|
9552
9723
|
]);
|
|
9553
9724
|
function createFeedMapper(bootstrap) {
|
|
9554
|
-
const runLifecycle = createRunLifecycle(
|
|
9725
|
+
const runLifecycle = createRunLifecycle({
|
|
9726
|
+
makeEvent,
|
|
9727
|
+
resetPerRunState: () => {
|
|
9728
|
+
toolCorrelation.resetForNewRun();
|
|
9729
|
+
decisionCorrelation.resetForNewRun();
|
|
9730
|
+
agentMessageStream.resetForNewRun();
|
|
9731
|
+
subagents.clear();
|
|
9732
|
+
}
|
|
9733
|
+
});
|
|
9555
9734
|
const decisionCorrelation = createDecisionCorrelation();
|
|
9556
9735
|
const toolCorrelation = createToolCorrelation();
|
|
9557
9736
|
const transcriptReader = createTranscriptReader();
|
|
9558
9737
|
const actors = new ActorRegistry();
|
|
9559
|
-
const
|
|
9560
|
-
const
|
|
9561
|
-
const subagents = createSubagentTracker();
|
|
9738
|
+
const taskState = createTaskStateTracker();
|
|
9739
|
+
const subagents = createSubagentLifecycle({ actors, runLifecycle });
|
|
9562
9740
|
function makeEvent(kind, level, actorId, data, runtimeEvent, cause) {
|
|
9563
9741
|
const s = runLifecycle.allocateSeq();
|
|
9564
9742
|
const runId = runLifecycle.getRunId();
|
|
@@ -9593,117 +9771,21 @@ function createFeedMapper(bootstrap) {
|
|
|
9593
9771
|
makeEvent,
|
|
9594
9772
|
transcriptReader
|
|
9595
9773
|
);
|
|
9596
|
-
function replayTaskLifecycleToolEvent(e) {
|
|
9597
|
-
if (e.kind !== "tool.pre" && e.kind !== "tool.post") return;
|
|
9598
|
-
const data = e.data;
|
|
9599
|
-
const toolInput = readObject(data.tool_input);
|
|
9600
|
-
if (data.tool_name === "TaskCreate" && e.kind === "tool.post") {
|
|
9601
|
-
const response = readObject(data.tool_response);
|
|
9602
|
-
const task = readObject(response["task"]);
|
|
9603
|
-
const taskId = readString(task["id"], task["task_id"]);
|
|
9604
|
-
const subject = readString(task["subject"], toolInput["subject"]);
|
|
9605
|
-
if (taskId && subject) {
|
|
9606
|
-
taskLifecycle.upsertCreated({
|
|
9607
|
-
taskId,
|
|
9608
|
-
subject,
|
|
9609
|
-
description: readString(toolInput["description"]),
|
|
9610
|
-
activeForm: readString(toolInput["activeForm"])
|
|
9611
|
-
});
|
|
9612
|
-
}
|
|
9613
|
-
}
|
|
9614
|
-
if (data.tool_name === "TaskUpdate") {
|
|
9615
|
-
const response = readObject(data.tool_response);
|
|
9616
|
-
const status = coerceTaskStatus(
|
|
9617
|
-
readObject(response["statusChange"])["to"] ?? toolInput["status"]
|
|
9618
|
-
);
|
|
9619
|
-
const taskId = readString(
|
|
9620
|
-
response["taskId"],
|
|
9621
|
-
response["task_id"],
|
|
9622
|
-
toolInput["taskId"],
|
|
9623
|
-
toolInput["task_id"]
|
|
9624
|
-
);
|
|
9625
|
-
if (taskId && status) {
|
|
9626
|
-
taskLifecycle.updateStatus({ taskId, status });
|
|
9627
|
-
}
|
|
9628
|
-
}
|
|
9629
|
-
}
|
|
9630
9774
|
if (bootstrap) {
|
|
9631
9775
|
runLifecycle.restoreFrom(bootstrap);
|
|
9632
|
-
|
|
9633
|
-
if (e.kind === "tool.pre" && e.actor_id === "agent:root" && e.data.tool_name === "TodoWrite") {
|
|
9634
|
-
rootPlan.set(
|
|
9635
|
-
extractTodoItems(e.data.tool_input)
|
|
9636
|
-
);
|
|
9637
|
-
}
|
|
9638
|
-
replayTaskLifecycleToolEvent(e);
|
|
9639
|
-
if (e.kind === "task.created") {
|
|
9640
|
-
const data = e.data;
|
|
9641
|
-
if (data.task_id && data.task_subject) {
|
|
9642
|
-
taskLifecycle.upsertCreated({
|
|
9643
|
-
taskId: data.task_id,
|
|
9644
|
-
subject: data.task_subject,
|
|
9645
|
-
description: data.task_description
|
|
9646
|
-
});
|
|
9647
|
-
}
|
|
9648
|
-
}
|
|
9649
|
-
if (e.kind === "task.completed") {
|
|
9650
|
-
const data = e.data;
|
|
9651
|
-
if (data.task_id) {
|
|
9652
|
-
taskLifecycle.markCompleted({
|
|
9653
|
-
taskId: data.task_id,
|
|
9654
|
-
subject: data.task_subject
|
|
9655
|
-
});
|
|
9656
|
-
}
|
|
9657
|
-
}
|
|
9658
|
-
}
|
|
9659
|
-
}
|
|
9660
|
-
function closeRunIntoEvent(runtimeEvent, status) {
|
|
9661
|
-
const closed = runLifecycle.closeRun(runtimeEvent.timestamp, status);
|
|
9662
|
-
if (!closed) return null;
|
|
9663
|
-
return makeEvent(
|
|
9664
|
-
"run.end",
|
|
9665
|
-
"info",
|
|
9666
|
-
"system",
|
|
9667
|
-
{ status, counters: { ...closed.counters } },
|
|
9668
|
-
runtimeEvent
|
|
9669
|
-
);
|
|
9670
|
-
}
|
|
9671
|
-
function ensureRunArray(runtimeEvent, triggerType = "other", promptPreview) {
|
|
9672
|
-
if (runLifecycle.getCurrentRun() && triggerType === "other") return [];
|
|
9673
|
-
const results = [];
|
|
9674
|
-
const closeEvt = closeRunIntoEvent(runtimeEvent, "completed");
|
|
9675
|
-
if (closeEvt) results.push(closeEvt);
|
|
9676
|
-
toolCorrelation.resetForNewRun();
|
|
9677
|
-
decisionCorrelation.resetForNewRun();
|
|
9678
|
-
agentMessageStream.resetForNewRun();
|
|
9679
|
-
subagents.clear();
|
|
9680
|
-
runLifecycle.openNewRun(
|
|
9681
|
-
runtimeEvent.timestamp,
|
|
9682
|
-
runtimeEvent.sessionId,
|
|
9683
|
-
triggerType,
|
|
9684
|
-
promptPreview
|
|
9685
|
-
);
|
|
9686
|
-
results.push(
|
|
9687
|
-
makeEvent(
|
|
9688
|
-
"run.start",
|
|
9689
|
-
"info",
|
|
9690
|
-
"system",
|
|
9691
|
-
{ trigger: { type: triggerType, prompt_preview: promptPreview } },
|
|
9692
|
-
runtimeEvent
|
|
9693
|
-
)
|
|
9694
|
-
);
|
|
9695
|
-
return results;
|
|
9776
|
+
taskState.restore(bootstrap.feedEvents);
|
|
9696
9777
|
}
|
|
9778
|
+
const ensureRunArray = runLifecycle.beginRun;
|
|
9779
|
+
const closeRunIntoEvent = runLifecycle.closeRunIntoEvent;
|
|
9697
9780
|
function resolveToolActor() {
|
|
9698
|
-
return subagents.
|
|
9781
|
+
return subagents.currentActor();
|
|
9699
9782
|
}
|
|
9700
9783
|
const toolProjection = createToolProjection({
|
|
9701
9784
|
ensureRunArray,
|
|
9702
9785
|
makeEvent,
|
|
9703
9786
|
runLifecycle,
|
|
9704
9787
|
toolCorrelation,
|
|
9705
|
-
|
|
9706
|
-
taskLifecycle,
|
|
9788
|
+
taskState,
|
|
9707
9789
|
subagents,
|
|
9708
9790
|
resolveToolActor
|
|
9709
9791
|
});
|
|
@@ -9721,8 +9803,6 @@ function createFeedMapper(bootstrap) {
|
|
|
9721
9803
|
const subagentProjection = createSubagentProjection({
|
|
9722
9804
|
ensureRunArray,
|
|
9723
9805
|
makeEvent,
|
|
9724
|
-
runLifecycle,
|
|
9725
|
-
actors,
|
|
9726
9806
|
subagents
|
|
9727
9807
|
});
|
|
9728
9808
|
const fileConfigProjection = createFileConfigProjection({
|
|
@@ -9732,7 +9812,7 @@ function createFeedMapper(bootstrap) {
|
|
|
9732
9812
|
const statusProjection = createStatusProjection({
|
|
9733
9813
|
ensureRunArray,
|
|
9734
9814
|
makeEvent,
|
|
9735
|
-
|
|
9815
|
+
taskState
|
|
9736
9816
|
});
|
|
9737
9817
|
const currentScope = () => subagents.currentScope();
|
|
9738
9818
|
const runSessionProjection = createRunSessionProjection({
|
|
@@ -9741,7 +9821,7 @@ function createFeedMapper(bootstrap) {
|
|
|
9741
9821
|
closeRunIntoEvent,
|
|
9742
9822
|
runLifecycle,
|
|
9743
9823
|
agentMessageStream,
|
|
9744
|
-
|
|
9824
|
+
taskState,
|
|
9745
9825
|
resolveToolActor,
|
|
9746
9826
|
currentScope
|
|
9747
9827
|
});
|
|
@@ -9749,33 +9829,13 @@ function createFeedMapper(bootstrap) {
|
|
|
9749
9829
|
const d = event.data;
|
|
9750
9830
|
const eventKind2 = event.kind;
|
|
9751
9831
|
const results = [];
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
|
|
9759
|
-
actorId,
|
|
9760
|
-
scope,
|
|
9761
|
-
message: msg,
|
|
9762
|
-
source: "hook",
|
|
9763
|
-
cause: parentEvt ? { parent_event_id: parentEvt.event_id } : void 0
|
|
9764
|
-
});
|
|
9765
|
-
if (ev) results.push(ev);
|
|
9766
|
-
}
|
|
9767
|
-
const transcriptPath = event.context.transcriptPath;
|
|
9768
|
-
const isStopEvent = eventKind2 === "stop.request" || eventKind2 === "subagent.stop";
|
|
9769
|
-
if (transcriptPath && !isStopEvent) {
|
|
9770
|
-
results.push(
|
|
9771
|
-
...agentMessageStream.emitTranscriptMessages(
|
|
9772
|
-
transcriptPath,
|
|
9773
|
-
event,
|
|
9774
|
-
resolveToolActor(),
|
|
9775
|
-
currentScope()
|
|
9776
|
-
)
|
|
9777
|
-
);
|
|
9778
|
-
}
|
|
9832
|
+
results.push(
|
|
9833
|
+
...agentMessageStream.replayBeforeEvent(
|
|
9834
|
+
event,
|
|
9835
|
+
resolveToolActor(),
|
|
9836
|
+
currentScope()
|
|
9837
|
+
)
|
|
9838
|
+
);
|
|
9779
9839
|
if (RUN_SESSION_EVENT_KINDS.has(eventKind2)) {
|
|
9780
9840
|
results.push(...runSessionProjection.mapRunSessionEvent(event, d));
|
|
9781
9841
|
} else if (TOOL_EVENT_KINDS.has(eventKind2)) {
|
|
@@ -9810,13 +9870,25 @@ function createFeedMapper(bootstrap) {
|
|
|
9810
9870
|
results.push(unknownEvt);
|
|
9811
9871
|
}
|
|
9812
9872
|
if (eventKind2 === "stop.request") {
|
|
9813
|
-
|
|
9814
|
-
|
|
9873
|
+
results.push(
|
|
9874
|
+
...agentMessageStream.emitStopFallback(event, {
|
|
9875
|
+
actorId: "agent:root",
|
|
9876
|
+
scope: "root",
|
|
9877
|
+
parentKind: "stop.request",
|
|
9878
|
+
priorResults: results
|
|
9879
|
+
})
|
|
9880
|
+
);
|
|
9815
9881
|
}
|
|
9816
9882
|
if (eventKind2 === "subagent.stop") {
|
|
9817
9883
|
const agentId = readString(d["agent_id"]) ?? "unknown";
|
|
9818
|
-
|
|
9819
|
-
|
|
9884
|
+
results.push(
|
|
9885
|
+
...agentMessageStream.emitStopFallback(event, {
|
|
9886
|
+
actorId: subagents.actorIdFor(agentId),
|
|
9887
|
+
scope: "subagent",
|
|
9888
|
+
parentKind: "subagent.stop",
|
|
9889
|
+
priorResults: results
|
|
9890
|
+
})
|
|
9891
|
+
);
|
|
9820
9892
|
}
|
|
9821
9893
|
return results;
|
|
9822
9894
|
}
|
|
@@ -9829,7 +9901,7 @@ function createFeedMapper(bootstrap) {
|
|
|
9829
9901
|
getSession: () => runLifecycle.getSession(),
|
|
9830
9902
|
getCurrentRun: () => runLifecycle.getCurrentRun(),
|
|
9831
9903
|
getActors: () => actors.all(),
|
|
9832
|
-
getTasks: () =>
|
|
9904
|
+
getTasks: () => taskState.current(),
|
|
9833
9905
|
allocateSeq: () => runLifecycle.allocateSeq()
|
|
9834
9906
|
};
|
|
9835
9907
|
}
|
|
@@ -12431,8 +12503,32 @@ var VERBOSE_ONLY_KINDS = /* @__PURE__ */ new Set([
|
|
|
12431
12503
|
"worktree.remove",
|
|
12432
12504
|
"turn.diff",
|
|
12433
12505
|
"usage.update",
|
|
12434
|
-
"reasoning.summary"
|
|
12506
|
+
"reasoning.summary",
|
|
12507
|
+
// Codex protocol bookkeeping that churns the feed without conveying
|
|
12508
|
+
// meaningful agent progress. `usage.update` (above) still feeds header
|
|
12509
|
+
// token/context metrics via the raw event stream — only the rendered row
|
|
12510
|
+
// is suppressed in the default (non-verbose) feed.
|
|
12511
|
+
"thread.status",
|
|
12512
|
+
"server.request.resolved"
|
|
12435
12513
|
]);
|
|
12514
|
+
var VERBOSE_ONLY_NOTIFICATION_TYPES = /* @__PURE__ */ new Set([
|
|
12515
|
+
"account.rate_limits_updated",
|
|
12516
|
+
"account.updated",
|
|
12517
|
+
"item.agentMessage.started",
|
|
12518
|
+
"raw_response_item.completed",
|
|
12519
|
+
"command_exec.output_delta",
|
|
12520
|
+
"fuzzy_file_search.updated",
|
|
12521
|
+
"fuzzy_file_search.completed",
|
|
12522
|
+
"app.list_updated",
|
|
12523
|
+
"thread_name",
|
|
12524
|
+
"thread.archived",
|
|
12525
|
+
"thread.unarchived",
|
|
12526
|
+
"thread.realtime.transcript_delta",
|
|
12527
|
+
"thread.realtime.output_audio_delta"
|
|
12528
|
+
]);
|
|
12529
|
+
function isVerboseOnlyNotification(event) {
|
|
12530
|
+
return event.kind === "notification" && typeof event.data.notification_type === "string" && VERBOSE_ONLY_NOTIFICATION_TYPES.has(event.data.notification_type);
|
|
12531
|
+
}
|
|
12436
12532
|
function toRunStatus(event) {
|
|
12437
12533
|
switch (event.data.status) {
|
|
12438
12534
|
case "completed":
|
|
@@ -13221,6 +13317,9 @@ function shouldSkipEvent(event, verbose) {
|
|
|
13221
13317
|
if (!verbose && event.kind === "stop.request" && !event.data.stop_hook_active) {
|
|
13222
13318
|
return true;
|
|
13223
13319
|
}
|
|
13320
|
+
if (!verbose && isVerboseOnlyNotification(event)) {
|
|
13321
|
+
return true;
|
|
13322
|
+
}
|
|
13224
13323
|
return false;
|
|
13225
13324
|
}
|
|
13226
13325
|
function mergedToolUseId(event, postByToolUseId) {
|
|
@@ -13880,7 +13979,7 @@ async function connect(opts) {
|
|
|
13880
13979
|
const entry = pending.get(requestId);
|
|
13881
13980
|
if (!entry) return;
|
|
13882
13981
|
pending.delete(requestId);
|
|
13883
|
-
clearTimeout(entry.timer);
|
|
13982
|
+
if (entry.timer) clearTimeout(entry.timer);
|
|
13884
13983
|
entry.resolve(parsed);
|
|
13885
13984
|
return;
|
|
13886
13985
|
}
|
|
@@ -13904,7 +14003,7 @@ async function connect(opts) {
|
|
|
13904
14003
|
)
|
|
13905
14004
|
);
|
|
13906
14005
|
for (const [, p] of pending) {
|
|
13907
|
-
clearTimeout(p.timer);
|
|
14006
|
+
if (p.timer) clearTimeout(p.timer);
|
|
13908
14007
|
p.reject(
|
|
13909
14008
|
new GatewayProtocolError("connection closed", "connection_closed")
|
|
13910
14009
|
);
|
|
@@ -13964,14 +14063,14 @@ async function connect(opts) {
|
|
|
13964
14063
|
kind,
|
|
13965
14064
|
payload
|
|
13966
14065
|
};
|
|
13967
|
-
const effectiveTimeoutMs = reqOpts?.timeoutMs
|
|
14066
|
+
const effectiveTimeoutMs = reqOpts?.timeoutMs === void 0 ? timeoutMs : reqOpts.timeoutMs;
|
|
13968
14067
|
const responsePromise = new Promise(
|
|
13969
14068
|
(resolve, reject) => {
|
|
13970
|
-
const timer = setTimeout(() => {
|
|
14069
|
+
const timer = effectiveTimeoutMs === null ? void 0 : setTimeout(() => {
|
|
13971
14070
|
pending.delete(requestId);
|
|
13972
14071
|
reject(new GatewayProtocolError(`request ${kind} timed out`));
|
|
13973
14072
|
}, effectiveTimeoutMs);
|
|
13974
|
-
pending.set(requestId, { resolve, reject, timer });
|
|
14073
|
+
pending.set(requestId, { resolve, reject, ...timer ? { timer } : {} });
|
|
13975
14074
|
}
|
|
13976
14075
|
);
|
|
13977
14076
|
connection.send(envelope);
|
|
@@ -14227,7 +14326,6 @@ function writeGatewayClientConfig(config, env = process.env) {
|
|
|
14227
14326
|
}
|
|
14228
14327
|
|
|
14229
14328
|
// src/app/channels/sessionBridge.ts
|
|
14230
|
-
var RELAY_REQUEST_TIMEOUT_MS = 6 * 6e4;
|
|
14231
14329
|
var RECONNECT_BACKOFF_MS = [1e3, 2e3, 4e3, 8e3, 16e3, 3e4];
|
|
14232
14330
|
var SessionBridge = class {
|
|
14233
14331
|
opts;
|
|
@@ -14379,9 +14477,9 @@ var SessionBridge = class {
|
|
|
14379
14477
|
toolName: req.toolName,
|
|
14380
14478
|
description: req.description,
|
|
14381
14479
|
inputPreview: req.inputPreview,
|
|
14382
|
-
|
|
14480
|
+
ttlMs: req.ttlMs ?? null
|
|
14383
14481
|
};
|
|
14384
|
-
const overallTimeoutMs = req.ttlMs
|
|
14482
|
+
const overallTimeoutMs = req.ttlMs ?? null;
|
|
14385
14483
|
return this.requestWithReconnect("relay.permission.request", payload, overallTimeoutMs);
|
|
14386
14484
|
}
|
|
14387
14485
|
async relayQuestion(req) {
|
|
@@ -14390,9 +14488,9 @@ var SessionBridge = class {
|
|
|
14390
14488
|
channelRequestId,
|
|
14391
14489
|
title: req.title,
|
|
14392
14490
|
questions: req.questions,
|
|
14393
|
-
|
|
14491
|
+
ttlMs: req.ttlMs ?? null
|
|
14394
14492
|
};
|
|
14395
|
-
const overallTimeoutMs = req.ttlMs
|
|
14493
|
+
const overallTimeoutMs = req.ttlMs ?? null;
|
|
14396
14494
|
return this.requestWithReconnect("relay.question.request", payload, overallTimeoutMs);
|
|
14397
14495
|
}
|
|
14398
14496
|
/**
|
|
@@ -14400,8 +14498,9 @@ var SessionBridge = class {
|
|
|
14400
14498
|
* survives a transient WS disconnect: on `connection closed`, wait for
|
|
14401
14499
|
* the bridge's reconnect to settle, then re-issue the same payload. The
|
|
14402
14500
|
* server attaches the replay to the existing pending entry by
|
|
14403
|
-
* `channelRequestId`, so adapters are not re-prompted.
|
|
14404
|
-
*
|
|
14501
|
+
* `channelRequestId`, so adapters are not re-prompted. If the caller
|
|
14502
|
+
* provided an explicit TTL, reconnect retries are bounded by that deadline;
|
|
14503
|
+
* otherwise human-in-the-loop relays wait until answered or cancelled.
|
|
14405
14504
|
*/
|
|
14406
14505
|
async requestWithReconnect(kind, payload, overallTimeoutMs) {
|
|
14407
14506
|
const deadline = overallTimeoutMs === null ? null : Date.now() + overallTimeoutMs;
|
|
@@ -14413,9 +14512,7 @@ var SessionBridge = class {
|
|
|
14413
14512
|
}
|
|
14414
14513
|
try {
|
|
14415
14514
|
return await client.request(kind, payload, {
|
|
14416
|
-
|
|
14417
|
-
// inner request never self-cancels in any human time scale.
|
|
14418
|
-
timeoutMs: remaining ?? 2147483647
|
|
14515
|
+
timeoutMs: remaining
|
|
14419
14516
|
});
|
|
14420
14517
|
} catch (err) {
|
|
14421
14518
|
if (err instanceof GatewayProtocolError && err.code === "connection_closed" && !this.stopped && (deadline === null || Date.now() < deadline)) {
|
|
@@ -15039,8 +15136,8 @@ async function runExec(options) {
|
|
|
15039
15136
|
const runtimeFactory = options.runtimeFactory ?? createRuntime;
|
|
15040
15137
|
const sessionStoreFactory = options.sessionStoreFactory ?? createSessionStore;
|
|
15041
15138
|
const athenaSessionId = options.athenaSessionId ?? crypto2.randomUUID();
|
|
15042
|
-
const
|
|
15043
|
-
const dashboardFeedPublisher = options.dashboardFeedPublisher ??
|
|
15139
|
+
const ownedFeedPublisher = options.dashboardFeedPublisher ? null : createPairedFeedPublisher();
|
|
15140
|
+
const dashboardFeedPublisher = options.dashboardFeedPublisher ?? ownedFeedPublisher;
|
|
15044
15141
|
const dashboardOrigin = options.dashboardOrigin ?? "local";
|
|
15045
15142
|
const output = createExecOutputWriter({
|
|
15046
15143
|
json,
|
|
@@ -15409,9 +15506,7 @@ async function runExec(options) {
|
|
|
15409
15506
|
}
|
|
15410
15507
|
await bridge?.stop();
|
|
15411
15508
|
store.close();
|
|
15412
|
-
|
|
15413
|
-
dashboardFeedPublisher.close();
|
|
15414
|
-
}
|
|
15509
|
+
ownedFeedPublisher?.close();
|
|
15415
15510
|
}
|
|
15416
15511
|
const resolvedFinalMessage = resolveFinalMessage({
|
|
15417
15512
|
streamMessage: streamFinalMessage,
|
|
@@ -16419,8 +16514,26 @@ function parseRemoteRunSpec(value) {
|
|
|
16419
16514
|
callbackToken: typeof callbackToken === "string" && callbackToken.length > 0 ? callbackToken : void 0
|
|
16420
16515
|
};
|
|
16421
16516
|
}
|
|
16422
|
-
function
|
|
16423
|
-
|
|
16517
|
+
function validateDashboardAssignment(frame) {
|
|
16518
|
+
const spec = parseRemoteRunSpec(frame.runSpec);
|
|
16519
|
+
if (!spec) {
|
|
16520
|
+
return {
|
|
16521
|
+
kind: "rejected",
|
|
16522
|
+
rejection: {
|
|
16523
|
+
reason: "malformed_assignment",
|
|
16524
|
+
message: "remote assignment missing prompt"
|
|
16525
|
+
}
|
|
16526
|
+
};
|
|
16527
|
+
}
|
|
16528
|
+
return {
|
|
16529
|
+
kind: "valid",
|
|
16530
|
+
assignment: {
|
|
16531
|
+
runId: frame.runId,
|
|
16532
|
+
runnerId: frame.runnerId ?? "legacy",
|
|
16533
|
+
spec,
|
|
16534
|
+
frame
|
|
16535
|
+
}
|
|
16536
|
+
};
|
|
16424
16537
|
}
|
|
16425
16538
|
function workflowNameFromRef(ref) {
|
|
16426
16539
|
if (!ref) return void 0;
|
|
@@ -16501,7 +16614,7 @@ function mergeRunSpecEnvIntoWorkflow(workflow, env) {
|
|
|
16501
16614
|
};
|
|
16502
16615
|
}
|
|
16503
16616
|
async function executeRemoteAssignment({
|
|
16504
|
-
|
|
16617
|
+
assignment,
|
|
16505
16618
|
client,
|
|
16506
16619
|
projectDir,
|
|
16507
16620
|
log = () => {
|
|
@@ -16524,11 +16637,11 @@ async function executeRemoteAssignment({
|
|
|
16524
16637
|
const deferredFailedCompletion = {
|
|
16525
16638
|
current: null
|
|
16526
16639
|
};
|
|
16527
|
-
const spec =
|
|
16640
|
+
const { spec, runId, frame } = assignment;
|
|
16528
16641
|
const runEventPublisher = await createRemoteRunEventPublisher({
|
|
16529
|
-
runId
|
|
16530
|
-
callbackWsUrl: spec
|
|
16531
|
-
callbackToken: spec
|
|
16642
|
+
runId,
|
|
16643
|
+
callbackWsUrl: spec.callbackWsUrl,
|
|
16644
|
+
callbackToken: spec.callbackToken,
|
|
16532
16645
|
client,
|
|
16533
16646
|
log,
|
|
16534
16647
|
now,
|
|
@@ -16543,10 +16656,6 @@ async function executeRemoteAssignment({
|
|
|
16543
16656
|
};
|
|
16544
16657
|
send("progress", { message: "assignment received" });
|
|
16545
16658
|
try {
|
|
16546
|
-
if (!spec) {
|
|
16547
|
-
send("error", { message: "remote assignment missing prompt" });
|
|
16548
|
-
return;
|
|
16549
|
-
}
|
|
16550
16659
|
let artifactUploadSpec;
|
|
16551
16660
|
try {
|
|
16552
16661
|
artifactUploadSpec = parseArtifactUploadSpec(frame.runSpec);
|
|
@@ -16627,7 +16736,7 @@ async function executeRemoteAssignment({
|
|
|
16627
16736
|
prompt: spec.prompt,
|
|
16628
16737
|
projectDir,
|
|
16629
16738
|
harness: runtimeConfig.harness,
|
|
16630
|
-
athenaSessionId: spec.athenaSessionId ?? spec.sessionId ?? `athena-${
|
|
16739
|
+
athenaSessionId: spec.athenaSessionId ?? spec.sessionId ?? `athena-${runId}`,
|
|
16631
16740
|
adapterResumeSessionId: spec.adapterResumeSessionId,
|
|
16632
16741
|
isolationConfig: runtimeConfig.isolationConfig,
|
|
16633
16742
|
pluginMcpConfig: runtimeConfig.pluginMcpConfig,
|
|
@@ -16644,8 +16753,8 @@ async function executeRemoteAssignment({
|
|
|
16644
16753
|
...decisionInbox ? { dashboardDecisionInbox: decisionInbox } : {},
|
|
16645
16754
|
...dashboardFeedPublisher ? { dashboardFeedPublisher } : {},
|
|
16646
16755
|
...artifactUploadSpec ? {
|
|
16647
|
-
beforeTerminalCompletion: async ({ result: result2, runId }) => {
|
|
16648
|
-
const artifactRunId =
|
|
16756
|
+
beforeTerminalCompletion: async ({ result: result2, runId: runId2 }) => {
|
|
16757
|
+
const artifactRunId = runId2 ?? assignment.runId;
|
|
16649
16758
|
const { feedEvent } = await captureAndUploadArtifacts({
|
|
16650
16759
|
spec: artifactUploadSpec,
|
|
16651
16760
|
projectDir,
|
|
@@ -17055,54 +17164,55 @@ function createDashboardPairedExecution(options) {
|
|
|
17055
17164
|
});
|
|
17056
17165
|
log("warn", `run ${runId} rejected: ${rejection.message}`);
|
|
17057
17166
|
}
|
|
17058
|
-
function
|
|
17167
|
+
function submitDashboardDecision(submission) {
|
|
17059
17168
|
decisionInbox.enqueue({
|
|
17060
|
-
athenaSessionId:
|
|
17061
|
-
requestId:
|
|
17062
|
-
decision:
|
|
17169
|
+
athenaSessionId: submission.athenaSessionId,
|
|
17170
|
+
requestId: submission.requestId,
|
|
17171
|
+
decision: submission.decision,
|
|
17063
17172
|
receivedAt: now()
|
|
17064
17173
|
});
|
|
17065
17174
|
client.sendDecisionAck({
|
|
17066
|
-
athenaSessionId:
|
|
17067
|
-
requestId:
|
|
17175
|
+
athenaSessionId: submission.athenaSessionId,
|
|
17176
|
+
requestId: submission.requestId
|
|
17068
17177
|
});
|
|
17069
17178
|
}
|
|
17070
|
-
function
|
|
17071
|
-
const entry = active.get(
|
|
17072
|
-
if (!entry) return;
|
|
17179
|
+
function cancelRun(runId) {
|
|
17180
|
+
const entry = active.get(runId);
|
|
17181
|
+
if (!entry) return false;
|
|
17073
17182
|
entry.record.status = "cancelled";
|
|
17074
17183
|
entry.controller.abort();
|
|
17184
|
+
return true;
|
|
17075
17185
|
}
|
|
17076
|
-
function handleAssignment(
|
|
17077
|
-
|
|
17186
|
+
function handleAssignment(assignment, input = {}) {
|
|
17187
|
+
const { runId, runnerId } = assignment;
|
|
17188
|
+
if (active.has(runId)) {
|
|
17078
17189
|
const rejection = {
|
|
17079
17190
|
reason: "duplicate",
|
|
17080
|
-
message: `duplicate active assignment ${
|
|
17191
|
+
message: `duplicate active assignment ${runId}`
|
|
17081
17192
|
};
|
|
17082
|
-
rejectAssignment(
|
|
17193
|
+
rejectAssignment(runId, rejection);
|
|
17083
17194
|
return { kind: "rejected", rejection };
|
|
17084
17195
|
}
|
|
17085
|
-
const
|
|
17086
|
-
const bucket = activeByRunner.get(runnerKey) ?? /* @__PURE__ */ new Set();
|
|
17196
|
+
const bucket = activeByRunner.get(runnerId) ?? /* @__PURE__ */ new Set();
|
|
17087
17197
|
if (bucket.size >= maxConcurrentRuns) {
|
|
17088
17198
|
const rejection = {
|
|
17089
17199
|
reason: "local_capacity",
|
|
17090
|
-
message: `runtime daemon at concurrency cap (${maxConcurrentRuns}) for runner ${
|
|
17200
|
+
message: `runtime daemon at concurrency cap (${maxConcurrentRuns}) for runner ${runnerId}`
|
|
17091
17201
|
};
|
|
17092
|
-
rejectAssignment(
|
|
17202
|
+
rejectAssignment(runId, rejection);
|
|
17093
17203
|
return { kind: "rejected", rejection };
|
|
17094
17204
|
}
|
|
17095
17205
|
const controller = new AbortController();
|
|
17096
17206
|
const record = {
|
|
17097
|
-
runId
|
|
17207
|
+
runId,
|
|
17098
17208
|
startedAt: now(),
|
|
17099
17209
|
status: "running"
|
|
17100
17210
|
};
|
|
17101
17211
|
recordRun(record);
|
|
17102
|
-
bucket.add(
|
|
17103
|
-
activeByRunner.set(
|
|
17212
|
+
bucket.add(runId);
|
|
17213
|
+
activeByRunner.set(runnerId, bucket);
|
|
17104
17214
|
const promise = executor({
|
|
17105
|
-
|
|
17215
|
+
assignment,
|
|
17106
17216
|
client,
|
|
17107
17217
|
projectDir: input.projectDir ?? projectDir,
|
|
17108
17218
|
log,
|
|
@@ -17118,40 +17228,33 @@ function createDashboardPairedExecution(options) {
|
|
|
17118
17228
|
record.error = err instanceof Error ? err.message : String(err);
|
|
17119
17229
|
log(
|
|
17120
17230
|
"error",
|
|
17121
|
-
`run ${
|
|
17231
|
+
`run ${runId} failed: ${err instanceof Error ? err.message : String(err)}`
|
|
17122
17232
|
);
|
|
17123
17233
|
}).finally(() => {
|
|
17124
17234
|
record.endedAt = now();
|
|
17125
17235
|
completedRuns += 1;
|
|
17126
|
-
active.delete(
|
|
17127
|
-
const remaining = activeByRunner.get(
|
|
17236
|
+
active.delete(runId);
|
|
17237
|
+
const remaining = activeByRunner.get(runnerId);
|
|
17128
17238
|
if (remaining) {
|
|
17129
|
-
remaining.delete(
|
|
17130
|
-
if (remaining.size === 0) activeByRunner.delete(
|
|
17239
|
+
remaining.delete(runId);
|
|
17240
|
+
if (remaining.size === 0) activeByRunner.delete(runnerId);
|
|
17131
17241
|
}
|
|
17132
17242
|
});
|
|
17133
|
-
active.set(
|
|
17243
|
+
active.set(runId, { controller, promise, record, runnerKey: runnerId });
|
|
17134
17244
|
return { kind: "accepted" };
|
|
17135
17245
|
}
|
|
17136
17246
|
return {
|
|
17137
17247
|
// `job_assignment` is intentionally not handled here: the runtime daemon
|
|
17138
17248
|
// routes assignments through `DashboardAssignmentIntake`, which gates
|
|
17139
17249
|
// admission on attachment readiness and then calls `admitAssignment`
|
|
17140
|
-
// directly.
|
|
17141
|
-
|
|
17142
|
-
|
|
17143
|
-
|
|
17144
|
-
|
|
17145
|
-
}
|
|
17146
|
-
if (frame.type === "cancel") {
|
|
17147
|
-
handleCancel(frame);
|
|
17148
|
-
return true;
|
|
17149
|
-
}
|
|
17150
|
-
return false;
|
|
17151
|
-
},
|
|
17152
|
-
admitAssignment(frame, input) {
|
|
17153
|
-
return handleAssignment(frame, input);
|
|
17250
|
+
// directly. Run-control frames (`dashboard_decision`, `cancel`) are
|
|
17251
|
+
// translated by `routeDashboardRunFrame` into `submitDashboardDecision`
|
|
17252
|
+
// and `cancelRun` calls.
|
|
17253
|
+
admitAssignment(assignment, input) {
|
|
17254
|
+
return handleAssignment(assignment, input);
|
|
17154
17255
|
},
|
|
17256
|
+
cancelRun,
|
|
17257
|
+
submitDashboardDecision,
|
|
17155
17258
|
rejectAssignment,
|
|
17156
17259
|
snapshot() {
|
|
17157
17260
|
return {
|
|
@@ -17182,22 +17285,12 @@ function createDashboardPairedExecution(options) {
|
|
|
17182
17285
|
import fs23 from "fs";
|
|
17183
17286
|
import os13 from "os";
|
|
17184
17287
|
import path21 from "path";
|
|
17185
|
-
function resolveRemoteWorkspace(
|
|
17186
|
-
const spec =
|
|
17187
|
-
if (!spec) {
|
|
17188
|
-
return {
|
|
17189
|
-
kind: "rejected",
|
|
17190
|
-
rejection: {
|
|
17191
|
-
reason: "workspace_unresolved",
|
|
17192
|
-
message: "remote assignment missing prompt"
|
|
17193
|
-
}
|
|
17194
|
-
};
|
|
17195
|
-
}
|
|
17288
|
+
function resolveRemoteWorkspace(assignment, options = {}) {
|
|
17289
|
+
const { spec, runId, runnerId } = assignment;
|
|
17196
17290
|
if (spec.projectDir) {
|
|
17197
17291
|
return validateProjectDir(spec.projectDir, options.env);
|
|
17198
17292
|
}
|
|
17199
17293
|
const sessionId = spec.athenaSessionId ?? spec.sessionId;
|
|
17200
|
-
const runnerId = frame.runnerId ?? "legacy";
|
|
17201
17294
|
const deploymentSlug = deploymentSlugFromUrl(options.dashboardUrl);
|
|
17202
17295
|
const stateDir = daemonStatePaths(options.env).dir;
|
|
17203
17296
|
const projectDir = sessionId ? path21.join(
|
|
@@ -17213,7 +17306,7 @@ function resolveRemoteWorkspace(frame, options = {}) {
|
|
|
17213
17306
|
deploymentSlug,
|
|
17214
17307
|
sanitizePathSegment(runnerId),
|
|
17215
17308
|
"runs",
|
|
17216
|
-
sanitizePathSegment(
|
|
17309
|
+
sanitizePathSegment(runId)
|
|
17217
17310
|
);
|
|
17218
17311
|
try {
|
|
17219
17312
|
fs23.mkdirSync(projectDir, { recursive: true, mode: 448 });
|
|
@@ -17296,23 +17389,21 @@ function sanitizePathSegment(value) {
|
|
|
17296
17389
|
function createDashboardAssignmentIntake(options) {
|
|
17297
17390
|
const log = options.log ?? (() => {
|
|
17298
17391
|
});
|
|
17299
|
-
const resolveWorkspace = options.resolveWorkspace ?? ((
|
|
17392
|
+
const resolveWorkspace = options.resolveWorkspace ?? ((assignment, context2) => resolveRemoteWorkspace(assignment, { dashboardUrl: context2.dashboardUrl }));
|
|
17300
17393
|
const pending = [];
|
|
17301
|
-
let
|
|
17302
|
-
function handle(frame) {
|
|
17303
|
-
|
|
17304
|
-
|
|
17305
|
-
|
|
17306
|
-
message: "remote assignment missing prompt"
|
|
17307
|
-
};
|
|
17308
|
-
options.execution.rejectAssignment(frame.runId, rejection);
|
|
17394
|
+
let context = null;
|
|
17395
|
+
function handle(frame, readyContext) {
|
|
17396
|
+
const validation = validateDashboardAssignment(frame);
|
|
17397
|
+
if (validation.kind === "rejected") {
|
|
17398
|
+
options.execution.rejectAssignment(frame.runId, validation.rejection);
|
|
17309
17399
|
options.client.sendAssignmentRejected({
|
|
17310
17400
|
runId: frame.runId,
|
|
17311
|
-
...rejection
|
|
17401
|
+
...validation.rejection
|
|
17312
17402
|
});
|
|
17313
17403
|
return;
|
|
17314
17404
|
}
|
|
17315
|
-
const
|
|
17405
|
+
const assignment = validation.assignment;
|
|
17406
|
+
const workspace = resolveWorkspace(assignment, readyContext);
|
|
17316
17407
|
if (workspace.kind === "rejected") {
|
|
17317
17408
|
options.execution.rejectAssignment(frame.runId, workspace.rejection);
|
|
17318
17409
|
options.client.sendAssignmentRejected({
|
|
@@ -17321,7 +17412,7 @@ function createDashboardAssignmentIntake(options) {
|
|
|
17321
17412
|
});
|
|
17322
17413
|
return;
|
|
17323
17414
|
}
|
|
17324
|
-
const outcome = options.execution.admitAssignment(
|
|
17415
|
+
const outcome = options.execution.admitAssignment(assignment, {
|
|
17325
17416
|
projectDir: workspace.projectDir
|
|
17326
17417
|
});
|
|
17327
17418
|
if (outcome.kind === "accepted") {
|
|
@@ -17334,15 +17425,15 @@ function createDashboardAssignmentIntake(options) {
|
|
|
17334
17425
|
});
|
|
17335
17426
|
}
|
|
17336
17427
|
function drain() {
|
|
17337
|
-
if (!
|
|
17428
|
+
if (!context) return;
|
|
17338
17429
|
while (pending.length > 0) {
|
|
17339
17430
|
const frame = pending.shift();
|
|
17340
|
-
if (frame) handle(frame);
|
|
17431
|
+
if (frame) handle(frame, context);
|
|
17341
17432
|
}
|
|
17342
17433
|
}
|
|
17343
17434
|
return {
|
|
17344
17435
|
receive(frame) {
|
|
17345
|
-
if (!
|
|
17436
|
+
if (!context) {
|
|
17346
17437
|
pending.push(frame);
|
|
17347
17438
|
log(
|
|
17348
17439
|
"debug",
|
|
@@ -17350,18 +17441,35 @@ function createDashboardAssignmentIntake(options) {
|
|
|
17350
17441
|
);
|
|
17351
17442
|
return;
|
|
17352
17443
|
}
|
|
17353
|
-
handle(frame);
|
|
17444
|
+
handle(frame, context);
|
|
17354
17445
|
},
|
|
17355
|
-
markReady() {
|
|
17356
|
-
|
|
17446
|
+
markReady(nextContext) {
|
|
17447
|
+
context = nextContext;
|
|
17357
17448
|
drain();
|
|
17358
17449
|
},
|
|
17359
17450
|
markNotReady() {
|
|
17360
|
-
|
|
17451
|
+
context = null;
|
|
17361
17452
|
}
|
|
17362
17453
|
};
|
|
17363
17454
|
}
|
|
17364
17455
|
|
|
17456
|
+
// src/app/dashboard/dashboardFrameRouter.ts
|
|
17457
|
+
function routeDashboardRunFrame(execution, frame) {
|
|
17458
|
+
if (frame.type === "dashboard_decision") {
|
|
17459
|
+
execution.submitDashboardDecision({
|
|
17460
|
+
athenaSessionId: frame.athenaSessionId,
|
|
17461
|
+
requestId: frame.requestId,
|
|
17462
|
+
decision: frame.decision
|
|
17463
|
+
});
|
|
17464
|
+
return true;
|
|
17465
|
+
}
|
|
17466
|
+
if (frame.type === "cancel") {
|
|
17467
|
+
execution.cancelRun(frame.runId);
|
|
17468
|
+
return true;
|
|
17469
|
+
}
|
|
17470
|
+
return false;
|
|
17471
|
+
}
|
|
17472
|
+
|
|
17365
17473
|
// src/app/dashboard/runtimeDaemon.ts
|
|
17366
17474
|
var DEFAULT_RECONNECT_DELAYS_MS2 = [1e3, 2e3, 5e3, 1e4, 3e4];
|
|
17367
17475
|
var DEFAULT_MAX_CONCURRENT_RUNS2 = 1;
|
|
@@ -17465,7 +17573,7 @@ async function runDashboardRuntimeDaemon(options = {}) {
|
|
|
17465
17573
|
},
|
|
17466
17574
|
execution: pairedExecution,
|
|
17467
17575
|
log,
|
|
17468
|
-
resolveWorkspace: (
|
|
17576
|
+
resolveWorkspace: (assignment, context) => resolveRemoteWorkspace(assignment, { dashboardUrl: context.dashboardUrl })
|
|
17469
17577
|
});
|
|
17470
17578
|
function nextReconnectDelay() {
|
|
17471
17579
|
if (reconnectDelays.length === 0) return 0;
|
|
@@ -17584,7 +17692,7 @@ async function runDashboardRuntimeDaemon(options = {}) {
|
|
|
17584
17692
|
assignmentIntake.receive(frame);
|
|
17585
17693
|
return;
|
|
17586
17694
|
}
|
|
17587
|
-
pairedExecution
|
|
17695
|
+
routeDashboardRunFrame(pairedExecution, frame);
|
|
17588
17696
|
});
|
|
17589
17697
|
next.onClose((reason) => {
|
|
17590
17698
|
if (stopped || client !== next) return;
|
|
@@ -17614,9 +17722,12 @@ async function runDashboardRuntimeDaemon(options = {}) {
|
|
|
17614
17722
|
);
|
|
17615
17723
|
}
|
|
17616
17724
|
if (stopped || client !== next) return;
|
|
17617
|
-
assignmentIntake.markReady();
|
|
17618
17725
|
currentInstanceId = token.instanceId;
|
|
17619
17726
|
currentDashboardUrl = config.dashboardUrl;
|
|
17727
|
+
assignmentIntake.markReady({
|
|
17728
|
+
dashboardUrl: config.dashboardUrl,
|
|
17729
|
+
instanceId: token.instanceId
|
|
17730
|
+
});
|
|
17620
17731
|
reconnectAttempt = 0;
|
|
17621
17732
|
scheduleRefresh(token.expiresInSec);
|
|
17622
17733
|
pairedFeedPublisher.attachTransport(next);
|
|
@@ -18076,4 +18187,4 @@ export {
|
|
|
18076
18187
|
startUdsServer,
|
|
18077
18188
|
sendUdsRequest
|
|
18078
18189
|
};
|
|
18079
|
-
//# sourceMappingURL=chunk-
|
|
18190
|
+
//# sourceMappingURL=chunk-BUNMENOT.js.map
|