@frockbot/kernel-agent-loop 0.3.10 → 0.3.12
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/package.json +5 -5
- package/src/index.ts +31 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frockbot/kernel-agent-loop",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@frockbot/kernel-contracts": "0.3.
|
|
15
|
+
"@frockbot/kernel-contracts": "0.3.12",
|
|
16
16
|
"cordis": "4.0.0-rc.8"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@frockbot/plugin-models": "0.3.
|
|
20
|
-
"@frockbot/plugin-prompt": "0.3.
|
|
21
|
-
"@frockbot/plugin-tools": "0.3.
|
|
19
|
+
"@frockbot/plugin-models": "0.3.12",
|
|
20
|
+
"@frockbot/plugin-prompt": "0.3.12",
|
|
21
|
+
"@frockbot/plugin-tools": "0.3.12",
|
|
22
22
|
"@types/bun": "1.4.0",
|
|
23
23
|
"@types/node": "26.2.0",
|
|
24
24
|
"typescript": "^7.0.2"
|
package/src/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type ToolCallOccurrence,
|
|
23
23
|
type ToolExecutionResult,
|
|
24
24
|
type TurnTypeV1,
|
|
25
|
+
TURN_DEADLINE_MS_V1,
|
|
25
26
|
toolCallOccurrences,
|
|
26
27
|
turnEndReason,
|
|
27
28
|
validateSettledToolOccurrenceJournal,
|
|
@@ -112,12 +113,12 @@ class StepLimitReachedError extends Error {
|
|
|
112
113
|
/**
|
|
113
114
|
* The longest a single Turn may run before the loop stops waiting for it.
|
|
114
115
|
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
116
|
+
* Defined in the contracts, because the loop is not its only reader: anything
|
|
117
|
+
* deciding whether a run still marked `running` can still be running needs the
|
|
118
|
+
* same number. Re-exported here because this is where every caller looks for
|
|
119
|
+
* it.
|
|
119
120
|
*/
|
|
120
|
-
export
|
|
121
|
+
export { TURN_DEADLINE_MS_V1 };
|
|
121
122
|
|
|
122
123
|
/**
|
|
123
124
|
* How many times one step will send its model request.
|
|
@@ -686,24 +687,8 @@ class LoopAgent implements Agent {
|
|
|
686
687
|
throw new StepLimitReachedError(this.#maxSteps);
|
|
687
688
|
} catch (error) {
|
|
688
689
|
if (this.#turnDeadlineReached) {
|
|
689
|
-
// Ahead of both the reconciliation and the cancellation branch on
|
|
690
|
-
// purpose. Cancellation, because the deadline aborts the same
|
|
691
|
-
// controller Stop does and a Turn the clock ended must not be reported
|
|
692
|
-
// to the person as one they stopped. Reconciliation, because the
|
|
693
|
-
// reconciliation branch writes no `turn/end` on the promise that the
|
|
694
|
-
// run may still resume — and a run the deadline stopped never will.
|
|
695
|
-
// Deferring to it left `model/reconciliation-required` as the last
|
|
696
|
-
// event of an open Turn, and every later Turn on that Bot refused with
|
|
697
|
-
// `409` for the life of the Bot.
|
|
698
|
-
//
|
|
699
|
-
// The uncertainty is still recorded: whatever the model request wrote
|
|
700
|
-
// before the clock ran out stays in the journal. What changes is that
|
|
701
|
-
// the Turn is settled here — the open step's tool occurrences closed
|
|
702
|
-
// as `interrupted`, then `step/end` and `turn/end` — exactly as
|
|
703
|
-
// `kernel-do`'s `settledEventsV1` settles a Stop or a supersede.
|
|
704
690
|
turnOutcome = "interrupted";
|
|
705
|
-
turnReason =
|
|
706
|
-
this.#ctx.emit("agent/error", this, error);
|
|
691
|
+
turnReason = this.#deadlineTurnReason(error);
|
|
707
692
|
} else if (
|
|
708
693
|
error instanceof ModelEffectReconciliationRequiredError ||
|
|
709
694
|
error instanceof ToolEffectReconciliationRequiredError ||
|
|
@@ -886,24 +871,8 @@ class LoopAgent implements Agent {
|
|
|
886
871
|
throw new StepLimitReachedError(this.#maxSteps);
|
|
887
872
|
} catch (error) {
|
|
888
873
|
if (this.#turnDeadlineReached) {
|
|
889
|
-
// Ahead of both the reconciliation and the cancellation branch on
|
|
890
|
-
// purpose. Cancellation, because the deadline aborts the same
|
|
891
|
-
// controller Stop does and a Turn the clock ended must not be reported
|
|
892
|
-
// to the person as one they stopped. Reconciliation, because the
|
|
893
|
-
// reconciliation branch writes no `turn/end` on the promise that the
|
|
894
|
-
// run may still resume — and a run the deadline stopped never will.
|
|
895
|
-
// Deferring to it left `model/reconciliation-required` as the last
|
|
896
|
-
// event of an open Turn, and every later Turn on that Bot refused with
|
|
897
|
-
// `409` for the life of the Bot.
|
|
898
|
-
//
|
|
899
|
-
// The uncertainty is still recorded: whatever the model request wrote
|
|
900
|
-
// before the clock ran out stays in the journal. What changes is that
|
|
901
|
-
// the Turn is settled here — the open step's tool occurrences closed
|
|
902
|
-
// as `interrupted`, then `step/end` and `turn/end` — exactly as
|
|
903
|
-
// `kernel-do`'s `settledEventsV1` settles a Stop or a supersede.
|
|
904
874
|
turnOutcome = "interrupted";
|
|
905
|
-
turnReason =
|
|
906
|
-
this.#ctx.emit("agent/error", this, error);
|
|
875
|
+
turnReason = this.#deadlineTurnReason(error);
|
|
907
876
|
} else if (
|
|
908
877
|
error instanceof ModelEffectReconciliationRequiredError ||
|
|
909
878
|
error instanceof ToolEffectReconciliationRequiredError ||
|
|
@@ -1421,6 +1390,29 @@ class LoopAgent implements Agent {
|
|
|
1421
1390
|
return decision.kind === "stop";
|
|
1422
1391
|
}
|
|
1423
1392
|
|
|
1393
|
+
/**
|
|
1394
|
+
* The reason a Turn the clock ended carries, and the one place that decides
|
|
1395
|
+
* a deadline is not a cancellation and not a reconciliation.
|
|
1396
|
+
*
|
|
1397
|
+
* Its branch runs ahead of both. Ahead of cancellation, because the deadline
|
|
1398
|
+
* aborts the same controller Stop does and a Turn the clock ended must not
|
|
1399
|
+
* be reported to the person as one they stopped. Ahead of reconciliation,
|
|
1400
|
+
* because that branch writes no `turn/end` on the promise the run may still
|
|
1401
|
+
* resume — and a run the deadline stopped never will. Deferring to it left
|
|
1402
|
+
* `model/reconciliation-required` as the last event of an open Turn, and
|
|
1403
|
+
* every later Turn on that Bot refused with `409` for the life of the Bot.
|
|
1404
|
+
*
|
|
1405
|
+
* The uncertainty is still recorded: whatever the model request wrote before
|
|
1406
|
+
* the clock ran out stays in the journal. What changes is that the Turn is
|
|
1407
|
+
* settled — the open step's tool occurrences closed as `interrupted`, then
|
|
1408
|
+
* `step/end` and `turn/end` — exactly as `kernel-do`'s `settledEventsV1`
|
|
1409
|
+
* settles a Stop or a supersede.
|
|
1410
|
+
*/
|
|
1411
|
+
#deadlineTurnReason(error: unknown): string | undefined {
|
|
1412
|
+
this.#ctx.emit("agent/error", this, error);
|
|
1413
|
+
return turnEndReason(TURN_DEADLINE_REASON_V1);
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1424
1416
|
async #settleCancelledStep(turn: number, step: number): Promise<void> {
|
|
1425
1417
|
const assistant = this.session.events.findLast(
|
|
1426
1418
|
(event) =>
|