orion-super-agent-dev 0.1.40 → 0.1.41
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/out/brains/darwin-arm64/orion-brain +0 -0
- package/out/brains/darwin-x64/orion-brain +0 -0
- package/out/brains/linux-arm64/orion-brain +0 -0
- package/out/brains/linux-x64/orion-brain +0 -0
- package/out/brains/win32-x64/orion-brain.exe +0 -0
- package/out/main.js +1071 -288
- package/package.json +1 -1
package/out/main.js
CHANGED
|
@@ -30114,6 +30114,29 @@ var require_refreshOnRefusal = __commonJS({
|
|
|
30114
30114
|
}
|
|
30115
30115
|
});
|
|
30116
30116
|
|
|
30117
|
+
// ../packages/orion-client-core/dist/boundaryEvents.js
|
|
30118
|
+
var require_boundaryEvents = __commonJS({
|
|
30119
|
+
"../packages/orion-client-core/dist/boundaryEvents.js"(exports2) {
|
|
30120
|
+
"use strict";
|
|
30121
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
30122
|
+
exports2.BOUNDARY_EVENTS = void 0;
|
|
30123
|
+
exports2.resumeTokenOf = resumeTokenOf;
|
|
30124
|
+
exports2.BOUNDARY_EVENTS = /* @__PURE__ */ new Set([
|
|
30125
|
+
"tool_request",
|
|
30126
|
+
"permission_request",
|
|
30127
|
+
"plan_approval_request",
|
|
30128
|
+
"user_input_request",
|
|
30129
|
+
"hook_request",
|
|
30130
|
+
"file_history_rewind_request"
|
|
30131
|
+
]);
|
|
30132
|
+
function resumeTokenOf(event) {
|
|
30133
|
+
if (!exports2.BOUNDARY_EVENTS.has(event.event))
|
|
30134
|
+
return void 0;
|
|
30135
|
+
return event.data?.resume_token ?? void 0;
|
|
30136
|
+
}
|
|
30137
|
+
}
|
|
30138
|
+
});
|
|
30139
|
+
|
|
30117
30140
|
// ../packages/orion-client-core/dist/atomicWrite.js
|
|
30118
30141
|
var require_atomicWrite = __commonJS({
|
|
30119
30142
|
"../packages/orion-client-core/dist/atomicWrite.js"(exports2) {
|
|
@@ -32038,6 +32061,41 @@ var require_interimModels = __commonJS({
|
|
|
32038
32061
|
}
|
|
32039
32062
|
});
|
|
32040
32063
|
|
|
32064
|
+
// ../packages/orion-client-core/dist/interruptedTurn.js
|
|
32065
|
+
var require_interruptedTurn = __commonJS({
|
|
32066
|
+
"../packages/orion-client-core/dist/interruptedTurn.js"(exports2) {
|
|
32067
|
+
"use strict";
|
|
32068
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
32069
|
+
exports2.MOVED_ON_NOTE = void 0;
|
|
32070
|
+
exports2.interruptedTurnMessages = interruptedTurnMessages;
|
|
32071
|
+
exports2.carryInterruptedTurn = carryInterruptedTurn;
|
|
32072
|
+
exports2.interruptedTurnOf = interruptedTurnOf2;
|
|
32073
|
+
var textBlock = (text) => ({ type: "text", text });
|
|
32074
|
+
exports2.MOVED_ON_NOTE = "[Reply cut off here \u2014 the user sent their next message before it finished. That message is what they want now: pick up from this point as it directs, without restarting this reply or remarking on the cut.]";
|
|
32075
|
+
function interruptedTurnMessages(messages, prompt, partialReply, cause = "stopped") {
|
|
32076
|
+
const out2 = [...messages];
|
|
32077
|
+
if (prompt && prompt.trim().length > 0) {
|
|
32078
|
+
out2.push({ role: "user", content: [textBlock(prompt)] });
|
|
32079
|
+
}
|
|
32080
|
+
if (partialReply && partialReply.trim().length > 0) {
|
|
32081
|
+
const content = [textBlock(partialReply)];
|
|
32082
|
+
if (cause === "moved_on")
|
|
32083
|
+
content.push(textBlock(exports2.MOVED_ON_NOTE));
|
|
32084
|
+
out2.push({ role: "assistant", content });
|
|
32085
|
+
}
|
|
32086
|
+
return out2;
|
|
32087
|
+
}
|
|
32088
|
+
var carried = /* @__PURE__ */ new WeakMap();
|
|
32089
|
+
function carryInterruptedTurn(error, turn) {
|
|
32090
|
+
if (typeof error === "object" && error !== null)
|
|
32091
|
+
carried.set(error, turn);
|
|
32092
|
+
}
|
|
32093
|
+
function interruptedTurnOf2(error) {
|
|
32094
|
+
return typeof error === "object" && error !== null ? carried.get(error) : void 0;
|
|
32095
|
+
}
|
|
32096
|
+
}
|
|
32097
|
+
});
|
|
32098
|
+
|
|
32041
32099
|
// ../packages/orion-client-core/dist/transportError.js
|
|
32042
32100
|
var require_transportError = __commonJS({
|
|
32043
32101
|
"../packages/orion-client-core/dist/transportError.js"(exports2) {
|
|
@@ -38006,6 +38064,309 @@ var require_toolConcurrency = __commonJS({
|
|
|
38006
38064
|
}
|
|
38007
38065
|
});
|
|
38008
38066
|
|
|
38067
|
+
// ../packages/orion-client-core/dist/turnClose.js
|
|
38068
|
+
var require_turnClose = __commonJS({
|
|
38069
|
+
"../packages/orion-client-core/dist/turnClose.js"(exports2) {
|
|
38070
|
+
"use strict";
|
|
38071
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
38072
|
+
exports2.CLOSE_TURNS_IN_BACKGROUND = exports2.STOPPED_TOOL_GRACE_MS = exports2.TURN_CLOSE_TIMEOUT_MS = exports2.TURN_CLOSE_WAIT_MS = void 0;
|
|
38073
|
+
exports2.closeTurn = closeTurn;
|
|
38074
|
+
var boundaryEvents_js_1 = require_boundaryEvents();
|
|
38075
|
+
var interruptedTurn_js_1 = require_interruptedTurn();
|
|
38076
|
+
exports2.TURN_CLOSE_WAIT_MS = 3e3;
|
|
38077
|
+
exports2.TURN_CLOSE_TIMEOUT_MS = 15e3;
|
|
38078
|
+
exports2.STOPPED_TOOL_GRACE_MS = 500;
|
|
38079
|
+
exports2.CLOSE_TURNS_IN_BACKGROUND = { turnCloseWaitMs: 0, stoppedToolGraceMs: 0 };
|
|
38080
|
+
var RUNS_THE_TURN = /* @__PURE__ */ new Set([
|
|
38081
|
+
"text_delta",
|
|
38082
|
+
"thinking_delta",
|
|
38083
|
+
"tool_use_start",
|
|
38084
|
+
"usage_recorded",
|
|
38085
|
+
...boundaryEvents_js_1.BOUNDARY_EVENTS,
|
|
38086
|
+
"turn_complete"
|
|
38087
|
+
]);
|
|
38088
|
+
async function closeTurn(trail, ending, deps2) {
|
|
38089
|
+
if (ending === "failed" && !trail.contentSeen)
|
|
38090
|
+
return void 0;
|
|
38091
|
+
const everything = await everythingTheTurnDid(trail, ending, deps2).catch(() => void 0);
|
|
38092
|
+
if (everything !== void 0)
|
|
38093
|
+
return everything;
|
|
38094
|
+
try {
|
|
38095
|
+
return {
|
|
38096
|
+
kept: "words",
|
|
38097
|
+
messages: (0, interruptedTurn_js_1.interruptedTurnMessages)(deps2.committed(), deps2.prompt, trail.words, deps2.cause)
|
|
38098
|
+
};
|
|
38099
|
+
} catch {
|
|
38100
|
+
return void 0;
|
|
38101
|
+
}
|
|
38102
|
+
}
|
|
38103
|
+
async function everythingTheTurnDid(trail, ending, deps2) {
|
|
38104
|
+
if (trail.resumeToken === void 0)
|
|
38105
|
+
return void 0;
|
|
38106
|
+
const parked = trail.parked;
|
|
38107
|
+
if (parked)
|
|
38108
|
+
await settledWithin(trail.stillRunning, deps2.graceMs);
|
|
38109
|
+
const closing = parked && ending === "stopped" ? "abandoned" : "recovery";
|
|
38110
|
+
const transcript = await engineTranscript(deps2.transport, deps2.closingBody(closing, trail.resumeToken, trail.answered), deps2.waitMs);
|
|
38111
|
+
if (transcript === void 0)
|
|
38112
|
+
return void 0;
|
|
38113
|
+
return {
|
|
38114
|
+
kept: "everything",
|
|
38115
|
+
// Parked, the token holds every word the turn said. Cut mid-stream, the words since
|
|
38116
|
+
// the last boundary are in no token: they follow the transcript as the step that was cut.
|
|
38117
|
+
messages: parked ? transcript : (0, interruptedTurn_js_1.interruptedTurnMessages)(transcript, null, trail.wordsSinceBoundary, deps2.cause)
|
|
38118
|
+
};
|
|
38119
|
+
}
|
|
38120
|
+
async function settledWithin(work, ms) {
|
|
38121
|
+
if (work.length === 0 || ms <= 0)
|
|
38122
|
+
return;
|
|
38123
|
+
let timer;
|
|
38124
|
+
const elapsed = new Promise((resolve5) => {
|
|
38125
|
+
timer = setTimeout(resolve5, ms);
|
|
38126
|
+
timer.unref?.();
|
|
38127
|
+
});
|
|
38128
|
+
try {
|
|
38129
|
+
await Promise.race([Promise.allSettled(work).then(() => void 0), elapsed]);
|
|
38130
|
+
} finally {
|
|
38131
|
+
if (timer !== void 0)
|
|
38132
|
+
clearTimeout(timer);
|
|
38133
|
+
}
|
|
38134
|
+
}
|
|
38135
|
+
function engineTranscript(transport, body2, waitMs) {
|
|
38136
|
+
return new Promise((resolve5) => {
|
|
38137
|
+
const ac = new AbortController();
|
|
38138
|
+
const timers = [];
|
|
38139
|
+
const after = (ms, act) => {
|
|
38140
|
+
const timer = setTimeout(act, ms);
|
|
38141
|
+
timer.unref?.();
|
|
38142
|
+
timers.push(timer);
|
|
38143
|
+
};
|
|
38144
|
+
const onEvent = (event) => {
|
|
38145
|
+
if (RUNS_THE_TURN.has(event.event)) {
|
|
38146
|
+
ac.abort();
|
|
38147
|
+
resolve5(void 0);
|
|
38148
|
+
return;
|
|
38149
|
+
}
|
|
38150
|
+
if (event.event !== "turn_error")
|
|
38151
|
+
return;
|
|
38152
|
+
const messages = event.data?.messages;
|
|
38153
|
+
resolve5(Array.isArray(messages) ? messages : void 0);
|
|
38154
|
+
};
|
|
38155
|
+
after(exports2.TURN_CLOSE_TIMEOUT_MS, () => ac.abort());
|
|
38156
|
+
if (waitMs > 0)
|
|
38157
|
+
after(waitMs, () => resolve5(void 0));
|
|
38158
|
+
else
|
|
38159
|
+
resolve5(void 0);
|
|
38160
|
+
let closing;
|
|
38161
|
+
try {
|
|
38162
|
+
closing = transport.streamSegment(body2, onEvent, ac.signal);
|
|
38163
|
+
} catch {
|
|
38164
|
+
closing = Promise.resolve();
|
|
38165
|
+
}
|
|
38166
|
+
void closing.catch(() => void 0).finally(() => {
|
|
38167
|
+
for (const timer of timers)
|
|
38168
|
+
clearTimeout(timer);
|
|
38169
|
+
resolve5(void 0);
|
|
38170
|
+
});
|
|
38171
|
+
});
|
|
38172
|
+
}
|
|
38173
|
+
}
|
|
38174
|
+
});
|
|
38175
|
+
|
|
38176
|
+
// ../packages/orion-client-core/dist/planState.js
|
|
38177
|
+
var require_planState = __commonJS({
|
|
38178
|
+
"../packages/orion-client-core/dist/planState.js"(exports2) {
|
|
38179
|
+
"use strict";
|
|
38180
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
38181
|
+
exports2.planOfEvent = planOfEvent2;
|
|
38182
|
+
function planOfEvent2(data) {
|
|
38183
|
+
if (typeof data !== "object" || data === null)
|
|
38184
|
+
return null;
|
|
38185
|
+
const { steps: rawSteps, current_step: pointer } = data;
|
|
38186
|
+
const steps = Array.isArray(rawSteps) ? rawSteps.filter((step) => typeof step === "string") : [];
|
|
38187
|
+
if (steps.length === 0)
|
|
38188
|
+
return null;
|
|
38189
|
+
return {
|
|
38190
|
+
steps,
|
|
38191
|
+
current_step: typeof pointer === "number" && Number.isFinite(pointer) ? pointer : 0
|
|
38192
|
+
};
|
|
38193
|
+
}
|
|
38194
|
+
}
|
|
38195
|
+
});
|
|
38196
|
+
|
|
38197
|
+
// ../packages/orion-client-core/dist/turnTrail.js
|
|
38198
|
+
var require_turnTrail = __commonJS({
|
|
38199
|
+
"../packages/orion-client-core/dist/turnTrail.js"(exports2) {
|
|
38200
|
+
"use strict";
|
|
38201
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
38202
|
+
exports2.TurnTrail = void 0;
|
|
38203
|
+
var boundaryEvents_js_1 = require_boundaryEvents();
|
|
38204
|
+
var planState_js_1 = require_planState();
|
|
38205
|
+
var StreamedWords = class {
|
|
38206
|
+
text = "";
|
|
38207
|
+
stepEnded = false;
|
|
38208
|
+
add(delta) {
|
|
38209
|
+
if (delta === "")
|
|
38210
|
+
return;
|
|
38211
|
+
if (this.stepEnded && this.text !== "")
|
|
38212
|
+
this.text = `${this.text.replace(/\n+$/, "")}
|
|
38213
|
+
|
|
38214
|
+
`;
|
|
38215
|
+
this.stepEnded = false;
|
|
38216
|
+
this.text += delta;
|
|
38217
|
+
}
|
|
38218
|
+
/** What follows belongs to the next step. */
|
|
38219
|
+
endStep() {
|
|
38220
|
+
this.stepEnded = true;
|
|
38221
|
+
}
|
|
38222
|
+
read() {
|
|
38223
|
+
return this.text;
|
|
38224
|
+
}
|
|
38225
|
+
};
|
|
38226
|
+
var TurnTrail = class {
|
|
38227
|
+
/** The `.orion` snapshot the turn's segments carry — a closing carries the same one. */
|
|
38228
|
+
orionResources;
|
|
38229
|
+
/** Whether anything of the turn reached the host. A turn that never did changed nothing. */
|
|
38230
|
+
contentSeen = false;
|
|
38231
|
+
/** The plan the engine last announced this turn; `undefined` = it announced none. */
|
|
38232
|
+
plan;
|
|
38233
|
+
token;
|
|
38234
|
+
isParked = false;
|
|
38235
|
+
resumedOn;
|
|
38236
|
+
carried = [];
|
|
38237
|
+
answer;
|
|
38238
|
+
batch = [];
|
|
38239
|
+
settled = /* @__PURE__ */ new Map();
|
|
38240
|
+
running = /* @__PURE__ */ new Set();
|
|
38241
|
+
turnWords = new StreamedWords();
|
|
38242
|
+
stepWords = new StreamedWords();
|
|
38243
|
+
// ── what happens to a turn ────────────────────────────────────────────────────────────
|
|
38244
|
+
/** A segment goes out, resumed on `result` (nothing, for the turn's first). The engine
|
|
38245
|
+
* owns the turn until it ends or parks. */
|
|
38246
|
+
segmentStarts(result) {
|
|
38247
|
+
this.isParked = false;
|
|
38248
|
+
this.resumedOn = result;
|
|
38249
|
+
this.carried = [];
|
|
38250
|
+
this.answer = void 0;
|
|
38251
|
+
this.batch = [];
|
|
38252
|
+
this.settled.clear();
|
|
38253
|
+
this.running.clear();
|
|
38254
|
+
this.stepWords = new StreamedWords();
|
|
38255
|
+
this.turnWords.endStep();
|
|
38256
|
+
}
|
|
38257
|
+
/** That segment carries `steering`: what the host had queued for the turn since the last
|
|
38258
|
+
* one — the user's words, a sub-agent's report. The engine folds it as the segment starts. */
|
|
38259
|
+
steeredWith(steering) {
|
|
38260
|
+
this.carried = steering;
|
|
38261
|
+
}
|
|
38262
|
+
/** The engine parked the turn at a boundary: it waits on this machine, and `token` holds
|
|
38263
|
+
* everything it did up to here — the words of the segment that parked it included, and
|
|
38264
|
+
* what that segment was steered with. Heard once per segment; the trail hears it from the
|
|
38265
|
+
* boundary event itself as it ARRIVES ({@link observe}), because a stop or a cut can land
|
|
38266
|
+
* before that segment's stream ends. */
|
|
38267
|
+
parkedAt(token) {
|
|
38268
|
+
if (this.isParked)
|
|
38269
|
+
return;
|
|
38270
|
+
this.token = token;
|
|
38271
|
+
this.isParked = true;
|
|
38272
|
+
this.resumedOn = void 0;
|
|
38273
|
+
this.carried = [];
|
|
38274
|
+
this.stepWords = new StreamedWords();
|
|
38275
|
+
this.turnWords.endStep();
|
|
38276
|
+
}
|
|
38277
|
+
/** The client answered the boundary in full; the turn stays parked until the next segment
|
|
38278
|
+
* goes out with the answer. */
|
|
38279
|
+
answeredWith(result) {
|
|
38280
|
+
this.answer = result;
|
|
38281
|
+
}
|
|
38282
|
+
/** One event of the turn's stream, as the host is about to see it. */
|
|
38283
|
+
observe(event) {
|
|
38284
|
+
this.contentSeen = true;
|
|
38285
|
+
const token = (0, boundaryEvents_js_1.resumeTokenOf)(event);
|
|
38286
|
+
if (token !== void 0)
|
|
38287
|
+
this.parkedAt(token);
|
|
38288
|
+
if (event.agent_id)
|
|
38289
|
+
return;
|
|
38290
|
+
const data = event.data;
|
|
38291
|
+
switch (event.event) {
|
|
38292
|
+
case "text_delta": {
|
|
38293
|
+
const delta = typeof data?.delta === "string" ? data.delta : "";
|
|
38294
|
+
this.turnWords.add(delta);
|
|
38295
|
+
this.stepWords.add(delta);
|
|
38296
|
+
break;
|
|
38297
|
+
}
|
|
38298
|
+
case "tool_use_start":
|
|
38299
|
+
this.turnWords.endStep();
|
|
38300
|
+
this.stepWords.endStep();
|
|
38301
|
+
break;
|
|
38302
|
+
case "plan_updated":
|
|
38303
|
+
this.plan = (0, planState_js_1.planOfEvent)(data);
|
|
38304
|
+
break;
|
|
38305
|
+
default:
|
|
38306
|
+
break;
|
|
38307
|
+
}
|
|
38308
|
+
}
|
|
38309
|
+
/** The parked boundary is a batch of client tools. */
|
|
38310
|
+
runsTools(batch) {
|
|
38311
|
+
this.batch = batch;
|
|
38312
|
+
}
|
|
38313
|
+
/** One tool of that batch, running: its result is kept the moment it settles, whether or
|
|
38314
|
+
* not the batch ever finishes. A tool that fails to settle leaves no result. */
|
|
38315
|
+
watch(request, run3) {
|
|
38316
|
+
const watched = run3.then((result) => {
|
|
38317
|
+
this.settled.set(request.request_id, result);
|
|
38318
|
+
}, () => void 0);
|
|
38319
|
+
this.running.add(watched);
|
|
38320
|
+
void watched.finally(() => this.running.delete(watched));
|
|
38321
|
+
return run3;
|
|
38322
|
+
}
|
|
38323
|
+
// ── what a closing reads ──────────────────────────────────────────────────────────────
|
|
38324
|
+
/** The last boundary's resume token; `undefined` before the turn reached one. */
|
|
38325
|
+
get resumeToken() {
|
|
38326
|
+
return this.token;
|
|
38327
|
+
}
|
|
38328
|
+
/** Whether the turn is waiting at that boundary (no segment is streaming). */
|
|
38329
|
+
get parked() {
|
|
38330
|
+
return this.isParked;
|
|
38331
|
+
}
|
|
38332
|
+
/** What the client has answered the last boundary with. While a segment STREAMS, the whole
|
|
38333
|
+
* answer it was resumed on. While the turn is PARKED, the whole answer once there is one;
|
|
38334
|
+
* until then, of a batch of tools, the results of those that have settled so far, in the
|
|
38335
|
+
* order they were asked for — and of a card, nothing. */
|
|
38336
|
+
get answered() {
|
|
38337
|
+
if (!this.isParked)
|
|
38338
|
+
return this.resumedOn;
|
|
38339
|
+
if (this.answer !== void 0)
|
|
38340
|
+
return this.answer;
|
|
38341
|
+
const results = this.batch.flatMap((request) => {
|
|
38342
|
+
const result = this.settled.get(request.request_id);
|
|
38343
|
+
return result === void 0 ? [] : [result];
|
|
38344
|
+
});
|
|
38345
|
+
return results.length === 0 ? void 0 : { kind: "tool_result", results };
|
|
38346
|
+
}
|
|
38347
|
+
/** What the segment in flight was steered with — in no token until that segment parks, so
|
|
38348
|
+
* a closing carries it again. Nothing while the turn is parked: the token holds what rode
|
|
38349
|
+
* the segment that parked it, and what was queued since is still the host's. */
|
|
38350
|
+
get steering() {
|
|
38351
|
+
return this.carried;
|
|
38352
|
+
}
|
|
38353
|
+
/** The tools of the parked batch that have not settled yet. */
|
|
38354
|
+
get stillRunning() {
|
|
38355
|
+
return [...this.running];
|
|
38356
|
+
}
|
|
38357
|
+
/** Every word the turn's main agent streamed. */
|
|
38358
|
+
get words() {
|
|
38359
|
+
return this.turnWords.read();
|
|
38360
|
+
}
|
|
38361
|
+
/** The words streamed since the last boundary — the ones no token holds. */
|
|
38362
|
+
get wordsSinceBoundary() {
|
|
38363
|
+
return this.stepWords.read();
|
|
38364
|
+
}
|
|
38365
|
+
};
|
|
38366
|
+
exports2.TurnTrail = TurnTrail;
|
|
38367
|
+
}
|
|
38368
|
+
});
|
|
38369
|
+
|
|
38009
38370
|
// ../packages/orion-client-core/dist/segmentDriver.js
|
|
38010
38371
|
var require_segmentDriver = __commonJS({
|
|
38011
38372
|
"../packages/orion-client-core/dist/segmentDriver.js"(exports2) {
|
|
@@ -38062,12 +38423,14 @@ var require_segmentDriver = __commonJS({
|
|
|
38062
38423
|
exports2.runToolBatch = runToolBatch;
|
|
38063
38424
|
var node_events_1 = __require("node:events");
|
|
38064
38425
|
var os9 = __importStar(__require("node:os"));
|
|
38426
|
+
var boundaryEvents_js_1 = require_boundaryEvents();
|
|
38065
38427
|
var compactionTrigger_js_1 = require_compactionTrigger();
|
|
38066
38428
|
var duetEntry_js_1 = require_duetEntry();
|
|
38067
38429
|
var duetRouterModel_js_1 = require_duetRouterModel();
|
|
38068
38430
|
var duetMode_js_1 = require_duetMode();
|
|
38069
38431
|
var duetPlan_js_1 = require_duetPlan();
|
|
38070
38432
|
var interimModels_js_1 = require_interimModels();
|
|
38433
|
+
var interruptedTurn_js_1 = require_interruptedTurn();
|
|
38071
38434
|
var retrievalModels_js_1 = require_retrievalModels();
|
|
38072
38435
|
var retrievalSteps_js_1 = require_retrievalSteps();
|
|
38073
38436
|
var repoIdentity_js_1 = require_repoIdentity();
|
|
@@ -38081,6 +38444,8 @@ var require_segmentDriver = __commonJS({
|
|
|
38081
38444
|
var wellFormed_js_1 = require_wellFormed();
|
|
38082
38445
|
var orionSnapshot_js_1 = require_orionSnapshot();
|
|
38083
38446
|
var toolConcurrency_js_1 = require_toolConcurrency();
|
|
38447
|
+
var turnClose_js_1 = require_turnClose();
|
|
38448
|
+
var turnTrail_js_1 = require_turnTrail();
|
|
38084
38449
|
function turnAbortController() {
|
|
38085
38450
|
const ac = new AbortController();
|
|
38086
38451
|
(0, node_events_1.setMaxListeners)(0, ac.signal);
|
|
@@ -38126,14 +38491,6 @@ var require_segmentDriver = __commonJS({
|
|
|
38126
38491
|
return error instanceof transportError_js_2.TransportError && (error.status === void 0 || error.status >= 500);
|
|
38127
38492
|
}
|
|
38128
38493
|
exports2.TERMINAL_EVENTS = /* @__PURE__ */ new Set(["turn_complete", "turn_error"]);
|
|
38129
|
-
var BOUNDARY_EVENTS = /* @__PURE__ */ new Set([
|
|
38130
|
-
"tool_request",
|
|
38131
|
-
"permission_request",
|
|
38132
|
-
"plan_approval_request",
|
|
38133
|
-
"user_input_request",
|
|
38134
|
-
"hook_request",
|
|
38135
|
-
"file_history_rewind_request"
|
|
38136
|
-
]);
|
|
38137
38494
|
function effectiveWirePermissionMode2(turbo, configured2) {
|
|
38138
38495
|
return turbo ? "full_access" : configured2;
|
|
38139
38496
|
}
|
|
@@ -38220,20 +38577,57 @@ var require_segmentDriver = __commonJS({
|
|
|
38220
38577
|
}
|
|
38221
38578
|
async function driveTurn3(transport, start2, handlers, opts) {
|
|
38222
38579
|
const work = (0, keepAwake_js_1.beginAgentTurn)();
|
|
38580
|
+
const trail = new turnTrail_js_1.TurnTrail();
|
|
38581
|
+
const closing = closingFor(transport, start2, handlers, trail, opts);
|
|
38223
38582
|
try {
|
|
38224
|
-
return await driveTurnToOutcome(transport, start2, cardsWaitOnPerson(handlers, work), opts);
|
|
38583
|
+
return await driveTurnToOutcome(transport, start2, cardsWaitOnPerson(handlers, work), opts, trail, closing);
|
|
38225
38584
|
} catch (error) {
|
|
38226
|
-
|
|
38585
|
+
const stopped = (0, transportError_js_2.isAbortError)(error) || stopRequested(handlers);
|
|
38586
|
+
if (stopped) {
|
|
38227
38587
|
try {
|
|
38228
38588
|
opts?.mirror?.(stoppedTerminal(start2.sessionId));
|
|
38229
38589
|
} catch {
|
|
38230
38590
|
}
|
|
38231
38591
|
}
|
|
38592
|
+
const left = await closing(stopped ? "stopped" : "failed");
|
|
38593
|
+
if (left !== void 0)
|
|
38594
|
+
(0, interruptedTurn_js_1.carryInterruptedTurn)(error, left);
|
|
38232
38595
|
throw error;
|
|
38233
38596
|
} finally {
|
|
38234
38597
|
work.end();
|
|
38235
38598
|
}
|
|
38236
38599
|
}
|
|
38600
|
+
function closingFor(transport, start2, handlers, trail, opts) {
|
|
38601
|
+
let closed;
|
|
38602
|
+
return (ending) => closed ??= (0, turnClose_js_1.closeTurn)(trail, ending, {
|
|
38603
|
+
transport,
|
|
38604
|
+
closingBody: (closing, token, answered) => buildSegmentBody(start2, { resumeToken: token, boundaryResult: answered, closing }, trail),
|
|
38605
|
+
committed: () => start2.getMessages(),
|
|
38606
|
+
prompt: promptOf2(start2),
|
|
38607
|
+
cause: ending === "stopped" ? stopCauseOf(handlers) : "stopped",
|
|
38608
|
+
waitMs: opts?.turnCloseWaitMs ?? turnClose_js_1.TURN_CLOSE_WAIT_MS,
|
|
38609
|
+
graceMs: opts?.stoppedToolGraceMs ?? turnClose_js_1.STOPPED_TOOL_GRACE_MS
|
|
38610
|
+
});
|
|
38611
|
+
}
|
|
38612
|
+
function stopRequested(handlers) {
|
|
38613
|
+
try {
|
|
38614
|
+
return handlers.signal?.aborted === true || handlers.isCancelRequested?.() === true;
|
|
38615
|
+
} catch {
|
|
38616
|
+
return false;
|
|
38617
|
+
}
|
|
38618
|
+
}
|
|
38619
|
+
function stopCauseOf(handlers) {
|
|
38620
|
+
try {
|
|
38621
|
+
return handlers.stopCause?.() ?? "stopped";
|
|
38622
|
+
} catch {
|
|
38623
|
+
return "stopped";
|
|
38624
|
+
}
|
|
38625
|
+
}
|
|
38626
|
+
function promptOf2(start2) {
|
|
38627
|
+
if (start2.skill)
|
|
38628
|
+
return `/${start2.skill.name}${start2.skill.args ? ` ${start2.skill.args}` : ""}`;
|
|
38629
|
+
return start2.text ?? null;
|
|
38630
|
+
}
|
|
38237
38631
|
function cardsWaitOnPerson(handlers, work) {
|
|
38238
38632
|
const waitingOnPerson = (card) => async (...args2) => {
|
|
38239
38633
|
const resume = work.waitOnPerson();
|
|
@@ -38250,8 +38644,8 @@ var require_segmentDriver = __commonJS({
|
|
|
38250
38644
|
onAskUser: waitingOnPerson(handlers.onAskUser)
|
|
38251
38645
|
};
|
|
38252
38646
|
}
|
|
38253
|
-
async function driveTurnToOutcome(transport, start2, handlers, opts) {
|
|
38254
|
-
|
|
38647
|
+
async function driveTurnToOutcome(transport, start2, handlers, opts, trail, closing) {
|
|
38648
|
+
trail.orionResources = start2.getOrionResources ? await start2.getOrionResources() : void 0;
|
|
38255
38649
|
void (0, scratchpad_js_1.ensureSessionScratchDir)({
|
|
38256
38650
|
sessionId: start2.sessionId,
|
|
38257
38651
|
workspaceRoot: (0, pathResolution_js_1.effectiveWorkspaceRoot)(start2.routing?.workspaceRoot ?? null)
|
|
@@ -38262,7 +38656,6 @@ var require_segmentDriver = __commonJS({
|
|
|
38262
38656
|
let transportRetried = false;
|
|
38263
38657
|
let busyAttempts = 0;
|
|
38264
38658
|
let busyWaitedMs = 0;
|
|
38265
|
-
const stoppedDuringWait = () => handlers.signal?.aborted === true || handlers.isCancelRequested?.() === true;
|
|
38266
38659
|
for (; ; ) {
|
|
38267
38660
|
let sawEvent = false;
|
|
38268
38661
|
let drained = [];
|
|
@@ -38275,7 +38668,7 @@ var require_segmentDriver = __commonJS({
|
|
|
38275
38668
|
}
|
|
38276
38669
|
};
|
|
38277
38670
|
try {
|
|
38278
|
-
return await driveTurnAttempt(transport, attemptStart, handlers,
|
|
38671
|
+
return await driveTurnAttempt(transport, attemptStart, handlers, trail, closing, () => {
|
|
38279
38672
|
sawEvent = true;
|
|
38280
38673
|
}, {
|
|
38281
38674
|
silenceMs: opts?.streamSilenceMs ?? exports2.STREAM_SILENCE_TIMEOUT_MS,
|
|
@@ -38283,7 +38676,7 @@ var require_segmentDriver = __commonJS({
|
|
|
38283
38676
|
}, busy !== null, opts?.mirror);
|
|
38284
38677
|
} catch (error) {
|
|
38285
38678
|
if (error instanceof SessionBusyRefusal) {
|
|
38286
|
-
if (busy !== null && busyWaitedMs < busy.maxWaitMs && !
|
|
38679
|
+
if (busy !== null && busyWaitedMs < busy.maxWaitMs && !stopRequested(handlers)) {
|
|
38287
38680
|
requeue = drained;
|
|
38288
38681
|
const delayMs = sessionBusyDelayMs(busyAttempts, busy);
|
|
38289
38682
|
busyAttempts += 1;
|
|
@@ -38295,7 +38688,7 @@ var require_segmentDriver = __commonJS({
|
|
|
38295
38688
|
setTimeout(resolve5, delayMs);
|
|
38296
38689
|
});
|
|
38297
38690
|
busyWaitedMs += delayMs;
|
|
38298
|
-
if (
|
|
38691
|
+
if (stopRequested(handlers))
|
|
38299
38692
|
throw new DOMException("turn aborted", "AbortError");
|
|
38300
38693
|
continue;
|
|
38301
38694
|
}
|
|
@@ -38442,6 +38835,19 @@ var require_segmentDriver = __commonJS({
|
|
|
38442
38835
|
};
|
|
38443
38836
|
return { event: "turn_error", session_id: sessionId, timestamp: Date.now() / 1e3, data };
|
|
38444
38837
|
}
|
|
38838
|
+
function endsWithNothing(ev, trail) {
|
|
38839
|
+
if (ev.event !== "turn_error")
|
|
38840
|
+
return false;
|
|
38841
|
+
const data = ev.data;
|
|
38842
|
+
if (Array.isArray(data.messages))
|
|
38843
|
+
return false;
|
|
38844
|
+
return data.error === exports2.TURN_CANCELLED_ERROR || trail.contentSeen;
|
|
38845
|
+
}
|
|
38846
|
+
async function withWhatTheTurnLeft(terminal, closing) {
|
|
38847
|
+
const stopped = terminal.data.error === exports2.TURN_CANCELLED_ERROR;
|
|
38848
|
+
const left = await closing(stopped ? "stopped" : "failed");
|
|
38849
|
+
return left === void 0 ? terminal : { ...terminal, data: { ...terminal.data, messages: left.messages } };
|
|
38850
|
+
}
|
|
38445
38851
|
function stoppedTerminal(sessionId) {
|
|
38446
38852
|
return {
|
|
38447
38853
|
event: "turn_error",
|
|
@@ -38460,11 +38866,10 @@ var require_segmentDriver = __commonJS({
|
|
|
38460
38866
|
const plan = file ? (0, planFile_js_1.readPlanFileSync)(file.path) : null;
|
|
38461
38867
|
return plan === null ? ev : { ...ev, data: { ...ev.data, plan } };
|
|
38462
38868
|
}
|
|
38463
|
-
async function driveTurnAttempt(transport, start2, handlers,
|
|
38869
|
+
async function driveTurnAttempt(transport, start2, handlers, trail, closing, markEvent, caps, busyRetry, mirror) {
|
|
38464
38870
|
let resumeToken;
|
|
38465
38871
|
let boundaryResult;
|
|
38466
38872
|
let first = true;
|
|
38467
|
-
let contentSeen = false;
|
|
38468
38873
|
const workspaceRoot = start2.routing?.workspaceRoot;
|
|
38469
38874
|
let applyChain = Promise.resolve();
|
|
38470
38875
|
const agentTouchedRoots = /* @__PURE__ */ new Set();
|
|
@@ -38483,7 +38888,7 @@ var require_segmentDriver = __commonJS({
|
|
|
38483
38888
|
handlers.onEvent(ev);
|
|
38484
38889
|
return;
|
|
38485
38890
|
}
|
|
38486
|
-
|
|
38891
|
+
trail.observe(ev);
|
|
38487
38892
|
markEvent();
|
|
38488
38893
|
if (ev.event === "client_write") {
|
|
38489
38894
|
const d2 = ev.data;
|
|
@@ -38528,10 +38933,12 @@ var require_segmentDriver = __commonJS({
|
|
|
38528
38933
|
throw new DOMException("turn aborted", "AbortError");
|
|
38529
38934
|
}
|
|
38530
38935
|
const openingSegment = first;
|
|
38531
|
-
|
|
38936
|
+
trail.segmentStarts(boundaryResult);
|
|
38937
|
+
const body2 = buildSegmentBody(start2, first ? "opening" : { resumeToken, boundaryResult }, trail);
|
|
38532
38938
|
first = false;
|
|
38533
38939
|
handlers.onPhaseChange?.("stream");
|
|
38534
38940
|
let terminal;
|
|
38941
|
+
let held;
|
|
38535
38942
|
let markTerminal;
|
|
38536
38943
|
const terminalSeen = new Promise((resolve5) => {
|
|
38537
38944
|
markTerminal = resolve5;
|
|
@@ -38540,11 +38947,19 @@ var require_segmentDriver = __commonJS({
|
|
|
38540
38947
|
let busyRefusal;
|
|
38541
38948
|
const segmentOnEvent = (ev) => {
|
|
38542
38949
|
watchdog.feed();
|
|
38543
|
-
if (busyRetry && openingSegment && !contentSeen && busyRefusal === void 0 && ev.event === "turn_error" && isSessionBusyRefusal(ev.data)) {
|
|
38950
|
+
if (busyRetry && openingSegment && !trail.contentSeen && busyRefusal === void 0 && ev.event === "turn_error" && isSessionBusyRefusal(ev.data)) {
|
|
38544
38951
|
busyRefusal = ev;
|
|
38545
38952
|
markTerminal();
|
|
38546
38953
|
return;
|
|
38547
38954
|
}
|
|
38955
|
+
if (!terminal && held === void 0 && endsWithNothing(ev, trail)) {
|
|
38956
|
+
held = ev;
|
|
38957
|
+
markTerminal();
|
|
38958
|
+
return;
|
|
38959
|
+
}
|
|
38960
|
+
deliver(ev);
|
|
38961
|
+
};
|
|
38962
|
+
const deliver = (ev) => {
|
|
38548
38963
|
onEvent(ev);
|
|
38549
38964
|
if (!terminal && (ev.event === "turn_complete" || ev.event === "turn_error")) {
|
|
38550
38965
|
terminal = ev;
|
|
@@ -38571,6 +38986,14 @@ var require_segmentDriver = __commonJS({
|
|
|
38571
38986
|
});
|
|
38572
38987
|
throw new SessionBusyRefusal(busyRefusal);
|
|
38573
38988
|
}
|
|
38989
|
+
if (held !== void 0 && !handlers.signal?.aborted) {
|
|
38990
|
+
watchdog.settle();
|
|
38991
|
+
void streamDone.catch(() => {
|
|
38992
|
+
});
|
|
38993
|
+
const whole = await withWhatTheTurnLeft(held, closing);
|
|
38994
|
+
deliver(whole);
|
|
38995
|
+
return { kind: "turn_error", event: whole };
|
|
38996
|
+
}
|
|
38574
38997
|
if (terminal) {
|
|
38575
38998
|
watchdog.settle();
|
|
38576
38999
|
void streamDone.catch(() => {
|
|
@@ -38582,8 +39005,8 @@ var require_segmentDriver = __commonJS({
|
|
|
38582
39005
|
watchdog.settle();
|
|
38583
39006
|
void streamDone.catch(() => {
|
|
38584
39007
|
});
|
|
38585
|
-
const synthetic = killTerminal(start2.sessionId, kill, watchdog.step(), (0, keepAwake_js_1.sleptDuring)(watchdog.armedAt()));
|
|
38586
|
-
|
|
39008
|
+
const synthetic = await withWhatTheTurnLeft(killTerminal(start2.sessionId, kill, watchdog.step(), (0, keepAwake_js_1.sleptDuring)(watchdog.armedAt())), closing);
|
|
39009
|
+
deliver(synthetic);
|
|
38587
39010
|
return { kind: "turn_error", event: synthetic };
|
|
38588
39011
|
}
|
|
38589
39012
|
if (handlers.signal?.aborted) {
|
|
@@ -38603,17 +39026,19 @@ var require_segmentDriver = __commonJS({
|
|
|
38603
39026
|
handlers.onPhaseChange?.("boundary");
|
|
38604
39027
|
resumeToken = readResumeToken(events);
|
|
38605
39028
|
if (resumeToken === void 0) {
|
|
38606
|
-
if (!events.some((e) => BOUNDARY_EVENTS.has(e.event))) {
|
|
39029
|
+
if (!events.some((e) => boundaryEvents_js_1.BOUNDARY_EVENTS.has(e.event))) {
|
|
38607
39030
|
throw new transportError_js_2.TransportError("segment stream ended without a terminal \u2014 the connection was cut mid-turn");
|
|
38608
39031
|
}
|
|
38609
39032
|
throw new Error("boundary segment carried no resume_token \u2014 cannot resume the turn");
|
|
38610
39033
|
}
|
|
39034
|
+
trail.parkedAt(resumeToken);
|
|
38611
39035
|
const tokenSaving = start2.routing?.tokenSaving;
|
|
38612
39036
|
const toolContext = tokenSaving === void 0 && handlers.signal === void 0 ? void 0 : {
|
|
38613
39037
|
...tokenSaving !== void 0 ? { tokenSaving } : {},
|
|
38614
39038
|
...handlers.signal !== void 0 ? { signal: handlers.signal } : {}
|
|
38615
39039
|
};
|
|
38616
|
-
boundaryResult = await untilStopped(resolveBoundary(events, handlers, start2.sessionId, toolContext), handlers.signal);
|
|
39040
|
+
boundaryResult = await untilStopped(resolveBoundary(events, handlers, start2.sessionId, toolContext, trail), handlers.signal);
|
|
39041
|
+
trail.answeredWith(boundaryResult);
|
|
38617
39042
|
}
|
|
38618
39043
|
}
|
|
38619
39044
|
function untilStopped(work, signal) {
|
|
@@ -38634,7 +39059,8 @@ var require_segmentDriver = __commonJS({
|
|
|
38634
39059
|
});
|
|
38635
39060
|
});
|
|
38636
39061
|
}
|
|
38637
|
-
function buildSegmentBody(start2,
|
|
39062
|
+
function buildSegmentBody(start2, segment, trail) {
|
|
39063
|
+
const orionResources = trail.orionResources;
|
|
38638
39064
|
const body2 = {
|
|
38639
39065
|
// Host-supplied extras ride first so the canonical fields below always win
|
|
38640
39066
|
// a key collision (rule: the driver owns the wire shape, extras only add).
|
|
@@ -38683,9 +39109,9 @@ var require_segmentDriver = __commonJS({
|
|
|
38683
39109
|
const repoIdentity = (0, repoIdentity_js_1.repoIdentityForSegment)(start2.routing?.workspaceRoot);
|
|
38684
39110
|
if (repoIdentity !== void 0)
|
|
38685
39111
|
Object.assign(body2, repoIdentity);
|
|
38686
|
-
const
|
|
38687
|
-
if (
|
|
38688
|
-
body2.client_state =
|
|
39112
|
+
const clientState = clientStateForSegment(start2.getClientState?.(), trail.plan);
|
|
39113
|
+
if (clientState !== void 0)
|
|
39114
|
+
body2.client_state = clientState;
|
|
38689
39115
|
const fileHistory = start2.getFileHistoryManifest?.();
|
|
38690
39116
|
if (fileHistory && fileHistory.snapshots.length > 0)
|
|
38691
39117
|
body2.file_history = fileHistory;
|
|
@@ -38701,7 +39127,8 @@ var require_segmentDriver = __commonJS({
|
|
|
38701
39127
|
if (attention && (attention.active || attention.open.length > 0 || attention.touched.length > 0)) {
|
|
38702
39128
|
body2.ovault_attention = attention;
|
|
38703
39129
|
}
|
|
38704
|
-
|
|
39130
|
+
const closing = segment === "opening" ? void 0 : segment.closing;
|
|
39131
|
+
if (segment === "opening") {
|
|
38705
39132
|
if (start2.skill) {
|
|
38706
39133
|
body2.skill = start2.skill;
|
|
38707
39134
|
} else {
|
|
@@ -38710,12 +39137,19 @@ var require_segmentDriver = __commonJS({
|
|
|
38710
39137
|
if (start2.attachments && start2.attachments.length > 0)
|
|
38711
39138
|
body2.attachments = start2.attachments;
|
|
38712
39139
|
} else {
|
|
38713
|
-
body2.resume_token = resumeToken;
|
|
38714
|
-
if (boundaryResult !== void 0)
|
|
38715
|
-
body2.boundary_result = boundaryResult;
|
|
38716
|
-
|
|
38717
|
-
|
|
38718
|
-
|
|
39140
|
+
body2.resume_token = segment.resumeToken;
|
|
39141
|
+
if (segment.boundaryResult !== void 0)
|
|
39142
|
+
body2.boundary_result = segment.boundaryResult;
|
|
39143
|
+
if (closing !== void 0) {
|
|
39144
|
+
body2.abandoned = true;
|
|
39145
|
+
if (closing === "recovery")
|
|
39146
|
+
body2.recovery = true;
|
|
39147
|
+
}
|
|
39148
|
+
}
|
|
39149
|
+
const queued = closing !== void 0 ? trail.steering : start2.drainQueuedInput?.() ?? [];
|
|
39150
|
+
if (closing === void 0)
|
|
39151
|
+
trail.steeredWith(queued);
|
|
39152
|
+
if (queued.length > 0)
|
|
38719
39153
|
body2.queued_input = queued.map(queuedInput_js_1.queuedInputWire);
|
|
38720
39154
|
const relayDepth = start2.peerRelayDepth?.();
|
|
38721
39155
|
if (relayDepth !== void 0)
|
|
@@ -38728,6 +39162,11 @@ var require_segmentDriver = __commonJS({
|
|
|
38728
39162
|
}
|
|
38729
39163
|
return (0, wellFormed_js_1.toWellFormedJsonDeep)(body2);
|
|
38730
39164
|
}
|
|
39165
|
+
function clientStateForSegment(state, announced) {
|
|
39166
|
+
if (announced === void 0)
|
|
39167
|
+
return state;
|
|
39168
|
+
return state === void 0 ? { plan: announced } : { ...state, plan: announced };
|
|
39169
|
+
}
|
|
38731
39170
|
function applyRouting(body2, routing) {
|
|
38732
39171
|
if (!routing)
|
|
38733
39172
|
return;
|
|
@@ -38772,15 +39211,13 @@ var require_segmentDriver = __commonJS({
|
|
|
38772
39211
|
}
|
|
38773
39212
|
function readResumeToken(events) {
|
|
38774
39213
|
for (const e of events) {
|
|
38775
|
-
|
|
38776
|
-
|
|
38777
|
-
|
|
38778
|
-
return t;
|
|
38779
|
-
}
|
|
39214
|
+
const token = (0, boundaryEvents_js_1.resumeTokenOf)(e);
|
|
39215
|
+
if (token !== void 0)
|
|
39216
|
+
return token;
|
|
38780
39217
|
}
|
|
38781
39218
|
return void 0;
|
|
38782
39219
|
}
|
|
38783
|
-
async function resolveBoundary(events, handlers, sessionId, toolContext) {
|
|
39220
|
+
async function resolveBoundary(events, handlers, sessionId, toolContext, trail) {
|
|
38784
39221
|
const hookReqs = events.filter((e) => e.event === "hook_request");
|
|
38785
39222
|
if (hookReqs.length > 0) {
|
|
38786
39223
|
const results = {};
|
|
@@ -38827,7 +39264,9 @@ var require_segmentDriver = __commonJS({
|
|
|
38827
39264
|
}
|
|
38828
39265
|
const toolReqs = events.filter((e) => e.event === "tool_request");
|
|
38829
39266
|
if (toolReqs.length > 0) {
|
|
38830
|
-
const
|
|
39267
|
+
const batch = toolReqs.map((e) => e.data);
|
|
39268
|
+
trail.runsTools(batch);
|
|
39269
|
+
const results = await runToolBatch(batch, (req) => trail.watch(req, handlers.runTool(req, sessionId, toolContext)), handlers.signal);
|
|
38831
39270
|
if (handlers.signal?.aborted)
|
|
38832
39271
|
throw new DOMException("turn aborted", "AbortError");
|
|
38833
39272
|
for (const result of results)
|
|
@@ -50954,6 +51393,7 @@ var require_agentManager = __commonJS({
|
|
|
50954
51393
|
} });
|
|
50955
51394
|
var agentNarration_2 = require_agentNarration();
|
|
50956
51395
|
var askAnswers_js_1 = require_askAnswers();
|
|
51396
|
+
var interruptedTurn_js_1 = require_interruptedTurn();
|
|
50957
51397
|
var awaitWake_js_1 = require_awaitWake();
|
|
50958
51398
|
var agentDefs_js_1 = require_agentDefs();
|
|
50959
51399
|
var dosePolicy_js_1 = require_dosePolicy();
|
|
@@ -51606,6 +52046,7 @@ ${(0, agentNarration_2.lastChars)(entry.partialText.trim(), 4e3)}`;
|
|
|
51606
52046
|
async runChild(entry, opts) {
|
|
51607
52047
|
let outcome;
|
|
51608
52048
|
let failure;
|
|
52049
|
+
let left;
|
|
51609
52050
|
try {
|
|
51610
52051
|
const start2 = this.childSegmentStart(entry, opts);
|
|
51611
52052
|
const handlers = this.childHandlers(entry);
|
|
@@ -51613,9 +52054,10 @@ ${(0, agentNarration_2.lastChars)(entry.partialText.trim(), 4e3)}`;
|
|
|
51613
52054
|
transportRetry: {}
|
|
51614
52055
|
});
|
|
51615
52056
|
} catch (e) {
|
|
52057
|
+
left = (0, interruptedTurn_js_1.interruptedTurnOf)(e);
|
|
51616
52058
|
failure = entry.status === "stopped" || entry.status === "lost" ? void 0 : e instanceof Error ? e.message : String(e);
|
|
51617
52059
|
}
|
|
51618
|
-
await this.settleChild(entry, outcome, failure);
|
|
52060
|
+
await this.settleChild(entry, outcome, failure, left);
|
|
51619
52061
|
}
|
|
51620
52062
|
childSegmentStart(entry, opts) {
|
|
51621
52063
|
const { def, routing } = opts;
|
|
@@ -51765,7 +52207,7 @@ When done, reply with your findings \u2014 your FINAL MESSAGE is your report and
|
|
|
51765
52207
|
* the worktree decision and `reportText` are final — a consumer that
|
|
51766
52208
|
* observes a terminal status (agent_check, dashboards, harnesses polling
|
|
51767
52209
|
* the registry) must never see half-settled terminal state. */
|
|
51768
|
-
async settleChild(entry, outcome, failure) {
|
|
52210
|
+
async settleChild(entry, outcome, failure, left) {
|
|
51769
52211
|
const wasStopped = entry.status === "stopped" || entry.status === "lost";
|
|
51770
52212
|
const terminal = wasStopped ? entry.status : outcome?.kind === "turn_complete" ? "finished" : "failed";
|
|
51771
52213
|
let summary;
|
|
@@ -51776,18 +52218,22 @@ When done, reply with your findings \u2014 your FINAL MESSAGE is your report and
|
|
|
51776
52218
|
entry.costUsd += typeof data.cost_usd === "number" ? data.cost_usd : 0;
|
|
51777
52219
|
summary = typeof data.assistant_message === "string" && data.assistant_message.trim() || entry.partialText.trim() || "(Sub-agent completed but returned no output.)";
|
|
51778
52220
|
success = !wasStopped;
|
|
51779
|
-
} else
|
|
51780
|
-
|
|
52221
|
+
} else {
|
|
52222
|
+
const transcript = outcome ? outcome.event.data.messages : left?.messages;
|
|
52223
|
+
if (Array.isArray(transcript))
|
|
52224
|
+
entry.transcript = transcript;
|
|
52225
|
+
if (wasStopped) {
|
|
52226
|
+
summary = entry.partialText.trim() ? `Stopped before finishing. Partial result:
|
|
51781
52227
|
|
|
51782
52228
|
${entry.partialText.trim()}` : "Stopped before producing any output.";
|
|
51783
|
-
|
|
51784
|
-
|
|
51785
|
-
|
|
51786
|
-
summary = entry.partialText.trim() ? `${error}
|
|
52229
|
+
} else {
|
|
52230
|
+
const error = failure ?? String(outcome?.event.data?.error ?? "turn failed");
|
|
52231
|
+
summary = entry.partialText.trim() ? `${error}
|
|
51787
52232
|
|
|
51788
52233
|
Partial result before the failure:
|
|
51789
52234
|
|
|
51790
52235
|
${entry.partialText.trim()}` : error;
|
|
52236
|
+
}
|
|
51791
52237
|
success = false;
|
|
51792
52238
|
}
|
|
51793
52239
|
const worktreeNote = await this.cleanupWorktree(entry);
|
|
@@ -62379,20 +62825,13 @@ var require_flushGate = __commonJS({
|
|
|
62379
62825
|
peek() {
|
|
62380
62826
|
return this.queue;
|
|
62381
62827
|
}
|
|
62382
|
-
/** Close the gate and hand back the queued items
|
|
62828
|
+
/** Close the gate and hand back the queued items IN ORDER. */
|
|
62383
62829
|
open() {
|
|
62384
62830
|
this.armed = false;
|
|
62385
62831
|
const items = this.queue;
|
|
62386
62832
|
this.queue = [];
|
|
62387
62833
|
return items;
|
|
62388
62834
|
}
|
|
62389
|
-
/** Permanent close: discard and report how many items were lost. */
|
|
62390
|
-
drop() {
|
|
62391
|
-
this.armed = false;
|
|
62392
|
-
const lost = this.queue.length;
|
|
62393
|
-
this.queue = [];
|
|
62394
|
-
return lost;
|
|
62395
|
-
}
|
|
62396
62835
|
};
|
|
62397
62836
|
exports2.FlushGate = FlushGate;
|
|
62398
62837
|
}
|
|
@@ -62519,6 +62958,7 @@ var require_mirror = __commonJS({
|
|
|
62519
62958
|
// observes every event before this check.
|
|
62520
62959
|
"tool_input_delta"
|
|
62521
62960
|
]);
|
|
62961
|
+
var ACK_KINDS = /* @__PURE__ */ new Set(["rc_ack", "rc_permission_resolved"]);
|
|
62522
62962
|
function coalesceInto(batch, event, n) {
|
|
62523
62963
|
const last = batch[batch.length - 1];
|
|
62524
62964
|
if (event.event === "thinking_delta") {
|
|
@@ -62615,19 +63055,27 @@ var require_mirror = __commonJS({
|
|
|
62615
63055
|
* and its ack must land regardless — the buffered channel replays it on attach. */
|
|
62616
63056
|
emitControl(event) {
|
|
62617
63057
|
if (this.phase === "dormant") {
|
|
62618
|
-
this.
|
|
62619
|
-
this.deps.reportOutcome({
|
|
62620
|
-
kind: "rc_control_publish_failed",
|
|
62621
|
-
session_id: this.sessionId,
|
|
62622
|
-
error: String(error)
|
|
62623
|
-
});
|
|
62624
|
-
}));
|
|
63058
|
+
this.publishDirect([event]);
|
|
62625
63059
|
return;
|
|
62626
63060
|
}
|
|
62627
63061
|
if (this.gate.enqueue(event))
|
|
62628
63062
|
return;
|
|
62629
63063
|
this.enqueueLive(event);
|
|
62630
63064
|
}
|
|
63065
|
+
/** Publish outside the batch — sequenced through the SAME chain as backfills and flushes,
|
|
63066
|
+
* deliberately NOT generation-fenced (an ack must land even across a mirror reset). A
|
|
63067
|
+
* detached fire-and-forget POST here races a backfill that starts a beat later, and the
|
|
63068
|
+
* gateway stamps order by ARRIVAL: the losing interleaving renders a user's prompt AFTER
|
|
63069
|
+
* the answer it caused. */
|
|
63070
|
+
publishDirect(events) {
|
|
63071
|
+
this.chain = this.chain.then(() => this.deps.publish(events).catch((error) => {
|
|
63072
|
+
this.deps.reportOutcome({
|
|
63073
|
+
kind: "rc_control_publish_failed",
|
|
63074
|
+
session_id: this.sessionId,
|
|
63075
|
+
error: String(error)
|
|
63076
|
+
});
|
|
63077
|
+
}));
|
|
63078
|
+
}
|
|
62631
63079
|
/** A viewer attached (the instant signal). `backfill` is the viewer's word on what it
|
|
62632
63080
|
* needs: `true` (every phone before the gateway-held transcript, and any signal that
|
|
62633
63081
|
* does not say) earns a fresh backfill — while LIVE too, a re-attaching phone's state
|
|
@@ -62815,17 +63263,9 @@ var require_mirror = __commonJS({
|
|
|
62815
63263
|
clearTimeout(this.timer);
|
|
62816
63264
|
this.timer = null;
|
|
62817
63265
|
}
|
|
62818
|
-
const
|
|
62819
|
-
const lostBatch = this.batch.length;
|
|
63266
|
+
const held = [...this.gate.open(), ...this.batch];
|
|
62820
63267
|
this.batch = [];
|
|
62821
|
-
|
|
62822
|
-
this.deps.reportOutcome({
|
|
62823
|
-
kind: "rc_mirror_dropped",
|
|
62824
|
-
session_id: this.sessionId,
|
|
62825
|
-
reason,
|
|
62826
|
-
events: lostGate + lostBatch
|
|
62827
|
-
});
|
|
62828
|
-
}
|
|
63268
|
+
this.salvageAcks(held, reason);
|
|
62829
63269
|
}
|
|
62830
63270
|
startBackfill() {
|
|
62831
63271
|
this.generation += 1;
|
|
@@ -62934,12 +63374,7 @@ var require_mirror = __commonJS({
|
|
|
62934
63374
|
const generation = this.generation;
|
|
62935
63375
|
this.chain = this.chain.then(async () => {
|
|
62936
63376
|
if (generation !== this.generation) {
|
|
62937
|
-
this.
|
|
62938
|
-
kind: "rc_mirror_dropped",
|
|
62939
|
-
session_id: this.sessionId,
|
|
62940
|
-
reason: "superseded_in_flight",
|
|
62941
|
-
events: events.length
|
|
62942
|
-
});
|
|
63377
|
+
this.salvageAcks(events, "superseded_in_flight");
|
|
62943
63378
|
return;
|
|
62944
63379
|
}
|
|
62945
63380
|
try {
|
|
@@ -62953,10 +63388,28 @@ var require_mirror = __commonJS({
|
|
|
62953
63388
|
events: events.length,
|
|
62954
63389
|
error: String(error)
|
|
62955
63390
|
});
|
|
63391
|
+
this.salvageAcks(events);
|
|
62956
63392
|
this.goDormant("publish_failed");
|
|
62957
63393
|
}
|
|
62958
63394
|
});
|
|
62959
63395
|
}
|
|
63396
|
+
/** Events that will not reach the wire the way they were meant to: the acks among them are
|
|
63397
|
+
* published on their own (`ACK_KINDS`), the rest is counted as loss under `reason` — or
|
|
63398
|
+
* left to the caller's own accounting when no reason is given. */
|
|
63399
|
+
salvageAcks(events, reason) {
|
|
63400
|
+
const acks = events.filter((event) => ACK_KINDS.has(event.event));
|
|
63401
|
+
if (acks.length > 0)
|
|
63402
|
+
this.publishDirect(acks);
|
|
63403
|
+
const lost = events.length - acks.length;
|
|
63404
|
+
if (reason !== void 0 && lost > 0) {
|
|
63405
|
+
this.deps.reportOutcome({
|
|
63406
|
+
kind: "rc_mirror_dropped",
|
|
63407
|
+
session_id: this.sessionId,
|
|
63408
|
+
reason,
|
|
63409
|
+
events: lost
|
|
63410
|
+
});
|
|
63411
|
+
}
|
|
63412
|
+
}
|
|
62960
63413
|
};
|
|
62961
63414
|
exports2.SessionMirror = SessionMirror;
|
|
62962
63415
|
function chunk(items, size) {
|
|
@@ -63106,6 +63559,17 @@ var require_hostBridge = __commonJS({
|
|
|
63106
63559
|
var mirror_js_1 = require_mirror();
|
|
63107
63560
|
var rcSettings_js_1 = require_rcSettings();
|
|
63108
63561
|
var types_js_1 = require_types();
|
|
63562
|
+
function mailboxStampOf(event) {
|
|
63563
|
+
const data = event.data;
|
|
63564
|
+
const stamp = data?.mailbox;
|
|
63565
|
+
if (typeof stamp !== "object" || stamp === null)
|
|
63566
|
+
return void 0;
|
|
63567
|
+
const { origin, seq } = stamp;
|
|
63568
|
+
if (typeof origin !== "string" || origin === "" || typeof seq !== "number")
|
|
63569
|
+
return void 0;
|
|
63570
|
+
return { origin, seq };
|
|
63571
|
+
}
|
|
63572
|
+
var MAILBOX_ORIGINS_MAX = 32;
|
|
63109
63573
|
function isFenceRefusal(message) {
|
|
63110
63574
|
const normalized = message.toLowerCase().replace(/[_-]/g, " ");
|
|
63111
63575
|
return normalized.includes("stale epoch") || normalized.includes("not registered");
|
|
@@ -63204,6 +63668,9 @@ var require_hostBridge = __commonJS({
|
|
|
63204
63668
|
const announced = /* @__PURE__ */ new Set();
|
|
63205
63669
|
let beatWaiters = [];
|
|
63206
63670
|
let mailboxCursor;
|
|
63671
|
+
let streamGeneration;
|
|
63672
|
+
const mailboxOrigins = /* @__PURE__ */ new Map();
|
|
63673
|
+
let streamBlockedSince = null;
|
|
63207
63674
|
let heartbeatTimer = null;
|
|
63208
63675
|
let debounceTimer = null;
|
|
63209
63676
|
let lastTickAt = null;
|
|
@@ -63506,12 +63973,47 @@ var require_hostBridge = __commonJS({
|
|
|
63506
63973
|
if (!watchFramed && epoch !== null) {
|
|
63507
63974
|
watchFramed = true;
|
|
63508
63975
|
linkState = "seen";
|
|
63976
|
+
if (streamBlockedSince !== null) {
|
|
63977
|
+
report({ kind: "rc_stream_restored", blocked_ms: clock() - streamBlockedSince });
|
|
63978
|
+
streamBlockedSince = null;
|
|
63979
|
+
}
|
|
63509
63980
|
setStatus({ phase: "connected" });
|
|
63510
63981
|
}
|
|
63511
63982
|
const event = raw;
|
|
63983
|
+
if (event.event === "stream_status") {
|
|
63984
|
+
const generation2 = event.data?.generation;
|
|
63985
|
+
if (typeof generation2 === "string" && generation2 !== "" && generation2 !== streamGeneration) {
|
|
63986
|
+
if (streamGeneration !== void 0)
|
|
63987
|
+
mailboxCursor = void 0;
|
|
63988
|
+
streamGeneration = generation2;
|
|
63989
|
+
}
|
|
63990
|
+
}
|
|
63512
63991
|
if (typeof event.seq === "number" && (mailboxCursor === void 0 || event.seq > mailboxCursor)) {
|
|
63513
63992
|
mailboxCursor = event.seq;
|
|
63514
63993
|
}
|
|
63994
|
+
applyControlFrame(event);
|
|
63995
|
+
}
|
|
63996
|
+
function applyControlFrame(event) {
|
|
63997
|
+
const stamp = mailboxStampOf(event);
|
|
63998
|
+
if (stamp !== void 0) {
|
|
63999
|
+
const known = mailboxOrigins.get(stamp.origin);
|
|
64000
|
+
mailboxOrigins.set(stamp.origin, {
|
|
64001
|
+
seq: Math.max(stamp.seq, known?.seq ?? 0),
|
|
64002
|
+
seenAtMs: clock()
|
|
64003
|
+
});
|
|
64004
|
+
if (mailboxOrigins.size > MAILBOX_ORIGINS_MAX) {
|
|
64005
|
+
let oldest;
|
|
64006
|
+
let oldestAt = Number.POSITIVE_INFINITY;
|
|
64007
|
+
for (const [origin, { seenAtMs }] of mailboxOrigins) {
|
|
64008
|
+
if (seenAtMs < oldestAt) {
|
|
64009
|
+
oldest = origin;
|
|
64010
|
+
oldestAt = seenAtMs;
|
|
64011
|
+
}
|
|
64012
|
+
}
|
|
64013
|
+
if (oldest !== void 0)
|
|
64014
|
+
mailboxOrigins.delete(oldest);
|
|
64015
|
+
}
|
|
64016
|
+
}
|
|
63515
64017
|
if (event.event === "rc_command") {
|
|
63516
64018
|
const stamped = event.data.epoch;
|
|
63517
64019
|
if (typeof stamped === "number" && epoch !== null && stamped !== epoch) {
|
|
@@ -63536,6 +64038,22 @@ var require_hostBridge = __commonJS({
|
|
|
63536
64038
|
}
|
|
63537
64039
|
}
|
|
63538
64040
|
}
|
|
64041
|
+
function mailboxCursorsForBeat() {
|
|
64042
|
+
const cursors = {};
|
|
64043
|
+
for (const [origin, { seq }] of mailboxOrigins)
|
|
64044
|
+
cursors[origin] = seq;
|
|
64045
|
+
return cursors;
|
|
64046
|
+
}
|
|
64047
|
+
function applyMailbox(mailbox) {
|
|
64048
|
+
if (!Array.isArray(mailbox) || mailbox.length === 0)
|
|
64049
|
+
return;
|
|
64050
|
+
const frames = mailbox.filter((frame) => typeof frame === "object" && frame !== null && typeof frame.event === "string");
|
|
64051
|
+
if (frames.length === 0)
|
|
64052
|
+
return;
|
|
64053
|
+
report({ kind: "rc_mailbox_read", frames: frames.length });
|
|
64054
|
+
for (const frame of frames)
|
|
64055
|
+
applyControlFrame(frame);
|
|
64056
|
+
}
|
|
63539
64057
|
function teardownChannel() {
|
|
63540
64058
|
controlWatch?.dispose();
|
|
63541
64059
|
controlWatch = null;
|
|
@@ -63546,9 +64064,23 @@ var require_hostBridge = __commonJS({
|
|
|
63546
64064
|
watchFramed = false;
|
|
63547
64065
|
watchOpenedAtMs = clock();
|
|
63548
64066
|
controlWatch = deps2.bridge.watchSession(channel, onControlEvent, {
|
|
63549
|
-
since: () => mailboxCursor
|
|
64067
|
+
since: () => mailboxCursor,
|
|
64068
|
+
generation: () => streamGeneration
|
|
63550
64069
|
});
|
|
63551
64070
|
}
|
|
64071
|
+
function judgeStream(linked) {
|
|
64072
|
+
if (watchFramed || linked === void 0 || controlWatch === null) {
|
|
64073
|
+
setStatus({ phase: "connected" });
|
|
64074
|
+
return;
|
|
64075
|
+
}
|
|
64076
|
+
if (watchAttaching())
|
|
64077
|
+
return;
|
|
64078
|
+
if (streamBlockedSince === null) {
|
|
64079
|
+
streamBlockedSince = clock();
|
|
64080
|
+
report({ kind: "rc_stream_blocked" });
|
|
64081
|
+
}
|
|
64082
|
+
setStatus({ phase: "stream_blocked", sinceMs: streamBlockedSince });
|
|
64083
|
+
}
|
|
63552
64084
|
function watchAttaching() {
|
|
63553
64085
|
return !watchFramed && clock() - watchOpenedAtMs < tuning.heartbeatMs / 2;
|
|
63554
64086
|
}
|
|
@@ -63863,7 +64395,11 @@ var require_hostBridge = __commonJS({
|
|
|
63863
64395
|
const result = await beatRpc("rc_heartbeat", {
|
|
63864
64396
|
host_id: hostId,
|
|
63865
64397
|
epoch: myEpoch,
|
|
63866
|
-
sessions: upserts
|
|
64398
|
+
sessions: upserts,
|
|
64399
|
+
// The heartbeat lane's two words: what this host has received off its mailbox, and
|
|
64400
|
+
// whether its stream delivers at all (what the phones are told beside this machine).
|
|
64401
|
+
mailbox_cursors: mailboxCursorsForBeat(),
|
|
64402
|
+
push_blocked: streamBlockedSince !== null
|
|
63867
64403
|
});
|
|
63868
64404
|
if (superseded())
|
|
63869
64405
|
return;
|
|
@@ -63907,8 +64443,9 @@ var require_hostBridge = __commonJS({
|
|
|
63907
64443
|
relinked = false;
|
|
63908
64444
|
linkState = "seen";
|
|
63909
64445
|
resetLinkFailures();
|
|
63910
|
-
|
|
64446
|
+
judgeStream(result.linked);
|
|
63911
64447
|
}
|
|
64448
|
+
applyMailbox(result.mailbox);
|
|
63912
64449
|
applyWatching(result.watching);
|
|
63913
64450
|
} catch (error) {
|
|
63914
64451
|
if (superseded())
|
|
@@ -64228,7 +64765,7 @@ var require_hostBridge = __commonJS({
|
|
|
64228
64765
|
tick();
|
|
64229
64766
|
},
|
|
64230
64767
|
canAnswerPermissions(sessionId) {
|
|
64231
|
-
return status.phase === "connected" && settings.enabled && sessions.has(sessionId) && !hidden(sessionId);
|
|
64768
|
+
return (status.phase === "connected" || status.phase === "stream_blocked") && settings.enabled && sessions.has(sessionId) && !hidden(sessionId);
|
|
64232
64769
|
},
|
|
64233
64770
|
status: () => status,
|
|
64234
64771
|
onStatusChange(listener) {
|
|
@@ -64541,6 +65078,13 @@ var require_statusText = __commonJS({
|
|
|
64541
65078
|
return { label: "connecting", detail: null, action: null, severity: "ok" };
|
|
64542
65079
|
case "connected":
|
|
64543
65080
|
return { label: "connected", detail: null, action: null, severity: "ok" };
|
|
65081
|
+
case "stream_blocked":
|
|
65082
|
+
return {
|
|
65083
|
+
label: "connected by heartbeat",
|
|
65084
|
+
detail: null,
|
|
65085
|
+
action: "Orion's live stream isn't reaching this machine \u2014 a proxy or VPN on this network is holding it \u2014 so your phone's messages arrive with its heartbeat, up to about twenty seconds later.",
|
|
65086
|
+
severity: "transport"
|
|
65087
|
+
};
|
|
64544
65088
|
case "reconnecting":
|
|
64545
65089
|
return { label: "reconnecting", detail: status.reason, action: null, severity: "transport" };
|
|
64546
65090
|
case "failed":
|
|
@@ -79398,7 +79942,7 @@ var require_toolExecutor = __commonJS({
|
|
|
79398
79942
|
};
|
|
79399
79943
|
}();
|
|
79400
79944
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
79401
|
-
exports2.ToolExecutor = exports2.STOPPED_COMMAND_STATUS = exports2.DETACHED_PROCESS_NOTE = exports2.DETACHED_OUTPUT_DRAIN_MS = exports2.SUBPROCESS_DEFAULT_TIMEOUT_S = exports2.UNBOUNDED_COMMAND_TIMEOUTS = exports2.DESKTOP_COMMAND_TIMEOUTS = void 0;
|
|
79945
|
+
exports2.ToolExecutor = exports2.STOPPED_WITH_TURN_NOTE = exports2.STOPPED_COMMAND_STATUS = exports2.DETACHED_PROCESS_NOTE = exports2.DETACHED_OUTPUT_DRAIN_MS = exports2.SUBPROCESS_DEFAULT_TIMEOUT_S = exports2.UNBOUNDED_COMMAND_TIMEOUTS = exports2.DESKTOP_COMMAND_TIMEOUTS = void 0;
|
|
79402
79946
|
exports2.enhancedSearchStamp = enhancedSearchStamp;
|
|
79403
79947
|
exports2.judgeSearchStamp = judgeSearchStamp;
|
|
79404
79948
|
exports2.formatErrorDiagnostics = formatErrorDiagnostics;
|
|
@@ -79780,16 +80324,50 @@ ${exports2.DETACHED_PROCESS_NOTE}`;
|
|
|
79780
80324
|
onChunk?.(note, "status");
|
|
79781
80325
|
return note;
|
|
79782
80326
|
}
|
|
79783
|
-
function endWithTurn(proc, signal) {
|
|
80327
|
+
function endWithTurn(proc, signal, onEnded) {
|
|
79784
80328
|
if (signal === void 0)
|
|
79785
80329
|
return;
|
|
79786
|
-
const stop2 = () =>
|
|
80330
|
+
const stop2 = () => {
|
|
80331
|
+
onEnded?.();
|
|
80332
|
+
void (0, processHardening_1.terminateChildTree)(proc);
|
|
80333
|
+
};
|
|
79787
80334
|
signal.addEventListener("abort", stop2, { once: true });
|
|
79788
80335
|
const release = () => signal.removeEventListener("abort", stop2);
|
|
79789
80336
|
proc.once("exit", release);
|
|
79790
80337
|
proc.once("error", release);
|
|
79791
80338
|
}
|
|
79792
80339
|
exports2.STOPPED_COMMAND_STATUS = "\n(exit null)";
|
|
80340
|
+
exports2.STOPPED_WITH_TURN_NOTE = "(the turn was stopped while this command was running \u2014 it did not finish)";
|
|
80341
|
+
var CommandStop = class {
|
|
80342
|
+
signal;
|
|
80343
|
+
ended = false;
|
|
80344
|
+
constructor(signal) {
|
|
80345
|
+
this.signal = signal;
|
|
80346
|
+
}
|
|
80347
|
+
/** End `proc` with the turn ({@link endWithTurn}). */
|
|
80348
|
+
watch(proc) {
|
|
80349
|
+
endWithTurn(proc, this.signal, () => {
|
|
80350
|
+
this.ended = true;
|
|
80351
|
+
});
|
|
80352
|
+
}
|
|
80353
|
+
/** Whether the stop landed while the command's process was alive. */
|
|
80354
|
+
get endedCommand() {
|
|
80355
|
+
return this.ended;
|
|
80356
|
+
}
|
|
80357
|
+
};
|
|
80358
|
+
var EXIT_TRAILER = /\n?(\(exit (?:null|-?\d+)\)\s*)$/;
|
|
80359
|
+
function stoppedWithTurn(result, stop2) {
|
|
80360
|
+
if (!stop2.endedCommand)
|
|
80361
|
+
return result;
|
|
80362
|
+
const trailer = EXIT_TRAILER.exec(result);
|
|
80363
|
+
if (trailer === null)
|
|
80364
|
+
return result;
|
|
80365
|
+
const printed = result.slice(0, trailer.index);
|
|
80366
|
+
const lead = printed === "" ? "" : `${printed}
|
|
80367
|
+
`;
|
|
80368
|
+
return `${lead}${exports2.STOPPED_WITH_TURN_NOTE}
|
|
80369
|
+
${trailer[1]}`;
|
|
80370
|
+
}
|
|
79793
80371
|
function openCommandCard(sink, sessionId, toolKey, command, signal) {
|
|
79794
80372
|
if (sink === null || signal?.aborted)
|
|
79795
80373
|
return { feed: void 0, close: () => void 0 };
|
|
@@ -81304,18 +81882,19 @@ exit $__orion_rc`;
|
|
|
81304
81882
|
const sandbox = this.sandboxForParams(params, sessionId);
|
|
81305
81883
|
const card = openCommandCard(params._agent_id ? null : this.termSink, sessionId, reqId, command, context.signal);
|
|
81306
81884
|
try {
|
|
81307
|
-
const
|
|
81885
|
+
const stop2 = new CommandStop(context.signal);
|
|
81886
|
+
const out2 = await this.runBash(wrapped, resolveCommandTimeoutS(params.timeout_s, this.commandTimeouts), effectiveCwd, card.feed, false, sandbox, command, stop2);
|
|
81308
81887
|
if (baseline) {
|
|
81309
81888
|
const changes = await (0, bashFileChanges_1.diffAgainstBaseline)(baseline);
|
|
81310
81889
|
if (changes.length > 0)
|
|
81311
81890
|
this.pendingBashChanges.set(reqId, changes);
|
|
81312
81891
|
}
|
|
81313
|
-
const compressed = (0, terminalOutputCompression_1.compressTerminalOutput)({
|
|
81892
|
+
const compressed = stoppedWithTurn((0, terminalOutputCompression_1.compressTerminalOutput)({
|
|
81314
81893
|
toolName: req.name,
|
|
81315
81894
|
command,
|
|
81316
81895
|
output: out2,
|
|
81317
81896
|
tokenSaving: context.tokenSaving
|
|
81318
|
-
});
|
|
81897
|
+
}), stop2);
|
|
81319
81898
|
if (sandbox && /\(exit \d+\)\s*$/.test(out2) && (0, bashSandbox_1.looksLikeSandboxDenial)(out2)) {
|
|
81320
81899
|
return compressed + bashSandbox_1.SANDBOX_RETRY_HINT;
|
|
81321
81900
|
}
|
|
@@ -81376,18 +81955,19 @@ exit $__orion_rc`;
|
|
|
81376
81955
|
const baseline = detectRoot && effectiveCwd && !inScratch ? await (0, bashFileChanges_1.captureBaseline)(effectiveCwd, detectRoot) : null;
|
|
81377
81956
|
const card = openCommandCard(params._agent_id ? null : this.termSink, sessionId, reqId, command, context.signal);
|
|
81378
81957
|
try {
|
|
81379
|
-
const
|
|
81958
|
+
const stop2 = new CommandStop(context.signal);
|
|
81959
|
+
const out2 = await this.runPowershell(wrapped, resolveCommandTimeoutS(params.timeout_s, this.commandTimeouts), effectiveCwd, card.feed, stop2);
|
|
81380
81960
|
if (baseline) {
|
|
81381
81961
|
const changes = await (0, bashFileChanges_1.diffAgainstBaseline)(baseline);
|
|
81382
81962
|
if (changes.length > 0)
|
|
81383
81963
|
this.pendingBashChanges.set(reqId, changes);
|
|
81384
81964
|
}
|
|
81385
|
-
return (0, terminalOutputCompression_1.compressTerminalOutput)({
|
|
81965
|
+
return stoppedWithTurn((0, terminalOutputCompression_1.compressTerminalOutput)({
|
|
81386
81966
|
toolName: req.name,
|
|
81387
81967
|
command,
|
|
81388
81968
|
output: out2,
|
|
81389
81969
|
tokenSaving: context.tokenSaving
|
|
81390
|
-
});
|
|
81970
|
+
}), stop2);
|
|
81391
81971
|
} finally {
|
|
81392
81972
|
card.close();
|
|
81393
81973
|
if (cwdFile) {
|
|
@@ -81815,8 +82395,8 @@ exit $__orion_rc`;
|
|
|
81815
82395
|
/** Spawn one PowerShell command. Shares `runBash`'s streaming, truncation,
|
|
81816
82396
|
* exit-marker and turn-stop conventions so the model reads the same shape of
|
|
81817
82397
|
* result from either shell; the interpreter and its flags are the only difference. */
|
|
81818
|
-
async runPowershell(command, timeoutS, cwd, onChunk,
|
|
81819
|
-
if (signal?.aborted)
|
|
82398
|
+
async runPowershell(command, timeoutS, cwd, onChunk, stop2) {
|
|
82399
|
+
if (stop2?.signal?.aborted)
|
|
81820
82400
|
throw new DOMException("turn aborted", "AbortError");
|
|
81821
82401
|
const inv = (0, powershellResolver_1.powershellInvocation)(command);
|
|
81822
82402
|
return await new Promise((resolve5, reject) => {
|
|
@@ -81840,7 +82420,7 @@ exit $__orion_rc`;
|
|
|
81840
82420
|
proc.stdout?.on("data", take);
|
|
81841
82421
|
proc.stderr?.on("data", take);
|
|
81842
82422
|
(0, processHardening_1.trackChild)(proc);
|
|
81843
|
-
|
|
82423
|
+
stop2?.watch(proc);
|
|
81844
82424
|
let timedOut = false;
|
|
81845
82425
|
const timer = timeoutS === null ? null : setTimeout(() => {
|
|
81846
82426
|
timedOut = true;
|
|
@@ -81873,8 +82453,8 @@ exit $__orion_rc`;
|
|
|
81873
82453
|
});
|
|
81874
82454
|
});
|
|
81875
82455
|
}
|
|
81876
|
-
async runBash(command, timeoutS, cwd, onChunk, partialOnTimeout = false, sandbox, label = command,
|
|
81877
|
-
if (signal?.aborted)
|
|
82456
|
+
async runBash(command, timeoutS, cwd, onChunk, partialOnTimeout = false, sandbox, label = command, stop2) {
|
|
82457
|
+
if (stop2?.signal?.aborted)
|
|
81878
82458
|
throw new DOMException("turn aborted", "AbortError");
|
|
81879
82459
|
const inv = sandbox && sandbox.capability ? (0, bashSandbox_1.buildSandboxedInvocation)(command, {
|
|
81880
82460
|
capability: sandbox.capability,
|
|
@@ -81918,7 +82498,7 @@ exit $__orion_rc`;
|
|
|
81918
82498
|
this.shellChildren.set(proc, label);
|
|
81919
82499
|
proc.once("exit", () => this.shellChildren.delete(proc));
|
|
81920
82500
|
proc.once("error", () => this.shellChildren.delete(proc));
|
|
81921
|
-
|
|
82501
|
+
stop2?.watch(proc);
|
|
81922
82502
|
let timedOut = false;
|
|
81923
82503
|
const timer = timeoutS === null ? null : setTimeout(() => {
|
|
81924
82504
|
timedOut = true;
|
|
@@ -87230,6 +87810,7 @@ var require_loopRunner = __commonJS({
|
|
|
87230
87810
|
var askAnswers_js_1 = require_askAnswers();
|
|
87231
87811
|
var anchorDrift_js_1 = require_anchorDrift();
|
|
87232
87812
|
var segmentDriver_js_1 = require_segmentDriver();
|
|
87813
|
+
var turnClose_js_1 = require_turnClose();
|
|
87233
87814
|
var common_js_1 = require_common();
|
|
87234
87815
|
var loopEnvelope_js_1 = require_loopEnvelope();
|
|
87235
87816
|
var loopRuns_js_1 = require_loopRuns();
|
|
@@ -87412,27 +87993,34 @@ var require_loopRunner = __commonJS({
|
|
|
87412
87993
|
let text = "";
|
|
87413
87994
|
let failure = "";
|
|
87414
87995
|
try {
|
|
87415
|
-
const outcome = await (0, segmentDriver_js_1.driveTurn)(
|
|
87416
|
-
|
|
87417
|
-
|
|
87418
|
-
|
|
87419
|
-
|
|
87420
|
-
|
|
87421
|
-
|
|
87422
|
-
|
|
87423
|
-
|
|
87424
|
-
|
|
87425
|
-
|
|
87426
|
-
|
|
87427
|
-
|
|
87428
|
-
|
|
87429
|
-
|
|
87430
|
-
|
|
87431
|
-
|
|
87432
|
-
|
|
87433
|
-
|
|
87434
|
-
|
|
87435
|
-
|
|
87996
|
+
const outcome = await (0, segmentDriver_js_1.driveTurn)(
|
|
87997
|
+
this.deps.transport,
|
|
87998
|
+
{
|
|
87999
|
+
sessionId,
|
|
88000
|
+
...decl.skill ? { skill: { name: decl.skill, args: "" } } : { text: decl.prompt },
|
|
88001
|
+
getMessages: () => [],
|
|
88002
|
+
routing,
|
|
88003
|
+
// No fan-out, no scheduling, no work graphs: a standing loop is one agent.
|
|
88004
|
+
clientCapabilities: []
|
|
88005
|
+
},
|
|
88006
|
+
this.handlers(decl, run3, budget, sessionId, (question) => {
|
|
88007
|
+
parkedQuestion = question;
|
|
88008
|
+
void this.deps.store.save({
|
|
88009
|
+
...base,
|
|
88010
|
+
status: "parked",
|
|
88011
|
+
session_id: sessionId,
|
|
88012
|
+
cost_usd: budget.spendUsd,
|
|
88013
|
+
parked: question,
|
|
88014
|
+
summary: `waiting on you: ${(0, common_js_1.clipTail)(question.question, 160)}`
|
|
88015
|
+
});
|
|
88016
|
+
if (decl.notify.on.includes("parked")) {
|
|
88017
|
+
this.deps.notify?.(`[loop ${decl.name}] waiting on you: ${question.question}`);
|
|
88018
|
+
}
|
|
88019
|
+
}),
|
|
88020
|
+
// A run starts from nothing and its session is closed behind it: nothing reads what a
|
|
88021
|
+
// run that was stopped left.
|
|
88022
|
+
turnClose_js_1.CLOSE_TURNS_IN_BACKGROUND
|
|
88023
|
+
);
|
|
87436
88024
|
if (outcome.kind === "turn_complete") {
|
|
87437
88025
|
const data = outcome.event.data;
|
|
87438
88026
|
text = typeof data.assistant_message === "string" ? data.assistant_message : "";
|
|
@@ -88833,7 +89421,7 @@ var require_dist = __commonJS({
|
|
|
88833
89421
|
for (var p in m2) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m2, p);
|
|
88834
89422
|
};
|
|
88835
89423
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
88836
|
-
exports2.safeSpawnCwd = exports2.gitFrom = exports2.reconcileMemoryIndex = exports2.memoryRootsFor = exports2.memoryRootOf = exports2.isAbsolutePath = exports2.frontmatterField = exports2.MEMORY_INDEX_FILENAME = exports2.watchUserSettingsFile = void 0;
|
|
89424
|
+
exports2.safeSpawnCwd = exports2.gitFrom = exports2.reconcileMemoryIndex = exports2.memoryRootsFor = exports2.memoryRootOf = exports2.isAbsolutePath = exports2.frontmatterField = exports2.MEMORY_INDEX_FILENAME = exports2.watchUserSettingsFile = exports2.TURN_CLOSE_WAIT_MS = exports2.TURN_CLOSE_TIMEOUT_MS = exports2.STOPPED_TOOL_GRACE_MS = exports2.CLOSE_TURNS_IN_BACKGROUND = void 0;
|
|
88837
89425
|
__exportStar(require_shims(), exports2);
|
|
88838
89426
|
__exportStar(require_protocol(), exports2);
|
|
88839
89427
|
__exportStar(require_askAnswers(), exports2);
|
|
@@ -88863,6 +89451,21 @@ var require_dist = __commonJS({
|
|
|
88863
89451
|
__exportStar(require_migrateChat(), exports2);
|
|
88864
89452
|
__exportStar(require_streamHealth(), exports2);
|
|
88865
89453
|
__exportStar(require_segmentDriver(), exports2);
|
|
89454
|
+
__exportStar(require_interruptedTurn(), exports2);
|
|
89455
|
+
var turnClose_1 = require_turnClose();
|
|
89456
|
+
Object.defineProperty(exports2, "CLOSE_TURNS_IN_BACKGROUND", { enumerable: true, get: function() {
|
|
89457
|
+
return turnClose_1.CLOSE_TURNS_IN_BACKGROUND;
|
|
89458
|
+
} });
|
|
89459
|
+
Object.defineProperty(exports2, "STOPPED_TOOL_GRACE_MS", { enumerable: true, get: function() {
|
|
89460
|
+
return turnClose_1.STOPPED_TOOL_GRACE_MS;
|
|
89461
|
+
} });
|
|
89462
|
+
Object.defineProperty(exports2, "TURN_CLOSE_TIMEOUT_MS", { enumerable: true, get: function() {
|
|
89463
|
+
return turnClose_1.TURN_CLOSE_TIMEOUT_MS;
|
|
89464
|
+
} });
|
|
89465
|
+
Object.defineProperty(exports2, "TURN_CLOSE_WAIT_MS", { enumerable: true, get: function() {
|
|
89466
|
+
return turnClose_1.TURN_CLOSE_WAIT_MS;
|
|
89467
|
+
} });
|
|
89468
|
+
__exportStar(require_planState(), exports2);
|
|
88866
89469
|
__exportStar(require_queuedInput(), exports2);
|
|
88867
89470
|
__exportStar(require_heldInputPen(), exports2);
|
|
88868
89471
|
__exportStar(require_customProviders(), exports2);
|
|
@@ -89172,31 +89775,6 @@ var require_clientState = __commonJS({
|
|
|
89172
89775
|
}
|
|
89173
89776
|
});
|
|
89174
89777
|
|
|
89175
|
-
// ../packages/orion-client-ui-core/dist/interruptedTurn.js
|
|
89176
|
-
var require_interruptedTurn = __commonJS({
|
|
89177
|
-
"../packages/orion-client-ui-core/dist/interruptedTurn.js"(exports2) {
|
|
89178
|
-
"use strict";
|
|
89179
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
89180
|
-
exports2.MOVED_ON_NOTE = void 0;
|
|
89181
|
-
exports2.interruptedTurnMessages = interruptedTurnMessages2;
|
|
89182
|
-
var textBlock = (text) => ({ type: "text", text });
|
|
89183
|
-
exports2.MOVED_ON_NOTE = "[Reply cut off here \u2014 the user sent their next message before it finished. That message is what they want now: pick up from this point as it directs, without restarting this reply or remarking on the cut.]";
|
|
89184
|
-
function interruptedTurnMessages2(messages, prompt, partialReply, cause = "stopped") {
|
|
89185
|
-
const out2 = [...messages];
|
|
89186
|
-
if (prompt && prompt.trim().length > 0) {
|
|
89187
|
-
out2.push({ role: "user", content: [textBlock(prompt)] });
|
|
89188
|
-
}
|
|
89189
|
-
if (partialReply && partialReply.trim().length > 0) {
|
|
89190
|
-
const content = [textBlock(partialReply)];
|
|
89191
|
-
if (cause === "moved_on")
|
|
89192
|
-
content.push(textBlock(exports2.MOVED_ON_NOTE));
|
|
89193
|
-
out2.push({ role: "assistant", content });
|
|
89194
|
-
}
|
|
89195
|
-
return out2;
|
|
89196
|
-
}
|
|
89197
|
-
}
|
|
89198
|
-
});
|
|
89199
|
-
|
|
89200
89778
|
// ../packages/orion-client-ui-core/dist/chatFork.js
|
|
89201
89779
|
var require_chatFork = __commonJS({
|
|
89202
89780
|
"../packages/orion-client-ui-core/dist/chatFork.js"(exports2) {
|
|
@@ -93094,7 +93672,7 @@ var require_progress = __commonJS({
|
|
|
93094
93672
|
"../packages/orion-client-ui-core/dist/progress.js"(exports2) {
|
|
93095
93673
|
"use strict";
|
|
93096
93674
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
93097
|
-
exports2.STALLED_LABEL = exports2.STALL_AFTER_MS = exports2.THINKING_STAGES_MS = exports2.WAITING_FOR_PREVIOUS_TURN = void 0;
|
|
93675
|
+
exports2.STALLED_LABEL = exports2.STALL_AFTER_MS = exports2.THINKING_STAGES_MS = exports2.STOPPING_TURN = exports2.WAITING_FOR_PREVIOUS_TURN = void 0;
|
|
93098
93676
|
exports2.formatMeterElapsed = formatMeterElapsed3;
|
|
93099
93677
|
exports2.formatMeterTokens = formatMeterTokens;
|
|
93100
93678
|
exports2.progressMeter = progressMeter;
|
|
@@ -93102,6 +93680,7 @@ var require_progress = __commonJS({
|
|
|
93102
93680
|
exports2.thinkingLabel = thinkingLabel;
|
|
93103
93681
|
exports2.isStalled = isStalled;
|
|
93104
93682
|
exports2.WAITING_FOR_PREVIOUS_TURN = "Waiting for the previous turn to finish\u2026";
|
|
93683
|
+
exports2.STOPPING_TURN = "Stopping\u2026";
|
|
93105
93684
|
function formatMeterElapsed3(ms) {
|
|
93106
93685
|
const total = Math.max(0, Math.floor(ms / 1e3));
|
|
93107
93686
|
const h = Math.floor(total / 3600);
|
|
@@ -93549,6 +94128,107 @@ var require_pasteRefs = __commonJS({
|
|
|
93549
94128
|
}
|
|
93550
94129
|
});
|
|
93551
94130
|
|
|
94131
|
+
// ../packages/orion-client-ui-core/dist/providerFailure.js
|
|
94132
|
+
var require_providerFailure = __commonJS({
|
|
94133
|
+
"../packages/orion-client-ui-core/dist/providerFailure.js"(exports2) {
|
|
94134
|
+
"use strict";
|
|
94135
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
94136
|
+
exports2.providerWords = providerWords;
|
|
94137
|
+
exports2.plainLine = plainLine;
|
|
94138
|
+
exports2.readEndpointFailure = readEndpointFailure;
|
|
94139
|
+
var toolLog_1 = require_toolLog();
|
|
94140
|
+
var ADAPTER_PREFIX = /provider request failed:\s*/i;
|
|
94141
|
+
var RELAY_WORDS = /^gateway (auth refused|rate limit|unavailable|stream)\b/i;
|
|
94142
|
+
function providerWords(text) {
|
|
94143
|
+
const m2 = ADAPTER_PREFIX.exec(text);
|
|
94144
|
+
if (!m2)
|
|
94145
|
+
return null;
|
|
94146
|
+
const words = text.slice(m2.index + m2[0].length);
|
|
94147
|
+
return RELAY_WORDS.test(words) ? null : words;
|
|
94148
|
+
}
|
|
94149
|
+
var HIDDEN = /[\u0000-\u001f\u007f-\u009f\u200b-\u200f\u2028-\u202e\u2060-\u206f\ufeff]/g;
|
|
94150
|
+
function plainLine(text, max) {
|
|
94151
|
+
return (0, toolLog_1.clip)(text.replace(HIDDEN, " "), max);
|
|
94152
|
+
}
|
|
94153
|
+
var DETAIL_MAX = 200;
|
|
94154
|
+
function messageIn(value, depth) {
|
|
94155
|
+
if (typeof value === "string")
|
|
94156
|
+
return value.trim() || null;
|
|
94157
|
+
if (depth > 3 || value === null || typeof value !== "object" || Array.isArray(value))
|
|
94158
|
+
return null;
|
|
94159
|
+
const record = value;
|
|
94160
|
+
for (const key of ["message", "detail", "error"]) {
|
|
94161
|
+
const found = messageIn(record[key], depth + 1);
|
|
94162
|
+
if (found !== null)
|
|
94163
|
+
return found;
|
|
94164
|
+
}
|
|
94165
|
+
return null;
|
|
94166
|
+
}
|
|
94167
|
+
var TITLE_SCAN = 4096;
|
|
94168
|
+
function bodyMessage(body2, status) {
|
|
94169
|
+
const raw = body2.trim();
|
|
94170
|
+
if (!raw)
|
|
94171
|
+
return "";
|
|
94172
|
+
let found = null;
|
|
94173
|
+
try {
|
|
94174
|
+
found = messageIn(JSON.parse(raw), 0);
|
|
94175
|
+
} catch {
|
|
94176
|
+
}
|
|
94177
|
+
if (found === null) {
|
|
94178
|
+
const title = /<title[^>]*>([\s\S]*?)<\/title>/i.exec(raw.slice(0, TITLE_SCAN));
|
|
94179
|
+
found = title ? title[1] : raw.startsWith("<") ? "" : raw;
|
|
94180
|
+
}
|
|
94181
|
+
return plainLine(found.replace(new RegExp(`^\\s*${status}\\b[\\s:-]*`), ""), DETAIL_MAX);
|
|
94182
|
+
}
|
|
94183
|
+
var HTTP_ANSWER = /^(\d{3})(?:[ \t]+([^:\r\n]*))?:[ \t]*([\s\S]*)$/;
|
|
94184
|
+
var STREAMED_ERROR = /^(?:openai responses|openai|anthropic) error \(([^)]*)\):\s*([\s\S]*)$/i;
|
|
94185
|
+
function answerDetail(status, words) {
|
|
94186
|
+
if (status === null)
|
|
94187
|
+
return words || null;
|
|
94188
|
+
return words ? `HTTP ${status}: ${words}` : `HTTP ${status}`;
|
|
94189
|
+
}
|
|
94190
|
+
var CONNECT_FAILURE = /^error sending request for url \(([^)\s]*)\)([\s\S]*)$/i;
|
|
94191
|
+
var RELAY_ROUTE = /\/llm\/v1\/stream(?:[?#]|$)/i;
|
|
94192
|
+
var TRANSPORT_FRAMING = /^(client error \(\w+\)|tcp connect error|dns error|error trying to connect|connection error)$/i;
|
|
94193
|
+
function reachDetail(url, chain) {
|
|
94194
|
+
let where = "";
|
|
94195
|
+
try {
|
|
94196
|
+
const origin = new URL(url).origin;
|
|
94197
|
+
where = origin === "null" ? "" : origin;
|
|
94198
|
+
} catch {
|
|
94199
|
+
}
|
|
94200
|
+
const cause = chain.split(/:\s+/).map((part) => part.trim()).find((part) => part.length > 0 && !TRANSPORT_FRAMING.test(part));
|
|
94201
|
+
const why = cause ? plainLine(cause.replace(/\s*\(os error \d+\)$/i, "").replace(/[.]$/, ""), 120) : "";
|
|
94202
|
+
if (why && where)
|
|
94203
|
+
return `${why} at ${where}`;
|
|
94204
|
+
return why || where || null;
|
|
94205
|
+
}
|
|
94206
|
+
var RELAYED = /^provider request failed:/i;
|
|
94207
|
+
function readEndpointFailure(said) {
|
|
94208
|
+
if (RELAYED.test(said))
|
|
94209
|
+
return null;
|
|
94210
|
+
const reach = CONNECT_FAILURE.exec(said);
|
|
94211
|
+
if (reach) {
|
|
94212
|
+
return RELAY_ROUTE.test(reach[1]) ? null : { shape: "unreachable", detail: reachDetail(reach[1], reach[2]) };
|
|
94213
|
+
}
|
|
94214
|
+
const http = HTTP_ANSWER.exec(said);
|
|
94215
|
+
if (http) {
|
|
94216
|
+
const status2 = Number(http[1]);
|
|
94217
|
+
const message2 = bodyMessage(http[3], http[1]);
|
|
94218
|
+
return { shape: "answer", status: status2, kind: "", message: message2, detail: answerDetail(status2, message2 || plainLine(http[2] ?? "", 80)) };
|
|
94219
|
+
}
|
|
94220
|
+
const streamed = STREAMED_ERROR.exec(said);
|
|
94221
|
+
if (!streamed)
|
|
94222
|
+
return null;
|
|
94223
|
+
const code = streamed[1].trim();
|
|
94224
|
+
const status = /^\d{3}$/.test(code) ? Number(code) : null;
|
|
94225
|
+
const kind = status === null ? code : "";
|
|
94226
|
+
const message = plainLine(streamed[2], DETAIL_MAX);
|
|
94227
|
+
return { shape: "answer", status, kind, message, detail: answerDetail(status, message || plainLine(kind, 80)) };
|
|
94228
|
+
}
|
|
94229
|
+
}
|
|
94230
|
+
});
|
|
94231
|
+
|
|
93552
94232
|
// ../packages/orion-client-ui-core/dist/turnErrors.js
|
|
93553
94233
|
var require_turnErrors = __commonJS({
|
|
93554
94234
|
"../packages/orion-client-ui-core/dist/turnErrors.js"(exports2) {
|
|
@@ -93556,6 +94236,7 @@ var require_turnErrors = __commonJS({
|
|
|
93556
94236
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
93557
94237
|
exports2.describeTurnError = describeTurnError3;
|
|
93558
94238
|
var client_core_1 = require_dist();
|
|
94239
|
+
var providerFailure_1 = require_providerFailure();
|
|
93559
94240
|
var HINTS = {
|
|
93560
94241
|
retry: "Send it again to retry.",
|
|
93561
94242
|
pick_model: "Pick another model.",
|
|
@@ -93565,6 +94246,8 @@ var require_turnErrors = __commonJS({
|
|
|
93565
94246
|
compact: "Compact the conversation, or start a new chat.",
|
|
93566
94247
|
none: null
|
|
93567
94248
|
};
|
|
94249
|
+
var CONTEXT_TOO_LONG = /context (window )?(too large|exceeded)|prompt is too long|too many tokens|exceeds the model's context/i;
|
|
94250
|
+
var BUSY = /rate.?limit|too many requests|\b429\b|overloaded|\b529\b/i;
|
|
93568
94251
|
function providerDetail(text) {
|
|
93569
94252
|
const m2 = /provider reported an error:\s*(.+)$/i.exec(text);
|
|
93570
94253
|
return m2 ? m2[1].trim() : null;
|
|
@@ -93576,6 +94259,51 @@ var require_turnErrors = __commonJS({
|
|
|
93576
94259
|
function capitalise(text) {
|
|
93577
94260
|
return text.length === 0 ? text : text[0].toUpperCase() + text.slice(1);
|
|
93578
94261
|
}
|
|
94262
|
+
function endpointOf(ctx) {
|
|
94263
|
+
const name2 = (0, client_core_1.parseCustomProviderRef)(ctx.provider?.trim() ?? "");
|
|
94264
|
+
if (name2 === null)
|
|
94265
|
+
return null;
|
|
94266
|
+
return ctx.mode === "duet" ? "" : name2;
|
|
94267
|
+
}
|
|
94268
|
+
var ENDPOINT_OUTCOMES = {
|
|
94269
|
+
refused: {
|
|
94270
|
+
headline: (who) => `${capitalise(who)} refused the request.`,
|
|
94271
|
+
hint: "Check the endpoint's API key and that its server is healthy, then send it again."
|
|
94272
|
+
},
|
|
94273
|
+
unreachable: {
|
|
94274
|
+
headline: (who) => `Orion couldn't reach ${who}.`,
|
|
94275
|
+
hint: "Check that the endpoint is running and its address is right, then send it again."
|
|
94276
|
+
},
|
|
94277
|
+
busy: {
|
|
94278
|
+
headline: (who) => `${capitalise(who)} is busy right now.`,
|
|
94279
|
+
hint: HINTS.retry
|
|
94280
|
+
},
|
|
94281
|
+
failed: {
|
|
94282
|
+
headline: (who) => `${capitalise(who)} returned an error.`,
|
|
94283
|
+
hint: "Check the endpoint's server, then send it again."
|
|
94284
|
+
}
|
|
94285
|
+
};
|
|
94286
|
+
var REFUSAL_KIND = /auth|permission|forbidden|unauthori[sz]ed|api.?key/i;
|
|
94287
|
+
function outcomeOf(reading) {
|
|
94288
|
+
if (reading.shape === "unreachable")
|
|
94289
|
+
return "unreachable";
|
|
94290
|
+
const { status, kind, message } = reading;
|
|
94291
|
+
if (status === 401 || status === 403 || status === null && REFUSAL_KIND.test(kind))
|
|
94292
|
+
return "refused";
|
|
94293
|
+
if (status === 429 || status === 529 || BUSY.test(kind) || BUSY.test(message))
|
|
94294
|
+
return "busy";
|
|
94295
|
+
return "failed";
|
|
94296
|
+
}
|
|
94297
|
+
function endpointFailure(said, name2) {
|
|
94298
|
+
if (CONTEXT_TOO_LONG.test(said))
|
|
94299
|
+
return null;
|
|
94300
|
+
const reading = (0, providerFailure_1.readEndpointFailure)(said);
|
|
94301
|
+
if (reading === null)
|
|
94302
|
+
return null;
|
|
94303
|
+
const who = name2 ? `your endpoint "${(0, providerFailure_1.plainLine)(name2, 60)}"` : "your endpoint";
|
|
94304
|
+
const { headline, hint } = ENDPOINT_OUTCOMES[outcomeOf(reading)];
|
|
94305
|
+
return { headline: headline(who), detail: reading.detail, action: "retry", hint, retryable: true };
|
|
94306
|
+
}
|
|
93579
94307
|
function describeTurnError3(data, ctx = {}) {
|
|
93580
94308
|
const text = typeof data?.error === "string" ? data.error.trim() : "";
|
|
93581
94309
|
const code = typeof data?.code === "string" ? data.code : "";
|
|
@@ -93594,6 +94322,13 @@ var require_turnErrors = __commonJS({
|
|
|
93594
94322
|
if ((0, client_core_1.describeNetworkFailure)(new Error(text)).kind === "tls-untrusted") {
|
|
93595
94323
|
return view((0, client_core_1.networkFailureText)(new Error(text)), "network_settings", null, true);
|
|
93596
94324
|
}
|
|
94325
|
+
const said = (0, providerFailure_1.providerWords)(text);
|
|
94326
|
+
const endpoint = endpointOf(ctx);
|
|
94327
|
+
if (said !== null && endpoint !== null) {
|
|
94328
|
+
const failure = endpointFailure(said, endpoint);
|
|
94329
|
+
if (failure !== null)
|
|
94330
|
+
return failure;
|
|
94331
|
+
}
|
|
93597
94332
|
if (/no provider adapter configured/i.test(text) || /provider .* not (configured|available)/i.test(text)) {
|
|
93598
94333
|
return view(`${model} can't run on this server.`, "pick_model");
|
|
93599
94334
|
}
|
|
@@ -93616,13 +94351,13 @@ var require_turnErrors = __commonJS({
|
|
|
93616
94351
|
if (/fetch failed|ECONNREFUSED|ENOTFOUND|ECONNRESET|network|unreachable|socket hang up|error sending request|client error \(Connect\)/i.test(text)) {
|
|
93617
94352
|
return view("Orion couldn't reach the backend.", "check_network", null, true);
|
|
93618
94353
|
}
|
|
93619
|
-
if (/gateway auth refused|\b401\b|unauthori[sz]ed|not signed in|sign-in|signin|token (expired|revoked|refused)|auth(entication)? (failed|error)/i.test(text)) {
|
|
94354
|
+
if (said === null && /gateway auth refused|\b401\b|unauthori[sz]ed|not signed in|sign-in|signin|token (expired|revoked|refused)|auth(entication)? (failed|error)/i.test(text)) {
|
|
93620
94355
|
return view("Your sign-in has expired.", "sign_in");
|
|
93621
94356
|
}
|
|
93622
|
-
if (
|
|
94357
|
+
if (CONTEXT_TOO_LONG.test(text)) {
|
|
93623
94358
|
return view("The conversation is too long for the model's window.", "compact");
|
|
93624
94359
|
}
|
|
93625
|
-
if (
|
|
94360
|
+
if (BUSY.test(text)) {
|
|
93626
94361
|
return view("The model provider is busy right now.", "retry");
|
|
93627
94362
|
}
|
|
93628
94363
|
if (text.length === 0) {
|
|
@@ -94048,6 +94783,8 @@ var require_placeholder = __commonJS({
|
|
|
94048
94783
|
const waiting = n === 1 ? "1 message waiting for the next step" : `${n} messages waiting for the next step`;
|
|
94049
94784
|
return host.queueEditKey ? `${waiting} \u2014 ${host.queueEditKey} edits, Enter adds another` : `${waiting} \u2014 Enter adds another`;
|
|
94050
94785
|
}
|
|
94786
|
+
case "stopping":
|
|
94787
|
+
return "Stopping the turn \u2014 what you send now goes next";
|
|
94051
94788
|
case "parked":
|
|
94052
94789
|
return situation.on === "permission" ? parkedComposer_1.PARKED_COMPOSER_WORDING.permissionPlaceholder : situation.on === "plan" ? parkedComposer_1.PARKED_COMPOSER_WORDING.plan : parkedComposer_1.PARKED_COMPOSER_WORDING.ask;
|
|
94053
94790
|
case "after-error":
|
|
@@ -94757,7 +95494,6 @@ var require_dist2 = __commonJS({
|
|
|
94757
95494
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
94758
95495
|
exports2.normalizeCapabilities = exports2.isRenderableGuard = exports2.isGuardEntitled = exports2.entitledGuards = exports2.productToggles = exports2.UNAVAILABLE_CAPABILITIES = exports2.GUARD_IDS = exports2.GUARD_FIELDS = exports2.parseUserCompaction = exports2.parseInputGuardEvent = exports2.parseTrust = void 0;
|
|
94759
95496
|
__exportStar(require_clientState(), exports2);
|
|
94760
|
-
__exportStar(require_interruptedTurn(), exports2);
|
|
94761
95497
|
__exportStar(require_chatFork(), exports2);
|
|
94762
95498
|
__exportStar(require_permissionCard(), exports2);
|
|
94763
95499
|
__exportStar(require_askCard(), exports2);
|
|
@@ -110384,7 +111120,7 @@ var ScrollBox2 = ScrollBox_default;
|
|
|
110384
111120
|
|
|
110385
111121
|
// src/main.tsx
|
|
110386
111122
|
var import_client_core61 = __toESM(require_dist(), 1);
|
|
110387
|
-
var
|
|
111123
|
+
var import_client_ui_core55 = __toESM(require_dist2(), 1);
|
|
110388
111124
|
var import_client_core62 = __toESM(require_dist(), 1);
|
|
110389
111125
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
110390
111126
|
import * as os8 from "os";
|
|
@@ -112594,6 +113330,9 @@ function fileModified(s, d2) {
|
|
|
112594
113330
|
const live = settlesBlock && f.live ? { ...f.live, liveCode: null } : f.live;
|
|
112595
113331
|
return { ...f, live, settled: [...f.settled, item] };
|
|
112596
113332
|
}
|
|
113333
|
+
function applyPlanUpdated(s, plan) {
|
|
113334
|
+
return { ...s, clientState: { ...s.clientState, plan } };
|
|
113335
|
+
}
|
|
112597
113336
|
function applyTurnComplete(s, data) {
|
|
112598
113337
|
const flushed = flushLive(s);
|
|
112599
113338
|
const messages = Array.isArray(data.messages) ? data.messages : flushed.messages;
|
|
@@ -112608,24 +113347,22 @@ function applyTurnComplete(s, data) {
|
|
|
112608
113347
|
live: null
|
|
112609
113348
|
});
|
|
112610
113349
|
}
|
|
112611
|
-
function
|
|
112612
|
-
return data.error === "cancelled" && !Array.isArray(data.messages);
|
|
112613
|
-
}
|
|
112614
|
-
function applyTurnError(s, data) {
|
|
112615
|
-
const flushed = flushLive(s);
|
|
112616
|
-
const messages = Array.isArray(data.messages) ? data.messages : flushed.messages;
|
|
112617
|
-
const settledTurn = { ...flushed, messages, committedCount: flushed.settled.length, live: null };
|
|
112618
|
-
return isUnrepairedStop(data) ? settledTurn : markTurnBoundary(settledTurn);
|
|
112619
|
-
}
|
|
112620
|
-
function applyTurnInterrupted(s, prompt, partialReply = "") {
|
|
112621
|
-
const partial = partialReply || s.live?.assistantText || "";
|
|
113350
|
+
function settleEndedTurn(s, left, forkable) {
|
|
112622
113351
|
const flushed = flushLive(s);
|
|
112623
|
-
|
|
113352
|
+
const settledTurn = {
|
|
112624
113353
|
...flushed,
|
|
112625
|
-
messages:
|
|
113354
|
+
messages: left ?? flushed.messages,
|
|
112626
113355
|
committedCount: flushed.settled.length,
|
|
112627
113356
|
live: null
|
|
112628
|
-
}
|
|
113357
|
+
};
|
|
113358
|
+
return forkable ? markTurnBoundary(settledTurn) : settledTurn;
|
|
113359
|
+
}
|
|
113360
|
+
function applyTurnError(s, data) {
|
|
113361
|
+
const left = Array.isArray(data.messages) ? data.messages : void 0;
|
|
113362
|
+
return settleEndedTurn(s, left, left !== void 0 || data.error !== "cancelled");
|
|
113363
|
+
}
|
|
113364
|
+
function applyTurnInterrupted(s, left) {
|
|
113365
|
+
return settleEndedTurn(s, left?.messages, left !== void 0);
|
|
112629
113366
|
}
|
|
112630
113367
|
function hydrate(sessionId, messages, clientState, transcript, contextGauge, turnMarks) {
|
|
112631
113368
|
const msgs = Array.isArray(messages) ? messages : [];
|
|
@@ -113273,6 +114010,7 @@ function sessionSwapReset(s) {
|
|
|
113273
114010
|
turnStartedAt: 0,
|
|
113274
114011
|
// a stale anchor from a mid-swap turn must never stamp an Orbited line
|
|
113275
114012
|
waitingOnPreviousTurn: false,
|
|
114013
|
+
stopping: false,
|
|
113276
114014
|
turnFacts: import_client_ui_core12.EMPTY_TURN_FACTS,
|
|
113277
114015
|
followUp: null,
|
|
113278
114016
|
lastTurnMs: 0,
|
|
@@ -113324,6 +114062,7 @@ function initialAppState(partial) {
|
|
|
113324
114062
|
turnStartedAt: 0,
|
|
113325
114063
|
turnModel: "",
|
|
113326
114064
|
waitingOnPreviousTurn: false,
|
|
114065
|
+
stopping: false,
|
|
113327
114066
|
turnFacts: import_client_ui_core12.EMPTY_TURN_FACTS,
|
|
113328
114067
|
followUp: null,
|
|
113329
114068
|
lastTurnMs: 0,
|
|
@@ -119063,6 +119802,20 @@ function applyIndexStatus(state, key, value) {
|
|
|
119063
119802
|
return state;
|
|
119064
119803
|
}
|
|
119065
119804
|
|
|
119805
|
+
// src/state/stoppedTurn.ts
|
|
119806
|
+
function showInterrupted(transcript, turn) {
|
|
119807
|
+
if (turn.settled) return;
|
|
119808
|
+
transcript.setState(
|
|
119809
|
+
(s) => s.sessionId !== turn.sessionId || s.live === null ? s : appendNote(applyTurnInterrupted(s, void 0), INTERRUPT_NOTE)
|
|
119810
|
+
);
|
|
119811
|
+
}
|
|
119812
|
+
function settleInterrupted(transcript, turn, left) {
|
|
119813
|
+
if (turn.settled) return;
|
|
119814
|
+
showInterrupted(transcript, turn);
|
|
119815
|
+
turn.settled = true;
|
|
119816
|
+
transcript.setState((s) => s.sessionId === turn.sessionId ? applyTurnInterrupted(s, left) : s);
|
|
119817
|
+
}
|
|
119818
|
+
|
|
119066
119819
|
// src/events/renderLane.ts
|
|
119067
119820
|
var import_client_core31 = __toESM(require_dist(), 1);
|
|
119068
119821
|
var import_client_ui_core21 = __toESM(require_dist2(), 1);
|
|
@@ -119079,8 +119832,8 @@ var TURN_ERROR_GESTURES = {
|
|
|
119079
119832
|
compact: "/compact shortens it; /new starts fresh.",
|
|
119080
119833
|
none: null
|
|
119081
119834
|
};
|
|
119082
|
-
function turnErrorNote(data, modelLabel) {
|
|
119083
|
-
const view = (0, import_client_ui_core20.describeTurnError)(data, { modelLabel });
|
|
119835
|
+
function turnErrorNote(data, modelLabel, route = {}) {
|
|
119836
|
+
const view = (0, import_client_ui_core20.describeTurnError)(data, { modelLabel, ...route });
|
|
119084
119837
|
const parts2 = [view.headline];
|
|
119085
119838
|
if (view.detail) parts2.push(`(${view.detail})`);
|
|
119086
119839
|
if (view.hint) parts2.push(view.hint);
|
|
@@ -119285,6 +120038,7 @@ function renderLane(transcript, app, ev) {
|
|
|
119285
120038
|
current_step: typeof d2.current_step === "number" ? d2.current_step : 0
|
|
119286
120039
|
}
|
|
119287
120040
|
}));
|
|
120041
|
+
transcript.setState((s) => applyPlanUpdated(s, (0, import_client_core32.planOfEvent)(d2)));
|
|
119288
120042
|
break;
|
|
119289
120043
|
case "agent_lifecycle": {
|
|
119290
120044
|
const agentId = String(d2.agent_id ?? ev.agent_id ?? "");
|
|
@@ -119425,8 +120179,8 @@ function renderLane(transcript, app, ev) {
|
|
|
119425
120179
|
}));
|
|
119426
120180
|
} else {
|
|
119427
120181
|
const quota = (0, import_client_core32.parseQuotaRefusal)(d2);
|
|
119428
|
-
const { modelLabel, model } = app.getState();
|
|
119429
|
-
const failure = turnErrorNote(data, modelLabel || displayModel(model));
|
|
120182
|
+
const { modelLabel, model, provider, mode } = app.getState();
|
|
120183
|
+
const failure = turnErrorNote(data, modelLabel || displayModel(model), { provider, mode });
|
|
119430
120184
|
transcript.setState(
|
|
119431
120185
|
(s) => quota ? appendQuota(applyTurnError(s, data), quota) : appendNote(applyTurnError(s, data), failure.text, { tone: "error" })
|
|
119432
120186
|
);
|
|
@@ -119636,7 +120390,7 @@ function startupFailureMessage(err2, apiUrl) {
|
|
|
119636
120390
|
}
|
|
119637
120391
|
|
|
119638
120392
|
// src/main.tsx
|
|
119639
|
-
var
|
|
120393
|
+
var import_client_ui_core56 = __toESM(require_dist2(), 1);
|
|
119640
120394
|
|
|
119641
120395
|
// src/services/goalTurn.ts
|
|
119642
120396
|
var GOAL_SEND_MAX_ATTEMPTS = 20;
|
|
@@ -120483,7 +121237,7 @@ var WorkPlanApprovalBridge = class {
|
|
|
120483
121237
|
};
|
|
120484
121238
|
|
|
120485
121239
|
// src/main.tsx
|
|
120486
|
-
var
|
|
121240
|
+
var import_client_ui_core57 = __toESM(require_dist2(), 1);
|
|
120487
121241
|
|
|
120488
121242
|
// src/components/layout/Transcript.tsx
|
|
120489
121243
|
var import_react30 = __toESM(require_react(), 1);
|
|
@@ -137771,7 +138525,7 @@ function detectTerminal2(env3 = process.env, platform2 = process.platform) {
|
|
|
137771
138525
|
|
|
137772
138526
|
// src/services/version.ts
|
|
137773
138527
|
function tuiVersion() {
|
|
137774
|
-
return "0.1.
|
|
138528
|
+
return "0.1.41".length > 0 ? "0.1.41" : null;
|
|
137775
138529
|
}
|
|
137776
138530
|
|
|
137777
138531
|
// src/components/layout/WelcomeCard.tsx
|
|
@@ -142640,15 +143394,33 @@ function WorkingStatus({
|
|
|
142640
143394
|
] });
|
|
142641
143395
|
}
|
|
142642
143396
|
|
|
142643
|
-
// src/
|
|
143397
|
+
// src/components/layout/footerWords.ts
|
|
142644
143398
|
var import_client_ui_core46 = __toESM(require_dist2(), 1);
|
|
143399
|
+
function stopUnderWay(moment) {
|
|
143400
|
+
return moment.stopping && moment.status === "streaming";
|
|
143401
|
+
}
|
|
143402
|
+
function workingLabel(moment) {
|
|
143403
|
+
if (stopUnderWay(moment)) return import_client_ui_core46.STOPPING_TURN;
|
|
143404
|
+
return moment.waitingOnPreviousTurn ? import_client_ui_core46.WAITING_FOR_PREVIOUS_TURN : void 0;
|
|
143405
|
+
}
|
|
143406
|
+
function composerSituation(moment) {
|
|
143407
|
+
if (moment.status === "error") return { kind: "after-error" };
|
|
143408
|
+
if (moment.status === "streaming") {
|
|
143409
|
+
if (moment.stopping) return { kind: "stopping" };
|
|
143410
|
+
return moment.queuedCount > 0 ? { kind: "queued", count: moment.queuedCount } : { kind: "busy" };
|
|
143411
|
+
}
|
|
143412
|
+
return moment.conversationStarted ? { kind: "idle" } : { kind: "first" };
|
|
143413
|
+
}
|
|
143414
|
+
|
|
143415
|
+
// src/state/inputQueue.ts
|
|
143416
|
+
var import_client_ui_core47 = __toESM(require_dist2(), 1);
|
|
142645
143417
|
function isEditable(entry) {
|
|
142646
|
-
return (0,
|
|
143418
|
+
return (0, import_client_ui_core47.isEditableSteer)(entry);
|
|
142647
143419
|
}
|
|
142648
143420
|
function popEditableQueue(app, draft) {
|
|
142649
143421
|
const own = app.getState().queuedMessages.filter(isEditable);
|
|
142650
143422
|
const attachments = own.flatMap((entry) => entry.attachments ?? []);
|
|
142651
|
-
const merged = (0,
|
|
143423
|
+
const merged = (0, import_client_ui_core47.mergeIntoDraft)(
|
|
142652
143424
|
own.map((entry) => entry.text),
|
|
142653
143425
|
draft
|
|
142654
143426
|
);
|
|
@@ -142658,7 +143430,7 @@ function popEditableQueue(app, draft) {
|
|
|
142658
143430
|
return merged ?? draft;
|
|
142659
143431
|
}
|
|
142660
143432
|
function queueRows(queued) {
|
|
142661
|
-
const { shown, hidden } = (0,
|
|
143433
|
+
const { shown, hidden } = (0, import_client_ui_core47.capMachineRows)(queued);
|
|
142662
143434
|
const rows = shown.map((entry) => ({ kind: "entry", entry }));
|
|
142663
143435
|
if (hidden > 0) rows.push({ kind: "overflow", hidden });
|
|
142664
143436
|
return rows;
|
|
@@ -142711,7 +143483,7 @@ function PendingAttachments({ items: all }) {
|
|
|
142711
143483
|
}
|
|
142712
143484
|
|
|
142713
143485
|
// src/components/layout/ReplFooter.tsx
|
|
142714
|
-
var
|
|
143486
|
+
var import_client_ui_core48 = __toESM(require_dist2(), 1);
|
|
142715
143487
|
var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
|
|
142716
143488
|
function ReplFooter({
|
|
142717
143489
|
appStore,
|
|
@@ -142761,11 +143533,12 @@ function ReplFooter({
|
|
|
142761
143533
|
const cloudJobStatus = useStoreSelector(appStore, (s) => s.cloudJobStatus);
|
|
142762
143534
|
const cloudWorking = cloudJobStatus !== null && agentWorking(cloudJobStatus);
|
|
142763
143535
|
const queuedCount = useStoreSelector(appStore, (s) => s.queuedMessages.length);
|
|
143536
|
+
const stopping = useStoreSelector(appStore, stopUnderWay);
|
|
142764
143537
|
const followUp = useStoreSelector(appStore, (s) => s.followUp);
|
|
142765
143538
|
const screenReader = useStoreSelector(appStore, (s) => s.screenReader);
|
|
142766
143539
|
const ghost = !cloud && !screenReader && status === "idle" && followUp ? followUp : void 0;
|
|
142767
|
-
const placeholder = cloud ? cloudJob ? (0,
|
|
142768
|
-
|
|
143540
|
+
const placeholder = cloud ? cloudJob ? (0, import_client_ui_core48.cloudInputPlaceholder)((0, import_client_ui_core48.inputModeFor)(cloudJobStatus ?? "queued", true), null) : (0, import_client_ui_core48.inputPlaceholder)("cloud") : (0, import_client_ui_core48.composerPlaceholder)(
|
|
143541
|
+
composerSituation({ status, stopping, queuedCount, conversationStarted }),
|
|
142769
143542
|
// No queue key here: the strip under the turn carries that hint itself.
|
|
142770
143543
|
{ shellPrefix: true, queueEditKey: null, helpKey: "?" }
|
|
142771
143544
|
);
|
|
@@ -142794,7 +143567,14 @@ function ReplFooter({
|
|
|
142794
143567
|
);
|
|
142795
143568
|
const [menuOpen, setMenuOpen] = import_react51.default.useState(false);
|
|
142796
143569
|
return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(import_jsx_runtime77.Fragment, { children: [
|
|
142797
|
-
streaming && !parked ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
143570
|
+
streaming && !parked ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
143571
|
+
WorkingStatus,
|
|
143572
|
+
{
|
|
143573
|
+
store: appStore,
|
|
143574
|
+
label: workingLabel({ status, stopping, waitingOnPreviousTurn }),
|
|
143575
|
+
stopKey: stopping ? null : vimMode ? "Ctrl+C" : "esc"
|
|
143576
|
+
}
|
|
143577
|
+
) : cloudWorking ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(WorkingStatus, { store: appStore, tokens: 0, stopKey: null }) : null,
|
|
142798
143578
|
plan && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(PlanCard, { plan }),
|
|
142799
143579
|
pendingWorkPlan ? /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
142800
143580
|
WorkPlanApprovalPrompt,
|
|
@@ -142987,13 +143767,13 @@ function FullscreenLayout({
|
|
|
142987
143767
|
// src/components/dialogs/AgentsDashboard.tsx
|
|
142988
143768
|
var import_react54 = __toESM(require_react(), 1);
|
|
142989
143769
|
var import_client_core51 = __toESM(require_dist(), 1);
|
|
142990
|
-
var
|
|
143770
|
+
var import_client_ui_core50 = __toESM(require_dist2(), 1);
|
|
142991
143771
|
var import_strip_ansi4 = __toESM(require_strip_ansi(), 1);
|
|
142992
143772
|
|
|
142993
143773
|
// src/components/dialogs/agentsHandback.tsx
|
|
142994
143774
|
var import_react53 = __toESM(require_react(), 1);
|
|
142995
143775
|
var import_client_core50 = __toESM(require_dist(), 1);
|
|
142996
|
-
var
|
|
143776
|
+
var import_client_ui_core49 = __toESM(require_dist2(), 1);
|
|
142997
143777
|
var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1);
|
|
142998
143778
|
function useHandback(host) {
|
|
142999
143779
|
const [mismatch, setMismatch] = (0, import_react53.useState)(null);
|
|
@@ -143006,7 +143786,7 @@ function useHandback(host) {
|
|
|
143006
143786
|
const hb = host.handback;
|
|
143007
143787
|
if (!hb) return;
|
|
143008
143788
|
const outcome = await hb.checkout(root2, branch, strategy);
|
|
143009
|
-
say((0,
|
|
143789
|
+
say((0, import_client_ui_core49.checkedOutNote)(outcome), outcome.ok ? "success" : "warning");
|
|
143010
143790
|
if (outcome.ok && then === "continue") {
|
|
143011
143791
|
await hb.continueLocally(job);
|
|
143012
143792
|
host.onClose();
|
|
@@ -143054,7 +143834,7 @@ function useHandback(host) {
|
|
|
143054
143834
|
const diff3 = await host.getDiff(job);
|
|
143055
143835
|
if (diff3.files.length === 0) return say("The agent has not pushed any changes yet.", "warning");
|
|
143056
143836
|
const outcome = await hb.apply(root2, diff3);
|
|
143057
|
-
say((0,
|
|
143837
|
+
say((0, import_client_ui_core49.appliedNote)(outcome, { nameFirstConflict: true }), outcome.conflicted.length ? "warning" : "success");
|
|
143058
143838
|
});
|
|
143059
143839
|
};
|
|
143060
143840
|
const handleCardKey = (job, input, escape) => {
|
|
@@ -143062,7 +143842,7 @@ function useHandback(host) {
|
|
|
143062
143842
|
if (escape) setMismatch(null);
|
|
143063
143843
|
else if (input === "!") setMismatch({ ...mismatch, remember: !mismatch.remember });
|
|
143064
143844
|
else {
|
|
143065
|
-
const choice =
|
|
143845
|
+
const choice = import_client_ui_core49.MISMATCH_CHOICES[Number(input) - 1];
|
|
143066
143846
|
if (choice) answerMismatch(job, choice.choice);
|
|
143067
143847
|
}
|
|
143068
143848
|
return true;
|
|
@@ -143071,14 +143851,14 @@ function useHandback(host) {
|
|
|
143071
143851
|
}
|
|
143072
143852
|
function MismatchCard({ job, card }) {
|
|
143073
143853
|
return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(Box2, { flexDirection: "column", children: [
|
|
143074
|
-
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: (0,
|
|
143854
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: (0, import_client_ui_core49.jobTitle)(job) }),
|
|
143075
143855
|
/* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(Box2, { flexDirection: "column", marginTop: 1, children: [
|
|
143076
|
-
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { colorKey: "warning", bold: true, wrap: "truncate-end", children: (0,
|
|
143077
|
-
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children:
|
|
143856
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { colorKey: "warning", bold: true, wrap: "truncate-end", children: (0, import_client_ui_core49.mismatchCardTitle)(card.currentBranch, card.files) }),
|
|
143857
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: import_client_ui_core49.MISMATCH_QUESTION }),
|
|
143078
143858
|
card.files.slice(0, 6).map((f) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: ` ${f}` }, f)),
|
|
143079
143859
|
card.files.length > 6 ? /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { dim: true, children: ` \u2026and ${card.files.length - 6} more` }) : null
|
|
143080
143860
|
] }),
|
|
143081
|
-
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(Box2, { flexDirection: "column", marginTop: 1, children:
|
|
143861
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(Box2, { flexDirection: "column", marginTop: 1, children: import_client_ui_core49.MISMATCH_CHOICES.map((c3, i2) => /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { colorKey: c3.choice === "discard" ? "error" : void 0, wrap: "truncate-end", children: ` ${i2 + 1} ${c3.label} \u2014 ${c3.detail}` }, c3.choice)) }),
|
|
143082
143862
|
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)(Box2, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: ` ! ${card.remember ? "[x]" : "[ ]"} don't ask again for this repository (stash or commit) \xB7 esc keeps the tree` }) })
|
|
143083
143863
|
] });
|
|
143084
143864
|
}
|
|
@@ -143129,7 +143909,7 @@ function AgentsDashboard({
|
|
|
143129
143909
|
const [board, setBoard] = (0, import_react54.useState)(panel.jobs);
|
|
143130
143910
|
const boardRef = (0, import_react54.useRef)(panel.jobs);
|
|
143131
143911
|
const feedRef = (0, import_react54.useRef)(null);
|
|
143132
|
-
const [transcript, setTranscript] = (0, import_react54.useState)(() => (0,
|
|
143912
|
+
const [transcript, setTranscript] = (0, import_react54.useState)(() => (0, import_client_ui_core50.emptyTranscript)());
|
|
143133
143913
|
const [diff3, setDiff] = (0, import_react54.useState)(null);
|
|
143134
143914
|
const diffFetchedFor = (0, import_react54.useRef)(null);
|
|
143135
143915
|
const [liveTerm, setLiveTerm] = (0, import_react54.useState)("");
|
|
@@ -143159,12 +143939,12 @@ function AgentsDashboard({
|
|
|
143159
143939
|
const launchRepos = panel.launchRepos ?? [];
|
|
143160
143940
|
const now2 = Date.now();
|
|
143161
143941
|
const byId = new Map(board.map((row) => [row.id, row]));
|
|
143162
|
-
const views = (0,
|
|
143942
|
+
const views = (0, import_client_ui_core50.sortJobRows)(board.map((row) => (0, import_client_ui_core50.jobRowView)(row, now2)));
|
|
143163
143943
|
const jobs = views.map((v2) => byId.get(v2.id));
|
|
143164
143944
|
const safeCursor = Math.min(cursor, Math.max(0, jobs.length - 1));
|
|
143165
143945
|
const detailId = screen.kind === "detail" ? screen.id : null;
|
|
143166
143946
|
const detailJob = detailId ? byId.get(detailId) ?? null : null;
|
|
143167
|
-
const inputMode = detailJob && (0, import_client_core51.isTerminal)(detailJob.status) ? (0,
|
|
143947
|
+
const inputMode = detailJob && (0, import_client_core51.isTerminal)(detailJob.status) ? (0, import_client_ui_core50.inputModeFor)(detailJob.status, true) : transcript.inputMode;
|
|
143168
143948
|
const panelRef = (0, import_react54.useRef)(panel);
|
|
143169
143949
|
panelRef.current = panel;
|
|
143170
143950
|
const screenRef = (0, import_react54.useRef)(screen);
|
|
@@ -143184,10 +143964,10 @@ function AgentsDashboard({
|
|
|
143184
143964
|
listJobs: (options) => panelRef.current.listJobs(options)
|
|
143185
143965
|
});
|
|
143186
143966
|
feedRef.current = feed;
|
|
143187
|
-
const deduper = new
|
|
143967
|
+
const deduper = new import_client_ui_core50.NotificationDeduper();
|
|
143188
143968
|
const sub = feed.subscribe((change) => {
|
|
143189
143969
|
if (change.kind === "patch") {
|
|
143190
|
-
const decision = (0,
|
|
143970
|
+
const decision = (0, import_client_ui_core50.notificationFor)(change.previous, change.job, { windowFocused: false, enabled: true });
|
|
143191
143971
|
if (decision && deduper.first(decision.dedupeKey)) panelRef.current.bell();
|
|
143192
143972
|
}
|
|
143193
143973
|
if (change.kind !== "health") {
|
|
@@ -143210,7 +143990,7 @@ function AgentsDashboard({
|
|
|
143210
143990
|
(0, import_react54.useEffect)(() => {
|
|
143211
143991
|
if (!detailId) return;
|
|
143212
143992
|
const seed = boardRef.current.find((row) => row.id === detailId);
|
|
143213
|
-
let current2 = seed ? (0,
|
|
143993
|
+
let current2 = seed ? (0, import_client_ui_core50.applyJobRow)((0, import_client_ui_core50.emptyTranscript)(detailId), seed) : (0, import_client_ui_core50.emptyTranscript)(detailId);
|
|
143214
143994
|
setTranscript(current2);
|
|
143215
143995
|
setDiff(null);
|
|
143216
143996
|
setLiveTerm("");
|
|
@@ -143254,7 +144034,7 @@ function AgentsDashboard({
|
|
|
143254
144034
|
}
|
|
143255
144035
|
}
|
|
143256
144036
|
if (message.kind === "job") feedRef.current?.applyRow(message.job.unread ? { ...message.job, unread: false } : message.job);
|
|
143257
|
-
current2 = (0,
|
|
144037
|
+
current2 = (0, import_client_ui_core50.applyStreamMessage)(current2, message);
|
|
143258
144038
|
schedule();
|
|
143259
144039
|
});
|
|
143260
144040
|
stream.start();
|
|
@@ -143842,13 +144622,13 @@ function footerHint(screen, job, messaging, conn, width, launch) {
|
|
|
143842
144622
|
}
|
|
143843
144623
|
function WatchLine({ status, accountsUrl }) {
|
|
143844
144624
|
if (!status) return null;
|
|
143845
|
-
const page = (0,
|
|
144625
|
+
const page = (0, import_client_ui_core50.watcherPageUrl)(accountsUrl);
|
|
143846
144626
|
return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(Box2, { flexDirection: "column", children: [
|
|
143847
144627
|
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(ThemedText, { children: [
|
|
143848
|
-
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: status.connections.length > 0 ? "success" : void 0, dim: status.connections.length === 0, children: `${status.connections.length > 0 ? "\u2691 " : ""}${(0,
|
|
144628
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: status.connections.length > 0 ? "success" : void 0, dim: status.connections.length === 0, children: `${status.connections.length > 0 ? "\u2691 " : ""}${(0, import_client_ui_core50.watchSummaryLine)(status.connections)}` }),
|
|
143849
144629
|
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { dim: true, children: page ? ` \xB7 manage at ${page}` : " \xB7 set up on the website" })
|
|
143850
144630
|
] }),
|
|
143851
|
-
status.connections.slice(0, 6).map((c3) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: ` ${(0,
|
|
144631
|
+
status.connections.slice(0, 6).map((c3) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { dim: true, wrap: "truncate-end", children: ` ${(0, import_client_ui_core50.watchConnectionLine)(c3)} \xB7 ${(0, import_client_ui_core50.watchHealthChip)(c3).label}` }, c3.id))
|
|
143852
144632
|
] });
|
|
143853
144633
|
}
|
|
143854
144634
|
function ConnectionsView({
|
|
@@ -144005,9 +144785,9 @@ function JobDetailView({
|
|
|
144005
144785
|
const terminal = (0, import_client_core51.isTerminal)(status);
|
|
144006
144786
|
const pending = queue.filter((item) => !item.sent_at);
|
|
144007
144787
|
const live = composer.mode !== "none" && composer.mode !== "launch";
|
|
144008
|
-
const row = job ? (0,
|
|
144009
|
-
const pill = row ? (0,
|
|
144010
|
-
const recording = job && (job.screen_state === "ready" || job.screen_state === "truncated") ? (0,
|
|
144788
|
+
const row = job ? (0, import_client_ui_core50.jobRowView)(job, Date.now()) : null;
|
|
144789
|
+
const pill = row ? (0, import_client_ui_core50.jobStatusPill)(status, row.failure) : null;
|
|
144790
|
+
const recording = job && (job.screen_state === "ready" || job.screen_state === "truncated") ? (0, import_client_ui_core50.recordingPageUrl)(accountsUrl, job.id) : null;
|
|
144011
144791
|
const errorLine = job?.error && !transcript.failure && terminal ? job.error : null;
|
|
144012
144792
|
(0, import_react54.useEffect)(() => {
|
|
144013
144793
|
const measure = () => {
|
|
@@ -144022,10 +144802,10 @@ function JobDetailView({
|
|
|
144022
144802
|
});
|
|
144023
144803
|
if (!job) return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { dim: true, children: "Job not found." });
|
|
144024
144804
|
if (handback?.mismatch) return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(MismatchCard, { job, card: handback.mismatch });
|
|
144025
|
-
const facts = [pill?.label ?? status, row?.sourceChip ?? "", repoName((0,
|
|
144805
|
+
const facts = [pill?.label ?? status, row?.sourceChip ?? "", repoName((0, import_client_ui_core50.repoSlug)(job.repo_url)), job.branch_name ?? (job.target_branch ? `\u2192 ${job.target_branch}` : ""), row?.elapsed ?? "", job.model ?? ""].filter(Boolean);
|
|
144026
144806
|
return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(Box2, { flexDirection: "column", flexGrow: 1, children: [
|
|
144027
144807
|
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(Box2, { flexDirection: "column", flexShrink: 0, children: [
|
|
144028
|
-
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: fitCell((0,
|
|
144808
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: "listSelection", bold: true, children: fitCell((0, import_client_ui_core50.jobTitle)(job), width).trimEnd() }),
|
|
144029
144809
|
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(Box2, { children: [
|
|
144030
144810
|
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: statusColorKey(status), bold: true, children: facts[0] }),
|
|
144031
144811
|
facts.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { dim: true, children: ` \xB7 ${fitCell(facts.slice(1).join(" \xB7 "), Math.max(0, width - facts[0].length - 5)).trimEnd()}` }) : null
|
|
@@ -144033,7 +144813,7 @@ function JobDetailView({
|
|
|
144033
144813
|
job.pr_url ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: "info", children: fitCell(`PR ${job.pr_url}${row?.prChip ? ` \xB7 ${row.prChip.replace(/^PR\s*/, "")}` : ""}`, width).trimEnd() }) : null,
|
|
144034
144814
|
recording ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: "info", children: fitCell(`Recording ${recording}${job.screen_state === "truncated" ? " \xB7 cut at the cap" : ""}`, width).trimEnd() }) : null,
|
|
144035
144815
|
errorLine ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: "error", children: fitCell(errorLine, width).trimEnd() }) : null,
|
|
144036
|
-
transcript.health === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: "error", children: fitCell((0,
|
|
144816
|
+
transcript.health === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { colorKey: "error", children: fitCell((0, import_client_ui_core50.streamFailureLine)(transcript), width).trimEnd() }) : transcript.health === "reconnecting" ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(ThemedText, { dim: true, children: "reconnecting\u2026" }) : null
|
|
144037
144817
|
] }),
|
|
144038
144818
|
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("ink-box", { ref: viewportRef, style: { flexDirection: "column", flexGrow: 1, flexShrink: 1, minHeight: 3, overflow: "hidden", marginTop: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("ink-box", { ref: bodyRef, style: { flexDirection: "column", flexShrink: 0, marginTop: -scroll }, children: [
|
|
144039
144819
|
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
@@ -144872,6 +145652,17 @@ var REMOTE_DENIED = /* @__PURE__ */ new Set([
|
|
|
144872
145652
|
"agent-messages"
|
|
144873
145653
|
]);
|
|
144874
145654
|
var REMOTE_ARG_REQUIRED = /* @__PURE__ */ new Set(["provider", "persona", "reasoning", "tokensave"]);
|
|
145655
|
+
function sendVerdict(outcome) {
|
|
145656
|
+
switch (outcome) {
|
|
145657
|
+
case "started":
|
|
145658
|
+
case "queued":
|
|
145659
|
+
return import_client_core54.RC_OK;
|
|
145660
|
+
case "declined":
|
|
145661
|
+
return (0, import_client_core54.rcRefusePhotosMidTurn)();
|
|
145662
|
+
case "blocked":
|
|
145663
|
+
return (0, import_client_core54.rcRefuse)("signed_out", "sign in on this machine and choose a model first");
|
|
145664
|
+
}
|
|
145665
|
+
}
|
|
144875
145666
|
function flattenInfoView(view) {
|
|
144876
145667
|
const lines = [view.title];
|
|
144877
145668
|
if (view.subtitle !== void 0 && view.subtitle !== "") lines.push(view.subtitle);
|
|
@@ -144922,8 +145713,8 @@ function startTuiRemoteControl(opts) {
|
|
|
144922
145713
|
opts.verbs.steer(text);
|
|
144923
145714
|
return import_client_core54.RC_OK;
|
|
144924
145715
|
}
|
|
144925
|
-
const
|
|
144926
|
-
return
|
|
145716
|
+
const outcome = attachments !== void 0 && attachments.length > 0 ? opts.verbs.send(text, attachments) : opts.verbs.send(text);
|
|
145717
|
+
return sendVerdict(outcome);
|
|
144927
145718
|
};
|
|
144928
145719
|
const commandCatalog = () => opts.commands === void 0 ? [] : opts.commands.registry.all().filter((command) => !REMOTE_DENIED.has(command.name)).map((command) => ({
|
|
144929
145720
|
name: command.name,
|
|
@@ -145188,7 +145979,7 @@ function startTuiRemoteControl(opts) {
|
|
|
145188
145979
|
|
|
145189
145980
|
// src/services/machineWake.ts
|
|
145190
145981
|
var import_client_core55 = __toESM(require_dist(), 1);
|
|
145191
|
-
var
|
|
145982
|
+
var import_client_ui_core51 = __toESM(require_dist2(), 1);
|
|
145192
145983
|
function createWakeIfIdle(deps2) {
|
|
145193
145984
|
return (prompt) => {
|
|
145194
145985
|
if (!deps2.isIdle()) return;
|
|
@@ -145210,7 +146001,7 @@ function createPeerDelivery(deps2) {
|
|
|
145210
146001
|
return (message) => {
|
|
145211
146002
|
const hold = (0, import_client_core55.inboundNoteToHold)(message, (userId) => deps2.trusted?.(userId) === true);
|
|
145212
146003
|
deps2.pen.hold(hold.item, hold.relayDepth, hold.turnStart);
|
|
145213
|
-
deps2.appendRow((0,
|
|
146004
|
+
deps2.appendRow((0, import_client_ui_core51.peerDeliveredRow)(message));
|
|
145214
146005
|
queueMicrotask(() => wakeIfIdle((0, import_client_core55.peerMessageWakePrompt)(message)));
|
|
145215
146006
|
};
|
|
145216
146007
|
}
|
|
@@ -145230,7 +146021,7 @@ function createTuiIdleWatcher(deps2) {
|
|
|
145230
146021
|
|
|
145231
146022
|
// src/services/friendsSurface.ts
|
|
145232
146023
|
var import_client_core56 = __toESM(require_dist(), 1);
|
|
145233
|
-
var
|
|
146024
|
+
var import_client_ui_core52 = __toESM(require_dist2(), 1);
|
|
145234
146025
|
function createTuiFriends(deps2) {
|
|
145235
146026
|
const store = new import_client_core56.FriendsStore({
|
|
145236
146027
|
api: {
|
|
@@ -145255,14 +146046,14 @@ function createTuiFriends(deps2) {
|
|
|
145255
146046
|
senderClass: () => deps2.senderClass(),
|
|
145256
146047
|
onSettled: (sessionId, review, outcome, detail) => {
|
|
145257
146048
|
if (sessionId !== deps2.currentSessionId()) return;
|
|
145258
|
-
deps2.appendRow((0,
|
|
145259
|
-
deps2.pen.hold((0, import_client_core56.harnessNoticeInput)((0,
|
|
146049
|
+
deps2.appendRow((0, import_client_ui_core52.friendSendSettledRow)(review, outcome, detail));
|
|
146050
|
+
deps2.pen.hold((0, import_client_core56.harnessNoticeInput)((0, import_client_ui_core52.friendSendNoticeForModel)(review, outcome, detail)));
|
|
145260
146051
|
},
|
|
145261
146052
|
onChanged: (sessionId) => {
|
|
145262
146053
|
if (sessionId !== deps2.currentSessionId()) return;
|
|
145263
146054
|
const pending = reviews.pendingFor(sessionId).length;
|
|
145264
146055
|
if (pendingReviews.arrived(sessionId, pending)) {
|
|
145265
|
-
deps2.appendRow(`${(0,
|
|
146056
|
+
deps2.appendRow(`${(0, import_client_ui_core52.friendSendPendingSummary)(pending)} \u2014 /messages to review`);
|
|
145266
146057
|
}
|
|
145267
146058
|
}
|
|
145268
146059
|
});
|
|
@@ -145544,12 +146335,12 @@ function shouldAutoApprove(fullyAutomatic, configAutoApprove) {
|
|
|
145544
146335
|
|
|
145545
146336
|
// src/headless/runHeadless.ts
|
|
145546
146337
|
var import_client_core59 = __toESM(require_dist(), 1);
|
|
145547
|
-
var
|
|
146338
|
+
var import_client_ui_core53 = __toESM(require_dist2(), 1);
|
|
145548
146339
|
import * as os7 from "os";
|
|
145549
146340
|
import { randomUUID } from "crypto";
|
|
145550
146341
|
function adoptTurnComplete(carry, data) {
|
|
145551
146342
|
if (Array.isArray(data.messages)) carry.messages = data.messages;
|
|
145552
|
-
(0,
|
|
146343
|
+
(0, import_client_ui_core53.mergeTurnComplete)(carry.clientState, data);
|
|
145553
146344
|
}
|
|
145554
146345
|
var HEADLESS_RESULT_PREFIX = "ORION_HEADLESS_RESULT ";
|
|
145555
146346
|
var HEADLESS_DEFAULT_MAX_TURNS = 100;
|
|
@@ -145790,7 +146581,7 @@ async function runHeadless(flags2) {
|
|
|
145790
146581
|
};
|
|
145791
146582
|
};
|
|
145792
146583
|
const sessionId = randomUUID();
|
|
145793
|
-
const carry = { messages: [], clientState: (0,
|
|
146584
|
+
const carry = { messages: [], clientState: (0, import_client_ui_core53.emptyClientState)() };
|
|
145794
146585
|
const trace = process.env.ORION_HEADLESS_TRACE === "1";
|
|
145795
146586
|
const runTurn = async (prompt) => {
|
|
145796
146587
|
const ac = new AbortController();
|
|
@@ -145819,7 +146610,9 @@ async function runHeadless(flags2) {
|
|
|
145819
146610
|
...boundary.makeHandlers(sessionId, ac.signal, onEvent),
|
|
145820
146611
|
isCancelRequested: () => false,
|
|
145821
146612
|
onPhaseChange: () => void 0
|
|
145822
|
-
}
|
|
146613
|
+
},
|
|
146614
|
+
// A turn that fails ends the run (below): nothing reads what it left.
|
|
146615
|
+
import_client_core59.CLOSE_TURNS_IN_BACKGROUND
|
|
145823
146616
|
);
|
|
145824
146617
|
const data = outcome.event.data ?? {};
|
|
145825
146618
|
if (outcome.kind === "turn_error") {
|
|
@@ -145869,7 +146662,7 @@ async function runHeadless(flags2) {
|
|
|
145869
146662
|
|
|
145870
146663
|
// src/services/feedbackGate.ts
|
|
145871
146664
|
var import_client_core60 = __toESM(require_dist(), 1);
|
|
145872
|
-
var
|
|
146665
|
+
var import_client_ui_core54 = __toESM(require_dist2(), 1);
|
|
145873
146666
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
145874
146667
|
var TuiFeedbackGate = class {
|
|
145875
146668
|
constructor(deps2) {
|
|
@@ -145889,13 +146682,13 @@ var TuiFeedbackGate = class {
|
|
|
145889
146682
|
maybeOffer(sessionId, turnId) {
|
|
145890
146683
|
const now2 = this.now();
|
|
145891
146684
|
const config = this.deps.loadConfig();
|
|
145892
|
-
let state = (0,
|
|
146685
|
+
let state = (0, import_client_ui_core54.feedbackStateFromScalars)(config, now2);
|
|
145893
146686
|
if (config.feedbackFirstSeenAt <= 0 || config.feedbackSeed === 0) {
|
|
145894
|
-
state = { ...state, seed: (0,
|
|
145895
|
-
this.safeSave((0,
|
|
146687
|
+
state = { ...state, seed: (0, import_client_ui_core54.mintFeedbackSeed)() };
|
|
146688
|
+
this.safeSave((0, import_client_ui_core54.feedbackScalarsFromState)(state));
|
|
145896
146689
|
}
|
|
145897
146690
|
const pendings = this.deps.getPendings();
|
|
145898
|
-
const offer = (0,
|
|
146691
|
+
const offer = (0, import_client_ui_core54.shouldOfferFeedback)(state, {
|
|
145899
146692
|
now: now2,
|
|
145900
146693
|
completedTurnsThisSession: this.turnsBySession.get(sessionId) ?? 0,
|
|
145901
146694
|
turnCompletedCleanly: true,
|
|
@@ -145906,8 +146699,8 @@ var TuiFeedbackGate = class {
|
|
|
145906
146699
|
forced: this.deps.forced
|
|
145907
146700
|
});
|
|
145908
146701
|
if (!offer) return;
|
|
145909
|
-
state = (0,
|
|
145910
|
-
this.safeSave((0,
|
|
146702
|
+
state = (0, import_client_ui_core54.applyFeedbackShown)(state, now2);
|
|
146703
|
+
this.safeSave((0, import_client_ui_core54.feedbackScalarsFromState)(state));
|
|
145911
146704
|
const routing = this.deps.getRouting();
|
|
145912
146705
|
const requestId = randomUUID2();
|
|
145913
146706
|
this.pendingId = requestId;
|
|
@@ -145929,10 +146722,10 @@ var TuiFeedbackGate = class {
|
|
|
145929
146722
|
const snapshot = this.deps.getMessages().slice();
|
|
145930
146723
|
const now2 = this.now();
|
|
145931
146724
|
const config = this.deps.loadConfig();
|
|
145932
|
-
const state = (0,
|
|
145933
|
-
this.safeSave((0,
|
|
145934
|
-
const card = (0,
|
|
145935
|
-
const body2 = (0,
|
|
146725
|
+
const state = (0, import_client_ui_core54.applyFeedbackSubmitted)((0, import_client_ui_core54.feedbackStateFromScalars)(config, now2), now2);
|
|
146726
|
+
this.safeSave((0, import_client_ui_core54.feedbackScalarsFromState)(state));
|
|
146727
|
+
const card = (0, import_client_ui_core54.feedbackSetWhy)((0, import_client_ui_core54.feedbackSelectScore)((0, import_client_ui_core54.createFeedbackCard)(), score), why);
|
|
146728
|
+
const body2 = (0, import_client_ui_core54.buildFeedbackSubmission)(card, {
|
|
145936
146729
|
submissionId: randomUUID2(),
|
|
145937
146730
|
sessionId: meta.sessionId,
|
|
145938
146731
|
turnId: meta.turnId,
|
|
@@ -145947,7 +146740,7 @@ var TuiFeedbackGate = class {
|
|
|
145947
146740
|
conversation,
|
|
145948
146741
|
conversation_truncated: truncated
|
|
145949
146742
|
});
|
|
145950
|
-
this.deps.appendNote(
|
|
146743
|
+
this.deps.appendNote(import_client_ui_core54.FEEDBACK_WORDING.transcriptNote);
|
|
145951
146744
|
return true;
|
|
145952
146745
|
}
|
|
145953
146746
|
/** The session/transcript under a pending card is going away (new chat, resume) —
|
|
@@ -145966,11 +146759,11 @@ var TuiFeedbackGate = class {
|
|
|
145966
146759
|
this.deps.setPendingFeedback(null);
|
|
145967
146760
|
if (explicit) {
|
|
145968
146761
|
const now2 = this.now();
|
|
145969
|
-
const state = (0,
|
|
145970
|
-
(0,
|
|
146762
|
+
const state = (0, import_client_ui_core54.applyFeedbackDismissed)(
|
|
146763
|
+
(0, import_client_ui_core54.feedbackStateFromScalars)(this.deps.loadConfig(), now2),
|
|
145971
146764
|
now2
|
|
145972
146765
|
);
|
|
145973
|
-
this.safeSave((0,
|
|
146766
|
+
this.safeSave((0, import_client_ui_core54.feedbackScalarsFromState)(state));
|
|
145974
146767
|
void (0, import_client_core60.sendFeedbackImpression)(this.deps.submit, "dismissed", "tui");
|
|
145975
146768
|
}
|
|
145976
146769
|
return true;
|
|
@@ -146045,10 +146838,10 @@ async function main() {
|
|
|
146045
146838
|
const flags2 = parseLaunchFlags(process.argv.slice(2));
|
|
146046
146839
|
const latestSaved = () => [...loadIndex()].sort((a, b2) => b2.updatedAt - a.updatedAt)[0]?.sessionId ?? null;
|
|
146047
146840
|
const resumeId = flags2.resumeId ?? (flags2.continueLast ? latestSaved() : null);
|
|
146048
|
-
const commandUsage = new
|
|
146841
|
+
const commandUsage = new import_client_ui_core56.CommandUsage(fileUsageStorage());
|
|
146049
146842
|
const sessionNumber = config.sessionsStarted + 1;
|
|
146050
146843
|
saveConfig({ sessionsStarted: sessionNumber });
|
|
146051
|
-
const tips = new
|
|
146844
|
+
const tips = new import_client_ui_core56.TipService({ host: "tui", state: config.tips, save: (state) => saveConfig({ tips: state }), session: sessionNumber });
|
|
146052
146845
|
let turnsCompleted = 0;
|
|
146053
146846
|
let steeredThisSession = 0;
|
|
146054
146847
|
let changedFilesSession = 0;
|
|
@@ -146275,7 +147068,7 @@ async function main() {
|
|
|
146275
147068
|
// the store's referential stability: unchanged state returns the same object.
|
|
146276
147069
|
(relPath) => transcriptStore.setState((s) => {
|
|
146277
147070
|
const clientState = { ...s.clientState };
|
|
146278
|
-
if (!(0,
|
|
147071
|
+
if (!(0, import_client_ui_core57.dropSeenPath)(clientState, relPath)) return s;
|
|
146279
147072
|
return { ...s, clientState };
|
|
146280
147073
|
}),
|
|
146281
147074
|
{ rgPath: ripgrep.locate(), mode: config.indexMode }
|
|
@@ -146383,15 +147176,6 @@ async function main() {
|
|
|
146383
147176
|
send: (text, attachments) => void sendTurn(text, void 0, attachments),
|
|
146384
147177
|
runCommand: (text) => routeInput(text)
|
|
146385
147178
|
});
|
|
146386
|
-
const settleInterrupted = (turn) => {
|
|
146387
|
-
if (turn.settled) return;
|
|
146388
|
-
turn.settled = true;
|
|
146389
|
-
transcriptStore.setState((s) => {
|
|
146390
|
-
const hadLive = s.live !== null;
|
|
146391
|
-
const next = applyTurnInterrupted(s, turn.promptText, turn.partialText);
|
|
146392
|
-
return hadLive ? appendNote(next, INTERRUPT_NOTE) : next;
|
|
146393
|
-
});
|
|
146394
|
-
};
|
|
146395
147179
|
let lastTurnComplete = null;
|
|
146396
147180
|
let lastDuetExecutorStatus = null;
|
|
146397
147181
|
const onRenderEvent = (rawEvent) => {
|
|
@@ -146698,19 +147482,19 @@ async function main() {
|
|
|
146698
147482
|
controller: turn.abort,
|
|
146699
147483
|
sendCancel: () => turnTransport.cancelTurn(turn.sessionId)
|
|
146700
147484
|
});
|
|
146701
|
-
appStore.setState((s) => ({ ...s, statusText: "stopping\u2026", ...clearParkedForStop(s) }));
|
|
147485
|
+
appStore.setState((s) => ({ ...s, stopping: true, statusText: "stopping\u2026", ...clearParkedForStop(s) }));
|
|
146702
147486
|
rejectPendingWorkPlan();
|
|
146703
147487
|
return;
|
|
146704
147488
|
}
|
|
146705
|
-
|
|
147489
|
+
const closing = turn !== null && !turn.settled;
|
|
147490
|
+
if (turn) showInterrupted(transcriptStore, turn);
|
|
146706
147491
|
turn?.abort.abort();
|
|
146707
147492
|
rejectPendingWorkPlan();
|
|
146708
147493
|
appStore.setState((s) => ({
|
|
146709
147494
|
...s,
|
|
146710
147495
|
...clearParkedForStop(s),
|
|
146711
147496
|
// same one definition as the graceful branch
|
|
146712
|
-
status: "idle",
|
|
146713
|
-
statusText: "",
|
|
147497
|
+
...closing ? { stopping: true } : { status: "idle", statusText: "", stopping: false },
|
|
146714
147498
|
turnStartedAt: 0,
|
|
146715
147499
|
// an interrupted turn stamps no Orbited line
|
|
146716
147500
|
waitingOnPreviousTurn: false
|
|
@@ -146760,7 +147544,7 @@ async function main() {
|
|
|
146760
147544
|
const pending = appStore.getState().pendingPlanApproval;
|
|
146761
147545
|
boundary.resolvePlanApproval(requestId, decision, sid, feedback);
|
|
146762
147546
|
if (pending?.requestId === requestId) {
|
|
146763
|
-
const record = (0,
|
|
147547
|
+
const record = (0, import_client_ui_core57.planDecisionRecord)({ decision, feedback }, { planPath: pending.planPath });
|
|
146764
147548
|
if (record) {
|
|
146765
147549
|
const note = planDecisionNote(record);
|
|
146766
147550
|
transcriptStore.setState((s) => appendNote(s, note.text, note.tone ? { tone: note.tone } : void 0));
|
|
@@ -146807,7 +147591,7 @@ async function main() {
|
|
|
146807
147591
|
notify: (sid, message, status) => {
|
|
146808
147592
|
rc?.host.reportAgentNotice(sid, message, status);
|
|
146809
147593
|
if (status === "expired" && sid === sessionId) {
|
|
146810
|
-
transcriptStore.setState((s) => appendNote(s, (0,
|
|
147594
|
+
transcriptStore.setState((s) => appendNote(s, (0, import_client_ui_core57.peerSettledRow)(message, "expired")));
|
|
146811
147595
|
}
|
|
146812
147596
|
},
|
|
146813
147597
|
onHeldChanged: (sid) => {
|
|
@@ -146816,14 +147600,14 @@ async function main() {
|
|
|
146816
147600
|
appStore.setState((s) => ({ ...s, heldPeerMessages: waiting }));
|
|
146817
147601
|
if (waiting > before) {
|
|
146818
147602
|
transcriptStore.setState(
|
|
146819
|
-
(s) => appendNote(s, `${(0,
|
|
147603
|
+
(s) => appendNote(s, `${(0, import_client_ui_core57.peerHeldSummary)(waiting)} \u2014 /messages to review`)
|
|
146820
147604
|
);
|
|
146821
147605
|
}
|
|
146822
147606
|
},
|
|
146823
147607
|
onWaitingChanged: (sid) => {
|
|
146824
147608
|
const arrived = waitingFriendNotes.arrived(sid, peerInbox.waitingFor(sid).length);
|
|
146825
147609
|
if (arrived && sid === sessionId) {
|
|
146826
|
-
transcriptStore.setState((s) => appendNote(s,
|
|
147610
|
+
transcriptStore.setState((s) => appendNote(s, import_client_ui_core55.FRIEND_NOTE_WAITING_ROW));
|
|
146827
147611
|
}
|
|
146828
147612
|
}
|
|
146829
147613
|
});
|
|
@@ -147002,7 +147786,7 @@ async function main() {
|
|
|
147002
147786
|
event: "file_modified",
|
|
147003
147787
|
session_id: sid,
|
|
147004
147788
|
timestamp: Date.now(),
|
|
147005
|
-
data: { ...data, agent_label: (0,
|
|
147789
|
+
data: { ...data, agent_label: (0, import_client_ui_core57.subagentLabel)(agent) }
|
|
147006
147790
|
}),
|
|
147007
147791
|
getOrionResources: () => (0, import_client_core61.buildOrionSnapshot)(config.workspaceRoot, void 0, sid),
|
|
147008
147792
|
// Full-dose source for review-persona children (lesson dosing) — the same
|
|
@@ -147129,11 +147913,6 @@ async function main() {
|
|
|
147129
147913
|
disposeFallback: null,
|
|
147130
147914
|
phase: "stream",
|
|
147131
147915
|
hadEdits: false,
|
|
147132
|
-
// The stop-repair inputs (see settleInterrupted): the OUTGOING prompt (a
|
|
147133
|
-
// skill turn is identified by its typed form); the partial reply
|
|
147134
|
-
// accumulates from this turn's own deltas in onEvent below.
|
|
147135
|
-
promptText: start2.text ?? (start2.skill ? `/${start2.skill.name}${start2.skill.args ? ` ${start2.skill.args}` : ""}` : null),
|
|
147136
|
-
partialText: "",
|
|
147137
147916
|
settled: false
|
|
147138
147917
|
};
|
|
147139
147918
|
currentTurn = turn;
|
|
@@ -147169,7 +147948,7 @@ async function main() {
|
|
|
147169
147948
|
)
|
|
147170
147949
|
);
|
|
147171
147950
|
if (currentTurn === turn) currentTurn = null;
|
|
147172
|
-
appStore.setState((s) => ({ ...s, status: "idle", statusText: "" }));
|
|
147951
|
+
appStore.setState((s) => ({ ...s, status: "idle", statusText: "", stopping: false }));
|
|
147173
147952
|
endSettle = { kind: "error", message: `custom endpoint '${name2}' is not configured` };
|
|
147174
147953
|
fireTurnEnd();
|
|
147175
147954
|
return;
|
|
@@ -147227,10 +148006,6 @@ async function main() {
|
|
|
147227
148006
|
let sawEvent = false;
|
|
147228
148007
|
const onEvent = (ev) => {
|
|
147229
148008
|
sawEvent = true;
|
|
147230
|
-
if (ev.event === "text_delta" && !ev.agent_id) {
|
|
147231
|
-
const delta = ev.data?.delta;
|
|
147232
|
-
if (typeof delta === "string") turn.partialText += delta;
|
|
147233
|
-
}
|
|
147234
148009
|
onRenderEvent(ev);
|
|
147235
148010
|
};
|
|
147236
148011
|
try {
|
|
@@ -147362,30 +148137,30 @@ async function main() {
|
|
|
147362
148137
|
kind: "error",
|
|
147363
148138
|
message: typeof data.error === "string" ? data.error : "turn failed"
|
|
147364
148139
|
};
|
|
147365
|
-
|
|
147366
|
-
settleInterrupted(turn);
|
|
147367
|
-
} else {
|
|
147368
|
-
turn.settled = true;
|
|
147369
|
-
}
|
|
148140
|
+
turn.settled = true;
|
|
147370
148141
|
}
|
|
147371
148142
|
} catch (e) {
|
|
147372
148143
|
if (ac.signal.aborted || turn.cancelRequested) {
|
|
147373
148144
|
settleOutcome = "cancelled";
|
|
147374
148145
|
endSettle = { kind: "cancelled" };
|
|
147375
|
-
settleInterrupted(turn);
|
|
148146
|
+
settleInterrupted(transcriptStore, turn, (0, import_client_core62.interruptedTurnOf)(e));
|
|
147376
148147
|
if (currentTurn === turn) {
|
|
147377
148148
|
appStore.setState((s) => ({ ...s, status: "idle", statusText: "", error: null }));
|
|
147378
148149
|
}
|
|
147379
148150
|
return;
|
|
147380
148151
|
}
|
|
147381
|
-
turn.settled = true;
|
|
147382
148152
|
settleOutcome = "error";
|
|
147383
148153
|
const msg = e instanceof Error ? e.message : String(e);
|
|
147384
148154
|
endSettle = { kind: "error", message: msg };
|
|
148155
|
+
const left = (0, import_client_core62.interruptedTurnOf)(e);
|
|
148156
|
+
if (left !== void 0 && transcriptStore.getState().sessionId === sid) {
|
|
148157
|
+
transcriptStore.setState((t) => applyTurnError(t, { error: msg, messages: left.messages }));
|
|
148158
|
+
}
|
|
148159
|
+
turn.settled = true;
|
|
147385
148160
|
if (currentTurn === turn) {
|
|
147386
148161
|
if (!sawEvent) transcriptStore.setState(() => snapshot);
|
|
147387
|
-
const { modelLabel, model } = appStore.getState();
|
|
147388
|
-
const failure = turnErrorNote({ error: msg }, modelLabel || displayModel(model));
|
|
148162
|
+
const { modelLabel, model, provider, mode } = appStore.getState();
|
|
148163
|
+
const failure = turnErrorNote({ error: msg }, modelLabel || displayModel(model), { provider, mode });
|
|
147389
148164
|
transcriptStore.setState((t) => appendNote(t, failure.text, { tone: "error" }));
|
|
147390
148165
|
appStore.setState((s) => ({ ...s, status: "error", statusText: failure.headline, error: msg }));
|
|
147391
148166
|
}
|
|
@@ -147423,7 +148198,10 @@ async function main() {
|
|
|
147423
148198
|
assistantText: endSettle.kind === "complete" ? endSettle.finalText : ""
|
|
147424
148199
|
});
|
|
147425
148200
|
}
|
|
147426
|
-
if (currentTurn === turn)
|
|
148201
|
+
if (currentTurn === turn) {
|
|
148202
|
+
currentTurn = null;
|
|
148203
|
+
appStore.setState((s) => s.stopping ? { ...s, stopping: false } : s);
|
|
148204
|
+
}
|
|
147427
148205
|
fireTurnEnd();
|
|
147428
148206
|
}
|
|
147429
148207
|
};
|
|
@@ -147688,18 +148466,23 @@ async function main() {
|
|
|
147688
148466
|
// is defined below; the closure reads it lazily, after startup has built it.
|
|
147689
148467
|
commands: { registry, contextFor: () => cmdCtx },
|
|
147690
148468
|
verbs: {
|
|
147691
|
-
|
|
147692
|
-
|
|
147693
|
-
|
|
147694
|
-
|
|
147695
|
-
|
|
148469
|
+
// A phone-driven turn is UNATTENDED at the terminal — origin "system" so the
|
|
148470
|
+
// feedback card never takes over a composer nobody is watching (the PA relies
|
|
148471
|
+
// on its isAttendedActive gate for the same path; the TUI has no attach state,
|
|
148472
|
+
// so origin is the equivalent signal). A send landing on a LIVE turn folds
|
|
148473
|
+
// into the steer queue (the gate — a phone can't race the terminal into two
|
|
148474
|
+
// concurrent turns); only a photo-bearing send declines then (the phone lane's
|
|
148475
|
+
// own rule, see `sendTurn`). The outcome itself goes back, so the phone hears
|
|
148476
|
+
// WHY a send did not start — signed out, no model chosen, photos mid-turn —
|
|
148477
|
+
// in the remote host's words for each.
|
|
148478
|
+
send: (text, attachments) => sendTurn(text, void 0, attachments, "system", { from: "phone" }),
|
|
147696
148479
|
steer: (text) => enqueueMachineSteer(text),
|
|
147697
148480
|
// Every note meets the receive policy first: delivered, held for the person at this
|
|
147698
148481
|
// terminal, or refused — and the sender is told which (`peerInbox.ts`).
|
|
147699
148482
|
deliverAgentMessage: (message) => void peerInbox.receive(sessionId, message),
|
|
147700
148483
|
deliverAgentNotice: (notice) => {
|
|
147701
|
-
transcriptStore.setState((s) => appendNote(s, (0,
|
|
147702
|
-
heldInputs.hold((0, import_client_core62.harnessNoticeInput)((0,
|
|
148484
|
+
transcriptStore.setState((s) => appendNote(s, (0, import_client_ui_core57.peerNoticeRow)(notice)));
|
|
148485
|
+
heldInputs.hold((0, import_client_core62.harnessNoticeInput)((0, import_client_ui_core57.peerNoticeForModel)(notice)));
|
|
147703
148486
|
},
|
|
147704
148487
|
agentMessagingEnabled: () => (0, import_client_core62.agentMessagesFor)(config.workspaceRoot).choice !== "off",
|
|
147705
148488
|
agentMailWithoutPhone: () => (0, import_client_core62.wantsMailWithoutPhone)((0, import_client_core62.agentMessagesFor)(config.workspaceRoot)),
|
|
@@ -147815,15 +148598,15 @@ async function main() {
|
|
|
147815
148598
|
};
|
|
147816
148599
|
const showTip = (force) => {
|
|
147817
148600
|
const tip = tips.next(currentTipMoment(), force);
|
|
147818
|
-
if (tip) transcriptStore.setState((t) => appendNote(t, (0,
|
|
148601
|
+
if (tip) transcriptStore.setState((t) => appendNote(t, (0, import_client_ui_core56.tipLine)(tip), { ephemeral: true }));
|
|
147819
148602
|
return tip !== null;
|
|
147820
148603
|
};
|
|
147821
148604
|
if (sessionNumber === 1) showTip(true);
|
|
147822
148605
|
{
|
|
147823
148606
|
const version = tuiVersion();
|
|
147824
|
-
if ((0,
|
|
147825
|
-
const url = (0,
|
|
147826
|
-
transcriptStore.setState((t) => appendNote(t, `${(0,
|
|
148607
|
+
if ((0, import_client_ui_core55.shouldOfferWhatsNew)(version, config.lastSeenVersion || null)) {
|
|
148608
|
+
const url = (0, import_client_ui_core55.changelogUrl)(config.accountsUrl);
|
|
148609
|
+
transcriptStore.setState((t) => appendNote(t, `${(0, import_client_ui_core55.whatsNewLine)(version)}${url ? ` \u2014 what changed: ${url}` : ""}`, { ephemeral: true }));
|
|
147827
148610
|
}
|
|
147828
148611
|
if (version && version !== config.lastSeenVersion) saveConfig({ lastSeenVersion: version });
|
|
147829
148612
|
}
|
|
@@ -148012,7 +148795,7 @@ async function main() {
|
|
|
148012
148795
|
void (0, import_client_core62.loadCustomProviders)(opts).then(panel);
|
|
148013
148796
|
}
|
|
148014
148797
|
};
|
|
148015
|
-
const commandTypoGuard = new
|
|
148798
|
+
const commandTypoGuard = new import_client_ui_core56.CommandTypoGuard(() => registry.all());
|
|
148016
148799
|
const routeInput = (text, source2 = "input") => {
|
|
148017
148800
|
appStore.setState((s) => s.status === "error" ? { ...s, status: "idle", statusText: "" } : s);
|
|
148018
148801
|
return routeChatInput(text, {
|