@drisp/cli 0.5.11 → 0.5.14
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-XZDDQJUX.js} +607 -481
- 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
|
}
|
|
@@ -11290,40 +11362,33 @@ var CURSOR_OFF = "\x1B[27m";
|
|
|
11290
11362
|
function cursorToVisualPosition(value, cursorOffset, width) {
|
|
11291
11363
|
if (width <= 0) return { line: 0, col: cursorOffset, totalLines: 1 };
|
|
11292
11364
|
const segments = value.split("\n");
|
|
11365
|
+
const segmentPieces = segments.map((seg) => wrapSegmentPieces(seg, width));
|
|
11366
|
+
const totalLines = segmentPieces.reduce((sum, ps) => sum + ps.length, 0);
|
|
11293
11367
|
let visualLine = 0;
|
|
11294
11368
|
let globalOffset = 0;
|
|
11295
11369
|
for (let s = 0; s < segments.length; s++) {
|
|
11296
11370
|
const seg = segments[s];
|
|
11371
|
+
const pieces = segmentPieces[s];
|
|
11297
11372
|
const segEnd = globalOffset + seg.length;
|
|
11298
11373
|
if (cursorOffset <= segEnd) {
|
|
11299
11374
|
const posInSeg = cursorOffset - globalOffset;
|
|
11300
|
-
|
|
11301
|
-
|
|
11302
|
-
|
|
11375
|
+
for (let p = 0; p < pieces.length; p++) {
|
|
11376
|
+
const piece = pieces[p];
|
|
11377
|
+
const end = piece.start + piece.text.length;
|
|
11378
|
+
if (posInSeg < end || p === pieces.length - 1) {
|
|
11379
|
+
return {
|
|
11380
|
+
line: visualLine + p,
|
|
11381
|
+
col: posInSeg - piece.start,
|
|
11382
|
+
totalLines
|
|
11383
|
+
};
|
|
11384
|
+
}
|
|
11303
11385
|
}
|
|
11304
|
-
const lineInSeg = Math.min(
|
|
11305
|
-
Math.floor(posInSeg / width),
|
|
11306
|
-
segmentVisualLines(seg.length, width) - 1
|
|
11307
|
-
);
|
|
11308
|
-
const colInLine = posInSeg - lineInSeg * width;
|
|
11309
|
-
return { line: visualLine + lineInSeg, col: colInLine, totalLines: totalLines2 };
|
|
11310
11386
|
}
|
|
11311
|
-
visualLine +=
|
|
11387
|
+
visualLine += pieces.length;
|
|
11312
11388
|
globalOffset = segEnd + 1;
|
|
11313
11389
|
}
|
|
11314
|
-
const totalLines = wrapText(value, width).length;
|
|
11315
11390
|
return { line: Math.max(0, totalLines - 1), col: 0, totalLines };
|
|
11316
11391
|
}
|
|
11317
|
-
function segmentVisualLines(segLen, width) {
|
|
11318
|
-
return segLen === 0 ? 1 : Math.ceil(segLen / width);
|
|
11319
|
-
}
|
|
11320
|
-
function countSegmentVisualLines(segments, fromIdx, width) {
|
|
11321
|
-
let count = 0;
|
|
11322
|
-
for (let i = fromIdx; i < segments.length; i++) {
|
|
11323
|
-
count += segmentVisualLines(segments[i].length, width);
|
|
11324
|
-
}
|
|
11325
|
-
return count;
|
|
11326
|
-
}
|
|
11327
11392
|
function visualPositionToOffset(value, targetLine, targetCol, width) {
|
|
11328
11393
|
if (width <= 0) return targetCol;
|
|
11329
11394
|
const segments = value.split("\n");
|
|
@@ -11331,14 +11396,12 @@ function visualPositionToOffset(value, targetLine, targetCol, width) {
|
|
|
11331
11396
|
let globalOffset = 0;
|
|
11332
11397
|
for (let s = 0; s < segments.length; s++) {
|
|
11333
11398
|
const seg = segments[s];
|
|
11334
|
-
const
|
|
11335
|
-
if (targetLine < visualLine +
|
|
11336
|
-
const
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
}
|
|
11341
|
-
visualLine += numWrappedLines;
|
|
11399
|
+
const pieces = wrapSegmentPieces(seg, width);
|
|
11400
|
+
if (targetLine < visualLine + pieces.length) {
|
|
11401
|
+
const piece = pieces[targetLine - visualLine];
|
|
11402
|
+
return globalOffset + piece.start + Math.min(targetCol, piece.text.length);
|
|
11403
|
+
}
|
|
11404
|
+
visualLine += pieces.length;
|
|
11342
11405
|
globalOffset += seg.length + 1;
|
|
11343
11406
|
}
|
|
11344
11407
|
return value.length;
|
|
@@ -11384,16 +11447,40 @@ function renderInputLines(value, cursorOffset, width, showCursor, placeholder) {
|
|
|
11384
11447
|
return fit(line, width);
|
|
11385
11448
|
});
|
|
11386
11449
|
}
|
|
11450
|
+
function wrapSegmentPieces(segment, width) {
|
|
11451
|
+
if (segment.length === 0) return [{ text: "", start: 0 }];
|
|
11452
|
+
if (isSimpleAscii(segment)) {
|
|
11453
|
+
const pieces2 = [];
|
|
11454
|
+
for (let i2 = 0; i2 < segment.length; i2 += width) {
|
|
11455
|
+
pieces2.push({ text: segment.slice(i2, i2 + width), start: i2 });
|
|
11456
|
+
}
|
|
11457
|
+
return pieces2;
|
|
11458
|
+
}
|
|
11459
|
+
const pieces = [];
|
|
11460
|
+
let pieceStart = 0;
|
|
11461
|
+
let pieceWidth = 0;
|
|
11462
|
+
let i = 0;
|
|
11463
|
+
while (i < segment.length) {
|
|
11464
|
+
const cp = segment.codePointAt(i);
|
|
11465
|
+
const chLen = cp > 65535 ? 2 : 1;
|
|
11466
|
+
const charWidth = cachedStringWidth(segment.slice(i, i + chLen));
|
|
11467
|
+
if (pieceWidth > 0 && pieceWidth + charWidth > width) {
|
|
11468
|
+
pieces.push({ text: segment.slice(pieceStart, i), start: pieceStart });
|
|
11469
|
+
pieceStart = i;
|
|
11470
|
+
pieceWidth = 0;
|
|
11471
|
+
}
|
|
11472
|
+
pieceWidth += charWidth;
|
|
11473
|
+
i += chLen;
|
|
11474
|
+
}
|
|
11475
|
+
pieces.push({ text: segment.slice(pieceStart), start: pieceStart });
|
|
11476
|
+
return pieces;
|
|
11477
|
+
}
|
|
11387
11478
|
function wrapText(text, width) {
|
|
11388
11479
|
if (width <= 0) return [text];
|
|
11389
11480
|
const lines = [];
|
|
11390
11481
|
for (const segment of text.split("\n")) {
|
|
11391
|
-
|
|
11392
|
-
lines.push(
|
|
11393
|
-
continue;
|
|
11394
|
-
}
|
|
11395
|
-
for (let i = 0; i < segment.length; i += width) {
|
|
11396
|
-
lines.push(segment.slice(i, i + width));
|
|
11482
|
+
for (const piece of wrapSegmentPieces(segment, width)) {
|
|
11483
|
+
lines.push(piece.text);
|
|
11397
11484
|
}
|
|
11398
11485
|
}
|
|
11399
11486
|
return lines;
|
|
@@ -12431,8 +12518,32 @@ var VERBOSE_ONLY_KINDS = /* @__PURE__ */ new Set([
|
|
|
12431
12518
|
"worktree.remove",
|
|
12432
12519
|
"turn.diff",
|
|
12433
12520
|
"usage.update",
|
|
12434
|
-
"reasoning.summary"
|
|
12521
|
+
"reasoning.summary",
|
|
12522
|
+
// Codex protocol bookkeeping that churns the feed without conveying
|
|
12523
|
+
// meaningful agent progress. `usage.update` (above) still feeds header
|
|
12524
|
+
// token/context metrics via the raw event stream — only the rendered row
|
|
12525
|
+
// is suppressed in the default (non-verbose) feed.
|
|
12526
|
+
"thread.status",
|
|
12527
|
+
"server.request.resolved"
|
|
12528
|
+
]);
|
|
12529
|
+
var VERBOSE_ONLY_NOTIFICATION_TYPES = /* @__PURE__ */ new Set([
|
|
12530
|
+
"account.rate_limits_updated",
|
|
12531
|
+
"account.updated",
|
|
12532
|
+
"item.agentMessage.started",
|
|
12533
|
+
"raw_response_item.completed",
|
|
12534
|
+
"command_exec.output_delta",
|
|
12535
|
+
"fuzzy_file_search.updated",
|
|
12536
|
+
"fuzzy_file_search.completed",
|
|
12537
|
+
"app.list_updated",
|
|
12538
|
+
"thread_name",
|
|
12539
|
+
"thread.archived",
|
|
12540
|
+
"thread.unarchived",
|
|
12541
|
+
"thread.realtime.transcript_delta",
|
|
12542
|
+
"thread.realtime.output_audio_delta"
|
|
12435
12543
|
]);
|
|
12544
|
+
function isVerboseOnlyNotification(event) {
|
|
12545
|
+
return event.kind === "notification" && typeof event.data.notification_type === "string" && VERBOSE_ONLY_NOTIFICATION_TYPES.has(event.data.notification_type);
|
|
12546
|
+
}
|
|
12436
12547
|
function toRunStatus(event) {
|
|
12437
12548
|
switch (event.data.status) {
|
|
12438
12549
|
case "completed":
|
|
@@ -13221,6 +13332,9 @@ function shouldSkipEvent(event, verbose) {
|
|
|
13221
13332
|
if (!verbose && event.kind === "stop.request" && !event.data.stop_hook_active) {
|
|
13222
13333
|
return true;
|
|
13223
13334
|
}
|
|
13335
|
+
if (!verbose && isVerboseOnlyNotification(event)) {
|
|
13336
|
+
return true;
|
|
13337
|
+
}
|
|
13224
13338
|
return false;
|
|
13225
13339
|
}
|
|
13226
13340
|
function mergedToolUseId(event, postByToolUseId) {
|
|
@@ -13880,7 +13994,7 @@ async function connect(opts) {
|
|
|
13880
13994
|
const entry = pending.get(requestId);
|
|
13881
13995
|
if (!entry) return;
|
|
13882
13996
|
pending.delete(requestId);
|
|
13883
|
-
clearTimeout(entry.timer);
|
|
13997
|
+
if (entry.timer) clearTimeout(entry.timer);
|
|
13884
13998
|
entry.resolve(parsed);
|
|
13885
13999
|
return;
|
|
13886
14000
|
}
|
|
@@ -13904,7 +14018,7 @@ async function connect(opts) {
|
|
|
13904
14018
|
)
|
|
13905
14019
|
);
|
|
13906
14020
|
for (const [, p] of pending) {
|
|
13907
|
-
clearTimeout(p.timer);
|
|
14021
|
+
if (p.timer) clearTimeout(p.timer);
|
|
13908
14022
|
p.reject(
|
|
13909
14023
|
new GatewayProtocolError("connection closed", "connection_closed")
|
|
13910
14024
|
);
|
|
@@ -13964,14 +14078,14 @@ async function connect(opts) {
|
|
|
13964
14078
|
kind,
|
|
13965
14079
|
payload
|
|
13966
14080
|
};
|
|
13967
|
-
const effectiveTimeoutMs = reqOpts?.timeoutMs
|
|
14081
|
+
const effectiveTimeoutMs = reqOpts?.timeoutMs === void 0 ? timeoutMs : reqOpts.timeoutMs;
|
|
13968
14082
|
const responsePromise = new Promise(
|
|
13969
14083
|
(resolve, reject) => {
|
|
13970
|
-
const timer = setTimeout(() => {
|
|
14084
|
+
const timer = effectiveTimeoutMs === null ? void 0 : setTimeout(() => {
|
|
13971
14085
|
pending.delete(requestId);
|
|
13972
14086
|
reject(new GatewayProtocolError(`request ${kind} timed out`));
|
|
13973
14087
|
}, effectiveTimeoutMs);
|
|
13974
|
-
pending.set(requestId, { resolve, reject, timer });
|
|
14088
|
+
pending.set(requestId, { resolve, reject, ...timer ? { timer } : {} });
|
|
13975
14089
|
}
|
|
13976
14090
|
);
|
|
13977
14091
|
connection.send(envelope);
|
|
@@ -14227,7 +14341,6 @@ function writeGatewayClientConfig(config, env = process.env) {
|
|
|
14227
14341
|
}
|
|
14228
14342
|
|
|
14229
14343
|
// src/app/channels/sessionBridge.ts
|
|
14230
|
-
var RELAY_REQUEST_TIMEOUT_MS = 6 * 6e4;
|
|
14231
14344
|
var RECONNECT_BACKOFF_MS = [1e3, 2e3, 4e3, 8e3, 16e3, 3e4];
|
|
14232
14345
|
var SessionBridge = class {
|
|
14233
14346
|
opts;
|
|
@@ -14379,9 +14492,9 @@ var SessionBridge = class {
|
|
|
14379
14492
|
toolName: req.toolName,
|
|
14380
14493
|
description: req.description,
|
|
14381
14494
|
inputPreview: req.inputPreview,
|
|
14382
|
-
|
|
14495
|
+
ttlMs: req.ttlMs ?? null
|
|
14383
14496
|
};
|
|
14384
|
-
const overallTimeoutMs = req.ttlMs
|
|
14497
|
+
const overallTimeoutMs = req.ttlMs ?? null;
|
|
14385
14498
|
return this.requestWithReconnect("relay.permission.request", payload, overallTimeoutMs);
|
|
14386
14499
|
}
|
|
14387
14500
|
async relayQuestion(req) {
|
|
@@ -14390,9 +14503,9 @@ var SessionBridge = class {
|
|
|
14390
14503
|
channelRequestId,
|
|
14391
14504
|
title: req.title,
|
|
14392
14505
|
questions: req.questions,
|
|
14393
|
-
|
|
14506
|
+
ttlMs: req.ttlMs ?? null
|
|
14394
14507
|
};
|
|
14395
|
-
const overallTimeoutMs = req.ttlMs
|
|
14508
|
+
const overallTimeoutMs = req.ttlMs ?? null;
|
|
14396
14509
|
return this.requestWithReconnect("relay.question.request", payload, overallTimeoutMs);
|
|
14397
14510
|
}
|
|
14398
14511
|
/**
|
|
@@ -14400,8 +14513,9 @@ var SessionBridge = class {
|
|
|
14400
14513
|
* survives a transient WS disconnect: on `connection closed`, wait for
|
|
14401
14514
|
* the bridge's reconnect to settle, then re-issue the same payload. The
|
|
14402
14515
|
* server attaches the replay to the existing pending entry by
|
|
14403
|
-
* `channelRequestId`, so adapters are not re-prompted.
|
|
14404
|
-
*
|
|
14516
|
+
* `channelRequestId`, so adapters are not re-prompted. If the caller
|
|
14517
|
+
* provided an explicit TTL, reconnect retries are bounded by that deadline;
|
|
14518
|
+
* otherwise human-in-the-loop relays wait until answered or cancelled.
|
|
14405
14519
|
*/
|
|
14406
14520
|
async requestWithReconnect(kind, payload, overallTimeoutMs) {
|
|
14407
14521
|
const deadline = overallTimeoutMs === null ? null : Date.now() + overallTimeoutMs;
|
|
@@ -14413,9 +14527,7 @@ var SessionBridge = class {
|
|
|
14413
14527
|
}
|
|
14414
14528
|
try {
|
|
14415
14529
|
return await client.request(kind, payload, {
|
|
14416
|
-
|
|
14417
|
-
// inner request never self-cancels in any human time scale.
|
|
14418
|
-
timeoutMs: remaining ?? 2147483647
|
|
14530
|
+
timeoutMs: remaining
|
|
14419
14531
|
});
|
|
14420
14532
|
} catch (err) {
|
|
14421
14533
|
if (err instanceof GatewayProtocolError && err.code === "connection_closed" && !this.stopped && (deadline === null || Date.now() < deadline)) {
|
|
@@ -15039,8 +15151,8 @@ async function runExec(options) {
|
|
|
15039
15151
|
const runtimeFactory = options.runtimeFactory ?? createRuntime;
|
|
15040
15152
|
const sessionStoreFactory = options.sessionStoreFactory ?? createSessionStore;
|
|
15041
15153
|
const athenaSessionId = options.athenaSessionId ?? crypto2.randomUUID();
|
|
15042
|
-
const
|
|
15043
|
-
const dashboardFeedPublisher = options.dashboardFeedPublisher ??
|
|
15154
|
+
const ownedFeedPublisher = options.dashboardFeedPublisher ? null : createPairedFeedPublisher();
|
|
15155
|
+
const dashboardFeedPublisher = options.dashboardFeedPublisher ?? ownedFeedPublisher;
|
|
15044
15156
|
const dashboardOrigin = options.dashboardOrigin ?? "local";
|
|
15045
15157
|
const output = createExecOutputWriter({
|
|
15046
15158
|
json,
|
|
@@ -15409,9 +15521,7 @@ async function runExec(options) {
|
|
|
15409
15521
|
}
|
|
15410
15522
|
await bridge?.stop();
|
|
15411
15523
|
store.close();
|
|
15412
|
-
|
|
15413
|
-
dashboardFeedPublisher.close();
|
|
15414
|
-
}
|
|
15524
|
+
ownedFeedPublisher?.close();
|
|
15415
15525
|
}
|
|
15416
15526
|
const resolvedFinalMessage = resolveFinalMessage({
|
|
15417
15527
|
streamMessage: streamFinalMessage,
|
|
@@ -16419,8 +16529,26 @@ function parseRemoteRunSpec(value) {
|
|
|
16419
16529
|
callbackToken: typeof callbackToken === "string" && callbackToken.length > 0 ? callbackToken : void 0
|
|
16420
16530
|
};
|
|
16421
16531
|
}
|
|
16422
|
-
function
|
|
16423
|
-
|
|
16532
|
+
function validateDashboardAssignment(frame) {
|
|
16533
|
+
const spec = parseRemoteRunSpec(frame.runSpec);
|
|
16534
|
+
if (!spec) {
|
|
16535
|
+
return {
|
|
16536
|
+
kind: "rejected",
|
|
16537
|
+
rejection: {
|
|
16538
|
+
reason: "malformed_assignment",
|
|
16539
|
+
message: "remote assignment missing prompt"
|
|
16540
|
+
}
|
|
16541
|
+
};
|
|
16542
|
+
}
|
|
16543
|
+
return {
|
|
16544
|
+
kind: "valid",
|
|
16545
|
+
assignment: {
|
|
16546
|
+
runId: frame.runId,
|
|
16547
|
+
runnerId: frame.runnerId ?? "legacy",
|
|
16548
|
+
spec,
|
|
16549
|
+
frame
|
|
16550
|
+
}
|
|
16551
|
+
};
|
|
16424
16552
|
}
|
|
16425
16553
|
function workflowNameFromRef(ref) {
|
|
16426
16554
|
if (!ref) return void 0;
|
|
@@ -16501,7 +16629,7 @@ function mergeRunSpecEnvIntoWorkflow(workflow, env) {
|
|
|
16501
16629
|
};
|
|
16502
16630
|
}
|
|
16503
16631
|
async function executeRemoteAssignment({
|
|
16504
|
-
|
|
16632
|
+
assignment,
|
|
16505
16633
|
client,
|
|
16506
16634
|
projectDir,
|
|
16507
16635
|
log = () => {
|
|
@@ -16524,11 +16652,11 @@ async function executeRemoteAssignment({
|
|
|
16524
16652
|
const deferredFailedCompletion = {
|
|
16525
16653
|
current: null
|
|
16526
16654
|
};
|
|
16527
|
-
const spec =
|
|
16655
|
+
const { spec, runId, frame } = assignment;
|
|
16528
16656
|
const runEventPublisher = await createRemoteRunEventPublisher({
|
|
16529
|
-
runId
|
|
16530
|
-
callbackWsUrl: spec
|
|
16531
|
-
callbackToken: spec
|
|
16657
|
+
runId,
|
|
16658
|
+
callbackWsUrl: spec.callbackWsUrl,
|
|
16659
|
+
callbackToken: spec.callbackToken,
|
|
16532
16660
|
client,
|
|
16533
16661
|
log,
|
|
16534
16662
|
now,
|
|
@@ -16543,10 +16671,6 @@ async function executeRemoteAssignment({
|
|
|
16543
16671
|
};
|
|
16544
16672
|
send("progress", { message: "assignment received" });
|
|
16545
16673
|
try {
|
|
16546
|
-
if (!spec) {
|
|
16547
|
-
send("error", { message: "remote assignment missing prompt" });
|
|
16548
|
-
return;
|
|
16549
|
-
}
|
|
16550
16674
|
let artifactUploadSpec;
|
|
16551
16675
|
try {
|
|
16552
16676
|
artifactUploadSpec = parseArtifactUploadSpec(frame.runSpec);
|
|
@@ -16627,7 +16751,7 @@ async function executeRemoteAssignment({
|
|
|
16627
16751
|
prompt: spec.prompt,
|
|
16628
16752
|
projectDir,
|
|
16629
16753
|
harness: runtimeConfig.harness,
|
|
16630
|
-
athenaSessionId: spec.athenaSessionId ?? spec.sessionId ?? `athena-${
|
|
16754
|
+
athenaSessionId: spec.athenaSessionId ?? spec.sessionId ?? `athena-${runId}`,
|
|
16631
16755
|
adapterResumeSessionId: spec.adapterResumeSessionId,
|
|
16632
16756
|
isolationConfig: runtimeConfig.isolationConfig,
|
|
16633
16757
|
pluginMcpConfig: runtimeConfig.pluginMcpConfig,
|
|
@@ -16644,8 +16768,8 @@ async function executeRemoteAssignment({
|
|
|
16644
16768
|
...decisionInbox ? { dashboardDecisionInbox: decisionInbox } : {},
|
|
16645
16769
|
...dashboardFeedPublisher ? { dashboardFeedPublisher } : {},
|
|
16646
16770
|
...artifactUploadSpec ? {
|
|
16647
|
-
beforeTerminalCompletion: async ({ result: result2, runId }) => {
|
|
16648
|
-
const artifactRunId =
|
|
16771
|
+
beforeTerminalCompletion: async ({ result: result2, runId: runId2 }) => {
|
|
16772
|
+
const artifactRunId = runId2 ?? assignment.runId;
|
|
16649
16773
|
const { feedEvent } = await captureAndUploadArtifacts({
|
|
16650
16774
|
spec: artifactUploadSpec,
|
|
16651
16775
|
projectDir,
|
|
@@ -17055,54 +17179,55 @@ function createDashboardPairedExecution(options) {
|
|
|
17055
17179
|
});
|
|
17056
17180
|
log("warn", `run ${runId} rejected: ${rejection.message}`);
|
|
17057
17181
|
}
|
|
17058
|
-
function
|
|
17182
|
+
function submitDashboardDecision(submission) {
|
|
17059
17183
|
decisionInbox.enqueue({
|
|
17060
|
-
athenaSessionId:
|
|
17061
|
-
requestId:
|
|
17062
|
-
decision:
|
|
17184
|
+
athenaSessionId: submission.athenaSessionId,
|
|
17185
|
+
requestId: submission.requestId,
|
|
17186
|
+
decision: submission.decision,
|
|
17063
17187
|
receivedAt: now()
|
|
17064
17188
|
});
|
|
17065
17189
|
client.sendDecisionAck({
|
|
17066
|
-
athenaSessionId:
|
|
17067
|
-
requestId:
|
|
17190
|
+
athenaSessionId: submission.athenaSessionId,
|
|
17191
|
+
requestId: submission.requestId
|
|
17068
17192
|
});
|
|
17069
17193
|
}
|
|
17070
|
-
function
|
|
17071
|
-
const entry = active.get(
|
|
17072
|
-
if (!entry) return;
|
|
17194
|
+
function cancelRun(runId) {
|
|
17195
|
+
const entry = active.get(runId);
|
|
17196
|
+
if (!entry) return false;
|
|
17073
17197
|
entry.record.status = "cancelled";
|
|
17074
17198
|
entry.controller.abort();
|
|
17199
|
+
return true;
|
|
17075
17200
|
}
|
|
17076
|
-
function handleAssignment(
|
|
17077
|
-
|
|
17201
|
+
function handleAssignment(assignment, input = {}) {
|
|
17202
|
+
const { runId, runnerId } = assignment;
|
|
17203
|
+
if (active.has(runId)) {
|
|
17078
17204
|
const rejection = {
|
|
17079
17205
|
reason: "duplicate",
|
|
17080
|
-
message: `duplicate active assignment ${
|
|
17206
|
+
message: `duplicate active assignment ${runId}`
|
|
17081
17207
|
};
|
|
17082
|
-
rejectAssignment(
|
|
17208
|
+
rejectAssignment(runId, rejection);
|
|
17083
17209
|
return { kind: "rejected", rejection };
|
|
17084
17210
|
}
|
|
17085
|
-
const
|
|
17086
|
-
const bucket = activeByRunner.get(runnerKey) ?? /* @__PURE__ */ new Set();
|
|
17211
|
+
const bucket = activeByRunner.get(runnerId) ?? /* @__PURE__ */ new Set();
|
|
17087
17212
|
if (bucket.size >= maxConcurrentRuns) {
|
|
17088
17213
|
const rejection = {
|
|
17089
17214
|
reason: "local_capacity",
|
|
17090
|
-
message: `runtime daemon at concurrency cap (${maxConcurrentRuns}) for runner ${
|
|
17215
|
+
message: `runtime daemon at concurrency cap (${maxConcurrentRuns}) for runner ${runnerId}`
|
|
17091
17216
|
};
|
|
17092
|
-
rejectAssignment(
|
|
17217
|
+
rejectAssignment(runId, rejection);
|
|
17093
17218
|
return { kind: "rejected", rejection };
|
|
17094
17219
|
}
|
|
17095
17220
|
const controller = new AbortController();
|
|
17096
17221
|
const record = {
|
|
17097
|
-
runId
|
|
17222
|
+
runId,
|
|
17098
17223
|
startedAt: now(),
|
|
17099
17224
|
status: "running"
|
|
17100
17225
|
};
|
|
17101
17226
|
recordRun(record);
|
|
17102
|
-
bucket.add(
|
|
17103
|
-
activeByRunner.set(
|
|
17227
|
+
bucket.add(runId);
|
|
17228
|
+
activeByRunner.set(runnerId, bucket);
|
|
17104
17229
|
const promise = executor({
|
|
17105
|
-
|
|
17230
|
+
assignment,
|
|
17106
17231
|
client,
|
|
17107
17232
|
projectDir: input.projectDir ?? projectDir,
|
|
17108
17233
|
log,
|
|
@@ -17118,40 +17243,33 @@ function createDashboardPairedExecution(options) {
|
|
|
17118
17243
|
record.error = err instanceof Error ? err.message : String(err);
|
|
17119
17244
|
log(
|
|
17120
17245
|
"error",
|
|
17121
|
-
`run ${
|
|
17246
|
+
`run ${runId} failed: ${err instanceof Error ? err.message : String(err)}`
|
|
17122
17247
|
);
|
|
17123
17248
|
}).finally(() => {
|
|
17124
17249
|
record.endedAt = now();
|
|
17125
17250
|
completedRuns += 1;
|
|
17126
|
-
active.delete(
|
|
17127
|
-
const remaining = activeByRunner.get(
|
|
17251
|
+
active.delete(runId);
|
|
17252
|
+
const remaining = activeByRunner.get(runnerId);
|
|
17128
17253
|
if (remaining) {
|
|
17129
|
-
remaining.delete(
|
|
17130
|
-
if (remaining.size === 0) activeByRunner.delete(
|
|
17254
|
+
remaining.delete(runId);
|
|
17255
|
+
if (remaining.size === 0) activeByRunner.delete(runnerId);
|
|
17131
17256
|
}
|
|
17132
17257
|
});
|
|
17133
|
-
active.set(
|
|
17258
|
+
active.set(runId, { controller, promise, record, runnerKey: runnerId });
|
|
17134
17259
|
return { kind: "accepted" };
|
|
17135
17260
|
}
|
|
17136
17261
|
return {
|
|
17137
17262
|
// `job_assignment` is intentionally not handled here: the runtime daemon
|
|
17138
17263
|
// routes assignments through `DashboardAssignmentIntake`, which gates
|
|
17139
17264
|
// 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);
|
|
17265
|
+
// directly. Run-control frames (`dashboard_decision`, `cancel`) are
|
|
17266
|
+
// translated by `routeDashboardRunFrame` into `submitDashboardDecision`
|
|
17267
|
+
// and `cancelRun` calls.
|
|
17268
|
+
admitAssignment(assignment, input) {
|
|
17269
|
+
return handleAssignment(assignment, input);
|
|
17154
17270
|
},
|
|
17271
|
+
cancelRun,
|
|
17272
|
+
submitDashboardDecision,
|
|
17155
17273
|
rejectAssignment,
|
|
17156
17274
|
snapshot() {
|
|
17157
17275
|
return {
|
|
@@ -17182,22 +17300,12 @@ function createDashboardPairedExecution(options) {
|
|
|
17182
17300
|
import fs23 from "fs";
|
|
17183
17301
|
import os13 from "os";
|
|
17184
17302
|
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
|
-
}
|
|
17303
|
+
function resolveRemoteWorkspace(assignment, options = {}) {
|
|
17304
|
+
const { spec, runId, runnerId } = assignment;
|
|
17196
17305
|
if (spec.projectDir) {
|
|
17197
17306
|
return validateProjectDir(spec.projectDir, options.env);
|
|
17198
17307
|
}
|
|
17199
17308
|
const sessionId = spec.athenaSessionId ?? spec.sessionId;
|
|
17200
|
-
const runnerId = frame.runnerId ?? "legacy";
|
|
17201
17309
|
const deploymentSlug = deploymentSlugFromUrl(options.dashboardUrl);
|
|
17202
17310
|
const stateDir = daemonStatePaths(options.env).dir;
|
|
17203
17311
|
const projectDir = sessionId ? path21.join(
|
|
@@ -17213,7 +17321,7 @@ function resolveRemoteWorkspace(frame, options = {}) {
|
|
|
17213
17321
|
deploymentSlug,
|
|
17214
17322
|
sanitizePathSegment(runnerId),
|
|
17215
17323
|
"runs",
|
|
17216
|
-
sanitizePathSegment(
|
|
17324
|
+
sanitizePathSegment(runId)
|
|
17217
17325
|
);
|
|
17218
17326
|
try {
|
|
17219
17327
|
fs23.mkdirSync(projectDir, { recursive: true, mode: 448 });
|
|
@@ -17296,23 +17404,21 @@ function sanitizePathSegment(value) {
|
|
|
17296
17404
|
function createDashboardAssignmentIntake(options) {
|
|
17297
17405
|
const log = options.log ?? (() => {
|
|
17298
17406
|
});
|
|
17299
|
-
const resolveWorkspace = options.resolveWorkspace ?? ((
|
|
17407
|
+
const resolveWorkspace = options.resolveWorkspace ?? ((assignment, context2) => resolveRemoteWorkspace(assignment, { dashboardUrl: context2.dashboardUrl }));
|
|
17300
17408
|
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);
|
|
17409
|
+
let context = null;
|
|
17410
|
+
function handle(frame, readyContext) {
|
|
17411
|
+
const validation = validateDashboardAssignment(frame);
|
|
17412
|
+
if (validation.kind === "rejected") {
|
|
17413
|
+
options.execution.rejectAssignment(frame.runId, validation.rejection);
|
|
17309
17414
|
options.client.sendAssignmentRejected({
|
|
17310
17415
|
runId: frame.runId,
|
|
17311
|
-
...rejection
|
|
17416
|
+
...validation.rejection
|
|
17312
17417
|
});
|
|
17313
17418
|
return;
|
|
17314
17419
|
}
|
|
17315
|
-
const
|
|
17420
|
+
const assignment = validation.assignment;
|
|
17421
|
+
const workspace = resolveWorkspace(assignment, readyContext);
|
|
17316
17422
|
if (workspace.kind === "rejected") {
|
|
17317
17423
|
options.execution.rejectAssignment(frame.runId, workspace.rejection);
|
|
17318
17424
|
options.client.sendAssignmentRejected({
|
|
@@ -17321,7 +17427,7 @@ function createDashboardAssignmentIntake(options) {
|
|
|
17321
17427
|
});
|
|
17322
17428
|
return;
|
|
17323
17429
|
}
|
|
17324
|
-
const outcome = options.execution.admitAssignment(
|
|
17430
|
+
const outcome = options.execution.admitAssignment(assignment, {
|
|
17325
17431
|
projectDir: workspace.projectDir
|
|
17326
17432
|
});
|
|
17327
17433
|
if (outcome.kind === "accepted") {
|
|
@@ -17334,15 +17440,15 @@ function createDashboardAssignmentIntake(options) {
|
|
|
17334
17440
|
});
|
|
17335
17441
|
}
|
|
17336
17442
|
function drain() {
|
|
17337
|
-
if (!
|
|
17443
|
+
if (!context) return;
|
|
17338
17444
|
while (pending.length > 0) {
|
|
17339
17445
|
const frame = pending.shift();
|
|
17340
|
-
if (frame) handle(frame);
|
|
17446
|
+
if (frame) handle(frame, context);
|
|
17341
17447
|
}
|
|
17342
17448
|
}
|
|
17343
17449
|
return {
|
|
17344
17450
|
receive(frame) {
|
|
17345
|
-
if (!
|
|
17451
|
+
if (!context) {
|
|
17346
17452
|
pending.push(frame);
|
|
17347
17453
|
log(
|
|
17348
17454
|
"debug",
|
|
@@ -17350,18 +17456,35 @@ function createDashboardAssignmentIntake(options) {
|
|
|
17350
17456
|
);
|
|
17351
17457
|
return;
|
|
17352
17458
|
}
|
|
17353
|
-
handle(frame);
|
|
17459
|
+
handle(frame, context);
|
|
17354
17460
|
},
|
|
17355
|
-
markReady() {
|
|
17356
|
-
|
|
17461
|
+
markReady(nextContext) {
|
|
17462
|
+
context = nextContext;
|
|
17357
17463
|
drain();
|
|
17358
17464
|
},
|
|
17359
17465
|
markNotReady() {
|
|
17360
|
-
|
|
17466
|
+
context = null;
|
|
17361
17467
|
}
|
|
17362
17468
|
};
|
|
17363
17469
|
}
|
|
17364
17470
|
|
|
17471
|
+
// src/app/dashboard/dashboardFrameRouter.ts
|
|
17472
|
+
function routeDashboardRunFrame(execution, frame) {
|
|
17473
|
+
if (frame.type === "dashboard_decision") {
|
|
17474
|
+
execution.submitDashboardDecision({
|
|
17475
|
+
athenaSessionId: frame.athenaSessionId,
|
|
17476
|
+
requestId: frame.requestId,
|
|
17477
|
+
decision: frame.decision
|
|
17478
|
+
});
|
|
17479
|
+
return true;
|
|
17480
|
+
}
|
|
17481
|
+
if (frame.type === "cancel") {
|
|
17482
|
+
execution.cancelRun(frame.runId);
|
|
17483
|
+
return true;
|
|
17484
|
+
}
|
|
17485
|
+
return false;
|
|
17486
|
+
}
|
|
17487
|
+
|
|
17365
17488
|
// src/app/dashboard/runtimeDaemon.ts
|
|
17366
17489
|
var DEFAULT_RECONNECT_DELAYS_MS2 = [1e3, 2e3, 5e3, 1e4, 3e4];
|
|
17367
17490
|
var DEFAULT_MAX_CONCURRENT_RUNS2 = 1;
|
|
@@ -17465,7 +17588,7 @@ async function runDashboardRuntimeDaemon(options = {}) {
|
|
|
17465
17588
|
},
|
|
17466
17589
|
execution: pairedExecution,
|
|
17467
17590
|
log,
|
|
17468
|
-
resolveWorkspace: (
|
|
17591
|
+
resolveWorkspace: (assignment, context) => resolveRemoteWorkspace(assignment, { dashboardUrl: context.dashboardUrl })
|
|
17469
17592
|
});
|
|
17470
17593
|
function nextReconnectDelay() {
|
|
17471
17594
|
if (reconnectDelays.length === 0) return 0;
|
|
@@ -17584,7 +17707,7 @@ async function runDashboardRuntimeDaemon(options = {}) {
|
|
|
17584
17707
|
assignmentIntake.receive(frame);
|
|
17585
17708
|
return;
|
|
17586
17709
|
}
|
|
17587
|
-
pairedExecution
|
|
17710
|
+
routeDashboardRunFrame(pairedExecution, frame);
|
|
17588
17711
|
});
|
|
17589
17712
|
next.onClose((reason) => {
|
|
17590
17713
|
if (stopped || client !== next) return;
|
|
@@ -17614,9 +17737,12 @@ async function runDashboardRuntimeDaemon(options = {}) {
|
|
|
17614
17737
|
);
|
|
17615
17738
|
}
|
|
17616
17739
|
if (stopped || client !== next) return;
|
|
17617
|
-
assignmentIntake.markReady();
|
|
17618
17740
|
currentInstanceId = token.instanceId;
|
|
17619
17741
|
currentDashboardUrl = config.dashboardUrl;
|
|
17742
|
+
assignmentIntake.markReady({
|
|
17743
|
+
dashboardUrl: config.dashboardUrl,
|
|
17744
|
+
instanceId: token.instanceId
|
|
17745
|
+
});
|
|
17620
17746
|
reconnectAttempt = 0;
|
|
17621
17747
|
scheduleRefresh(token.expiresInSec);
|
|
17622
17748
|
pairedFeedPublisher.attachTransport(next);
|
|
@@ -18076,4 +18202,4 @@ export {
|
|
|
18076
18202
|
startUdsServer,
|
|
18077
18203
|
sendUdsRequest
|
|
18078
18204
|
};
|
|
18079
|
-
//# sourceMappingURL=chunk-
|
|
18205
|
+
//# sourceMappingURL=chunk-XZDDQJUX.js.map
|