@dudousxd/nestjs-agent-opencode 0.4.0 → 0.4.1
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/README.md +10 -3
- package/dist/durable/index.cjs +261 -12
- package/dist/durable/index.cjs.map +1 -1
- package/dist/durable/index.d.cts +3 -2
- package/dist/durable/index.d.ts +3 -2
- package/dist/durable/index.js +261 -12
- package/dist/durable/index.js.map +1 -1
- package/dist/{engine-BNNxQAFV.d.cts → engine-BX6MLzxs.d.cts} +102 -8
- package/dist/{engine-BNNxQAFV.d.ts → engine-BX6MLzxs.d.ts} +102 -8
- package/dist/index.cjs +257 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +256 -10
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ var index_exports = {};
|
|
|
23
23
|
__export(index_exports, {
|
|
24
24
|
FormAnswerError: () => FormAnswerError,
|
|
25
25
|
InMemoryOpenCodeSessionStore: () => InMemoryOpenCodeSessionStore,
|
|
26
|
+
LOST_ANSWER_ERROR: () => LOST_ANSWER_ERROR,
|
|
26
27
|
OPENCODE_HOST: () => OPENCODE_HOST,
|
|
27
28
|
OPENCODE_MCP_ENDPOINT: () => OPENCODE_MCP_ENDPOINT,
|
|
28
29
|
OPENCODE_OPTIONS: () => OPENCODE_OPTIONS,
|
|
@@ -326,6 +327,9 @@ function subUsage(a, b) {
|
|
|
326
327
|
};
|
|
327
328
|
}
|
|
328
329
|
__name(subUsage, "subUsage");
|
|
330
|
+
var LOST_ANSWER_ERROR = "The answer was lost while the agent restarted; ask again.";
|
|
331
|
+
var RECOVER_PAGES = 10;
|
|
332
|
+
var RECOVER_PAGE_SIZE = 100;
|
|
329
333
|
var ASK_TOOL_NAME = "ask";
|
|
330
334
|
var FAILED_STATUSES = /* @__PURE__ */ new Set([
|
|
331
335
|
"error",
|
|
@@ -414,6 +418,14 @@ var OpenCodeTurn = class {
|
|
|
414
418
|
wroteMessage = false;
|
|
415
419
|
ended = false;
|
|
416
420
|
stepError;
|
|
421
|
+
/** What this turn object took from the session's assistant messages (see {@link TurnProgress}). */
|
|
422
|
+
took = {
|
|
423
|
+
text: /* @__PURE__ */ new Map(),
|
|
424
|
+
reasoning: /* @__PURE__ */ new Map(),
|
|
425
|
+
called: /* @__PURE__ */ new Set(),
|
|
426
|
+
settled: /* @__PURE__ */ new Set(),
|
|
427
|
+
steps: /* @__PURE__ */ new Set()
|
|
428
|
+
};
|
|
417
429
|
constructor(a) {
|
|
418
430
|
this.a = a;
|
|
419
431
|
this.model = modelOfLabel(a.input.model);
|
|
@@ -431,6 +443,30 @@ var OpenCodeTurn = class {
|
|
|
431
443
|
tokens: info.tokens
|
|
432
444
|
};
|
|
433
445
|
}
|
|
446
|
+
/** What the turn took so far: carried from before this turn object, plus what it took. */
|
|
447
|
+
progress() {
|
|
448
|
+
const before = this.a.progress;
|
|
449
|
+
const merged = /* @__PURE__ */ __name((carried, own) => {
|
|
450
|
+
const out = {
|
|
451
|
+
...carried ?? {}
|
|
452
|
+
};
|
|
453
|
+
for (const [id, n] of own) out[id] = (out[id] ?? 0) + n;
|
|
454
|
+
return out;
|
|
455
|
+
}, "merged");
|
|
456
|
+
const union = /* @__PURE__ */ __name((carried, own) => [
|
|
457
|
+
.../* @__PURE__ */ new Set([
|
|
458
|
+
...carried ?? [],
|
|
459
|
+
...own
|
|
460
|
+
])
|
|
461
|
+
], "union");
|
|
462
|
+
return {
|
|
463
|
+
text: merged(before?.text, this.took.text),
|
|
464
|
+
reasoning: merged(before?.reasoning, this.took.reasoning),
|
|
465
|
+
called: union(before?.called, this.took.called),
|
|
466
|
+
settled: union(before?.settled, this.took.settled),
|
|
467
|
+
steps: union(before?.steps, this.took.steps)
|
|
468
|
+
};
|
|
469
|
+
}
|
|
434
470
|
/** What the run spent so far: carried from before this turn object, plus what it saw. */
|
|
435
471
|
totalUsage() {
|
|
436
472
|
return addUsage(this.a.carried, this.spent);
|
|
@@ -521,7 +557,11 @@ var OpenCodeTurn = class {
|
|
|
521
557
|
this.reported = {
|
|
522
558
|
...this.spent
|
|
523
559
|
};
|
|
524
|
-
const milestone = {
|
|
560
|
+
const milestone = reached.kind === "ask" ? {
|
|
561
|
+
...reached,
|
|
562
|
+
usage,
|
|
563
|
+
progress: this.progress()
|
|
564
|
+
} : {
|
|
525
565
|
...reached,
|
|
526
566
|
usage
|
|
527
567
|
};
|
|
@@ -576,6 +616,7 @@ var OpenCodeTurn = class {
|
|
|
576
616
|
innerSettled: /* @__PURE__ */ new Set()
|
|
577
617
|
};
|
|
578
618
|
this.tools.set(id, state);
|
|
619
|
+
this.took.called.add(id);
|
|
579
620
|
this.segment.calls.push({
|
|
580
621
|
id,
|
|
581
622
|
name,
|
|
@@ -703,6 +744,7 @@ var OpenCodeTurn = class {
|
|
|
703
744
|
case "session.text.delta": {
|
|
704
745
|
const delta = typeof d.delta === "string" ? d.delta : "";
|
|
705
746
|
if (!delta) return;
|
|
747
|
+
this.count(this.took.text, d.assistantMessageID, delta.length);
|
|
706
748
|
this.endReasoning();
|
|
707
749
|
if (!this.sawText && !delta.trim()) return;
|
|
708
750
|
await this.step();
|
|
@@ -724,6 +766,7 @@ ${delta}` : delta;
|
|
|
724
766
|
case "session.reasoning.delta": {
|
|
725
767
|
const delta = typeof d.delta === "string" ? d.delta : "";
|
|
726
768
|
if (!delta) return;
|
|
769
|
+
this.count(this.took.reasoning, d.assistantMessageID, delta.length);
|
|
727
770
|
this.reasoningSince ??= Date.now();
|
|
728
771
|
await this.step();
|
|
729
772
|
this.segment.reasoning += delta;
|
|
@@ -778,6 +821,7 @@ ${delta}` : delta;
|
|
|
778
821
|
}
|
|
779
822
|
case "session.step.ended":
|
|
780
823
|
this.endReasoning();
|
|
824
|
+
if (typeof d.assistantMessageID === "string") this.took.steps.add(d.assistantMessageID);
|
|
781
825
|
await this.stepEnded(d);
|
|
782
826
|
return;
|
|
783
827
|
case "session.step.failed":
|
|
@@ -818,10 +862,16 @@ ${delta}` : delta;
|
|
|
818
862
|
return;
|
|
819
863
|
}
|
|
820
864
|
}
|
|
865
|
+
/** Characters taken from an assistant message's text or reasoning. */
|
|
866
|
+
count(into, messageId, n) {
|
|
867
|
+
if (typeof messageId !== "string") return;
|
|
868
|
+
into.set(messageId, (into.get(messageId) ?? 0) + n);
|
|
869
|
+
}
|
|
821
870
|
async settleTool(id, ok, error = "failed") {
|
|
822
871
|
const state = this.tool(id);
|
|
823
872
|
if (state.settled) return;
|
|
824
873
|
state.settled = true;
|
|
874
|
+
this.took.settled.add(id);
|
|
825
875
|
if (ok) {
|
|
826
876
|
this.segment.results.push({
|
|
827
877
|
id,
|
|
@@ -1371,9 +1421,171 @@ ${delta}` : delta;
|
|
|
1371
1421
|
cost: cost < 1e-9 ? 0 : cost
|
|
1372
1422
|
}, this.compacted ? "history_summary" : "title");
|
|
1373
1423
|
}
|
|
1374
|
-
|
|
1424
|
+
/**
|
|
1425
|
+
* The session's messages since this turn's prompt, oldest first: everything after its newest user
|
|
1426
|
+
* message. `undefined` when they cannot be read (no `message.list`, no prompt within reach); empty
|
|
1427
|
+
* when the newest prompt is another run's (this turn's never reached the session).
|
|
1428
|
+
*/
|
|
1429
|
+
async messagesSincePrompt() {
|
|
1430
|
+
const messages = this.a.client.message;
|
|
1431
|
+
if (messages === void 0) return void 0;
|
|
1432
|
+
const since = [];
|
|
1433
|
+
let cursor;
|
|
1434
|
+
for (let page = 0; page < RECOVER_PAGES; page += 1) {
|
|
1435
|
+
const listed = await messages.list({
|
|
1436
|
+
sessionID: this.a.sessionId,
|
|
1437
|
+
order: "desc",
|
|
1438
|
+
limit: RECOVER_PAGE_SIZE,
|
|
1439
|
+
...cursor !== void 0 ? {
|
|
1440
|
+
cursor
|
|
1441
|
+
} : {}
|
|
1442
|
+
});
|
|
1443
|
+
for (const message of listed.data) {
|
|
1444
|
+
if (message.type === "user") {
|
|
1445
|
+
const runId = message.metadata?.runId;
|
|
1446
|
+
if (typeof runId === "string" && runId !== this.a.runId) return [];
|
|
1447
|
+
return since.reverse();
|
|
1448
|
+
}
|
|
1449
|
+
since.push(message);
|
|
1450
|
+
}
|
|
1451
|
+
const next = listed.cursor?.next;
|
|
1452
|
+
if (typeof next !== "string" || next.length === 0 || listed.data.length === 0) break;
|
|
1453
|
+
cursor = next;
|
|
1454
|
+
}
|
|
1455
|
+
return void 0;
|
|
1456
|
+
}
|
|
1457
|
+
/**
|
|
1458
|
+
* A turn rebuilt after a restart heard only what the session said once it re-attached: what it
|
|
1459
|
+
* said in between — read back from the session's messages since the prompt, less what an earlier
|
|
1460
|
+
* process already took ({@link TurnProgress}) and what this one heard — is taken now, as its
|
|
1461
|
+
* events would have been: text, reasoning, tool calls and results, each step's usage. A session
|
|
1462
|
+
* that left nothing for the turn fails it ({@link LOST_ANSWER_ERROR}) rather than reading as an
|
|
1463
|
+
* empty answer.
|
|
1464
|
+
*/
|
|
1465
|
+
async recover(outcome) {
|
|
1466
|
+
const messages = await this.messagesSincePrompt().catch((error) => {
|
|
1467
|
+
this.a.logger.warn(`run ${this.a.runId}: ${errorText(error, "could not read the session messages")}`);
|
|
1468
|
+
return void 0;
|
|
1469
|
+
});
|
|
1470
|
+
const before = this.a.progress;
|
|
1471
|
+
const text = [];
|
|
1472
|
+
let reasoning = "";
|
|
1473
|
+
let lastError;
|
|
1474
|
+
for (const message of messages ?? []) {
|
|
1475
|
+
if (message.type !== "assistant") continue;
|
|
1476
|
+
const id = message.id;
|
|
1477
|
+
const parts = message.content ?? [];
|
|
1478
|
+
text.push(...missed(parts, "text", before?.text[id] ?? 0, this.took.text.get(id) ?? 0));
|
|
1479
|
+
reasoning += missed(parts, "reasoning", before?.reasoning[id] ?? 0, this.took.reasoning.get(id) ?? 0).map((piece) => piece.text).join("");
|
|
1480
|
+
for (const part of parts) if (part.type === "tool") await this.missedTool(part);
|
|
1481
|
+
if (message.tokens !== void 0 && !before?.steps.includes(id) && !this.took.steps.has(id)) {
|
|
1482
|
+
this.took.steps.add(id);
|
|
1483
|
+
const model = message.model;
|
|
1484
|
+
if (typeof model?.id === "string" && typeof model.providerID === "string") this.model = {
|
|
1485
|
+
providerID: model.providerID,
|
|
1486
|
+
id: model.id
|
|
1487
|
+
};
|
|
1488
|
+
await this.spend({
|
|
1489
|
+
tokens: message.tokens,
|
|
1490
|
+
cost: message.cost
|
|
1491
|
+
}, "chat");
|
|
1492
|
+
}
|
|
1493
|
+
if (message.error?.message) lastError = message.error.message;
|
|
1494
|
+
}
|
|
1495
|
+
const recovered = text.map((piece) => piece.text).join("\n\n").trimStart();
|
|
1496
|
+
if (recovered.trim()) {
|
|
1497
|
+
await this.step();
|
|
1498
|
+
const joint = this.segment.text && !text.at(-1)?.continues ? "\n\n" : "";
|
|
1499
|
+
this.segment.text = `${recovered}${joint}${this.segment.text}`;
|
|
1500
|
+
this.sawText = true;
|
|
1501
|
+
await this.write({
|
|
1502
|
+
kind: "text",
|
|
1503
|
+
text: recovered
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
1506
|
+
if (reasoning) {
|
|
1507
|
+
await this.step();
|
|
1508
|
+
this.segment.reasoning = `${reasoning}${this.segment.reasoning}`;
|
|
1509
|
+
await this.write({
|
|
1510
|
+
kind: "reasoning",
|
|
1511
|
+
text: reasoning
|
|
1512
|
+
});
|
|
1513
|
+
}
|
|
1514
|
+
if (outcome.status !== "succeeded") return outcome;
|
|
1515
|
+
const idle = (messages ?? []).filter((m) => m.type === "idle").at(-1);
|
|
1516
|
+
if (idle?.outcome === "failed") return {
|
|
1517
|
+
status: "failed",
|
|
1518
|
+
error: lastError ?? this.stepError ?? "the execution failed"
|
|
1519
|
+
};
|
|
1520
|
+
if (idle?.outcome === "interrupted") return {
|
|
1521
|
+
status: "interrupted"
|
|
1522
|
+
};
|
|
1523
|
+
const s = this.segment;
|
|
1524
|
+
const said = s.text || s.reasoning || s.calls.length > 0 || s.ui.length > 0;
|
|
1525
|
+
const progress = this.progress();
|
|
1526
|
+
const tookAny = Object.keys(progress.text).length > 0 || progress.called.length > 0 || progress.steps.length > 0;
|
|
1527
|
+
if (!said && !this.wroteMessage && !tookAny) return {
|
|
1528
|
+
status: "failed",
|
|
1529
|
+
error: LOST_ANSWER_ERROR
|
|
1530
|
+
};
|
|
1531
|
+
return outcome;
|
|
1532
|
+
}
|
|
1533
|
+
/** A tool part of a message the turn did not hear: its call, its result, whichever it lacks. */
|
|
1534
|
+
async missedTool(part) {
|
|
1535
|
+
const id = part.id;
|
|
1536
|
+
const name = part.name ?? "tool";
|
|
1537
|
+
if (id === void 0 || HIDDEN_TOOLS.has(name)) return;
|
|
1538
|
+
const state = part.state ?? {};
|
|
1539
|
+
const before = this.a.progress;
|
|
1540
|
+
if (!before?.called.includes(id) && !this.tools.has(id)) {
|
|
1541
|
+
await this.step();
|
|
1542
|
+
this.setInput(id, state.input, name);
|
|
1543
|
+
await this.makeAvailable(id);
|
|
1544
|
+
}
|
|
1545
|
+
const ok = state.status === "completed";
|
|
1546
|
+
if (!ok && state.status !== "error" || before?.settled.includes(id)) return;
|
|
1547
|
+
const error = errorText(state.error, "tool failed");
|
|
1548
|
+
if (this.tools.has(id)) {
|
|
1549
|
+
await this.settleTool(id, ok, error);
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
this.took.settled.add(id);
|
|
1553
|
+
const result = ok ? {
|
|
1554
|
+
id,
|
|
1555
|
+
name,
|
|
1556
|
+
output: {
|
|
1557
|
+
ok: true
|
|
1558
|
+
}
|
|
1559
|
+
} : {
|
|
1560
|
+
id,
|
|
1561
|
+
name,
|
|
1562
|
+
output: {
|
|
1563
|
+
ok: false
|
|
1564
|
+
},
|
|
1565
|
+
error
|
|
1566
|
+
};
|
|
1567
|
+
const messageId = await this.messageOf(id);
|
|
1568
|
+
if (messageId !== void 0) await this.addResult(messageId, result);
|
|
1569
|
+
else this.segment.results.push(result);
|
|
1570
|
+
await this.write(ok ? {
|
|
1571
|
+
kind: "tool-output",
|
|
1572
|
+
id,
|
|
1573
|
+
output: {
|
|
1574
|
+
ok: true
|
|
1575
|
+
}
|
|
1576
|
+
} : {
|
|
1577
|
+
kind: "tool-output-error",
|
|
1578
|
+
id,
|
|
1579
|
+
error
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
async end(ended) {
|
|
1375
1583
|
if (this.ended) return;
|
|
1376
1584
|
this.ended = true;
|
|
1585
|
+
const outcome = this.a.resumed === true ? await this.recover(ended).catch((error) => {
|
|
1586
|
+
this.a.logger.warn(`run ${this.a.runId}: ${errorText(error, "could not recover the turn")}`);
|
|
1587
|
+
return ended;
|
|
1588
|
+
}) : ended;
|
|
1377
1589
|
await this.unreported().catch((error) => this.a.logger.warn(`run ${this.a.runId}: ${errorText(error, "could not read the session usage")}`));
|
|
1378
1590
|
if (outcome.status !== "failed" || this.segment.text || this.segment.calls.length > 0 || this.segment.ui.length > 0) {
|
|
1379
1591
|
await this.flush(true);
|
|
@@ -1390,6 +1602,26 @@ ${delta}` : delta;
|
|
|
1390
1602
|
});
|
|
1391
1603
|
}
|
|
1392
1604
|
};
|
|
1605
|
+
function missed(parts, type, head, tail) {
|
|
1606
|
+
const texts = parts.flatMap((p) => p.type === type && typeof p.text === "string" ? [
|
|
1607
|
+
p.text
|
|
1608
|
+
] : []);
|
|
1609
|
+
const total = texts.reduce((n, t) => n + t.length, 0);
|
|
1610
|
+
const end = total - tail;
|
|
1611
|
+
const out = [];
|
|
1612
|
+
let at = 0;
|
|
1613
|
+
for (const t of texts) {
|
|
1614
|
+
const from = Math.max(head, at);
|
|
1615
|
+
const to = Math.min(end, at + t.length);
|
|
1616
|
+
if (to > from) out.push({
|
|
1617
|
+
text: t.slice(from - at, to - at),
|
|
1618
|
+
continues: to < at + t.length
|
|
1619
|
+
});
|
|
1620
|
+
at += t.length;
|
|
1621
|
+
}
|
|
1622
|
+
return out;
|
|
1623
|
+
}
|
|
1624
|
+
__name(missed, "missed");
|
|
1393
1625
|
function modelOfLabel(label) {
|
|
1394
1626
|
const slash = label?.indexOf("/") ?? -1;
|
|
1395
1627
|
if (label === void 0 || slash <= 0 || slash === label.length - 1) return void 0;
|
|
@@ -2535,7 +2767,11 @@ ${body}
|
|
|
2535
2767
|
text: prompt.text,
|
|
2536
2768
|
...prompt.files?.length ? {
|
|
2537
2769
|
files: prompt.files
|
|
2538
|
-
} : {}
|
|
2770
|
+
} : {},
|
|
2771
|
+
// Marks the prompt as this run's: a turn resumed after a restart reads what came after it.
|
|
2772
|
+
metadata: {
|
|
2773
|
+
runId
|
|
2774
|
+
}
|
|
2539
2775
|
});
|
|
2540
2776
|
} catch (error) {
|
|
2541
2777
|
live.turn.fail(`OpenCode refused the message: ${error.message}`);
|
|
@@ -2548,9 +2784,11 @@ ${body}
|
|
|
2548
2784
|
*
|
|
2549
2785
|
* `spent` is what the run spent before (the sum of the `usage` of its earlier milestones): a turn
|
|
2550
2786
|
* rebuilt here starts from it, so the answer it persists carries the whole run's usage.
|
|
2787
|
+
* `progress` is what the turn took before (its last `ask` milestone's): a turn rebuilt here reads
|
|
2788
|
+
* back from the session's messages, when the execution ends, what nobody heard after that.
|
|
2551
2789
|
*/
|
|
2552
|
-
async observe(runId, input, handle, spent) {
|
|
2553
|
-
const live = await this.ensureLive(runId, input, handle, true, spent);
|
|
2790
|
+
async observe(runId, input, handle, spent, progress) {
|
|
2791
|
+
const live = await this.ensureLive(runId, input, handle, true, spent, progress);
|
|
2554
2792
|
const { turn, client } = live;
|
|
2555
2793
|
if (turn.hasMilestone()) return this.reached(runId, input, handle, await turn.next());
|
|
2556
2794
|
let done = false;
|
|
@@ -2589,12 +2827,12 @@ ${body}
|
|
|
2589
2827
|
* request is gone with it: a new session is opened, told what the person decided, and prompted
|
|
2590
2828
|
* to go on.
|
|
2591
2829
|
*/
|
|
2592
|
-
async reply(runId, input, handle, ask, reply, spent) {
|
|
2830
|
+
async reply(runId, input, handle, ask, reply, spent, progress) {
|
|
2593
2831
|
const server = await this.host.server(input.actor);
|
|
2594
2832
|
if (server.key !== handle.serverKey || server.bootId !== handle.bootId) {
|
|
2595
2833
|
return this.continueAfterRestart(runId, input, server, ask, reply, spent);
|
|
2596
2834
|
}
|
|
2597
|
-
const live = await this.ensureLive(runId, input, handle, false, spent);
|
|
2835
|
+
const live = await this.ensureLive(runId, input, handle, false, spent, progress);
|
|
2598
2836
|
await live.turn.decide(ask, reply);
|
|
2599
2837
|
return handle;
|
|
2600
2838
|
}
|
|
@@ -2612,7 +2850,10 @@ ${body}
|
|
|
2612
2850
|
live.turn.setBaseline(await this.sessionUsage(live.client, handle.sessionId));
|
|
2613
2851
|
await live.client.session.prompt({
|
|
2614
2852
|
sessionID: handle.sessionId,
|
|
2615
|
-
text: note
|
|
2853
|
+
text: note,
|
|
2854
|
+
metadata: {
|
|
2855
|
+
runId
|
|
2856
|
+
}
|
|
2616
2857
|
});
|
|
2617
2858
|
return handle;
|
|
2618
2859
|
}
|
|
@@ -2636,9 +2877,10 @@ ${body}
|
|
|
2636
2877
|
sessionID: known.sessionId
|
|
2637
2878
|
});
|
|
2638
2879
|
}
|
|
2639
|
-
async ensureLive(runId, input, handle, catchUp, spent) {
|
|
2880
|
+
async ensureLive(runId, input, handle, catchUp, spent, progress) {
|
|
2640
2881
|
const current = this.live.get(runId);
|
|
2641
2882
|
if (current !== void 0 && current.handle.sessionId === handle.sessionId) return current;
|
|
2883
|
+
const resumed = catchUp && current === void 0;
|
|
2642
2884
|
current?.stop();
|
|
2643
2885
|
const server = await this.host.server(input.actor);
|
|
2644
2886
|
const deps = this.deps.forAgent(input.agentName);
|
|
@@ -2669,6 +2911,10 @@ ${body}
|
|
|
2669
2911
|
...spent !== void 0 ? {
|
|
2670
2912
|
carried: spent
|
|
2671
2913
|
} : {},
|
|
2914
|
+
...progress !== void 0 ? {
|
|
2915
|
+
progress
|
|
2916
|
+
} : {},
|
|
2917
|
+
resumed,
|
|
2672
2918
|
logger: this.logger,
|
|
2673
2919
|
onGranted: /* @__PURE__ */ __name((action, id) => {
|
|
2674
2920
|
const grants = this.grants.get(runId) ?? [];
|
|
@@ -2688,7 +2934,7 @@ ${body}
|
|
|
2688
2934
|
stop
|
|
2689
2935
|
};
|
|
2690
2936
|
this.live.set(runId, live);
|
|
2691
|
-
if (
|
|
2937
|
+
if (resumed) await turn.catchUp().catch(() => void 0);
|
|
2692
2938
|
return live;
|
|
2693
2939
|
}
|
|
2694
2940
|
/** Stop following a run in this process. */
|
|
@@ -3231,6 +3477,7 @@ __name(openCodeProviders, "openCodeProviders");
|
|
|
3231
3477
|
0 && (module.exports = {
|
|
3232
3478
|
FormAnswerError,
|
|
3233
3479
|
InMemoryOpenCodeSessionStore,
|
|
3480
|
+
LOST_ANSWER_ERROR,
|
|
3234
3481
|
OPENCODE_HOST,
|
|
3235
3482
|
OPENCODE_MCP_ENDPOINT,
|
|
3236
3483
|
OPENCODE_OPTIONS,
|