@orkestrel/agent 0.0.36 → 0.0.38
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 +696 -106
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +364 -40
- package/dist/src/core/index.d.ts +364 -40
- package/dist/src/core/index.js +685 -107
- package/dist/src/core/index.js.map +1 -1
- package/package.json +7 -7
package/dist/src/core/index.cjs
CHANGED
|
@@ -2756,6 +2756,7 @@ var AgentJudge = class {
|
|
|
2756
2756
|
*
|
|
2757
2757
|
* @remarks
|
|
2758
2758
|
* The caller supplies the server origin and model. Every question travels in one request.
|
|
2759
|
+
* Wire keys are zero-based positions in question entry order; answers return under the caller's ids.
|
|
2759
2760
|
* Server measures are ignored; the response model is preserved.
|
|
2760
2761
|
* `headers` supplies authentication through the shared judge engine.
|
|
2761
2762
|
* The example readings are those of the response Ollama 0.40.0 returned for that request on 2026-10-07.
|
|
@@ -2812,7 +2813,7 @@ var SystemOneJudge = class extends AgentJudge {
|
|
|
2812
2813
|
/** Identifies the System One protocol. */
|
|
2813
2814
|
name = "systemone";
|
|
2814
2815
|
/**
|
|
2815
|
-
* Projects the state and questions onto the System One request with the configured model.
|
|
2816
|
+
* Projects the state and questions onto the System One request with the configured model and positional keys.
|
|
2816
2817
|
*
|
|
2817
2818
|
* @param request - The state and questions keyed by caller id
|
|
2818
2819
|
* @returns The System One request body
|
|
@@ -2821,11 +2822,11 @@ var SystemOneJudge = class extends AgentJudge {
|
|
|
2821
2822
|
return {
|
|
2822
2823
|
state: request.state,
|
|
2823
2824
|
model: this.model,
|
|
2824
|
-
questions: Object.fromEntries(Object.
|
|
2825
|
+
questions: Object.fromEntries(Object.values(request.questions).map((question, index) => [String(index), questionToSystemOne(question)]))
|
|
2825
2826
|
};
|
|
2826
2827
|
}
|
|
2827
2828
|
/**
|
|
2828
|
-
* Decodes
|
|
2829
|
+
* Decodes positional System One answers under caller ids and reports the server model and available usage.
|
|
2829
2830
|
*
|
|
2830
2831
|
* @param value - The parsed response body
|
|
2831
2832
|
* @param request - The questions defining the expected answers
|
|
@@ -2835,9 +2836,10 @@ var SystemOneJudge = class extends AgentJudge {
|
|
|
2835
2836
|
*/
|
|
2836
2837
|
read(value, request) {
|
|
2837
2838
|
if (!isSystemOneResponse(value)) throw new JudgeError("PROTOCOL", `judge error: invalid System One response envelope; received ${(0, _orkestrel_contract.preview)(value)}`);
|
|
2838
|
-
const entries = Object.entries(request.questions).map(([id, question]) => {
|
|
2839
|
-
|
|
2840
|
-
|
|
2839
|
+
const entries = Object.entries(request.questions).map(([id, question], index) => {
|
|
2840
|
+
const position = String(index);
|
|
2841
|
+
if (!Object.hasOwn(value.answers, position)) throw new JudgeError("PROTOCOL", `judge error: question ${id} has no System One answer`);
|
|
2842
|
+
const wire = value.answers[position];
|
|
2841
2843
|
if (!isSystemOneAnswer(wire)) throw new JudgeError("PROTOCOL", `judge error: question ${id} has an invalid System One answer; received ${(0, _orkestrel_contract.preview)(wire)}`);
|
|
2842
2844
|
const answer = extractSystemOneAnswer(wire, question);
|
|
2843
2845
|
if (answer === void 0) throw new JudgeError("PROTOCOL", `judge error: question ${id} has a mismatched or incomplete System One answer`);
|
|
@@ -8806,6 +8808,11 @@ var PLACED_CATEGORIES = Object.freeze(["rule", "correction"]);
|
|
|
8806
8808
|
var LEDGER_RULES_KEY = "rules";
|
|
8807
8809
|
/** Prefixes the key of an owner's record, which the owner's id follows. */
|
|
8808
8810
|
var LEDGER_OWNER_PREFIX = "owner:";
|
|
8811
|
+
/** Labels recalled conversation text by its origin. */
|
|
8812
|
+
var LEDGER_RECALL_LABELS = Object.freeze({
|
|
8813
|
+
request: "Earlier request:",
|
|
8814
|
+
reply: "Earlier reply:"
|
|
8815
|
+
});
|
|
8809
8816
|
/**
|
|
8810
8817
|
* Supplies the wording of every question the ledger asks its judge.
|
|
8811
8818
|
*
|
|
@@ -8953,6 +8960,108 @@ function isLedgerError(value) {
|
|
|
8953
8960
|
}
|
|
8954
8961
|
// src/core/ledgers/helpers.ts
|
|
8955
8962
|
/**
|
|
8963
|
+
* Digests held messages, lookup call context, stored copies, and sentence receipts using canonical text.
|
|
8964
|
+
* This non-cryptographic checksum detects host edits and makes no security claim.
|
|
8965
|
+
* @param exchanges - The stored exchange entries
|
|
8966
|
+
* @param messages - The conversation holding their messages
|
|
8967
|
+
* @returns The hexadecimal checksum, or undefined when a required message is absent or canonical encoding fails
|
|
8968
|
+
* @example
|
|
8969
|
+
* ```ts
|
|
8970
|
+
* digestLedgerWindow([], []) // a deterministic hexadecimal checksum
|
|
8971
|
+
* ```
|
|
8972
|
+
*/
|
|
8973
|
+
function digestLedgerWindow(exchanges, messages) {
|
|
8974
|
+
const byId = new Map(messages.map((message) => [message.id, message]));
|
|
8975
|
+
const held = [...new Set(exchanges.flatMap((entry) => [
|
|
8976
|
+
entry.request,
|
|
8977
|
+
entry.reply,
|
|
8978
|
+
...entry.lines.map((line) => line.source)
|
|
8979
|
+
]))].map((id) => byId.get(id));
|
|
8980
|
+
const callers = messages.filter((message) => message.role === "tool" || message.calls !== void 0);
|
|
8981
|
+
const encoded = (0, _orkestrel_contract.attempt)(() => {
|
|
8982
|
+
const values = [...held, ...callers].map((message) => (0, _orkestrel_contract.canonicalStringify)(message));
|
|
8983
|
+
return values.some((value) => value === void 0) ? void 0 : (0, _orkestrel_contract.canonicalStringify)([values, exchanges.map((entry) => [entry.copy ?? null, entry.lines])]);
|
|
8984
|
+
});
|
|
8985
|
+
if (!encoded.success || encoded.value === void 0) return void 0;
|
|
8986
|
+
const hash = [...encoded.value].reduce((prior, character) => {
|
|
8987
|
+
const code = character.codePointAt(0) ?? 0;
|
|
8988
|
+
return {
|
|
8989
|
+
first: Math.imul(prior.first ^ code, 16777619) >>> 0,
|
|
8990
|
+
second: Math.imul(prior.second ^ code, 16777619) >>> 0
|
|
8991
|
+
};
|
|
8992
|
+
}, {
|
|
8993
|
+
first: 2166136261,
|
|
8994
|
+
second: 3335557771
|
|
8995
|
+
});
|
|
8996
|
+
return hash.first.toString(16).padStart(8, "0") + hash.second.toString(16).padStart(8, "0");
|
|
8997
|
+
}
|
|
8998
|
+
/**
|
|
8999
|
+
* Collects stored messages eligible to open the recall offer.
|
|
9000
|
+
* @remarks
|
|
9001
|
+
* Notes and findings without a result do not open the offer. User statements, including quiet
|
|
9002
|
+
* statements available through recall's word route, can open it; this helper does not filter results.
|
|
9003
|
+
* @param input - The messages, findings, and classification
|
|
9004
|
+
* @param requests - The marked request ids
|
|
9005
|
+
* @param notes - The annotation ids to exclude
|
|
9006
|
+
* @returns User statements, lookup findings with results, marked requests, and nonblank call-free replies
|
|
9007
|
+
* @example
|
|
9008
|
+
* ```ts
|
|
9009
|
+
* collectRecallMessages(input, new Set(), new Set()) // eligible stored messages
|
|
9010
|
+
* ```
|
|
9011
|
+
*/
|
|
9012
|
+
function collectRecallMessages(input, requests, notes) {
|
|
9013
|
+
const findings = new Set(input.findings.filter((finding) => finding.result !== void 0).map((finding) => finding.id));
|
|
9014
|
+
return input.messages.filter((message) => !notes.has(message.id) && (requests.has(message.id) || message.role === "assistant" && !hasCalls(message) && message.content.trim() !== "" || message.role === "user" && !hasCalls(message) || message.role === "tool" && findings.has(message.id)));
|
|
9015
|
+
}
|
|
9016
|
+
/**
|
|
9017
|
+
* Checks whether an eligible earlier message is absent from the prompt or incompletely covered.
|
|
9018
|
+
* A successful finding is held when a finding with the same canonical identity and text is fully received.
|
|
9019
|
+
* @param input - The messages, findings, and classification
|
|
9020
|
+
* @param request - The current request id; only messages before it count
|
|
9021
|
+
* @param requests - The marked request ids
|
|
9022
|
+
* @param notes - The annotation ids to exclude
|
|
9023
|
+
* @param messages - The seed tail and held exchange messages; lookup stubs retain their rendered text
|
|
9024
|
+
* @param lines - The receipts held by the window and the request copy together
|
|
9025
|
+
* @returns True if an eligible earlier message is absent or only partly covered; false otherwise
|
|
9026
|
+
* @example
|
|
9027
|
+
* ```ts
|
|
9028
|
+
* hasHiddenRecall(input, request.id, requests, notes, tail, lines) // whether to offer recall
|
|
9029
|
+
* ```
|
|
9030
|
+
*/
|
|
9031
|
+
function hasHiddenRecall(input, request, requests, notes, messages, lines) {
|
|
9032
|
+
const start = input.messages.findIndex((message) => message.id === request);
|
|
9033
|
+
const before = new Set(input.messages.slice(0, Math.max(0, start)).map((message) => message.id));
|
|
9034
|
+
const present = new Map(messages.map((message) => [message.id, message]));
|
|
9035
|
+
const receipts = Map.groupBy(lines, (line) => line.source);
|
|
9036
|
+
return collectRecallMessages(input, requests, notes).some((message) => {
|
|
9037
|
+
if (!before.has(message.id)) return false;
|
|
9038
|
+
if (requests.has(message.id) || message.role === "assistant") return !present.has(message.id);
|
|
9039
|
+
if (present.get(message.id)?.content === message.content) return false;
|
|
9040
|
+
const finding = input.findings.find((one) => one.id === message.id);
|
|
9041
|
+
return !(finding === void 0 ? [message.id] : input.findings.filter((one) => before.has(one.id) && matchesLookup(finding, one)).map((one) => one.id)).some((id) => {
|
|
9042
|
+
if (present.get(id)?.content === message.content) return true;
|
|
9043
|
+
const held = new Set((receipts.get(id) ?? []).map((line) => line.sentence));
|
|
9044
|
+
return splitSentences(message.content).every((_, at) => held.has(at));
|
|
9045
|
+
});
|
|
9046
|
+
});
|
|
9047
|
+
}
|
|
9048
|
+
/**
|
|
9049
|
+
* Checks whether two successful findings carry the same text for the same canonical lookup.
|
|
9050
|
+
* @param left - The finding to compare
|
|
9051
|
+
* @param right - The candidate copy
|
|
9052
|
+
* @returns True for the same finding or equal canonical identities and text; unkeyable findings match only themselves
|
|
9053
|
+
* @example
|
|
9054
|
+
* ```ts
|
|
9055
|
+
* matchesLookup(finding, finding) // true when it has a result
|
|
9056
|
+
* ```
|
|
9057
|
+
*/
|
|
9058
|
+
function matchesLookup(left, right) {
|
|
9059
|
+
if (left.result === void 0 || right.result === void 0 || left.text !== right.text) return false;
|
|
9060
|
+
if (left.id === right.id) return true;
|
|
9061
|
+
const identity = identifyLookup(left.name, left.arguments);
|
|
9062
|
+
return identity !== void 0 && identity === identifyLookup(right.name, right.arguments);
|
|
9063
|
+
}
|
|
9064
|
+
/**
|
|
8956
9065
|
* Collects the live message ids placed in records or left without a record.
|
|
8957
9066
|
* @param projection - The projected records and unplaced ids
|
|
8958
9067
|
* @returns The distinct live message ids
|
|
@@ -9508,17 +9617,17 @@ function matchEntities(index, text, partial) {
|
|
|
9508
9617
|
* Projects the owner records and the rules record from a conversation's messages.
|
|
9509
9618
|
*
|
|
9510
9619
|
* @remarks
|
|
9511
|
-
* Each line is a sentence of a live message, verbatim except that a sentence that opens with a
|
|
9512
|
-
*
|
|
9513
|
-
*
|
|
9514
|
-
*
|
|
9620
|
+
* Each line is a sentence of a live message, verbatim except that a sentence that opens with a
|
|
9621
|
+
* pronoun opens with its party and a colon. {@link collectLive} retains user messages and the
|
|
9622
|
+
* earliest finding in each call identity's last run of identical text, subject to exclusions,
|
|
9623
|
+
* quiet classification, and supersessions. An undefined result still replaces the earlier finding.
|
|
9515
9624
|
*
|
|
9516
9625
|
* A live message joins the owner records its entities name, directly or through a linked lookup
|
|
9517
9626
|
* argument. A message that names no owner joins where its earlier side of an amendment pair joins,
|
|
9518
9627
|
* or on the rules record when it is filed as a rule or a correction, and is an orphan otherwise.
|
|
9519
9628
|
*
|
|
9520
|
-
* Every live sentence is retained. Accepted
|
|
9521
|
-
*
|
|
9629
|
+
* Every live sentence is retained. Accepted edges are listed in `amendments`. An amender that is
|
|
9630
|
+
* superseded points to its newest live successor, or retains its endpoint when none exists.
|
|
9522
9631
|
*
|
|
9523
9632
|
* A sentence that opens with a pronoun takes the party named in the sentence before it. The reading
|
|
9524
9633
|
* trusts capitals, so a capitalized word that is no person, such as a carrier named mid-sentence,
|
|
@@ -9726,12 +9835,19 @@ function splitTopic(topic) {
|
|
|
9726
9835
|
* Cuts entries to a room and names how many it left out.
|
|
9727
9836
|
*
|
|
9728
9837
|
* @remarks
|
|
9729
|
-
*
|
|
9838
|
+
* By default the cut keeps at least one entry. With `first: false`, it keeps whole entries only
|
|
9839
|
+
* when the joined result, tool framing, and omission line fit, and considers later entries after
|
|
9840
|
+
* an oversized group. When it leaves some entries out, its last line reads
|
|
9730
9841
|
* `N older items not shown; name a narrower topic to narrow the recall`, which
|
|
9731
|
-
* {@link matchesCutLine} recognizes.
|
|
9842
|
+
* {@link matchesCutLine} recognizes. Pass `more` when the entries aren't in age order, so the line
|
|
9843
|
+
* doesn't claim an omitted entry is older than a kept one. A fitted cut also uses `more` when it
|
|
9844
|
+
* skips an entry before a kept one. With no kept entry it reads
|
|
9845
|
+
* `N older items didn't fit in this request; answer from the messages you can see`.
|
|
9732
9846
|
*
|
|
9733
9847
|
* @param entries - The entries in the order they are kept
|
|
9734
9848
|
* @param room - The estimate units the joined entries can take
|
|
9849
|
+
* @param kind - What the cut line calls an omitted entry. Default: `older`
|
|
9850
|
+
* @param first - If `true`, keeps the first entry regardless of room; if `false`, fits every entry and the omission line. Default: `true`
|
|
9735
9851
|
* @returns The kept entries followed by the cut line when any were left out, joined by newlines
|
|
9736
9852
|
*
|
|
9737
9853
|
* @example
|
|
@@ -9739,7 +9855,30 @@ function splitTopic(topic) {
|
|
|
9739
9855
|
* cutListing(['first entry', 'second entry'], 1) // 'first entry\n1 older item not shown; name a narrower topic to narrow the recall'
|
|
9740
9856
|
* ```
|
|
9741
9857
|
*/
|
|
9742
|
-
function cutListing(entries, room) {
|
|
9858
|
+
function cutListing(entries, room, kind = "older", first = true) {
|
|
9859
|
+
if (!first) {
|
|
9860
|
+
if (estimateMessages([{
|
|
9861
|
+
id: "recall",
|
|
9862
|
+
role: "tool",
|
|
9863
|
+
content: entries.join("\n")
|
|
9864
|
+
}]) <= room) return entries.join("\n");
|
|
9865
|
+
const kept = entries.reduce((accepted, entry, at) => {
|
|
9866
|
+
const left = entries.length - accepted.length - 1;
|
|
9867
|
+
const omitted = accepted.length < at ? "more" : kind;
|
|
9868
|
+
return estimateMessages([{
|
|
9869
|
+
id: "recall",
|
|
9870
|
+
role: "tool",
|
|
9871
|
+
content: [
|
|
9872
|
+
...accepted.map((index) => entries[index]),
|
|
9873
|
+
entry,
|
|
9874
|
+
...left > 0 ? [`${left} ${omitted} item${left === 1 ? "" : "s"} not shown; name a narrower topic to narrow the recall`] : []
|
|
9875
|
+
].join("\n")
|
|
9876
|
+
}]) <= room ? [...accepted, at] : accepted;
|
|
9877
|
+
}, []);
|
|
9878
|
+
const left = entries.length - kept.length;
|
|
9879
|
+
const omitted = kept.some((at, index) => at !== index) ? "more" : kind;
|
|
9880
|
+
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");
|
|
9881
|
+
}
|
|
9743
9882
|
const stop = [...entries.keys()].findIndex((at) => at > 0 && estimateMessages([{
|
|
9744
9883
|
id: "recall",
|
|
9745
9884
|
role: "tool",
|
|
@@ -9747,7 +9886,7 @@ function cutListing(entries, room) {
|
|
|
9747
9886
|
}]) > room);
|
|
9748
9887
|
const kept = entries.slice(0, stop === -1 ? void 0 : stop);
|
|
9749
9888
|
const left = entries.length - kept.length;
|
|
9750
|
-
return [...kept, ...left > 0 ? [`${left}
|
|
9889
|
+
return [...kept, ...left > 0 ? [`${left} ${kind} item${left === 1 ? "" : "s"} not shown; name a narrower topic to narrow the recall`] : []].join("\n");
|
|
9751
9890
|
}
|
|
9752
9891
|
/**
|
|
9753
9892
|
* Checks whether a line is the cut line {@link cutListing} writes.
|
|
@@ -9761,7 +9900,7 @@ function cutListing(entries, room) {
|
|
|
9761
9900
|
* ```
|
|
9762
9901
|
*/
|
|
9763
9902
|
function matchesCutLine(line) {
|
|
9764
|
-
return /^\d+ older items? not shown; /.test(line);
|
|
9903
|
+
return /^\d+ (?:older|more) items? (?:not shown; |didn't fit in this request; answer from the messages you can see$)/.test(line);
|
|
9765
9904
|
}
|
|
9766
9905
|
/**
|
|
9767
9906
|
* Renders the tail stub of a lookup result from an earlier request.
|
|
@@ -9822,11 +9961,12 @@ function fitSlope(groups) {
|
|
|
9822
9961
|
* Collects the ids of the live messages in conversation order.
|
|
9823
9962
|
*
|
|
9824
9963
|
* @remarks
|
|
9825
|
-
* A message is live when it is a user message
|
|
9826
|
-
* call, and the input neither excludes it nor files it quiet
|
|
9827
|
-
*
|
|
9828
|
-
*
|
|
9829
|
-
*
|
|
9964
|
+
* A message is live when it is a user message or the first unsuperseded finding in its canonical
|
|
9965
|
+
* call identity's last run of identical text, and the input neither excludes it nor files it quiet
|
|
9966
|
+
* or superseded. When the whole run is superseded, its first finding reaches that final filter.
|
|
9967
|
+
* Different text or an undefined result replaces the earlier run, so an empty lookup leaves the
|
|
9968
|
+
* earlier result out of every record. A thrown lookup leaves the earlier result live. A finding
|
|
9969
|
+
* with no canonical identity participates in no replacement.
|
|
9830
9970
|
*
|
|
9831
9971
|
* @param input - The messages, findings, and classification to read
|
|
9832
9972
|
* @returns The live message ids
|
|
@@ -9842,7 +9982,14 @@ function collectLive(input) {
|
|
|
9842
9982
|
const position = new Map(input.messages.map((message, at) => [message.id, at]));
|
|
9843
9983
|
const findings = input.findings.filter((finding) => position.has(finding.id));
|
|
9844
9984
|
const identities = new Map(findings.map((finding) => [finding.id, identifyLookup(finding.name, finding.arguments)]));
|
|
9845
|
-
const current = new Set(
|
|
9985
|
+
const current = new Set([...Map.groupBy(findings, (finding) => identities.get(finding.id) ?? finding).values()].flatMap((group) => {
|
|
9986
|
+
const ordered = group.toSorted((left, right) => (position.get(left.id) ?? -1) - (position.get(right.id) ?? -1));
|
|
9987
|
+
const last = ordered.at(-1);
|
|
9988
|
+
if (last?.result === void 0) return [];
|
|
9989
|
+
const boundary = ordered.findLastIndex((finding) => finding.result === void 0 || finding.text !== last.text);
|
|
9990
|
+
const first = ordered.slice(boundary + 1).find((finding) => (classification.supersessions.get(finding.id) ?? []).length === 0) ?? ordered[boundary + 1];
|
|
9991
|
+
return first === void 0 ? [] : [first.id];
|
|
9992
|
+
}));
|
|
9846
9993
|
return [...new Map(input.messages.map((message) => [message.id, message])).values()].filter((message) => message.role === "user" || message.role === "tool" && current.has(message.id)).map((message) => message.id).filter((id) => !excluded.has(id) && !classification.quiet.has(id) && (classification.supersessions.get(id) ?? []).length === 0);
|
|
9847
9994
|
}
|
|
9848
9995
|
/**
|
|
@@ -9897,17 +10044,18 @@ function placeMember(input, links, amended, id, seen, settled) {
|
|
|
9897
10044
|
return keys;
|
|
9898
10045
|
}
|
|
9899
10046
|
/**
|
|
9900
|
-
* Collects accepted
|
|
10047
|
+
* Collects accepted amendments of live messages, following superseded amenders to live successors.
|
|
9901
10048
|
*
|
|
9902
10049
|
* @remarks
|
|
9903
10050
|
* An accepted edge relates an earlier live message to an amender without claiming which sentences
|
|
9904
|
-
* changed.
|
|
9905
|
-
*
|
|
10051
|
+
* changed. A superseded amender points to its newest reachable live successor in conversation order,
|
|
10052
|
+
* with cycles guarded and duplicate endpoints removed. With no live successor, its endpoint stays.
|
|
10053
|
+
* This never restores superseded text. An excluded or quiet user or tool message has no effect.
|
|
9906
10054
|
*
|
|
9907
10055
|
* @param input - The exclusions and classification to read
|
|
9908
10056
|
* @param byId - The messages by id
|
|
9909
10057
|
* @param live - The live message ids from {@link collectLive}
|
|
9910
|
-
* @returns The distinct accepted
|
|
10058
|
+
* @returns The distinct accepted edges in conversation order
|
|
9911
10059
|
*
|
|
9912
10060
|
* @example
|
|
9913
10061
|
* ```ts
|
|
@@ -9921,7 +10069,10 @@ function collectAmendments(input, byId, live) {
|
|
|
9921
10069
|
const ordered = [...new Set(input.messages.map((message) => message.id))];
|
|
9922
10070
|
const positions = new Map(ordered.map((id, index) => [id, index]));
|
|
9923
10071
|
const effective = /* @__PURE__ */ new Set([...live, ...[...byId.values()].filter((message) => message.role !== "assistant" && !excluded.has(message.id) && !classification.quiet.has(message.id) && (classification.supersessions.get(message.id) ?? []).length > 0).map((message) => message.id)]);
|
|
9924
|
-
return ordered.filter((id) => living.has(id)).flatMap((earlier) => [...new Set(classification.amendments.get(earlier) ?? [])
|
|
10072
|
+
return ordered.filter((id) => living.has(id)).flatMap((earlier) => [...new Set((classification.amendments.get(earlier) ?? []).filter((later) => effective.has(later) && positions.has(later)).map((later) => {
|
|
10073
|
+
const successors = new Set(scanAmendments(classification.supersessions, later, () => true));
|
|
10074
|
+
return ordered.findLast((id) => living.has(id) && successors.has(id)) ?? later;
|
|
10075
|
+
}))].sort((a, b) => (positions.get(a) ?? 0) - (positions.get(b) ?? 0)).map((later) => ({
|
|
9925
10076
|
earlier,
|
|
9926
10077
|
later
|
|
9927
10078
|
})));
|
|
@@ -9967,6 +10118,83 @@ function buildLines(input, byId, id, holders, system) {
|
|
|
9967
10118
|
}];
|
|
9968
10119
|
});
|
|
9969
10120
|
}
|
|
10121
|
+
/**
|
|
10122
|
+
* Encodes a sentence's record placement without comparing rendered text.
|
|
10123
|
+
* @param line - The record key, title, source, and zero-based sentence index
|
|
10124
|
+
* @returns The serialized placement identity
|
|
10125
|
+
* @example
|
|
10126
|
+
* ```ts
|
|
10127
|
+
* buildLedgerLineKey({ key: 'rules', title: 'Rules', source: 'one', sentence: 0 })
|
|
10128
|
+
* ```
|
|
10129
|
+
*/
|
|
10130
|
+
function buildLedgerLineKey(line) {
|
|
10131
|
+
return JSON.stringify([
|
|
10132
|
+
line.key,
|
|
10133
|
+
line.title,
|
|
10134
|
+
line.source,
|
|
10135
|
+
line.sentence
|
|
10136
|
+
]);
|
|
10137
|
+
}
|
|
10138
|
+
/**
|
|
10139
|
+
* Collects the record's sentence receipts not already held by a window.
|
|
10140
|
+
* @param record - The selected record with its original sentence identities
|
|
10141
|
+
* @param held - Placement identities already rendered in the window
|
|
10142
|
+
* @returns The remaining sentences with their record placement
|
|
10143
|
+
* @example
|
|
10144
|
+
* ```ts
|
|
10145
|
+
* collectLedgerLines({ key: 'rules', title: 'Rules', members: [], lines: [] }, new Set()) // []
|
|
10146
|
+
* ```
|
|
10147
|
+
*/
|
|
10148
|
+
function collectLedgerLines(record, held) {
|
|
10149
|
+
return record.lines.map((line) => ({
|
|
10150
|
+
...line,
|
|
10151
|
+
key: record.key,
|
|
10152
|
+
title: record.title
|
|
10153
|
+
})).filter((line) => !held.has(buildLedgerLineKey(line)));
|
|
10154
|
+
}
|
|
10155
|
+
/**
|
|
10156
|
+
* Selects each marked request's unambiguous final call-free reply.
|
|
10157
|
+
* @param messages - Stored conversation messages in order
|
|
10158
|
+
* @param requests - Marked request ids delimiting reply intervals
|
|
10159
|
+
* @param notes - Ledger notes that separate answer passes
|
|
10160
|
+
* @returns Eligible final replies keyed by request id
|
|
10161
|
+
* @example
|
|
10162
|
+
* ```ts
|
|
10163
|
+
* collectLedgerReplies([], new Set(), new Set()).size // 0
|
|
10164
|
+
* ```
|
|
10165
|
+
*/
|
|
10166
|
+
function collectLedgerReplies(messages, requests, notes) {
|
|
10167
|
+
const positions = messages.flatMap((message, at) => requests.has(message.id) ? [at] : []);
|
|
10168
|
+
return new Map(positions.flatMap((position, index) => {
|
|
10169
|
+
const request = messages[position];
|
|
10170
|
+
const turns = messages.slice(position + 1, positions[index + 1]);
|
|
10171
|
+
const reply = turns.findLast((message) => message.role === "assistant" && !hasCalls(message));
|
|
10172
|
+
const answers = turns.flatMap((message, at) => message.role === "assistant" && !hasCalls(message) && message.content.trim() !== "" ? [at] : []);
|
|
10173
|
+
const certain = answers.every((at, offset) => offset === 0 || turns.slice((answers[offset - 1] ?? -1) + 1, at).some((message) => notes.has(message.id)));
|
|
10174
|
+
return request !== void 0 && certain && reply !== void 0 && reply.content.trim() !== "" ? [[request.id, reply]] : [];
|
|
10175
|
+
}));
|
|
10176
|
+
}
|
|
10177
|
+
/**
|
|
10178
|
+
* Captures source bytes and direct amendment edges for a held window.
|
|
10179
|
+
* @param messages - Current stored messages
|
|
10180
|
+
* @param sources - Requests, replies, and record sources the window holds
|
|
10181
|
+
* @param amendments - Accepted direct amendment edges from the current projection
|
|
10182
|
+
* @returns Source and edge identities for stale detection
|
|
10183
|
+
* @example
|
|
10184
|
+
* ```ts
|
|
10185
|
+
* collectLedgerEvidence([], new Set(), []).messages.size // 0
|
|
10186
|
+
* ```
|
|
10187
|
+
*/
|
|
10188
|
+
function collectLedgerEvidence(messages, sources, amendments) {
|
|
10189
|
+
return {
|
|
10190
|
+
messages: new Set(messages.filter((message) => sources.has(message.id)).map((message) => JSON.stringify(["message", message]))),
|
|
10191
|
+
amendments: new Map(amendments.filter((edge) => sources.has(edge.earlier) || sources.has(edge.later)).map((edge) => [JSON.stringify([
|
|
10192
|
+
"edge",
|
|
10193
|
+
edge.earlier,
|
|
10194
|
+
edge.later
|
|
10195
|
+
]), { ...edge }]))
|
|
10196
|
+
};
|
|
10197
|
+
}
|
|
9970
10198
|
// src/core/ledgers/Classifier.ts
|
|
9971
10199
|
/**
|
|
9972
10200
|
* Files messages through the conversation's judgment manager and reads their categories and corrections.
|
|
@@ -10011,7 +10239,7 @@ var Classifier = class {
|
|
|
10011
10239
|
/**
|
|
10012
10240
|
* Reads the category a message is filed under.
|
|
10013
10241
|
* @param id - The message id
|
|
10014
|
-
* @returns The assigned category, the recorded category at the cutoff, or `undefined
|
|
10242
|
+
* @returns The assigned category, the recorded category at the cutoff, or `undefined`; a quiet winner suppressed by the user literal floor remains undecided
|
|
10015
10243
|
*/
|
|
10016
10244
|
category(id) {
|
|
10017
10245
|
const message = this.#options.conversation.message(id);
|
|
@@ -10020,25 +10248,29 @@ var Classifier = class {
|
|
|
10020
10248
|
if (assigned !== void 0) return assigned;
|
|
10021
10249
|
const answer = this.#readCategories(id);
|
|
10022
10250
|
const cutoff = this.#options.thresholds.category;
|
|
10023
|
-
|
|
10251
|
+
const winner = LEDGER_CATEGORIES.flatMap((category) => {
|
|
10024
10252
|
const probability = answer?.probabilities[category];
|
|
10025
10253
|
return probability !== void 0 && probability >= cutoff ? [{
|
|
10026
10254
|
category,
|
|
10027
10255
|
probability
|
|
10028
10256
|
}] : [];
|
|
10029
10257
|
}).reduce((best, candidate) => best === void 0 || candidate.probability > best.probability ? candidate : best, void 0)?.category;
|
|
10258
|
+
return winner !== void 0 && QUIET_CATEGORIES.includes(winner) && !this.quiet(id) ? void 0 : winner;
|
|
10030
10259
|
}
|
|
10031
10260
|
/**
|
|
10032
10261
|
* Reports whether a message files under a quiet category.
|
|
10033
10262
|
* @param id - The message id
|
|
10034
|
-
* @returns True if the assigned or recorded
|
|
10263
|
+
* @returns True if the assigned category is quiet or the recorded quiet weight reaches the cutoff, except for a user message carrying an id or number; false otherwise
|
|
10035
10264
|
*/
|
|
10036
10265
|
quiet(id) {
|
|
10037
10266
|
const message = this.#options.conversation.message(id);
|
|
10038
10267
|
if (message === void 0) return false;
|
|
10039
10268
|
const assigned = this.#options.assign(message);
|
|
10040
10269
|
if (assigned !== void 0) return QUIET_CATEGORIES.includes(assigned);
|
|
10041
|
-
|
|
10270
|
+
if (this.#weigh(id, QUIET_CATEGORIES) < this.#options.thresholds.category) return false;
|
|
10271
|
+
if (message.role !== "user") return true;
|
|
10272
|
+
const literals = extractLiterals(message.content);
|
|
10273
|
+
return literals.ids.size + literals.numbers.size === 0;
|
|
10042
10274
|
}
|
|
10043
10275
|
/**
|
|
10044
10276
|
* Reports whether a message files under a decisive category.
|
|
@@ -10077,7 +10309,7 @@ var Classifier = class {
|
|
|
10077
10309
|
if (head !== "amends" && head !== "supersedes" || !(0, _orkestrel_contract.isString)(earlier) || !(0, _orkestrel_contract.isString)(later)) return [];
|
|
10078
10310
|
const before = this.#options.conversation.message(earlier);
|
|
10079
10311
|
const after = this.#options.conversation.message(later);
|
|
10080
|
-
if (before === void 0 || after === void 0 || (this.#readNoul(this.#buildPair(head, earlier, later)) ?? 0) < this.#options.thresholds[head]) return [];
|
|
10312
|
+
if (before === void 0 || after === void 0 || (this.#readNoul(this.#buildPair(head, earlier, later)) ?? 0) < this.#options.thresholds[head] || this.quiet(later)) return [];
|
|
10081
10313
|
return head === "amends" && !this.#sharesLiteral(extractLiterals(before.content), extractLiterals(after.content)) ? [] : [{
|
|
10082
10314
|
head,
|
|
10083
10315
|
earlier,
|
|
@@ -10329,8 +10561,9 @@ var Classifier = class {
|
|
|
10329
10561
|
* has left.
|
|
10330
10562
|
*
|
|
10331
10563
|
* @remarks
|
|
10332
|
-
* `observe` rescales from the first call
|
|
10333
|
-
*
|
|
10564
|
+
* `observe` rescales from the first call only when `spared` is absent, zero, or at least `overhead`,
|
|
10565
|
+
* with `max(0, overhead - spared)` taken out. A partially spared call keeps the existing scale.
|
|
10566
|
+
* It keeps that request's calls for the marginal rate and the longest final completion for the reply
|
|
10334
10567
|
* reserve after subtracting its thinking. `overhead` never changes after construction.
|
|
10335
10568
|
* {@link GaugeOptions} defines the measured use, reply reserve, and recall-room formulas.
|
|
10336
10569
|
* {@link LedgerOptions} defines the ledger's plan budget and recall close rule.
|
|
@@ -10388,7 +10621,7 @@ var Gauge = class {
|
|
|
10388
10621
|
}
|
|
10389
10622
|
remainder(calls) {
|
|
10390
10623
|
const call = calls.at(-1);
|
|
10391
|
-
const used = (0, _orkestrel_contract.isFiniteNumber)(call?.prompt) ? call.prompt + (call.completion ?? 0) - (this.#replay === "none" ? call.thinking ?? 0 : 0) : this.#overhead + this.#scale * (call?.estimate ?? 0);
|
|
10624
|
+
const used = (0, _orkestrel_contract.isFiniteNumber)(call?.prompt) ? call.prompt + (call.completion ?? 0) - (this.#replay === "none" ? call.thinking ?? 0 : 0) : Math.max(0, this.#overhead - (call?.spared ?? 0)) + this.#scale * (call?.estimate ?? 0);
|
|
10392
10625
|
return Math.max(0, this.#capacity - used);
|
|
10393
10626
|
}
|
|
10394
10627
|
reserve(calls, longest) {
|
|
@@ -10408,8 +10641,8 @@ var Gauge = class {
|
|
|
10408
10641
|
}
|
|
10409
10642
|
observe(calls, reply) {
|
|
10410
10643
|
const first = calls[0];
|
|
10411
|
-
if (first !== void 0 && (0, _orkestrel_contract.isFiniteNumber)(first.prompt) && first.estimate > 0) {
|
|
10412
|
-
const priced = first.prompt - this.#overhead;
|
|
10644
|
+
if (first !== void 0 && (0, _orkestrel_contract.isFiniteNumber)(first.prompt) && first.estimate > 0 && ((first.spared ?? 0) === 0 || (first.spared ?? 0) >= this.#overhead)) {
|
|
10645
|
+
const priced = first.prompt - Math.max(0, this.#overhead - (first.spared ?? 0));
|
|
10413
10646
|
if (priced > 0) this.#scale = priced / first.estimate;
|
|
10414
10647
|
}
|
|
10415
10648
|
this.#history = [...this.#history, [...calls]];
|
|
@@ -10586,10 +10819,13 @@ var LedgerRequest = class {
|
|
|
10586
10819
|
#faults = /* @__PURE__ */ new Set();
|
|
10587
10820
|
#message;
|
|
10588
10821
|
#plan;
|
|
10822
|
+
#scope;
|
|
10823
|
+
#draft;
|
|
10824
|
+
#sent;
|
|
10589
10825
|
#passes = [];
|
|
10590
10826
|
#attempts = [];
|
|
10591
10827
|
#admitted = /* @__PURE__ */ new Set();
|
|
10592
|
-
#listed =
|
|
10828
|
+
#listed = [];
|
|
10593
10829
|
#recalls = 0;
|
|
10594
10830
|
#closed = false;
|
|
10595
10831
|
/**
|
|
@@ -10620,6 +10856,16 @@ var LedgerRequest = class {
|
|
|
10620
10856
|
get plan() {
|
|
10621
10857
|
return this.#plan;
|
|
10622
10858
|
}
|
|
10859
|
+
get scope() {
|
|
10860
|
+
return this.#scope;
|
|
10861
|
+
}
|
|
10862
|
+
apply(scope) {
|
|
10863
|
+
this.#scope = scope;
|
|
10864
|
+
}
|
|
10865
|
+
/** Returns the copy and receipts adopted by the last provider turn. */
|
|
10866
|
+
get sent() {
|
|
10867
|
+
return this.#sent;
|
|
10868
|
+
}
|
|
10623
10869
|
/**
|
|
10624
10870
|
* Returns the selection the current pass's run adopted last.
|
|
10625
10871
|
*
|
|
@@ -10675,6 +10921,8 @@ var LedgerRequest = class {
|
|
|
10675
10921
|
this.#passes.at(-1)?.adopt(selection, boundary);
|
|
10676
10922
|
}
|
|
10677
10923
|
observe(call, position) {
|
|
10924
|
+
const draft = this.#draft;
|
|
10925
|
+
this.#sent = draft !== void 0 && this.selection?.messages.some((message) => message.id === draft.copy.id && message.content === draft.copy.content) ? draft : void 0;
|
|
10678
10926
|
this.#passes.at(-1)?.observe(call, position);
|
|
10679
10927
|
}
|
|
10680
10928
|
spend(usage) {
|
|
@@ -10695,8 +10943,9 @@ var LedgerRequest = class {
|
|
|
10695
10943
|
faulted(error) {
|
|
10696
10944
|
return this.#faults.has(error);
|
|
10697
10945
|
}
|
|
10698
|
-
file(attempts, plan) {
|
|
10946
|
+
file(attempts, plan, draft) {
|
|
10699
10947
|
this.#attempts = [...this.#attempts, ...attempts];
|
|
10948
|
+
this.#draft = draft;
|
|
10700
10949
|
if (plan !== void 0) this.#plan = plan;
|
|
10701
10950
|
}
|
|
10702
10951
|
admit(name, args) {
|
|
@@ -10713,11 +10962,24 @@ var LedgerRequest = class {
|
|
|
10713
10962
|
close() {
|
|
10714
10963
|
this.#closed = true;
|
|
10715
10964
|
}
|
|
10716
|
-
list(result, lines) {
|
|
10717
|
-
|
|
10965
|
+
list(result, lines, groups) {
|
|
10966
|
+
const accepted = groups.reduce((kept, group) => {
|
|
10967
|
+
const offset = kept.length === 0 ? 0 : kept.join("\n").length + 1;
|
|
10968
|
+
return result.slice(offset) === group || result.slice(offset).startsWith(`${group}\n`) ? [...kept, group] : kept;
|
|
10969
|
+
}, []);
|
|
10970
|
+
this.#listed = [...this.#listed, {
|
|
10971
|
+
result,
|
|
10972
|
+
lines,
|
|
10973
|
+
groups: accepted,
|
|
10974
|
+
turn: this.calls.length
|
|
10975
|
+
}];
|
|
10976
|
+
}
|
|
10977
|
+
/** Returns recall results with their accepted whole groups and provider-turn positions. */
|
|
10978
|
+
get listings() {
|
|
10979
|
+
return this.#listed;
|
|
10718
10980
|
}
|
|
10719
10981
|
lines(result) {
|
|
10720
|
-
return this.#listed.
|
|
10982
|
+
return this.#listed.findLast((listing) => listing.result === result)?.lines;
|
|
10721
10983
|
}
|
|
10722
10984
|
};
|
|
10723
10985
|
// src/core/ledgers/LedgerScan.ts
|
|
@@ -10828,6 +11090,29 @@ var LedgerScan = class {
|
|
|
10828
11090
|
}
|
|
10829
11091
|
};
|
|
10830
11092
|
// src/core/ledgers/shapers.ts
|
|
11093
|
+
/** Describes the minimal serialized evidence of a nonempty exchange window. */
|
|
11094
|
+
var ledgerWindowShape = (0, _orkestrel_contract.objectShape)({
|
|
11095
|
+
digest: (0, _orkestrel_contract.stringShape)(),
|
|
11096
|
+
exchanges: (0, _orkestrel_contract.arrayShape)((0, _orkestrel_contract.objectShape)({
|
|
11097
|
+
request: (0, _orkestrel_contract.stringShape)(),
|
|
11098
|
+
copy: (0, _orkestrel_contract.optionalShape)((0, _orkestrel_contract.stringShape)()),
|
|
11099
|
+
reply: (0, _orkestrel_contract.stringShape)(),
|
|
11100
|
+
lines: (0, _orkestrel_contract.arrayShape)((0, _orkestrel_contract.objectShape)({
|
|
11101
|
+
key: (0, _orkestrel_contract.stringShape)(),
|
|
11102
|
+
title: (0, _orkestrel_contract.stringShape)(),
|
|
11103
|
+
source: (0, _orkestrel_contract.stringShape)(),
|
|
11104
|
+
sentence: (0, _orkestrel_contract.numberShape)({
|
|
11105
|
+
integer: true,
|
|
11106
|
+
min: 0,
|
|
11107
|
+
max: Number.MAX_SAFE_INTEGER
|
|
11108
|
+
})
|
|
11109
|
+
}))
|
|
11110
|
+
}), { min: 1 }),
|
|
11111
|
+
amendments: (0, _orkestrel_contract.arrayShape)((0, _orkestrel_contract.objectShape)({
|
|
11112
|
+
earlier: (0, _orkestrel_contract.stringShape)(),
|
|
11113
|
+
later: (0, _orkestrel_contract.stringShape)()
|
|
11114
|
+
}))
|
|
11115
|
+
});
|
|
10831
11116
|
/**
|
|
10832
11117
|
* Describes a ledger snapshot exactly: an unknown key refuses, so a key a later version adds never reads
|
|
10833
11118
|
* as absent.
|
|
@@ -10845,13 +11130,36 @@ var ledgerSnapshotShape = (0, _orkestrel_contract.objectShape)({
|
|
|
10845
11130
|
gauge: (0, _orkestrel_contract.optionalShape)((0, _orkestrel_contract.objectShape)({
|
|
10846
11131
|
scale: (0, _orkestrel_contract.numberShape)(),
|
|
10847
11132
|
overhead: (0, _orkestrel_contract.numberShape)()
|
|
10848
|
-
}))
|
|
11133
|
+
})),
|
|
11134
|
+
window: (0, _orkestrel_contract.optionalShape)(ledgerWindowShape)
|
|
10849
11135
|
});
|
|
10850
11136
|
// src/core/ledgers/contracts.ts
|
|
10851
|
-
/** Reads
|
|
11137
|
+
/** Reads structural faults of a serialized exchange window. */
|
|
11138
|
+
var ledgerWindowContract = (0, _orkestrel_contract.createContract)(ledgerWindowShape);
|
|
11139
|
+
/** Reads structural faults of a ledger snapshot, including its optional held exchange window. */
|
|
10852
11140
|
var ledgerSnapshotContract = (0, _orkestrel_contract.createContract)(ledgerSnapshotShape);
|
|
10853
11141
|
// src/core/ledgers/validators.ts
|
|
10854
11142
|
/**
|
|
11143
|
+
* Checks whether a value has the exact shape of a nonempty exchange window.
|
|
11144
|
+
* @param value - The untrusted window
|
|
11145
|
+
* @returns True if the window and its members are well shaped; false otherwise
|
|
11146
|
+
* @example
|
|
11147
|
+
* ```ts
|
|
11148
|
+
* isLedgerWindowSnapshot({ digest: 'checksum', exchanges: [{ request: 'request', reply: 'reply', lines: [] }], amendments: [] }) // true
|
|
11149
|
+
* ```
|
|
11150
|
+
*/
|
|
11151
|
+
function isLedgerWindowSnapshot(value) {
|
|
11152
|
+
return (0, _orkestrel_contract.holds)(() => {
|
|
11153
|
+
if (!(0, _orkestrel_contract.isRecord)(value) || Object.keys(value).length !== 3 || !(0, _orkestrel_contract.isString)(value.digest)) return false;
|
|
11154
|
+
const { exchanges, amendments } = value;
|
|
11155
|
+
if (!(0, _orkestrel_contract.arrayOf)(_orkestrel_contract.isRecord)(exchanges) || exchanges.length === 0 || !(0, _orkestrel_contract.arrayOf)(_orkestrel_contract.isRecord)(amendments)) return false;
|
|
11156
|
+
return exchanges.every((entry) => {
|
|
11157
|
+
const { request, reply, copy, lines } = entry;
|
|
11158
|
+
return Object.keys(entry).length === 3 + Number(copy !== void 0) && (0, _orkestrel_contract.isString)(request) && (0, _orkestrel_contract.isString)(reply) && (copy === void 0 || (0, _orkestrel_contract.isString)(copy)) && (0, _orkestrel_contract.arrayOf)(_orkestrel_contract.isRecord)(lines) && lines.every((line) => Object.keys(line).length === 4 && (0, _orkestrel_contract.isString)(line.key) && (0, _orkestrel_contract.isString)(line.title) && (0, _orkestrel_contract.isString)(line.source) && isNonNegativeSafeInteger(line.sentence));
|
|
11159
|
+
}) && amendments.every((edge) => Object.keys(edge).length === 2 && (0, _orkestrel_contract.isString)(edge.earlier) && (0, _orkestrel_contract.isString)(edge.later));
|
|
11160
|
+
});
|
|
11161
|
+
}
|
|
11162
|
+
/**
|
|
10855
11163
|
* Checks whether a value is finite and lies in the interval (0, 1].
|
|
10856
11164
|
* @param value - The value to inspect
|
|
10857
11165
|
* @returns True if the value is a valid ledger fraction; false otherwise
|
|
@@ -10902,6 +11210,8 @@ function isLedgerQuestion(value) {
|
|
|
10902
11210
|
* guard is structural: it admits a conversation holding a stored `system` role
|
|
10903
11211
|
* or a repeated id, which `requireConversationSnapshot` and the `Conversation` constructor then
|
|
10904
11212
|
* refuse as the stored-data check a ledger's hydrate runs.
|
|
11213
|
+
* A present `window` must be nonempty and exactly shaped. This guard does not audit its references
|
|
11214
|
+
* or sentence ranges. Hydration discards the window when its digest disagrees or cannot be computed.
|
|
10905
11215
|
*
|
|
10906
11216
|
* @param value - The value to inspect, such as a parsed checkpoint
|
|
10907
11217
|
* @returns True if the value has the shape of a ledger snapshot whose marked ids name messages of its own conversation; false otherwise
|
|
@@ -10915,8 +11225,8 @@ function isLedgerQuestion(value) {
|
|
|
10915
11225
|
function isLedgerSnapshot(value) {
|
|
10916
11226
|
return (0, _orkestrel_contract.holds)(() => {
|
|
10917
11227
|
if (!(0, _orkestrel_contract.isRecord)(value)) return false;
|
|
10918
|
-
const { conversation, requests, notes, failures, gauge } = value;
|
|
10919
|
-
if (Object.keys(value).length !== (gauge
|
|
11228
|
+
const { conversation, requests, notes, failures, gauge, window } = value;
|
|
11229
|
+
if (Object.keys(value).length !== 4 + Number(gauge !== void 0) + Number(window !== void 0)) return false;
|
|
10920
11230
|
if (!isConversationSnapshot(conversation)) return false;
|
|
10921
11231
|
const isIds = (0, _orkestrel_contract.arrayOf)(_orkestrel_contract.isString);
|
|
10922
11232
|
if (!isIds(requests) || !isIds(notes) || !isIds(failures)) return false;
|
|
@@ -10926,7 +11236,7 @@ function isLedgerSnapshot(value) {
|
|
|
10926
11236
|
if (!(0, _orkestrel_contract.isFiniteNumber)(scale) || scale <= 0 || !(0, _orkestrel_contract.isFiniteNumber)(overhead) || overhead < 0) return false;
|
|
10927
11237
|
}
|
|
10928
11238
|
const roles = new Map(conversation.messages.map((message) => [message.id, message.role]));
|
|
10929
|
-
return requests.every((id) => roles.get(id) === "user") && notes.every((id) => roles.get(id) === "user") && failures.every((id) => roles.get(id) === "tool");
|
|
11239
|
+
return requests.every((id) => roles.get(id) === "user") && notes.every((id) => roles.get(id) === "user") && failures.every((id) => roles.get(id) === "tool") && (window === void 0 || isLedgerWindowSnapshot(window));
|
|
10930
11240
|
});
|
|
10931
11241
|
}
|
|
10932
11242
|
// src/core/ledgers/Ledger.ts
|
|
@@ -10956,6 +11266,8 @@ var Ledger = class {
|
|
|
10956
11266
|
#scans = /* @__PURE__ */ new Set();
|
|
10957
11267
|
#calibrations = /* @__PURE__ */ new Set();
|
|
10958
11268
|
#gauge;
|
|
11269
|
+
#window = [];
|
|
11270
|
+
#evidence = collectLedgerEvidence([], /* @__PURE__ */ new Set(), []);
|
|
10959
11271
|
/**
|
|
10960
11272
|
* Composes the conversation, classifier, tools, and agent.
|
|
10961
11273
|
* @param provider - The provider that serves the conversation
|
|
@@ -10989,7 +11301,8 @@ var Ledger = class {
|
|
|
10989
11301
|
if (!isLedgerQuestion(options.questions)) throw new LedgerError("QUESTION", "questions must hold a choice category question whose criteria describe every category, a non-empty topic string, and noul amends and supersedes questions; pass the LEDGER_QUESTIONS constant for the measured wording");
|
|
10990
11302
|
const snapshot = options.snapshot;
|
|
10991
11303
|
if (snapshot !== void 0 && !isLedgerSnapshot(snapshot)) {
|
|
10992
|
-
const
|
|
11304
|
+
const candidate = options.snapshot;
|
|
11305
|
+
const faults = ledgerSnapshotContract.audit(candidate);
|
|
10993
11306
|
throw new LedgerError("SNAPSHOT", `snapshot must be well formed and mark only messages of its conversation; pass what snapshot() returned${faults.length === 0 ? "" : `\n${(0, _orkestrel_contract.describeFaults)(faults, ledgerSnapshotContract.schema)}`}`, { context: { faults } });
|
|
10994
11307
|
}
|
|
10995
11308
|
this.#provider = provider;
|
|
@@ -11037,7 +11350,7 @@ var Ledger = class {
|
|
|
11037
11350
|
}));
|
|
11038
11351
|
tools.add((0, _orkestrel_tool.createTool)({
|
|
11039
11352
|
name: "recall",
|
|
11040
|
-
description: `
|
|
11353
|
+
description: `Find something said earlier that isn't in the messages you can see, by an owner name, an id, or one of the topics ${renderTopicNames(options.topics)}. Returns statements and lookup findings first, then earlier requests and replies labeled by origin; newest first within each group.`,
|
|
11041
11354
|
contract: (0, _orkestrel_contract.objectShape)({ topic: (0, _orkestrel_contract.stringShape)({
|
|
11042
11355
|
min: 1,
|
|
11043
11356
|
description: "An owner name, an id, or a topic"
|
|
@@ -11121,8 +11434,8 @@ var Ledger = class {
|
|
|
11121
11434
|
}
|
|
11122
11435
|
}
|
|
11123
11436
|
/**
|
|
11124
|
-
* Serializes the conversation,
|
|
11125
|
-
* @returns The snapshot, each id list in conversation order
|
|
11437
|
+
* Serializes the conversation, marked ids, gauge, and completed exchange window for a later ledger.
|
|
11438
|
+
* @returns The snapshot, each id list in conversation order, with a gauge and window only when held
|
|
11126
11439
|
* @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
|
|
11127
11440
|
*/
|
|
11128
11441
|
snapshot() {
|
|
@@ -11131,12 +11444,31 @@ var Ledger = class {
|
|
|
11131
11444
|
const conversation = this.#conversation.snapshot();
|
|
11132
11445
|
const ids = conversation.messages.map((message) => message.id);
|
|
11133
11446
|
const gauge = this.gauge;
|
|
11447
|
+
const window = {
|
|
11448
|
+
exchanges: this.#window.map((entry) => ({
|
|
11449
|
+
request: entry.request.id,
|
|
11450
|
+
...entry.request.content === this.#conversation.message(entry.request.id)?.content ? {} : { copy: entry.request.content },
|
|
11451
|
+
reply: entry.reply.id,
|
|
11452
|
+
lines: entry.lines.map(({ key, title, source, sentence }) => ({
|
|
11453
|
+
key,
|
|
11454
|
+
title,
|
|
11455
|
+
source,
|
|
11456
|
+
sentence
|
|
11457
|
+
}))
|
|
11458
|
+
})),
|
|
11459
|
+
amendments: [...this.#evidence.amendments.values()].map((edge) => ({ ...edge }))
|
|
11460
|
+
};
|
|
11461
|
+
const digest = window.exchanges.length === 0 ? void 0 : digestLedgerWindow(window.exchanges, conversation.messages);
|
|
11134
11462
|
return {
|
|
11135
11463
|
conversation,
|
|
11136
11464
|
requests: ids.filter((id) => this.#requests.has(id)),
|
|
11137
11465
|
notes: ids.filter((id) => this.#annotations.has(id)),
|
|
11138
11466
|
failures: ids.filter((id) => this.#results.get(id)?.success === false),
|
|
11139
|
-
...gauge === void 0 ? {} : { gauge }
|
|
11467
|
+
...gauge === void 0 ? {} : { gauge },
|
|
11468
|
+
...window.exchanges.length === 0 || digest === void 0 ? {} : { window: {
|
|
11469
|
+
...window,
|
|
11470
|
+
digest
|
|
11471
|
+
} }
|
|
11140
11472
|
};
|
|
11141
11473
|
}
|
|
11142
11474
|
/**
|
|
@@ -11154,6 +11486,7 @@ var Ledger = class {
|
|
|
11154
11486
|
if (this.#busy()) throw new AgentError("CONCURRENCY", "a ledger request is already active");
|
|
11155
11487
|
const caller = (0, _orkestrel_abort.createAbort)({ ...signal === void 0 ? {} : { signal } }).signal;
|
|
11156
11488
|
const request = new LedgerRequest(content, this.#options.recall?.limit);
|
|
11489
|
+
const scope = this.#agent.context.scope;
|
|
11157
11490
|
this.#live.add(request);
|
|
11158
11491
|
try {
|
|
11159
11492
|
if (this.#gauge === void 0) await this.#measureGauge(caller);
|
|
@@ -11169,17 +11502,18 @@ var Ledger = class {
|
|
|
11169
11502
|
});
|
|
11170
11503
|
const passes = [first];
|
|
11171
11504
|
if (!caller.aborted && (first.partial || first.content.trim() === "")) {
|
|
11172
|
-
const
|
|
11173
|
-
if (digest !== void 0) this.#annotations.add(this.#conversation.add({
|
|
11505
|
+
const recovery = this.#buildDigest(request, entered);
|
|
11506
|
+
if (recovery.digest !== void 0) this.#annotations.add(this.#conversation.add({
|
|
11174
11507
|
role: "user",
|
|
11175
|
-
content: digest
|
|
11508
|
+
content: recovery.digest
|
|
11176
11509
|
}).id);
|
|
11177
11510
|
this.#annotations.add(this.#conversation.add({
|
|
11178
11511
|
role: "user",
|
|
11179
11512
|
content: LEDGER_NOTES.cue
|
|
11180
11513
|
}).id);
|
|
11181
11514
|
const previous = this.#agent.context.scope;
|
|
11182
|
-
|
|
11515
|
+
const answer = createScope({
|
|
11516
|
+
...previous,
|
|
11183
11517
|
name: "answer",
|
|
11184
11518
|
tools: [],
|
|
11185
11519
|
select: async (conversation, message, runSignal) => {
|
|
@@ -11187,14 +11521,15 @@ var Ledger = class {
|
|
|
11187
11521
|
if (selection.fault !== void 0) return selection;
|
|
11188
11522
|
return {
|
|
11189
11523
|
...selection,
|
|
11190
|
-
messages: selection.messages.filter((one) => one.role !== "tool" && !hasCalls(one))
|
|
11524
|
+
messages: selection.messages.filter((one) => one.role !== "tool" && !hasCalls(one) && !recovery.omitted.has(one.id))
|
|
11191
11525
|
};
|
|
11192
11526
|
}
|
|
11193
|
-
})
|
|
11527
|
+
});
|
|
11528
|
+
this.#agent.context.apply(answer);
|
|
11194
11529
|
try {
|
|
11195
11530
|
passes.push(await this.#generatePass(request, caller, false));
|
|
11196
11531
|
} finally {
|
|
11197
|
-
this.#agent.context.apply(previous);
|
|
11532
|
+
if (this.#agent.context.scope === answer) this.#agent.context.apply(previous);
|
|
11198
11533
|
}
|
|
11199
11534
|
}
|
|
11200
11535
|
const last = passes.at(-1) ?? first;
|
|
@@ -11213,7 +11548,9 @@ var Ledger = class {
|
|
|
11213
11548
|
...last.stop === void 0 ? {} : { stop: last.stop }
|
|
11214
11549
|
};
|
|
11215
11550
|
} finally {
|
|
11551
|
+
if (request.scope !== void 0 && this.#agent.context.scope === request.scope) this.#agent.context.apply(scope);
|
|
11216
11552
|
this.#flush();
|
|
11553
|
+
this.#commitExchange(request);
|
|
11217
11554
|
this.#live.delete(request);
|
|
11218
11555
|
}
|
|
11219
11556
|
}
|
|
@@ -11276,6 +11613,37 @@ var Ledger = class {
|
|
|
11276
11613
|
for (const id of snapshot.requests) this.#requests.add(id);
|
|
11277
11614
|
for (const id of snapshot.notes) this.#annotations.add(id);
|
|
11278
11615
|
const messages = this.#conversation.messages();
|
|
11616
|
+
if (snapshot.window !== void 0 && digestLedgerWindow(snapshot.window.exchanges, messages) === snapshot.window.digest) {
|
|
11617
|
+
const window = snapshot.window.exchanges.map((entry) => {
|
|
11618
|
+
const request = this.#conversation.message(entry.request);
|
|
11619
|
+
const reply = this.#conversation.message(entry.reply);
|
|
11620
|
+
if (request === void 0 || reply === void 0) throw new LedgerError("SNAPSHOT", "window pair must belong to its conversation");
|
|
11621
|
+
const lines = entry.lines.map((line) => {
|
|
11622
|
+
const source = this.#conversation.message(line.source);
|
|
11623
|
+
if (source === void 0) throw new LedgerError("SNAPSHOT", "window source must belong to its conversation");
|
|
11624
|
+
return {
|
|
11625
|
+
...line,
|
|
11626
|
+
text: splitSentences(source.content)[line.sentence] ?? "",
|
|
11627
|
+
topics: [],
|
|
11628
|
+
role: source.role
|
|
11629
|
+
};
|
|
11630
|
+
});
|
|
11631
|
+
return {
|
|
11632
|
+
request: {
|
|
11633
|
+
...request,
|
|
11634
|
+
content: entry.copy ?? request.content
|
|
11635
|
+
},
|
|
11636
|
+
reply,
|
|
11637
|
+
lines
|
|
11638
|
+
};
|
|
11639
|
+
});
|
|
11640
|
+
this.#window = window;
|
|
11641
|
+
this.#evidence = collectLedgerEvidence(messages, new Set(this.#window.flatMap((entry) => [
|
|
11642
|
+
entry.request.id,
|
|
11643
|
+
entry.reply.id,
|
|
11644
|
+
...entry.lines.map((line) => line.source)
|
|
11645
|
+
])), snapshot.window.amendments);
|
|
11646
|
+
}
|
|
11279
11647
|
const groups = collectToolGroups(messages);
|
|
11280
11648
|
for (const message of messages) {
|
|
11281
11649
|
if (!snapshot.failures.includes(message.id)) continue;
|
|
@@ -11406,20 +11774,26 @@ var Ledger = class {
|
|
|
11406
11774
|
const { attempts, failure, ...filed } = classified;
|
|
11407
11775
|
const planned = (0, _orkestrel_contract.attempt)(() => {
|
|
11408
11776
|
if (filed.fault !== void 0) throw filed.fault;
|
|
11777
|
+
const { draft, ...plan } = this.#plan(selected, this.#rescan());
|
|
11409
11778
|
return {
|
|
11410
|
-
|
|
11411
|
-
|
|
11412
|
-
|
|
11779
|
+
draft,
|
|
11780
|
+
selection: {
|
|
11781
|
+
...plan,
|
|
11782
|
+
...filed,
|
|
11783
|
+
...failure === void 0 ? {} : { fault: failure }
|
|
11784
|
+
}
|
|
11413
11785
|
};
|
|
11414
11786
|
});
|
|
11415
|
-
request.file(attempts, planned.success ? planned.value : void 0);
|
|
11787
|
+
request.file(attempts, planned.success ? planned.value.selection : void 0, planned.success ? planned.value.draft : void 0);
|
|
11416
11788
|
if (!planned.success) return this.#refuse(planned.error, filed, this.#conversation);
|
|
11789
|
+
const selection = planned.value.selection;
|
|
11417
11790
|
return this.#annotations.has(message.id) ? {
|
|
11418
|
-
...
|
|
11419
|
-
messages: [...
|
|
11420
|
-
} :
|
|
11791
|
+
...selection,
|
|
11792
|
+
messages: [...selection.messages, ...this.#collectAfter(selected)]
|
|
11793
|
+
} : selection;
|
|
11421
11794
|
}
|
|
11422
11795
|
#refuse(error, filed, conversation) {
|
|
11796
|
+
if (conversation === this.#conversation && !(isLedgerError(error) && error.code === "REQUEST")) this.#current()?.file([]);
|
|
11423
11797
|
return {
|
|
11424
11798
|
...filed,
|
|
11425
11799
|
messages: conversation.view(),
|
|
@@ -11446,7 +11820,11 @@ var Ledger = class {
|
|
|
11446
11820
|
topics: [...near]
|
|
11447
11821
|
});
|
|
11448
11822
|
const total = Math.max(0, (this.#options.capacity - this.#predict) * this.#share.prompt - (this.#gauge?.overhead ?? 0)) / (1 + LEDGER_SCALE_DRIFT);
|
|
11449
|
-
const
|
|
11823
|
+
const built = this.#agent.context.build({
|
|
11824
|
+
messages: [request],
|
|
11825
|
+
judgments: []
|
|
11826
|
+
});
|
|
11827
|
+
const tail = this.#selectTail(request, total, input, scan);
|
|
11450
11828
|
const tailIds = new Set(tail.map((message) => message.id));
|
|
11451
11829
|
const scoped = records.some((record) => record.key !== LEDGER_RULES_KEY);
|
|
11452
11830
|
const held = /* @__PURE__ */ new Set([...projection.records.filter((record) => scoped || record.key === "rules").flatMap((record) => record.members), ...records.length > 0 ? projection.records.flatMap((record) => record.members.filter((id) => this.#conversation.message(id)?.role === "user" && this.#classifier.category(id) === "rule" && this.#classifier.decisive(id))) : []]);
|
|
@@ -11494,25 +11872,121 @@ var Ledger = class {
|
|
|
11494
11872
|
source: unit.source,
|
|
11495
11873
|
record: this.#buildUnitRecord(unit.source, unit.category, input, projection, held)
|
|
11496
11874
|
}));
|
|
11497
|
-
const trimmed = this.#trim(steps, records, mapped, new Set(ordered.map((unit) => unit.source)),
|
|
11498
|
-
const
|
|
11499
|
-
|
|
11500
|
-
|
|
11501
|
-
|
|
11502
|
-
|
|
11503
|
-
|
|
11504
|
-
|
|
11505
|
-
|
|
11506
|
-
const
|
|
11507
|
-
|
|
11508
|
-
|
|
11875
|
+
const trimmed = this.#trim(steps, records, mapped, new Set(ordered.map((unit) => unit.source)), built, tail, total, projection.amendments, scan);
|
|
11876
|
+
const replies = collectLedgerReplies(scan.messages, this.#requests, this.#annotations);
|
|
11877
|
+
const sources = new Set(this.#window.flatMap((entry) => [
|
|
11878
|
+
entry.request.id,
|
|
11879
|
+
entry.reply.id,
|
|
11880
|
+
...entry.lines.map((line) => line.source)
|
|
11881
|
+
]));
|
|
11882
|
+
const evidence = collectLedgerEvidence(scan.messages, sources, projection.amendments);
|
|
11883
|
+
const prefix = this.#window.flatMap((entry) => entry.lines);
|
|
11884
|
+
const prior = buildLedgerRenderContext(scan.messages, prefix, projection.amendments);
|
|
11885
|
+
const combined = buildLedgerRenderContext(scan.messages, [...prefix, ...trimmed.rendered.lines], projection.amendments);
|
|
11886
|
+
const stale = evidence.messages.size !== this.#evidence.messages.size || [...evidence.messages].some((receipt) => !this.#evidence.messages.has(receipt)) || evidence.amendments.size !== this.#evidence.amendments.size || [...evidence.amendments.keys()].some((receipt) => !this.#evidence.amendments.has(receipt)) || this.#window.some((entry) => replies.get(entry.request.id)?.id !== entry.reply.id || entry.lines.some((line) => !live.has(line.source))) || projection.amendments.some((edge) => prior.first.has(edge.earlier) && prior.complete.has(edge.later) !== combined.complete.has(edge.later) || prior.first.has(edge.later) && combined.complete.has(edge.later) && !prior.first.has(edge.earlier) && combined.first.has(edge.earlier));
|
|
11887
|
+
const last = stale ? this.#window.at(-1) : void 0;
|
|
11888
|
+
const retained = last === void 0 || replies.get(last.request.id)?.id !== last.reply.id ? void 0 : this.#conversation.message(last.request.id);
|
|
11889
|
+
if (stale) this.#window = [];
|
|
11890
|
+
const [previous, reply] = this.#window.length === 0 ? this.#selectExchange(request, input) : [];
|
|
11891
|
+
const window = this.#window.length > 0 ? this.#window : previous !== void 0 && reply !== void 0 ? [{
|
|
11892
|
+
request: previous,
|
|
11893
|
+
reply,
|
|
11894
|
+
lines: []
|
|
11895
|
+
}] : retained !== void 0 && last !== void 0 ? [{
|
|
11896
|
+
request: retained,
|
|
11897
|
+
reply: last.reply,
|
|
11898
|
+
lines: []
|
|
11899
|
+
}] : [];
|
|
11900
|
+
if (this.#window.length === 0) {
|
|
11901
|
+
const derived = collectLedgerEvidence(scan.messages, new Set(window.flatMap((entry) => [entry.request.id, entry.reply.id])), projection.amendments);
|
|
11902
|
+
this.#window = window;
|
|
11903
|
+
this.#evidence = derived;
|
|
11904
|
+
}
|
|
11905
|
+
const carried = window.flatMap((entry) => entry.lines);
|
|
11906
|
+
const delta = this.#render(trimmed.records, mapped, trimmed.included, projection.amendments, scan, new Set(carried.map(buildLedgerLineKey)), carried);
|
|
11907
|
+
const newest = window.at(-1);
|
|
11908
|
+
const plain = newest === void 0 ? void 0 : this.#conversation.message(newest.request.id);
|
|
11909
|
+
const fallback = newest === void 0 || plain === void 0 ? [] : [{
|
|
11910
|
+
request: plain,
|
|
11911
|
+
reply: newest.reply,
|
|
11912
|
+
lines: []
|
|
11913
|
+
}];
|
|
11914
|
+
const empty = {
|
|
11915
|
+
window: [],
|
|
11916
|
+
rendered: trimmed.rendered
|
|
11917
|
+
};
|
|
11918
|
+
const rungs = [
|
|
11919
|
+
{
|
|
11920
|
+
window,
|
|
11921
|
+
rendered: delta
|
|
11922
|
+
},
|
|
11923
|
+
{
|
|
11924
|
+
window: fallback,
|
|
11925
|
+
rendered: trimmed.rendered
|
|
11926
|
+
},
|
|
11927
|
+
empty
|
|
11928
|
+
];
|
|
11929
|
+
const probes = rungs.map((rung) => [...built.slice(0, -1), ...stripThinking([
|
|
11930
|
+
...tail.slice(0, -1),
|
|
11931
|
+
...rung.window.flatMap((entry) => [entry.request, entry.reply]),
|
|
11932
|
+
buildRequestMessage(built.at(-1) ?? request, rung.rendered.text)
|
|
11933
|
+
], this.#replay)]);
|
|
11934
|
+
const names = this.#agent.context.scope?.tools;
|
|
11935
|
+
const definitions = this.#agent.context.tools.definitions();
|
|
11936
|
+
const offered = rungs.map((rung) => hasHiddenRecall(input, request.id, this.#requests, this.#annotations, [...tail.slice(0, -1), ...rung.window.flatMap((entry) => [entry.request, entry.reply])], [...rung.window.flatMap((entry) => entry.lines), ...rung.rendered.lines]));
|
|
11937
|
+
const longest = this.#findLongest();
|
|
11938
|
+
const closed = probes.map((messages, at) => {
|
|
11939
|
+
const tools = definitions.filter((tool) => (names === void 0 || names.includes(tool.name)) && (tool.name !== "recall" || offered[at]));
|
|
11940
|
+
const calls = [{
|
|
11941
|
+
estimate: estimateMessages(messages),
|
|
11942
|
+
tools: tools.length,
|
|
11943
|
+
spared: this.#spared(tools)
|
|
11944
|
+
}];
|
|
11945
|
+
return offered[at] === true && this.#gauge !== void 0 && this.#gauge.remainder(calls) - this.#predict < 2 * this.#gauge.reserve(calls, longest);
|
|
11509
11946
|
});
|
|
11947
|
+
const prices = probes.map((messages) => this.#price(messages));
|
|
11948
|
+
const admitted = rungs.find((_rung, at) => (prices[at] ?? Infinity) <= total && (closed[2] === true || closed[at] === false)) ?? empty;
|
|
11949
|
+
if (offered[rungs.indexOf(admitted)] === false && (names === void 0 || names.includes("recall"))) {
|
|
11950
|
+
const tools = definitions.filter((tool) => tool.name !== "recall").map((tool) => tool.name);
|
|
11951
|
+
const narrowed = this.#agent.context.scope?.narrow({ tools }) ?? createScope({
|
|
11952
|
+
name: "ledger",
|
|
11953
|
+
tools
|
|
11954
|
+
});
|
|
11955
|
+
this.#current()?.apply(narrowed);
|
|
11956
|
+
this.#agent.context.apply(narrowed);
|
|
11957
|
+
}
|
|
11958
|
+
const copy = buildRequestMessage(request, admitted.rendered.text);
|
|
11959
|
+
const kept = admitted.window.flatMap((entry) => entry.lines);
|
|
11960
|
+
const origins = /* @__PURE__ */ new Set([
|
|
11961
|
+
request.id,
|
|
11962
|
+
...admitted.window.flatMap((entry) => [entry.request.id, entry.reply.id]),
|
|
11963
|
+
...kept.map((line) => line.source),
|
|
11964
|
+
...admitted.rendered.lines.map((line) => line.source)
|
|
11965
|
+
]);
|
|
11966
|
+
const draft = {
|
|
11967
|
+
copy,
|
|
11968
|
+
lines: admitted.rendered.lines,
|
|
11969
|
+
evidence: collectLedgerEvidence(scan.messages, origins, projection.amendments),
|
|
11970
|
+
window: admitted.window
|
|
11971
|
+
};
|
|
11972
|
+
const shown = buildLedgerRenderContext(scan.messages, [...kept, ...admitted.rendered.lines], []).complete;
|
|
11973
|
+
return {
|
|
11974
|
+
draft,
|
|
11975
|
+
messages: [
|
|
11976
|
+
...tail.slice(0, -1).map((message) => message.role === "tool" ? this.#renderTailStub(message, scan, shown) : message),
|
|
11977
|
+
...admitted.window.flatMap((entry) => [entry.request, entry.reply]),
|
|
11978
|
+
copy
|
|
11979
|
+
]
|
|
11980
|
+
};
|
|
11981
|
+
}
|
|
11982
|
+
#trim(steps, records, mapped, included, built, tail, total, amendments, scan) {
|
|
11510
11983
|
const head = built.slice(0, -1);
|
|
11511
|
-
const priced = built.at(-1)
|
|
11984
|
+
const priced = built.at(-1);
|
|
11985
|
+
if (priced === void 0) throw new Error("a built plan holds its request");
|
|
11512
11986
|
const found = findLedgerCut(0, steps.length, (count) => {
|
|
11513
11987
|
const cut = buildLedgerCut(steps.slice(0, count), records, included);
|
|
11514
11988
|
const rendered = this.#render(cut.records, mapped, cut.included, amendments, scan);
|
|
11515
|
-
const copy = buildRequestMessage(priced, rendered);
|
|
11989
|
+
const copy = buildRequestMessage(priced, rendered.text);
|
|
11516
11990
|
return this.#price([...head, ...stripThinking([...tail.slice(0, -1), copy], this.#replay)]) <= total ? {
|
|
11517
11991
|
...cut,
|
|
11518
11992
|
rendered
|
|
@@ -11537,36 +12011,48 @@ var Ledger = class {
|
|
|
11537
12011
|
const live = collectProjectionIds(projection);
|
|
11538
12012
|
return scanAmendments(input.classification.amendments, source, (id) => id === source || !held.has(id) && live.has(id)).flatMap((id) => this.#projectLines(input, id));
|
|
11539
12013
|
}
|
|
11540
|
-
#render(records, mapped, included, amendments, scan) {
|
|
11541
|
-
const
|
|
12014
|
+
#render(records, mapped, included, amendments, scan, held = /* @__PURE__ */ new Set(), prefix = []) {
|
|
12015
|
+
const population = records.map((record) => ({
|
|
12016
|
+
...record,
|
|
12017
|
+
lines: collectLedgerLines(record, held)
|
|
12018
|
+
}));
|
|
12019
|
+
const entries = mapped.filter((unit) => included.has(unit.source)).flatMap(({ record: unit }) => [...Map.groupBy(collectLedgerLines(unit, /* @__PURE__ */ new Set()), (line) => line.source)].map(([source, lines]) => ({
|
|
11542
12020
|
unit,
|
|
11543
12021
|
source,
|
|
11544
12022
|
lines
|
|
11545
12023
|
})));
|
|
11546
12024
|
const first = new Map(entries.toReversed().map((entry) => [entry.source, entry]));
|
|
11547
|
-
const unique = entries.filter((entry) => first.get(entry.source) === entry)
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
12025
|
+
const unique = entries.filter((entry) => first.get(entry.source) === entry).map((entry) => ({
|
|
12026
|
+
...entry,
|
|
12027
|
+
lines: entry.lines.filter((line) => !prefix.some((prior) => prior.source === line.source && prior.sentence === line.sentence))
|
|
12028
|
+
})).filter((entry) => entry.lines.length > 0);
|
|
12029
|
+
const record = population.find((candidate) => candidate.key === "rules" && candidate.lines.length > 0);
|
|
12030
|
+
const ownerRecords = population.filter((candidate) => candidate.key !== "rules" && candidate.lines.length > 0);
|
|
12031
|
+
const lines = [
|
|
11551
12032
|
...ownerRecords.flatMap((candidate) => candidate.lines),
|
|
11552
12033
|
...unique.filter((entry) => entry.unit.key !== LEDGER_RULES_KEY).flatMap((entry) => entry.lines),
|
|
11553
12034
|
...record?.lines ?? [],
|
|
11554
12035
|
...unique.filter((entry) => entry.unit.key === LEDGER_RULES_KEY).flatMap((entry) => entry.lines)
|
|
11555
|
-
]
|
|
12036
|
+
];
|
|
12037
|
+
const context = buildLedgerRenderContext(scan.messages, [...prefix, ...lines], amendments);
|
|
11556
12038
|
const owners = ownerRecords.map((owner) => renderLedgerPinned(owner, context)).join("\n\n");
|
|
11557
|
-
const rendered = unique.map(({ unit, source, lines }) => {
|
|
12039
|
+
const rendered = unique.map(({ unit, source, lines: retained }) => {
|
|
11558
12040
|
const sentences = splitSentences(this.#conversation.message(source)?.content ?? "");
|
|
11559
12041
|
return {
|
|
11560
12042
|
rules: unit.key === LEDGER_RULES_KEY,
|
|
11561
|
-
texts: unit.key === "rules" && source === unit.members[0] ?
|
|
12043
|
+
texts: unit.key === "rules" && source === unit.members[0] ? retained.map((line) => this.#renderSource(source, sentences, [line], context, scan)) : [this.#renderSource(source, sentences, retained, context, scan)]
|
|
11562
12044
|
};
|
|
11563
12045
|
});
|
|
11564
12046
|
const pinned = rendered.filter((one) => !one.rules).flatMap((one) => one.texts);
|
|
11565
12047
|
const rules = rendered.filter((one) => one.rules).flatMap((one) => one.texts);
|
|
11566
12048
|
const body = [owners, pinned.join("\n")].filter((text) => text !== "").join("\n\n");
|
|
11567
|
-
return
|
|
12049
|
+
return {
|
|
12050
|
+
text: [body === "" ? "" : `## Records\n${body}`, record === void 0 ? rules.length === 0 ? "" : ["## Rules", ...rules].join("\n") : [renderLedgerRecord(record, context), ...rules].join("\n")].filter((part) => part !== "").join("\n\n"),
|
|
12051
|
+
lines
|
|
12052
|
+
};
|
|
11568
12053
|
}
|
|
11569
|
-
#selectTail(request,
|
|
12054
|
+
#selectTail(request, total, input, scan) {
|
|
12055
|
+
const cap = total * this.#share.tail;
|
|
11570
12056
|
const first = input.messages.findIndex((message) => this.#requests.has(message.id));
|
|
11571
12057
|
const seed = input.messages.slice(0, first < 0 ? input.messages.findIndex((message) => message.id === request.id) : first);
|
|
11572
12058
|
const groups = collectToolGroups(seed).flatMap((group) => {
|
|
@@ -11597,6 +12083,29 @@ var Ledger = class {
|
|
|
11597
12083
|
const stop = exchanges.findIndex((_exchange, index) => this.#price(stripThinking([...exchanges.slice(0, index + 1).toReversed().flat(), request], this.#replay)) > cap);
|
|
11598
12084
|
return [...exchanges.slice(0, stop === -1 ? exchanges.length : stop).toReversed().flat(), request];
|
|
11599
12085
|
}
|
|
12086
|
+
#selectExchange(request, input) {
|
|
12087
|
+
const before = input.messages.slice(0, input.messages.findIndex((message) => message.id === request.id));
|
|
12088
|
+
const previous = before.findLast((message) => this.#requests.has(message.id));
|
|
12089
|
+
const reply = previous === void 0 ? void 0 : collectLedgerReplies(before, this.#requests, this.#annotations).get(previous.id);
|
|
12090
|
+
return previous !== void 0 && reply !== void 0 ? [previous, reply] : [];
|
|
12091
|
+
}
|
|
12092
|
+
#commitExchange(request) {
|
|
12093
|
+
const draft = request.sent;
|
|
12094
|
+
const message = request.message;
|
|
12095
|
+
if (message === void 0) return;
|
|
12096
|
+
const reply = collectLedgerReplies(this.#conversation.messages(), this.#requests, this.#annotations).get(message.id);
|
|
12097
|
+
if (reply === void 0) return;
|
|
12098
|
+
this.#window = [...draft?.window ?? this.#window, {
|
|
12099
|
+
request: draft?.copy ?? message,
|
|
12100
|
+
reply,
|
|
12101
|
+
lines: draft?.lines ?? []
|
|
12102
|
+
}];
|
|
12103
|
+
const evidence = draft?.evidence ?? this.#evidence;
|
|
12104
|
+
this.#evidence = {
|
|
12105
|
+
messages: /* @__PURE__ */ new Set([...evidence.messages, ...collectLedgerEvidence([message, reply], /* @__PURE__ */ new Set([message.id, reply.id]), []).messages]),
|
|
12106
|
+
amendments: evidence.amendments
|
|
12107
|
+
};
|
|
12108
|
+
}
|
|
11600
12109
|
#renderTailStub(message, scan, shown) {
|
|
11601
12110
|
const group = scan.group(message.id);
|
|
11602
12111
|
const call = group === void 0 ? void 0 : findLedgerCall(group, message);
|
|
@@ -11605,7 +12114,7 @@ var Ledger = class {
|
|
|
11605
12114
|
const visible = renderStub(call?.name ?? "tool", call?.arguments ?? {}, "shown");
|
|
11606
12115
|
return {
|
|
11607
12116
|
...message,
|
|
11608
|
-
content: renderStub(call?.name ?? "tool", call?.arguments ?? {}, this.#results.get(message.id)?.success === false ? "failed" : finding?.result === void 0 ? "empty" : shown === void 0 ? hidden.length > visible.length ? "hidden" : "shown" : shown.has(
|
|
12117
|
+
content: renderStub(call?.name ?? "tool", call?.arguments ?? {}, this.#results.get(message.id)?.success === false ? "failed" : finding?.result === void 0 ? "empty" : shown === void 0 ? hidden.length > visible.length ? "hidden" : "shown" : scan.findings.some((other) => shown.has(other.id) && matchesLookup(finding, other)) ? "shown" : "hidden")
|
|
11609
12118
|
};
|
|
11610
12119
|
}
|
|
11611
12120
|
#observeTurn() {
|
|
@@ -11616,11 +12125,19 @@ var Ledger = class {
|
|
|
11616
12125
|
const additions = this.#conversation.messages().slice(boundary);
|
|
11617
12126
|
const messages = this.#agent.context.build(request.selection);
|
|
11618
12127
|
const names = this.#agent.context.scope?.tools;
|
|
12128
|
+
const tools = this.#agent.context.tools.definitions().filter((tool) => names === void 0 || names.includes(tool.name));
|
|
11619
12129
|
request.observe({
|
|
11620
12130
|
estimate: estimateMessages(stripThinking([...messages, ...additions], this.#replay)),
|
|
11621
|
-
tools:
|
|
12131
|
+
tools: tools.length,
|
|
12132
|
+
spared: this.#spared(tools)
|
|
11622
12133
|
}, this.#conversation.messages().length);
|
|
11623
12134
|
}
|
|
12135
|
+
#spared(tools) {
|
|
12136
|
+
const overhead = this.#gauge?.overhead ?? 0;
|
|
12137
|
+
if (tools.length === 0) return overhead;
|
|
12138
|
+
const missing = this.#agent.context.tools.definitions().filter((tool) => !tools.some((one) => one.name === tool.name));
|
|
12139
|
+
return missing.length === 0 ? 0 : Math.min(overhead, estimateTokens(JSON.stringify(missing)) * (this.#gauge?.scale ?? 1));
|
|
12140
|
+
}
|
|
11624
12141
|
#findLongest() {
|
|
11625
12142
|
return this.#conversation.messages().filter((message) => message.role === "assistant").reduce((longest, message) => message.content.length > longest.length ? message.content : longest, "");
|
|
11626
12143
|
}
|
|
@@ -11637,11 +12154,21 @@ var Ledger = class {
|
|
|
11637
12154
|
request?.admit("recall", { topic });
|
|
11638
12155
|
const gauge = this.#gauge;
|
|
11639
12156
|
const calls = request?.calls ?? [];
|
|
11640
|
-
if (gauge !== void 0 && calls.length > 0 && gauge.remainder(calls) - this.#predict < 2 * gauge.reserve(calls, this.#findLongest())) request?.close();
|
|
11641
12157
|
request?.recall();
|
|
11642
12158
|
const guidance = `an owner name, an id, or one of ${renderTopicNames(this.#options.topics)}`;
|
|
11643
12159
|
if (topic === "") throw new Error(`recall needs a topic: ${guidance}`);
|
|
11644
|
-
const
|
|
12160
|
+
const rate = this.#recallRate(request) * (1 + LEDGER_SCALE_DRIFT);
|
|
12161
|
+
const call = calls.at(-1);
|
|
12162
|
+
const carried = request === void 0 ? 0 : estimateMessages(stripThinking([...this.#agent.context.build(request.selection), ...this.#conversation.messages().slice(request.boundary)], this.#replay));
|
|
12163
|
+
const completion = (0, _orkestrel_contract.isFiniteNumber)(call?.prompt) ? (call.completion ?? 0) - (this.#replay === "none" ? call.thinking ?? 0 : 0) : 0;
|
|
12164
|
+
const extra = Math.max(0, (carried - (call?.estimate ?? carried)) * rate - completion);
|
|
12165
|
+
const drift = (0, _orkestrel_contract.isFiniteNumber)(call?.prompt) ? 0 : Math.max(0, (call?.estimate ?? 0) * (rate - (gauge?.scale ?? rate)));
|
|
12166
|
+
const siblings = estimateMessages((request?.listings ?? []).filter((listing) => listing.turn === calls.length).map((listing) => ({
|
|
12167
|
+
id: "result",
|
|
12168
|
+
role: "tool",
|
|
12169
|
+
content: listing.result
|
|
12170
|
+
})));
|
|
12171
|
+
const room = gauge === void 0 ? -estimateMessages([buildRecallMessage(topic)]) : (gauge.remainder(calls) - this.#predict - extra - drift) / rate - siblings;
|
|
11645
12172
|
const scan = this.#scan(this.#conversation.messages());
|
|
11646
12173
|
const added = this.#scans.size === 0;
|
|
11647
12174
|
if (added) this.#hold(scan);
|
|
@@ -11673,11 +12200,12 @@ var Ledger = class {
|
|
|
11673
12200
|
const source = listable.get(id);
|
|
11674
12201
|
if (source === void 0) return [];
|
|
11675
12202
|
const lookup = scan.finding(id);
|
|
11676
|
-
const
|
|
12203
|
+
const content = source.content.replace(/(^|[\n\v\f\r\u0085\u2028\u2029])(?=Earlier (?:request|reply):)/g, "$1 ");
|
|
12204
|
+
const text = lookup === void 0 ? content : `${renderLookupCall(lookup.name, lookup.arguments)}: ${content}`;
|
|
11677
12205
|
return [{
|
|
11678
12206
|
id,
|
|
11679
12207
|
text,
|
|
11680
|
-
stored: lookup === void 0 ? [] : [[splitResultLines(text)[0] ?? "", splitResultLines(
|
|
12208
|
+
stored: lookup === void 0 ? [] : [[splitResultLines(text)[0] ?? "", splitResultLines(content)[0] ?? ""]]
|
|
11681
12209
|
}];
|
|
11682
12210
|
});
|
|
11683
12211
|
return {
|
|
@@ -11690,8 +12218,15 @@ var Ledger = class {
|
|
|
11690
12218
|
listed: [],
|
|
11691
12219
|
recalled: /* @__PURE__ */ new Map()
|
|
11692
12220
|
});
|
|
11693
|
-
const
|
|
11694
|
-
|
|
12221
|
+
const earlier = input.messages.slice(0, Math.max(0, start)).reverse().flatMap((message) => {
|
|
12222
|
+
if (gathered.done.has(message.id) || this.#annotations.has(message.id)) return [];
|
|
12223
|
+
const label = this.#requests.has(message.id) ? LEDGER_RECALL_LABELS.request : message.role === "assistant" && !hasCalls(message) && message.content.trim() !== "" ? LEDGER_RECALL_LABELS.reply : void 0;
|
|
12224
|
+
if (label === void 0 || !searches.some((search) => search.words.length > 0 && search.words.every((word) => message.content.toLowerCase().includes(word)))) return [];
|
|
12225
|
+
return [`${label} ${message.content.replace(/[\n\v\f\r\u0085\u2028\u2029]+/g, "\n ")}`];
|
|
12226
|
+
});
|
|
12227
|
+
const listed = [...gathered.listed, ...earlier];
|
|
12228
|
+
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);
|
|
12229
|
+
request?.list(result, gathered.recalled, listed);
|
|
11695
12230
|
return result;
|
|
11696
12231
|
} finally {
|
|
11697
12232
|
if (added) this.#scans.delete(scan);
|
|
@@ -11699,15 +12234,58 @@ var Ledger = class {
|
|
|
11699
12234
|
}
|
|
11700
12235
|
#buildDigest(request, entered) {
|
|
11701
12236
|
this.#flush();
|
|
11702
|
-
const
|
|
12237
|
+
const groups = [...new Set(this.#collectAfter(entered).flatMap((message) => {
|
|
11703
12238
|
const result = this.#results.get(message.id);
|
|
11704
12239
|
if (message.role !== "tool" || result?.success !== true) return [];
|
|
11705
12240
|
const recalled = result.name === "recall";
|
|
11706
|
-
if (recalled && /^nothing on /.test(message.content)) return [];
|
|
11707
|
-
const
|
|
11708
|
-
return
|
|
12241
|
+
if (recalled && /^nothing earlier on /.test(message.content)) return [];
|
|
12242
|
+
const listing = recalled ? request.listings.findLast((one) => one.result === message.content) : void 0;
|
|
12243
|
+
return (listing?.groups ?? [message.content]).map((group) => splitResultLines(group).map((line) => listing?.lines.get(line) ?? line).join("\n")).filter((group) => group !== "");
|
|
11709
12244
|
}))];
|
|
11710
|
-
|
|
12245
|
+
const unique = groups.filter((group, at) => !splitResultLines(group).every((line) => groups.slice(0, at).some((earlier) => splitResultLines(earlier).includes(line))));
|
|
12246
|
+
const digest = unique.length === 0 ? void 0 : `${LEDGER_NOTES.results}\n${unique.join("\n")}`;
|
|
12247
|
+
const omitted = /* @__PURE__ */ new Set();
|
|
12248
|
+
const rate = this.#recallRate(request) * (1 + LEDGER_SCALE_DRIFT);
|
|
12249
|
+
const allowance = (this.#options.capacity - this.#predict) / rate;
|
|
12250
|
+
const after = this.#collectAfter(entered);
|
|
12251
|
+
const messages = [
|
|
12252
|
+
...request.plan?.messages ?? request.selection?.messages ?? [],
|
|
12253
|
+
...after,
|
|
12254
|
+
{
|
|
12255
|
+
id: "cue",
|
|
12256
|
+
role: "user",
|
|
12257
|
+
content: LEDGER_NOTES.cue
|
|
12258
|
+
}
|
|
12259
|
+
].filter((message) => message.role !== "tool" && !hasCalls(message));
|
|
12260
|
+
const note = digest === void 0 ? [] : [{
|
|
12261
|
+
id: "results",
|
|
12262
|
+
role: "user",
|
|
12263
|
+
content: digest
|
|
12264
|
+
}];
|
|
12265
|
+
if (this.#gauge === void 0 || estimateMessages(stripThinking(this.#agent.context.build({
|
|
12266
|
+
messages: [...messages, ...note],
|
|
12267
|
+
judgments: []
|
|
12268
|
+
}), this.#replay)) <= allowance) return {
|
|
12269
|
+
digest,
|
|
12270
|
+
omitted
|
|
12271
|
+
};
|
|
12272
|
+
const partials = new Set(after.filter((message) => message.role === "assistant" && !hasCalls(message)).map((message) => message.id));
|
|
12273
|
+
const fitted = cutListing(unique, allowance - estimateMessages(stripThinking(this.#agent.context.build({
|
|
12274
|
+
messages: messages.filter((message) => !partials.has(message.id)),
|
|
12275
|
+
judgments: []
|
|
12276
|
+
}), this.#replay)) - estimateTokens(`${LEDGER_NOTES.results}\n`), "more", false);
|
|
12277
|
+
return {
|
|
12278
|
+
digest: fitted === "" ? void 0 : `${LEDGER_NOTES.results}\n${fitted}`,
|
|
12279
|
+
omitted: partials
|
|
12280
|
+
};
|
|
12281
|
+
}
|
|
12282
|
+
#recallRate(request) {
|
|
12283
|
+
const gauge = this.#gauge;
|
|
12284
|
+
if (gauge === void 0) return 1;
|
|
12285
|
+
const calls = request?.calls ?? [];
|
|
12286
|
+
const last = calls.findLast((call) => (0, _orkestrel_contract.isFiniteNumber)(call.prompt));
|
|
12287
|
+
const measured = last !== void 0 && (0, _orkestrel_contract.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;
|
|
12288
|
+
return Math.max(gauge.rate(calls), measured);
|
|
11711
12289
|
}
|
|
11712
12290
|
};
|
|
11713
12291
|
// src/core/ledgers/factories.ts
|
|
@@ -11768,6 +12346,7 @@ exports.LEDGER_CATEGORIES = LEDGER_CATEGORIES;
|
|
|
11768
12346
|
exports.LEDGER_NOTES = LEDGER_NOTES;
|
|
11769
12347
|
exports.LEDGER_OWNER_PREFIX = LEDGER_OWNER_PREFIX;
|
|
11770
12348
|
exports.LEDGER_QUESTIONS = LEDGER_QUESTIONS;
|
|
12349
|
+
exports.LEDGER_RECALL_LABELS = LEDGER_RECALL_LABELS;
|
|
11771
12350
|
exports.LEDGER_RULES_KEY = LEDGER_RULES_KEY;
|
|
11772
12351
|
exports.LEDGER_SCALE_DRIFT = LEDGER_SCALE_DRIFT;
|
|
11773
12352
|
exports.LEDGER_SLICE = LEDGER_SLICE;
|
|
@@ -11826,6 +12405,7 @@ exports.buildJudgeResult = buildJudgeResult;
|
|
|
11826
12405
|
exports.buildJudgments = buildJudgments;
|
|
11827
12406
|
exports.buildLedgerCut = buildLedgerCut;
|
|
11828
12407
|
exports.buildLedgerIndex = buildLedgerIndex;
|
|
12408
|
+
exports.buildLedgerLineKey = buildLedgerLineKey;
|
|
11829
12409
|
exports.buildLedgerRenderContext = buildLedgerRenderContext;
|
|
11830
12410
|
exports.buildLines = buildLines;
|
|
11831
12411
|
exports.buildProviderHeaders = buildProviderHeaders;
|
|
@@ -11840,9 +12420,13 @@ exports.chargeUsage = chargeUsage;
|
|
|
11840
12420
|
exports.collectAmendments = collectAmendments;
|
|
11841
12421
|
exports.collectExchanges = collectExchanges;
|
|
11842
12422
|
exports.collectImageData = collectImageData;
|
|
12423
|
+
exports.collectLedgerEvidence = collectLedgerEvidence;
|
|
12424
|
+
exports.collectLedgerLines = collectLedgerLines;
|
|
12425
|
+
exports.collectLedgerReplies = collectLedgerReplies;
|
|
11843
12426
|
exports.collectLive = collectLive;
|
|
11844
12427
|
exports.collectNames = collectNames;
|
|
11845
12428
|
exports.collectProjectionIds = collectProjectionIds;
|
|
12429
|
+
exports.collectRecallMessages = collectRecallMessages;
|
|
11846
12430
|
exports.collectRegistry = collectRegistry;
|
|
11847
12431
|
exports.collectToolGroups = collectToolGroups;
|
|
11848
12432
|
exports.computeThinking = computeThinking;
|
|
@@ -11879,6 +12463,7 @@ exports.denyCall = denyCall;
|
|
|
11879
12463
|
exports.describeQuestionRefusal = describeQuestionRefusal;
|
|
11880
12464
|
exports.describeRelayRefusal = describeRelayRefusal;
|
|
11881
12465
|
exports.describeSnapshotRefusal = describeSnapshotRefusal;
|
|
12466
|
+
exports.digestLedgerWindow = digestLedgerWindow;
|
|
11882
12467
|
exports.estimateMessages = estimateMessages;
|
|
11883
12468
|
exports.estimateRequest = estimateRequest;
|
|
11884
12469
|
exports.estimateTokens = estimateTokens;
|
|
@@ -11894,6 +12479,7 @@ exports.fitSlope = fitSlope;
|
|
|
11894
12479
|
exports.freezeJSON = freezeJSON;
|
|
11895
12480
|
exports.handleAgentQueueJob = handleAgentQueueJob;
|
|
11896
12481
|
exports.hasCalls = hasCalls;
|
|
12482
|
+
exports.hasHiddenRecall = hasHiddenRecall;
|
|
11897
12483
|
exports.identifyLookup = identifyLookup;
|
|
11898
12484
|
exports.inferStop = inferStop;
|
|
11899
12485
|
exports.intersectKeys = intersectKeys;
|
|
@@ -11915,6 +12501,7 @@ exports.isJudgment = isJudgment;
|
|
|
11915
12501
|
exports.isLedgerError = isLedgerError;
|
|
11916
12502
|
exports.isLedgerQuestion = isLedgerQuestion;
|
|
11917
12503
|
exports.isLedgerSnapshot = isLedgerSnapshot;
|
|
12504
|
+
exports.isLedgerWindowSnapshot = isLedgerWindowSnapshot;
|
|
11918
12505
|
exports.isMemo = isMemo;
|
|
11919
12506
|
exports.isMemoOrigin = isMemoOrigin;
|
|
11920
12507
|
exports.isMemoSnapshot = isMemoSnapshot;
|
|
@@ -11938,11 +12525,14 @@ exports.judgmentContract = judgmentContract;
|
|
|
11938
12525
|
exports.judgmentShape = judgmentShape;
|
|
11939
12526
|
exports.ledgerSnapshotContract = ledgerSnapshotContract;
|
|
11940
12527
|
exports.ledgerSnapshotShape = ledgerSnapshotShape;
|
|
12528
|
+
exports.ledgerWindowContract = ledgerWindowContract;
|
|
12529
|
+
exports.ledgerWindowShape = ledgerWindowShape;
|
|
11941
12530
|
exports.linkOwners = linkOwners;
|
|
11942
12531
|
exports.matchEntities = matchEntities;
|
|
11943
12532
|
exports.matchesCutLine = matchesCutLine;
|
|
11944
12533
|
exports.matchesJSON = matchesJSON;
|
|
11945
12534
|
exports.matchesJudgment = matchesJudgment;
|
|
12535
|
+
exports.matchesLookup = matchesLookup;
|
|
11946
12536
|
exports.measureAnswer = measureAnswer;
|
|
11947
12537
|
exports.measureMessage = measureMessage;
|
|
11948
12538
|
exports.measureRequest = measureRequest;
|