@orkestrel/agent 0.0.37 → 0.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/core/index.cjs +122 -26
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +42 -10
- package/dist/src/core/index.d.ts +42 -10
- package/dist/src/core/index.js +122 -26
- package/dist/src/core/index.js.map +1 -1
- package/package.json +11 -11
|
@@ -5349,14 +5349,19 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
|
|
|
5349
5349
|
* Cuts entries to a room and names how many it left out.
|
|
5350
5350
|
*
|
|
5351
5351
|
* @remarks
|
|
5352
|
-
*
|
|
5352
|
+
* By default the cut keeps at least one entry. With `first: false`, it keeps whole entries only
|
|
5353
|
+
* when the joined result, tool framing, and omission line fit, and considers later entries after
|
|
5354
|
+
* an oversized group. When it leaves some entries out, its last line reads
|
|
5353
5355
|
* `N older items not shown; name a narrower topic to narrow the recall`, which
|
|
5354
5356
|
* {@link matchesCutLine} recognizes. Pass `more` when the entries aren't in age order, so the line
|
|
5355
|
-
* doesn't claim an omitted entry is older than a kept one.
|
|
5357
|
+
* doesn't claim an omitted entry is older than a kept one. A fitted cut also uses `more` when it
|
|
5358
|
+
* skips an entry before a kept one. With no kept entry it reads
|
|
5359
|
+
* `N older items didn't fit in this request; answer from the messages you can see`.
|
|
5356
5360
|
*
|
|
5357
5361
|
* @param entries - The entries in the order they are kept
|
|
5358
5362
|
* @param room - The estimate units the joined entries can take
|
|
5359
5363
|
* @param kind - What the cut line calls an omitted entry. Default: `older`
|
|
5364
|
+
* @param first - If `true`, keeps the first entry regardless of room; if `false`, fits every entry and the omission line. Default: `true`
|
|
5360
5365
|
* @returns The kept entries followed by the cut line when any were left out, joined by newlines
|
|
5361
5366
|
*
|
|
5362
5367
|
* @example
|
|
@@ -5364,7 +5369,7 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
|
|
|
5364
5369
|
* cutListing(['first entry', 'second entry'], 1) // 'first entry\n1 older item not shown; name a narrower topic to narrow the recall'
|
|
5365
5370
|
* ```
|
|
5366
5371
|
*/
|
|
5367
|
-
export declare function cutListing(entries: readonly string[], room: number, kind?: 'older' | 'more'): string;
|
|
5372
|
+
export declare function cutListing(entries: readonly string[], room: number, kind?: 'older' | 'more', first?: boolean): string;
|
|
5368
5373
|
|
|
5369
5374
|
/**
|
|
5370
5375
|
* Backs a {@link ConversationStoreInterface} with one table of the `databases` layer — a
|
|
@@ -6091,8 +6096,12 @@ export declare interface GaugeInterface extends LedgerGauge {
|
|
|
6091
6096
|
* `max(0, overhead - (spared ?? 0)) + scale * estimate`.
|
|
6092
6097
|
* Capacity left is `max(0, capacity - used)`. The reply reserve adds recall uniform at the marginal
|
|
6093
6098
|
* rate to the largest observed reply's `completion - (thinking ?? 0)` for every policy.
|
|
6094
|
-
* Without a positive reply observation, it prices the longest reply text at that rate.
|
|
6095
|
-
* `max(0, (remainder - predict - reserve) / 2 / rate)
|
|
6099
|
+
* Without a positive reply observation, it prices the longest reply text at that rate. The room formula
|
|
6100
|
+
* `max(0, (remainder - predict - reserve) / 2 / rate)` is the planning forecast. The ledger's runtime
|
|
6101
|
+
* recall instead fits results below `capacity - predict`, anchoring the prefix to reported usage
|
|
6102
|
+
* and pricing additions at the larger of the marginal rate and the request's measured rate, with
|
|
6103
|
+
* `LEDGER_SCALE_DRIFT` headroom. The measured rate subtracts overhead only where `observe` would
|
|
6104
|
+
* rescale; partially spared calls retain the marginal rate. Missing usage uses an estimate.
|
|
6096
6105
|
*/
|
|
6097
6106
|
export declare interface GaugeOptions extends LedgerGauge {
|
|
6098
6107
|
readonly capacity: number;
|
|
@@ -8035,6 +8044,14 @@ export declare interface LedgerLine {
|
|
|
8035
8044
|
readonly role: MessageRole;
|
|
8036
8045
|
}
|
|
8037
8046
|
|
|
8047
|
+
/** Carries a recall result, its accepted whole groups, lookup line translations, and provider-turn position. */
|
|
8048
|
+
export declare interface LedgerListing {
|
|
8049
|
+
readonly result: string;
|
|
8050
|
+
readonly lines: ReadonlyMap<string, string>;
|
|
8051
|
+
readonly groups: readonly string[];
|
|
8052
|
+
readonly turn: number;
|
|
8053
|
+
}
|
|
8054
|
+
|
|
8038
8055
|
/**
|
|
8039
8056
|
* Carries one application lookup: the tool the model calls and the handler that reads its results.
|
|
8040
8057
|
*
|
|
@@ -8134,7 +8151,10 @@ export declare interface LedgerOccurrence extends LedgerLine, LedgerReceipt {
|
|
|
8134
8151
|
* nonnegative safe integer less than `capacity`; construction throws `LedgerError` with code
|
|
8135
8152
|
* `'CAPACITY'` otherwise. The plan budgets
|
|
8136
8153
|
* `max(0, (capacity - predict) * share.prompt - overhead) / (1 + LEDGER_SCALE_DRIFT)`.
|
|
8137
|
-
*
|
|
8154
|
+
* The plan retains its `remainder - predict < 2 * reserve` admission rule. Runtime recall fits whole
|
|
8155
|
+
* results to measured remaining capacity at the larger of the gauge rate and the request's measured
|
|
8156
|
+
* rate, allowing `LEDGER_SCALE_DRIFT` for new text. Lack of room omits results without closing recall.
|
|
8157
|
+
* `snapshot` hydrates the conversation and
|
|
8138
8158
|
* the marked ids a ledger's `snapshot()` returned; construction throws `LedgerError` with code
|
|
8139
8159
|
* `'SNAPSHOT'` when `isLedgerSnapshot` refuses it, and `ConversationError` with code `'ROLE'` or
|
|
8140
8160
|
* `'SNAPSHOT'` when its conversation holds a `system` message or repeats an id.
|
|
@@ -8273,6 +8293,12 @@ export declare interface LedgerRecord {
|
|
|
8273
8293
|
readonly lines: readonly LedgerLine[];
|
|
8274
8294
|
}
|
|
8275
8295
|
|
|
8296
|
+
/** Carries the answer note and the partial messages omitted from its prompt. */
|
|
8297
|
+
export declare interface LedgerRecovery {
|
|
8298
|
+
readonly digest: string | undefined;
|
|
8299
|
+
readonly omitted: ReadonlySet<string>;
|
|
8300
|
+
}
|
|
8301
|
+
|
|
8276
8302
|
/**
|
|
8277
8303
|
* Carries the ids the ledger's lookups named and the owners among them.
|
|
8278
8304
|
*
|
|
@@ -8397,7 +8423,9 @@ export declare class LedgerRequest implements LedgerRequestInterface {
|
|
|
8397
8423
|
admit(name: string, args: Readonly<Record<string, unknown>>): void;
|
|
8398
8424
|
recall(): void;
|
|
8399
8425
|
close(): void;
|
|
8400
|
-
list(result: string, lines: ReadonlyMap<string, string
|
|
8426
|
+
list(result: string, lines: ReadonlyMap<string, string>, groups: readonly string[]): void;
|
|
8427
|
+
/** Returns recall results with their accepted whole groups and provider-turn positions. */
|
|
8428
|
+
get listings(): readonly LedgerListing[];
|
|
8401
8429
|
lines(result: string): ReadonlyMap<string, string> | undefined;
|
|
8402
8430
|
}
|
|
8403
8431
|
|
|
@@ -8517,8 +8545,11 @@ export declare interface LedgerRequestInterface {
|
|
|
8517
8545
|
*
|
|
8518
8546
|
* @param result - The recall result text
|
|
8519
8547
|
* @param lines - Each listed lookup line mapped to the first line of its stored content
|
|
8548
|
+
* @param groups - The complete candidate groups, in listing order; only groups present in the result are retained
|
|
8520
8549
|
*/
|
|
8521
|
-
list(result: string, lines: ReadonlyMap<string, string
|
|
8550
|
+
list(result: string, lines: ReadonlyMap<string, string>, groups: readonly string[]): void;
|
|
8551
|
+
/** Holds each recall result with its accepted groups and provider-turn position. */
|
|
8552
|
+
readonly listings: readonly LedgerListing[];
|
|
8522
8553
|
/**
|
|
8523
8554
|
* Returns the stored first lines a recall result listed.
|
|
8524
8555
|
*
|
|
@@ -12496,6 +12527,7 @@ export declare type SystemOneEntry = JudgeEntry | null;
|
|
|
12496
12527
|
*
|
|
12497
12528
|
* @remarks
|
|
12498
12529
|
* The caller supplies the server origin and model. Every question travels in one request.
|
|
12530
|
+
* Wire keys are zero-based positions in question entry order; answers return under the caller's ids.
|
|
12499
12531
|
* Server measures are ignored; the response model is preserved.
|
|
12500
12532
|
* `headers` supplies authentication through the shared judge engine.
|
|
12501
12533
|
* The example readings are those of the response Ollama 0.40.0 returned for that request on 2026-10-07.
|
|
@@ -12546,14 +12578,14 @@ export declare class SystemOneJudge extends AgentJudge {
|
|
|
12546
12578
|
/** Identifies the System One protocol. */
|
|
12547
12579
|
readonly name = "systemone";
|
|
12548
12580
|
/**
|
|
12549
|
-
* Projects the state and questions onto the System One request with the configured model.
|
|
12581
|
+
* Projects the state and questions onto the System One request with the configured model and positional keys.
|
|
12550
12582
|
*
|
|
12551
12583
|
* @param request - The state and questions keyed by caller id
|
|
12552
12584
|
* @returns The System One request body
|
|
12553
12585
|
*/
|
|
12554
12586
|
encode(request: JudgeRequest): SystemOneRequest;
|
|
12555
12587
|
/**
|
|
12556
|
-
* Decodes
|
|
12588
|
+
* Decodes positional System One answers under caller ids and reports the server model and available usage.
|
|
12557
12589
|
*
|
|
12558
12590
|
* @param value - The parsed response body
|
|
12559
12591
|
* @param request - The questions defining the expected answers
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -5349,14 +5349,19 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
|
|
|
5349
5349
|
* Cuts entries to a room and names how many it left out.
|
|
5350
5350
|
*
|
|
5351
5351
|
* @remarks
|
|
5352
|
-
*
|
|
5352
|
+
* By default the cut keeps at least one entry. With `first: false`, it keeps whole entries only
|
|
5353
|
+
* when the joined result, tool framing, and omission line fit, and considers later entries after
|
|
5354
|
+
* an oversized group. When it leaves some entries out, its last line reads
|
|
5353
5355
|
* `N older items not shown; name a narrower topic to narrow the recall`, which
|
|
5354
5356
|
* {@link matchesCutLine} recognizes. Pass `more` when the entries aren't in age order, so the line
|
|
5355
|
-
* doesn't claim an omitted entry is older than a kept one.
|
|
5357
|
+
* doesn't claim an omitted entry is older than a kept one. A fitted cut also uses `more` when it
|
|
5358
|
+
* skips an entry before a kept one. With no kept entry it reads
|
|
5359
|
+
* `N older items didn't fit in this request; answer from the messages you can see`.
|
|
5356
5360
|
*
|
|
5357
5361
|
* @param entries - The entries in the order they are kept
|
|
5358
5362
|
* @param room - The estimate units the joined entries can take
|
|
5359
5363
|
* @param kind - What the cut line calls an omitted entry. Default: `older`
|
|
5364
|
+
* @param first - If `true`, keeps the first entry regardless of room; if `false`, fits every entry and the omission line. Default: `true`
|
|
5360
5365
|
* @returns The kept entries followed by the cut line when any were left out, joined by newlines
|
|
5361
5366
|
*
|
|
5362
5367
|
* @example
|
|
@@ -5364,7 +5369,7 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
|
|
|
5364
5369
|
* cutListing(['first entry', 'second entry'], 1) // 'first entry\n1 older item not shown; name a narrower topic to narrow the recall'
|
|
5365
5370
|
* ```
|
|
5366
5371
|
*/
|
|
5367
|
-
export declare function cutListing(entries: readonly string[], room: number, kind?: 'older' | 'more'): string;
|
|
5372
|
+
export declare function cutListing(entries: readonly string[], room: number, kind?: 'older' | 'more', first?: boolean): string;
|
|
5368
5373
|
|
|
5369
5374
|
/**
|
|
5370
5375
|
* Backs a {@link ConversationStoreInterface} with one table of the `databases` layer — a
|
|
@@ -6091,8 +6096,12 @@ export declare interface GaugeInterface extends LedgerGauge {
|
|
|
6091
6096
|
* `max(0, overhead - (spared ?? 0)) + scale * estimate`.
|
|
6092
6097
|
* Capacity left is `max(0, capacity - used)`. The reply reserve adds recall uniform at the marginal
|
|
6093
6098
|
* rate to the largest observed reply's `completion - (thinking ?? 0)` for every policy.
|
|
6094
|
-
* Without a positive reply observation, it prices the longest reply text at that rate.
|
|
6095
|
-
* `max(0, (remainder - predict - reserve) / 2 / rate)
|
|
6099
|
+
* Without a positive reply observation, it prices the longest reply text at that rate. The room formula
|
|
6100
|
+
* `max(0, (remainder - predict - reserve) / 2 / rate)` is the planning forecast. The ledger's runtime
|
|
6101
|
+
* recall instead fits results below `capacity - predict`, anchoring the prefix to reported usage
|
|
6102
|
+
* and pricing additions at the larger of the marginal rate and the request's measured rate, with
|
|
6103
|
+
* `LEDGER_SCALE_DRIFT` headroom. The measured rate subtracts overhead only where `observe` would
|
|
6104
|
+
* rescale; partially spared calls retain the marginal rate. Missing usage uses an estimate.
|
|
6096
6105
|
*/
|
|
6097
6106
|
export declare interface GaugeOptions extends LedgerGauge {
|
|
6098
6107
|
readonly capacity: number;
|
|
@@ -8035,6 +8044,14 @@ export declare interface LedgerLine {
|
|
|
8035
8044
|
readonly role: MessageRole;
|
|
8036
8045
|
}
|
|
8037
8046
|
|
|
8047
|
+
/** Carries a recall result, its accepted whole groups, lookup line translations, and provider-turn position. */
|
|
8048
|
+
export declare interface LedgerListing {
|
|
8049
|
+
readonly result: string;
|
|
8050
|
+
readonly lines: ReadonlyMap<string, string>;
|
|
8051
|
+
readonly groups: readonly string[];
|
|
8052
|
+
readonly turn: number;
|
|
8053
|
+
}
|
|
8054
|
+
|
|
8038
8055
|
/**
|
|
8039
8056
|
* Carries one application lookup: the tool the model calls and the handler that reads its results.
|
|
8040
8057
|
*
|
|
@@ -8134,7 +8151,10 @@ export declare interface LedgerOccurrence extends LedgerLine, LedgerReceipt {
|
|
|
8134
8151
|
* nonnegative safe integer less than `capacity`; construction throws `LedgerError` with code
|
|
8135
8152
|
* `'CAPACITY'` otherwise. The plan budgets
|
|
8136
8153
|
* `max(0, (capacity - predict) * share.prompt - overhead) / (1 + LEDGER_SCALE_DRIFT)`.
|
|
8137
|
-
*
|
|
8154
|
+
* The plan retains its `remainder - predict < 2 * reserve` admission rule. Runtime recall fits whole
|
|
8155
|
+
* results to measured remaining capacity at the larger of the gauge rate and the request's measured
|
|
8156
|
+
* rate, allowing `LEDGER_SCALE_DRIFT` for new text. Lack of room omits results without closing recall.
|
|
8157
|
+
* `snapshot` hydrates the conversation and
|
|
8138
8158
|
* the marked ids a ledger's `snapshot()` returned; construction throws `LedgerError` with code
|
|
8139
8159
|
* `'SNAPSHOT'` when `isLedgerSnapshot` refuses it, and `ConversationError` with code `'ROLE'` or
|
|
8140
8160
|
* `'SNAPSHOT'` when its conversation holds a `system` message or repeats an id.
|
|
@@ -8273,6 +8293,12 @@ export declare interface LedgerRecord {
|
|
|
8273
8293
|
readonly lines: readonly LedgerLine[];
|
|
8274
8294
|
}
|
|
8275
8295
|
|
|
8296
|
+
/** Carries the answer note and the partial messages omitted from its prompt. */
|
|
8297
|
+
export declare interface LedgerRecovery {
|
|
8298
|
+
readonly digest: string | undefined;
|
|
8299
|
+
readonly omitted: ReadonlySet<string>;
|
|
8300
|
+
}
|
|
8301
|
+
|
|
8276
8302
|
/**
|
|
8277
8303
|
* Carries the ids the ledger's lookups named and the owners among them.
|
|
8278
8304
|
*
|
|
@@ -8397,7 +8423,9 @@ export declare class LedgerRequest implements LedgerRequestInterface {
|
|
|
8397
8423
|
admit(name: string, args: Readonly<Record<string, unknown>>): void;
|
|
8398
8424
|
recall(): void;
|
|
8399
8425
|
close(): void;
|
|
8400
|
-
list(result: string, lines: ReadonlyMap<string, string
|
|
8426
|
+
list(result: string, lines: ReadonlyMap<string, string>, groups: readonly string[]): void;
|
|
8427
|
+
/** Returns recall results with their accepted whole groups and provider-turn positions. */
|
|
8428
|
+
get listings(): readonly LedgerListing[];
|
|
8401
8429
|
lines(result: string): ReadonlyMap<string, string> | undefined;
|
|
8402
8430
|
}
|
|
8403
8431
|
|
|
@@ -8517,8 +8545,11 @@ export declare interface LedgerRequestInterface {
|
|
|
8517
8545
|
*
|
|
8518
8546
|
* @param result - The recall result text
|
|
8519
8547
|
* @param lines - Each listed lookup line mapped to the first line of its stored content
|
|
8548
|
+
* @param groups - The complete candidate groups, in listing order; only groups present in the result are retained
|
|
8520
8549
|
*/
|
|
8521
|
-
list(result: string, lines: ReadonlyMap<string, string
|
|
8550
|
+
list(result: string, lines: ReadonlyMap<string, string>, groups: readonly string[]): void;
|
|
8551
|
+
/** Holds each recall result with its accepted groups and provider-turn position. */
|
|
8552
|
+
readonly listings: readonly LedgerListing[];
|
|
8522
8553
|
/**
|
|
8523
8554
|
* Returns the stored first lines a recall result listed.
|
|
8524
8555
|
*
|
|
@@ -12496,6 +12527,7 @@ export declare type SystemOneEntry = JudgeEntry | null;
|
|
|
12496
12527
|
*
|
|
12497
12528
|
* @remarks
|
|
12498
12529
|
* The caller supplies the server origin and model. Every question travels in one request.
|
|
12530
|
+
* Wire keys are zero-based positions in question entry order; answers return under the caller's ids.
|
|
12499
12531
|
* Server measures are ignored; the response model is preserved.
|
|
12500
12532
|
* `headers` supplies authentication through the shared judge engine.
|
|
12501
12533
|
* The example readings are those of the response Ollama 0.40.0 returned for that request on 2026-10-07.
|
|
@@ -12546,14 +12578,14 @@ export declare class SystemOneJudge extends AgentJudge {
|
|
|
12546
12578
|
/** Identifies the System One protocol. */
|
|
12547
12579
|
readonly name = "systemone";
|
|
12548
12580
|
/**
|
|
12549
|
-
* Projects the state and questions onto the System One request with the configured model.
|
|
12581
|
+
* Projects the state and questions onto the System One request with the configured model and positional keys.
|
|
12550
12582
|
*
|
|
12551
12583
|
* @param request - The state and questions keyed by caller id
|
|
12552
12584
|
* @returns The System One request body
|
|
12553
12585
|
*/
|
|
12554
12586
|
encode(request: JudgeRequest): SystemOneRequest;
|
|
12555
12587
|
/**
|
|
12556
|
-
* Decodes
|
|
12588
|
+
* Decodes positional System One answers under caller ids and reports the server model and available usage.
|
|
12557
12589
|
*
|
|
12558
12590
|
* @param value - The parsed response body
|
|
12559
12591
|
* @param request - The questions defining the expected answers
|
package/dist/src/core/index.js
CHANGED
|
@@ -2755,6 +2755,7 @@ var AgentJudge = class {
|
|
|
2755
2755
|
*
|
|
2756
2756
|
* @remarks
|
|
2757
2757
|
* The caller supplies the server origin and model. Every question travels in one request.
|
|
2758
|
+
* Wire keys are zero-based positions in question entry order; answers return under the caller's ids.
|
|
2758
2759
|
* Server measures are ignored; the response model is preserved.
|
|
2759
2760
|
* `headers` supplies authentication through the shared judge engine.
|
|
2760
2761
|
* The example readings are those of the response Ollama 0.40.0 returned for that request on 2026-10-07.
|
|
@@ -2811,7 +2812,7 @@ var SystemOneJudge = class extends AgentJudge {
|
|
|
2811
2812
|
/** Identifies the System One protocol. */
|
|
2812
2813
|
name = "systemone";
|
|
2813
2814
|
/**
|
|
2814
|
-
* Projects the state and questions onto the System One request with the configured model.
|
|
2815
|
+
* Projects the state and questions onto the System One request with the configured model and positional keys.
|
|
2815
2816
|
*
|
|
2816
2817
|
* @param request - The state and questions keyed by caller id
|
|
2817
2818
|
* @returns The System One request body
|
|
@@ -2820,11 +2821,11 @@ var SystemOneJudge = class extends AgentJudge {
|
|
|
2820
2821
|
return {
|
|
2821
2822
|
state: request.state,
|
|
2822
2823
|
model: this.model,
|
|
2823
|
-
questions: Object.fromEntries(Object.
|
|
2824
|
+
questions: Object.fromEntries(Object.values(request.questions).map((question, index) => [String(index), questionToSystemOne(question)]))
|
|
2824
2825
|
};
|
|
2825
2826
|
}
|
|
2826
2827
|
/**
|
|
2827
|
-
* Decodes
|
|
2828
|
+
* Decodes positional System One answers under caller ids and reports the server model and available usage.
|
|
2828
2829
|
*
|
|
2829
2830
|
* @param value - The parsed response body
|
|
2830
2831
|
* @param request - The questions defining the expected answers
|
|
@@ -2834,9 +2835,10 @@ var SystemOneJudge = class extends AgentJudge {
|
|
|
2834
2835
|
*/
|
|
2835
2836
|
read(value, request) {
|
|
2836
2837
|
if (!isSystemOneResponse(value)) throw new JudgeError("PROTOCOL", `judge error: invalid System One response envelope; received ${preview(value)}`);
|
|
2837
|
-
const entries = Object.entries(request.questions).map(([id, question]) => {
|
|
2838
|
-
|
|
2839
|
-
|
|
2838
|
+
const entries = Object.entries(request.questions).map(([id, question], index) => {
|
|
2839
|
+
const position = String(index);
|
|
2840
|
+
if (!Object.hasOwn(value.answers, position)) throw new JudgeError("PROTOCOL", `judge error: question ${id} has no System One answer`);
|
|
2841
|
+
const wire = value.answers[position];
|
|
2840
2842
|
if (!isSystemOneAnswer(wire)) throw new JudgeError("PROTOCOL", `judge error: question ${id} has an invalid System One answer; received ${preview(wire)}`);
|
|
2841
2843
|
const answer = extractSystemOneAnswer(wire, question);
|
|
2842
2844
|
if (answer === void 0) throw new JudgeError("PROTOCOL", `judge error: question ${id} has a mismatched or incomplete System One answer`);
|
|
@@ -9832,14 +9834,19 @@ function splitTopic(topic) {
|
|
|
9832
9834
|
* Cuts entries to a room and names how many it left out.
|
|
9833
9835
|
*
|
|
9834
9836
|
* @remarks
|
|
9835
|
-
*
|
|
9837
|
+
* By default the cut keeps at least one entry. With `first: false`, it keeps whole entries only
|
|
9838
|
+
* when the joined result, tool framing, and omission line fit, and considers later entries after
|
|
9839
|
+
* an oversized group. When it leaves some entries out, its last line reads
|
|
9836
9840
|
* `N older items not shown; name a narrower topic to narrow the recall`, which
|
|
9837
9841
|
* {@link matchesCutLine} recognizes. Pass `more` when the entries aren't in age order, so the line
|
|
9838
|
-
* doesn't claim an omitted entry is older than a kept one.
|
|
9842
|
+
* doesn't claim an omitted entry is older than a kept one. A fitted cut also uses `more` when it
|
|
9843
|
+
* skips an entry before a kept one. With no kept entry it reads
|
|
9844
|
+
* `N older items didn't fit in this request; answer from the messages you can see`.
|
|
9839
9845
|
*
|
|
9840
9846
|
* @param entries - The entries in the order they are kept
|
|
9841
9847
|
* @param room - The estimate units the joined entries can take
|
|
9842
9848
|
* @param kind - What the cut line calls an omitted entry. Default: `older`
|
|
9849
|
+
* @param first - If `true`, keeps the first entry regardless of room; if `false`, fits every entry and the omission line. Default: `true`
|
|
9843
9850
|
* @returns The kept entries followed by the cut line when any were left out, joined by newlines
|
|
9844
9851
|
*
|
|
9845
9852
|
* @example
|
|
@@ -9847,7 +9854,30 @@ function splitTopic(topic) {
|
|
|
9847
9854
|
* cutListing(['first entry', 'second entry'], 1) // 'first entry\n1 older item not shown; name a narrower topic to narrow the recall'
|
|
9848
9855
|
* ```
|
|
9849
9856
|
*/
|
|
9850
|
-
function cutListing(entries, room, kind = "older") {
|
|
9857
|
+
function cutListing(entries, room, kind = "older", first = true) {
|
|
9858
|
+
if (!first) {
|
|
9859
|
+
if (estimateMessages([{
|
|
9860
|
+
id: "recall",
|
|
9861
|
+
role: "tool",
|
|
9862
|
+
content: entries.join("\n")
|
|
9863
|
+
}]) <= room) return entries.join("\n");
|
|
9864
|
+
const kept = entries.reduce((accepted, entry, at) => {
|
|
9865
|
+
const left = entries.length - accepted.length - 1;
|
|
9866
|
+
const omitted = accepted.length < at ? "more" : kind;
|
|
9867
|
+
return estimateMessages([{
|
|
9868
|
+
id: "recall",
|
|
9869
|
+
role: "tool",
|
|
9870
|
+
content: [
|
|
9871
|
+
...accepted.map((index) => entries[index]),
|
|
9872
|
+
entry,
|
|
9873
|
+
...left > 0 ? [`${left} ${omitted} item${left === 1 ? "" : "s"} not shown; name a narrower topic to narrow the recall`] : []
|
|
9874
|
+
].join("\n")
|
|
9875
|
+
}]) <= room ? [...accepted, at] : accepted;
|
|
9876
|
+
}, []);
|
|
9877
|
+
const left = entries.length - kept.length;
|
|
9878
|
+
const omitted = kept.some((at, index) => at !== index) ? "more" : kind;
|
|
9879
|
+
return [...kept.map((at) => entries[at]), ...left > 0 ? [`${left} ${omitted} item${left === 1 ? "" : "s"} ${kept.length === 0 ? "didn't fit in this request; answer from the messages you can see" : "not shown; name a narrower topic to narrow the recall"}`] : []].join("\n");
|
|
9880
|
+
}
|
|
9851
9881
|
const stop = [...entries.keys()].findIndex((at) => at > 0 && estimateMessages([{
|
|
9852
9882
|
id: "recall",
|
|
9853
9883
|
role: "tool",
|
|
@@ -9869,7 +9899,7 @@ function cutListing(entries, room, kind = "older") {
|
|
|
9869
9899
|
* ```
|
|
9870
9900
|
*/
|
|
9871
9901
|
function matchesCutLine(line) {
|
|
9872
|
-
return /^\d+ (?:older|more) items? not shown; /.test(line);
|
|
9902
|
+
return /^\d+ (?:older|more) items? (?:not shown; |didn't fit in this request; answer from the messages you can see$)/.test(line);
|
|
9873
9903
|
}
|
|
9874
9904
|
/**
|
|
9875
9905
|
* Renders the tail stub of a lookup result from an earlier request.
|
|
@@ -10794,7 +10824,7 @@ var LedgerRequest = class {
|
|
|
10794
10824
|
#passes = [];
|
|
10795
10825
|
#attempts = [];
|
|
10796
10826
|
#admitted = /* @__PURE__ */ new Set();
|
|
10797
|
-
#listed =
|
|
10827
|
+
#listed = [];
|
|
10798
10828
|
#recalls = 0;
|
|
10799
10829
|
#closed = false;
|
|
10800
10830
|
/**
|
|
@@ -10931,11 +10961,24 @@ var LedgerRequest = class {
|
|
|
10931
10961
|
close() {
|
|
10932
10962
|
this.#closed = true;
|
|
10933
10963
|
}
|
|
10934
|
-
list(result, lines) {
|
|
10935
|
-
|
|
10964
|
+
list(result, lines, groups) {
|
|
10965
|
+
const accepted = groups.reduce((kept, group) => {
|
|
10966
|
+
const offset = kept.length === 0 ? 0 : kept.join("\n").length + 1;
|
|
10967
|
+
return result.slice(offset) === group || result.slice(offset).startsWith(`${group}\n`) ? [...kept, group] : kept;
|
|
10968
|
+
}, []);
|
|
10969
|
+
this.#listed = [...this.#listed, {
|
|
10970
|
+
result,
|
|
10971
|
+
lines,
|
|
10972
|
+
groups: accepted,
|
|
10973
|
+
turn: this.calls.length
|
|
10974
|
+
}];
|
|
10975
|
+
}
|
|
10976
|
+
/** Returns recall results with their accepted whole groups and provider-turn positions. */
|
|
10977
|
+
get listings() {
|
|
10978
|
+
return this.#listed;
|
|
10936
10979
|
}
|
|
10937
10980
|
lines(result) {
|
|
10938
|
-
return this.#listed.
|
|
10981
|
+
return this.#listed.findLast((listing) => listing.result === result)?.lines;
|
|
10939
10982
|
}
|
|
10940
10983
|
};
|
|
10941
10984
|
// src/core/ledgers/LedgerScan.ts
|
|
@@ -11458,10 +11501,10 @@ var Ledger = class {
|
|
|
11458
11501
|
});
|
|
11459
11502
|
const passes = [first];
|
|
11460
11503
|
if (!caller.aborted && (first.partial || first.content.trim() === "")) {
|
|
11461
|
-
const
|
|
11462
|
-
if (digest !== void 0) this.#annotations.add(this.#conversation.add({
|
|
11504
|
+
const recovery = this.#buildDigest(request, entered);
|
|
11505
|
+
if (recovery.digest !== void 0) this.#annotations.add(this.#conversation.add({
|
|
11463
11506
|
role: "user",
|
|
11464
|
-
content: digest
|
|
11507
|
+
content: recovery.digest
|
|
11465
11508
|
}).id);
|
|
11466
11509
|
this.#annotations.add(this.#conversation.add({
|
|
11467
11510
|
role: "user",
|
|
@@ -11477,7 +11520,7 @@ var Ledger = class {
|
|
|
11477
11520
|
if (selection.fault !== void 0) return selection;
|
|
11478
11521
|
return {
|
|
11479
11522
|
...selection,
|
|
11480
|
-
messages: selection.messages.filter((one) => one.role !== "tool" && !hasCalls(one))
|
|
11523
|
+
messages: selection.messages.filter((one) => one.role !== "tool" && !hasCalls(one) && !recovery.omitted.has(one.id))
|
|
11481
11524
|
};
|
|
11482
11525
|
}
|
|
11483
11526
|
});
|
|
@@ -12110,11 +12153,21 @@ var Ledger = class {
|
|
|
12110
12153
|
request?.admit("recall", { topic });
|
|
12111
12154
|
const gauge = this.#gauge;
|
|
12112
12155
|
const calls = request?.calls ?? [];
|
|
12113
|
-
if (gauge !== void 0 && calls.length > 0 && gauge.remainder(calls) - this.#predict < 2 * gauge.reserve(calls, this.#findLongest())) request?.close();
|
|
12114
12156
|
request?.recall();
|
|
12115
12157
|
const guidance = `an owner name, an id, or one of ${renderTopicNames(this.#options.topics)}`;
|
|
12116
12158
|
if (topic === "") throw new Error(`recall needs a topic: ${guidance}`);
|
|
12117
|
-
const
|
|
12159
|
+
const rate = this.#recallRate(request) * (1 + LEDGER_SCALE_DRIFT);
|
|
12160
|
+
const call = calls.at(-1);
|
|
12161
|
+
const carried = request === void 0 ? 0 : estimateMessages(stripThinking([...this.#agent.context.build(request.selection), ...this.#conversation.messages().slice(request.boundary)], this.#replay));
|
|
12162
|
+
const completion = isFiniteNumber(call?.prompt) ? (call.completion ?? 0) - (this.#replay === "none" ? call.thinking ?? 0 : 0) : 0;
|
|
12163
|
+
const extra = Math.max(0, (carried - (call?.estimate ?? carried)) * rate - completion);
|
|
12164
|
+
const drift = isFiniteNumber(call?.prompt) ? 0 : Math.max(0, (call?.estimate ?? 0) * (rate - (gauge?.scale ?? rate)));
|
|
12165
|
+
const siblings = estimateMessages((request?.listings ?? []).filter((listing) => listing.turn === calls.length).map((listing) => ({
|
|
12166
|
+
id: "result",
|
|
12167
|
+
role: "tool",
|
|
12168
|
+
content: listing.result
|
|
12169
|
+
})));
|
|
12170
|
+
const room = gauge === void 0 ? -estimateMessages([buildRecallMessage(topic)]) : (gauge.remainder(calls) - this.#predict - extra - drift) / rate - siblings;
|
|
12118
12171
|
const scan = this.#scan(this.#conversation.messages());
|
|
12119
12172
|
const added = this.#scans.size === 0;
|
|
12120
12173
|
if (added) this.#hold(scan);
|
|
@@ -12171,8 +12224,8 @@ var Ledger = class {
|
|
|
12171
12224
|
return [`${label} ${message.content.replace(/[\n\v\f\r\u0085\u2028\u2029]+/g, "\n ")}`];
|
|
12172
12225
|
});
|
|
12173
12226
|
const listed = [...gathered.listed, ...earlier];
|
|
12174
|
-
const result = listed.length === 0 ? `nothing earlier on "${topic}"; answer from the messages you can see` : cutListing(listed, room, earlier.length > 0 ? "more" : "older");
|
|
12175
|
-
request?.list(result, gathered.recalled);
|
|
12227
|
+
const result = listed.length === 0 ? `nothing earlier on "${topic}"; answer from the messages you can see` : cutListing(listed, room, earlier.length > 0 ? "more" : "older", gauge === void 0);
|
|
12228
|
+
request?.list(result, gathered.recalled, listed);
|
|
12176
12229
|
return result;
|
|
12177
12230
|
} finally {
|
|
12178
12231
|
if (added) this.#scans.delete(scan);
|
|
@@ -12180,15 +12233,58 @@ var Ledger = class {
|
|
|
12180
12233
|
}
|
|
12181
12234
|
#buildDigest(request, entered) {
|
|
12182
12235
|
this.#flush();
|
|
12183
|
-
const
|
|
12236
|
+
const groups = [...new Set(this.#collectAfter(entered).flatMap((message) => {
|
|
12184
12237
|
const result = this.#results.get(message.id);
|
|
12185
12238
|
if (message.role !== "tool" || result?.success !== true) return [];
|
|
12186
12239
|
const recalled = result.name === "recall";
|
|
12187
12240
|
if (recalled && /^nothing earlier on /.test(message.content)) return [];
|
|
12188
|
-
const
|
|
12189
|
-
return
|
|
12241
|
+
const listing = recalled ? request.listings.findLast((one) => one.result === message.content) : void 0;
|
|
12242
|
+
return (listing?.groups ?? [message.content]).map((group) => splitResultLines(group).map((line) => listing?.lines.get(line) ?? line).join("\n")).filter((group) => group !== "");
|
|
12190
12243
|
}))];
|
|
12191
|
-
|
|
12244
|
+
const unique = groups.filter((group, at) => !splitResultLines(group).every((line) => groups.slice(0, at).some((earlier) => splitResultLines(earlier).includes(line))));
|
|
12245
|
+
const digest = unique.length === 0 ? void 0 : `${LEDGER_NOTES.results}\n${unique.join("\n")}`;
|
|
12246
|
+
const omitted = /* @__PURE__ */ new Set();
|
|
12247
|
+
const rate = this.#recallRate(request) * (1 + LEDGER_SCALE_DRIFT);
|
|
12248
|
+
const allowance = (this.#options.capacity - this.#predict) / rate;
|
|
12249
|
+
const after = this.#collectAfter(entered);
|
|
12250
|
+
const messages = [
|
|
12251
|
+
...request.plan?.messages ?? request.selection?.messages ?? [],
|
|
12252
|
+
...after,
|
|
12253
|
+
{
|
|
12254
|
+
id: "cue",
|
|
12255
|
+
role: "user",
|
|
12256
|
+
content: LEDGER_NOTES.cue
|
|
12257
|
+
}
|
|
12258
|
+
].filter((message) => message.role !== "tool" && !hasCalls(message));
|
|
12259
|
+
const note = digest === void 0 ? [] : [{
|
|
12260
|
+
id: "results",
|
|
12261
|
+
role: "user",
|
|
12262
|
+
content: digest
|
|
12263
|
+
}];
|
|
12264
|
+
if (this.#gauge === void 0 || estimateMessages(stripThinking(this.#agent.context.build({
|
|
12265
|
+
messages: [...messages, ...note],
|
|
12266
|
+
judgments: []
|
|
12267
|
+
}), this.#replay)) <= allowance) return {
|
|
12268
|
+
digest,
|
|
12269
|
+
omitted
|
|
12270
|
+
};
|
|
12271
|
+
const partials = new Set(after.filter((message) => message.role === "assistant" && !hasCalls(message)).map((message) => message.id));
|
|
12272
|
+
const fitted = cutListing(unique, allowance - estimateMessages(stripThinking(this.#agent.context.build({
|
|
12273
|
+
messages: messages.filter((message) => !partials.has(message.id)),
|
|
12274
|
+
judgments: []
|
|
12275
|
+
}), this.#replay)) - estimateTokens(`${LEDGER_NOTES.results}\n`), "more", false);
|
|
12276
|
+
return {
|
|
12277
|
+
digest: fitted === "" ? void 0 : `${LEDGER_NOTES.results}\n${fitted}`,
|
|
12278
|
+
omitted: partials
|
|
12279
|
+
};
|
|
12280
|
+
}
|
|
12281
|
+
#recallRate(request) {
|
|
12282
|
+
const gauge = this.#gauge;
|
|
12283
|
+
if (gauge === void 0) return 1;
|
|
12284
|
+
const calls = request?.calls ?? [];
|
|
12285
|
+
const last = calls.findLast((call) => isFiniteNumber(call.prompt));
|
|
12286
|
+
const measured = last !== void 0 && isFiniteNumber(last.prompt) && last.estimate > 0 && ((last.spared ?? 0) === 0 || (last.spared ?? 0) >= gauge.overhead) ? (last.prompt - Math.max(0, gauge.overhead - (last.spared ?? 0))) / last.estimate : 0;
|
|
12287
|
+
return Math.max(gauge.rate(calls), measured);
|
|
12192
12288
|
}
|
|
12193
12289
|
};
|
|
12194
12290
|
// src/core/ledgers/factories.ts
|