@plurnk/plurnk-service 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.defaults +22 -27
- package/INSTALL.md +22 -17
- package/README.md +1 -1
- package/SPEC.md +505 -362
- package/dist/build-info.json +1 -1
- package/dist/content/edit-collision.d.ts +5 -0
- package/dist/content/edit-collision.d.ts.map +1 -0
- package/dist/content/edit-collision.js +14 -0
- package/dist/content/edit-collision.js.map +1 -0
- package/dist/content/edit-receipt.d.ts +3 -2
- package/dist/content/edit-receipt.d.ts.map +1 -1
- package/dist/content/edit-receipt.js +58 -13
- package/dist/content/edit-receipt.js.map +1 -1
- package/dist/content/index.d.ts +4 -1
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +3 -1
- package/dist/content/index.js.map +1 -1
- package/dist/content/line-anchors.d.ts +41 -0
- package/dist/content/line-anchors.d.ts.map +1 -0
- package/dist/content/line-anchors.js +191 -0
- package/dist/content/line-anchors.js.map +1 -0
- package/dist/content/read-projector.d.ts +7 -1
- package/dist/content/read-projector.d.ts.map +1 -1
- package/dist/content/read-projector.js +46 -10
- package/dist/content/read-projector.js.map +1 -1
- package/dist/content/read-resolve.js +3 -3
- package/dist/content/read-resolve.js.map +1 -1
- package/dist/core/BudgetReadout.d.ts.map +1 -1
- package/dist/core/BudgetReadout.js +9 -2
- package/dist/core/BudgetReadout.js.map +1 -1
- package/dist/core/ChannelWrite.js +1 -1
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/ChannelWrite.sql +3 -3
- package/dist/core/CoreSchemeServices.d.ts +1 -1
- package/dist/core/CoreSchemeServices.d.ts.map +1 -1
- package/dist/core/CoreSchemeServices.js +1 -1
- package/dist/core/CoreSchemeServices.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +15 -5
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +220 -978
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/DurableStatement.d.ts.map +1 -1
- package/dist/core/DurableStatement.js +2 -0
- package/dist/core/DurableStatement.js.map +1 -1
- package/dist/core/Engine.d.ts +18 -43
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +90 -1554
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +192 -112
- package/dist/core/ExecutableTools.d.ts +10 -0
- package/dist/core/ExecutableTools.d.ts.map +1 -0
- package/dist/core/ExecutableTools.js +41 -0
- package/dist/core/ExecutableTools.js.map +1 -0
- package/dist/core/ExecutorRegistry.d.ts +3 -3
- package/dist/core/ExecutorRegistry.d.ts.map +1 -1
- package/dist/core/ExecutorRegistry.js +2 -2
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/LogBody.d.ts +3 -0
- package/dist/core/LogBody.d.ts.map +1 -1
- package/dist/core/LogBody.js +21 -5
- package/dist/core/LogBody.js.map +1 -1
- package/dist/core/LogEntryProjection.d.ts +14 -0
- package/dist/core/LogEntryProjection.d.ts.map +1 -0
- package/dist/core/LogEntryProjection.js +38 -0
- package/dist/core/LogEntryProjection.js.map +1 -0
- package/dist/core/ModelCall.d.ts +27 -0
- package/dist/core/ModelCall.d.ts.map +1 -0
- package/dist/core/ModelCall.js +127 -0
- package/dist/core/ModelCall.js.map +1 -0
- package/dist/core/PacketBuilder.d.ts +14 -25
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +170 -244
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/ProblemLog.d.ts +1 -1
- package/dist/core/ProblemLog.d.ts.map +1 -1
- package/dist/core/ProblemLog.js +15 -3
- package/dist/core/ProblemLog.js.map +1 -1
- package/dist/core/ProposalLifecycle.d.ts +2 -2
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +17 -9
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/ProviderInstantiate.d.ts.map +1 -1
- package/dist/core/ProviderInstantiate.js +25 -8
- package/dist/core/ProviderInstantiate.js.map +1 -1
- package/dist/core/ResourceMutations.d.ts +73 -0
- package/dist/core/ResourceMutations.d.ts.map +1 -0
- package/dist/core/ResourceMutations.js +1142 -0
- package/dist/core/ResourceMutations.js.map +1 -0
- package/dist/core/SchemeRegistry.js +10 -10
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/StoredPacket.d.ts +2 -2
- package/dist/core/StoredPacket.js +7 -7
- package/dist/core/StrikeRail.d.ts +0 -1
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +6 -4
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/TurnRunner.d.ts +72 -0
- package/dist/core/TurnRunner.d.ts.map +1 -0
- package/dist/core/TurnRunner.js +1730 -0
- package/dist/core/TurnRunner.js.map +1 -0
- package/dist/core/caps/CapsResolve.js +1 -1
- package/dist/core/caps/CapsResolve.js.map +1 -1
- package/dist/core/caps/DbChannelCaps.js +4 -4
- package/dist/core/caps/DbChannelCaps.js.map +1 -1
- package/dist/core/caps/DbEntryCaps.d.ts +2 -1
- package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
- package/dist/core/caps/DbEntryCaps.js +8 -5
- package/dist/core/caps/DbEntryCaps.js.map +1 -1
- package/dist/core/caps/DbProjectionCaps.d.ts +1 -0
- package/dist/core/caps/DbProjectionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbProjectionCaps.js +29 -0
- package/dist/core/caps/DbProjectionCaps.js.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.d.ts +5 -2
- package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.js +6 -4
- package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
- package/dist/core/content-hash.js +2 -2
- package/dist/core/content-hash.js.map +1 -1
- package/dist/core/content-weight.d.ts +2 -0
- package/dist/core/content-weight.d.ts.map +1 -0
- package/dist/core/content-weight.js +4 -0
- package/dist/core/content-weight.js.map +1 -0
- package/dist/core/content_weight.d.ts +4 -0
- package/dist/core/content_weight.d.ts.map +1 -0
- package/dist/core/content_weight.js +6 -0
- package/dist/core/content_weight.js.map +1 -0
- package/dist/core/fork.d.ts.map +1 -1
- package/dist/core/fork.js +23 -7
- package/dist/core/fork.js.map +1 -1
- package/dist/core/fork.sql +38 -17
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +1 -2
- package/dist/core/git-membership.js.map +1 -1
- package/dist/core/git-state.js +1 -1
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/packet-wire.d.ts +6 -3
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +257 -99
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/provider-accounting.d.ts +24 -0
- package/dist/core/provider-accounting.d.ts.map +1 -0
- package/dist/core/provider-accounting.js +76 -0
- package/dist/core/provider-accounting.js.map +1 -0
- package/dist/core/scheme-types.d.ts +1 -1
- package/dist/core/scheme-types.d.ts.map +1 -1
- package/dist/core/search-gate.d.ts +2 -2
- package/dist/core/search-gate.d.ts.map +1 -1
- package/dist/core/search-gate.js +8 -8
- package/dist/core/search-gate.js.map +1 -1
- package/dist/core/turn-scheduler.js +1 -1
- package/dist/core/turn-scheduler.js.map +1 -1
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +221 -110
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/digest.sql +40 -18
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +136 -110
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +1 -1
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/File.d.ts +5 -4
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +25 -23
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts +11 -0
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +172 -107
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Log.sql +48 -32
- package/dist/schemes/Prompt.d.ts +3 -3
- package/dist/schemes/Prompt.d.ts.map +1 -1
- package/dist/schemes/Prompt.js +4 -1
- package/dist/schemes/Prompt.js.map +1 -1
- package/dist/schemes/Skill.d.ts +4 -4
- package/dist/schemes/Skill.d.ts.map +1 -1
- package/dist/schemes/Skill.js +3 -0
- package/dist/schemes/Skill.js.map +1 -1
- package/dist/schemes/Worker.d.ts +4 -4
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +11 -7
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts +0 -1
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js +19 -13
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-crud.sql +4 -16
- package/dist/schemes/_entry-find.d.ts +17 -16
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +58 -52
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-find.sql +2 -21
- package/dist/schemes/_entry-graph.sql +1 -1
- package/dist/schemes/_entry-manifest.d.ts +5 -17
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-manifest.js +32 -28
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-ops.d.ts +5 -4
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +89 -49
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-ops.sql +30 -4
- package/dist/schemes/_entry-send.js +4 -4
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/schemes/_search-index.d.ts.map +1 -1
- package/dist/schemes/_search-index.js +10 -2
- package/dist/schemes/_search-index.js.map +1 -1
- package/dist/schemes/exec-abort.js +2 -2
- package/dist/schemes/exec-abort.js.map +1 -1
- package/dist/server/Daemon.d.ts +7 -42
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +139 -900
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DrainSupervisor.d.ts +117 -0
- package/dist/server/DrainSupervisor.d.ts.map +1 -0
- package/dist/server/DrainSupervisor.js +802 -0
- package/dist/server/DrainSupervisor.js.map +1 -0
- package/dist/server/drain.sql +2 -2
- package/dist/server/envelope.d.ts +0 -2
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/envelope.sql +2 -2
- package/dist/server/lifecycle-recovery.sql +28 -15
- package/dist/server/logEntry.d.ts +2 -1
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js +14 -2
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/logEntry.sql +5 -1
- package/dist/server/seam-entry-read.sql +2 -2
- package/dist/service.js +1 -1
- package/dist/service.js.map +1 -1
- package/migrations/001_schema.sql +622 -216
- package/package.json +39 -34
- package/dist/core/BudgetOverflow.d.ts +0 -20
- package/dist/core/BudgetOverflow.d.ts.map +0 -1
- package/dist/core/BudgetOverflow.js +0 -49
- package/dist/core/BudgetOverflow.js.map +0 -1
- package/dist/core/caps/DbTagCaps.d.ts +0 -10
- package/dist/core/caps/DbTagCaps.d.ts.map +0 -1
- package/dist/core/caps/DbTagCaps.js +0 -46
- package/dist/core/caps/DbTagCaps.js.map +0 -1
- package/dist/core/ruler_count.d.ts +0 -4
- package/dist/core/ruler_count.d.ts.map +0 -1
- package/dist/core/ruler_count.js +0 -7
- package/dist/core/ruler_count.js.map +0 -1
- package/dist/core/token-ruler.d.ts +0 -2
- package/dist/core/token-ruler.d.ts.map +0 -1
- package/dist/core/token-ruler.js +0 -5
- package/dist/core/token-ruler.js.map +0 -1
package/dist/digest/Digest.js
CHANGED
|
@@ -36,13 +36,16 @@ import { dirname, join, resolve } from "node:path";
|
|
|
36
36
|
import { randomUUID } from "node:crypto";
|
|
37
37
|
import { fileURLToPath } from "node:url";
|
|
38
38
|
import { homedir } from "node:os";
|
|
39
|
+
import { isDeepStrictEqual } from "node:util";
|
|
39
40
|
import SqlRiteSync from "@possumtech/sqlrite/sync";
|
|
40
41
|
import { observedSync } from "../observe/spans.js";
|
|
41
42
|
import PacketWire from "../core/packet-wire.js";
|
|
43
|
+
import LogBody from "../core/LogBody.js";
|
|
42
44
|
import StoredPacket from "../core/StoredPacket.js";
|
|
43
45
|
import { renderTarget } from "../core/plurnk-uri.js";
|
|
44
46
|
import ProviderInstantiate from "../core/ProviderInstantiate.js";
|
|
45
|
-
import {
|
|
47
|
+
import { aggregateProviderAccounting, ProviderError, validateProviderRequestAccounting, } from "@plurnk/plurnk-providers";
|
|
48
|
+
import { providerRequestFromStorageRow, } from "../core/provider-accounting.js";
|
|
46
49
|
import { Validator, } from "@plurnk/plurnk-contracts";
|
|
47
50
|
// The requiem prompt ({§digest-requiem}): the model's exit interview. Absolution up front - the system is
|
|
48
51
|
// under test, not the model - so RLHF'd self-blame doesn't crowd out the system indictment. The
|
|
@@ -53,7 +56,9 @@ const isRecord = (value) => typeof value === "object" && value !== null && !Arra
|
|
|
53
56
|
const requiemResponseEvidence = (response) => {
|
|
54
57
|
if (!isRecord(response))
|
|
55
58
|
return response;
|
|
56
|
-
const { rawBody: _rawBody, ...withoutRawBody } = response;
|
|
59
|
+
const { rawBody: _rawBody, accounting: _accounting, ...withoutRawBody } = response;
|
|
60
|
+
void _rawBody;
|
|
61
|
+
void _accounting;
|
|
57
62
|
if (!isRecord(withoutRawBody.assistantRaw))
|
|
58
63
|
return withoutRawBody;
|
|
59
64
|
const { rawBody: _nestedRawBody, ...assistantRaw } = withoutRawBody.assistantRaw;
|
|
@@ -110,20 +115,27 @@ export default class Digest {
|
|
|
110
115
|
return fallback;
|
|
111
116
|
}
|
|
112
117
|
}
|
|
113
|
-
static #
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return
|
|
118
|
-
}
|
|
119
|
-
static #providerCost(raw, subject) {
|
|
120
|
-
return validateProviderCost(Digest.#parseJson(raw));
|
|
118
|
+
static #requestAccounting(row) {
|
|
119
|
+
if (row.state !== "settled" || row.outcome === null || row.cost_kind === null) {
|
|
120
|
+
throw new TypeError(`digest: provider request ${row.id} is not settled`);
|
|
121
|
+
}
|
|
122
|
+
return providerRequestFromStorageRow(row);
|
|
121
123
|
}
|
|
122
|
-
static #
|
|
123
|
-
|
|
124
|
-
return values.some((value) => value === null)
|
|
124
|
+
static #accounting(rows) {
|
|
125
|
+
return rows.some((row) => row.state !== "settled")
|
|
125
126
|
? null
|
|
126
|
-
:
|
|
127
|
+
: aggregateProviderAccounting(rows.map((row) => Digest.#requestAccounting(row)));
|
|
128
|
+
}
|
|
129
|
+
static #usageSummary(accounting) {
|
|
130
|
+
if (accounting === null)
|
|
131
|
+
return "accounting=incomplete";
|
|
132
|
+
const usage = accounting.usage;
|
|
133
|
+
return [
|
|
134
|
+
`input=${usage?.inputTokens ?? "unknown"}`,
|
|
135
|
+
`output=${usage?.outputTokens ?? "unknown"}`,
|
|
136
|
+
`reasoning=${usage?.outputTokenDetails?.reasoningTokens ?? "unknown"}`,
|
|
137
|
+
`cache-read=${usage?.inputTokenDetails?.cacheReadTokens ?? "unknown"}`,
|
|
138
|
+
].join(" ");
|
|
127
139
|
}
|
|
128
140
|
static #operationResult(raw, subject) {
|
|
129
141
|
try {
|
|
@@ -173,8 +185,13 @@ export default class Digest {
|
|
|
173
185
|
static #renderGroupedOpLine(row) {
|
|
174
186
|
const attrs = Digest.#parseJson(row.attrs, {});
|
|
175
187
|
const materialized = row.origin === "plurnk" && row.op === "EDIT" && attrs.kind === "entry_materialized";
|
|
176
|
-
const
|
|
177
|
-
|
|
188
|
+
const actionlessKind = row.op === null
|
|
189
|
+
? LogBody.actionlessKind({ op: row.op, attrs })
|
|
190
|
+
: null;
|
|
191
|
+
const label = actionlessKind === "model_emission"
|
|
192
|
+
? "model emission"
|
|
193
|
+
: actionlessKind ?? row.op ?? "actionless row";
|
|
194
|
+
return Digest.#renderOpLine(row, materialized ? "materialized entry" : label);
|
|
178
195
|
}
|
|
179
196
|
// Human triage is not a row dump. Preserve every row in digest.json, but
|
|
180
197
|
// collapse identical rendered outcomes in the Markdown waterfall. Using the
|
|
@@ -223,11 +240,11 @@ export default class Digest {
|
|
|
223
240
|
const assistant = packet !== null && StoredPacket.isAdmitted(packet) ? packet.assistant : null;
|
|
224
241
|
const content = assistant?.content ?? "";
|
|
225
242
|
const reasoning = assistant?.reasoning ?? null;
|
|
226
|
-
const
|
|
227
|
-
Digest.#
|
|
228
|
-
const cost =
|
|
243
|
+
const accounting = Digest.#accounting(m.requestsByTurn.get(turn.id) ?? []);
|
|
244
|
+
const tokens = Digest.#usageSummary(accounting);
|
|
245
|
+
const cost = accounting === null || accounting.costUsd === null
|
|
229
246
|
? " cost=unavailable"
|
|
230
|
-
: ` cost=$${
|
|
247
|
+
: ` cost=$${accounting.costUsd}`;
|
|
231
248
|
const finishReason = turn.finish_reason ?? "—";
|
|
232
249
|
// Render only observed constraint metadata; absence makes no claim
|
|
233
250
|
// about endpoint-owned settings. {§rail-truth-engine-verdict}
|
|
@@ -270,13 +287,14 @@ export default class Digest {
|
|
|
270
287
|
// every worker has exactly one rollup row — digest_worker_rollups is FROM workers
|
|
271
288
|
const roll = m.workerRollups.get(worker.id);
|
|
272
289
|
const opMix = (m.opMixByWorker.get(worker.id) ?? []).map((o) => `${o.op}=${o.n}`).join(" ");
|
|
273
|
-
const
|
|
290
|
+
const accounting = Digest.#accounting(m.requestsByWorker.get(worker.id) ?? []);
|
|
291
|
+
const costStr = accounting === null || accounting.costUsd === null ? "unknown" : `$${accounting.costUsd}`;
|
|
274
292
|
return [
|
|
275
293
|
`Loops: ${roll.loops}`,
|
|
276
294
|
`Turns: ${roll.turns}`,
|
|
277
295
|
`Last turn: ${roll.last_status !== null ? `status=${roll.last_status}` : "(none)"}`,
|
|
278
|
-
`Tokens:
|
|
279
|
-
`Cost: ${costStr}
|
|
296
|
+
`Tokens: ${Digest.#usageSummary(accounting)}`,
|
|
297
|
+
`Cost: ${costStr}`,
|
|
280
298
|
`Op mix: ${opMix.length > 0 ? opMix : "(no ops)"}`,
|
|
281
299
|
].join("\n");
|
|
282
300
|
}
|
|
@@ -286,9 +304,11 @@ export default class Digest {
|
|
|
286
304
|
lines.push("");
|
|
287
305
|
lines.push(`DB: ${m.dbPath}`);
|
|
288
306
|
const rejectedAttempts = m.turnAttempts.filter((attempt) => attempt.accepted === 0).length;
|
|
289
|
-
const
|
|
290
|
-
const
|
|
291
|
-
|
|
307
|
+
const erroredCalls = m.modelCalls.filter((call) => call.state === "error").length;
|
|
308
|
+
const pendingCalls = m.modelCalls.filter((call) => call.state === "pending").length;
|
|
309
|
+
const bareCalls = m.modelCalls.filter((call) => call.kind === "bare").length;
|
|
310
|
+
const pendingRequests = m.providerRequests.filter((request) => request.state === "pending").length;
|
|
311
|
+
lines.push(`Workspaces: ${m.workspaces.length} Workers: ${m.workers.length} Loops: ${m.loops.length} Turns: ${m.turns.length} Model calls: ${m.modelCalls.length} (${bareCalls} BARE, ${erroredCalls} errored, ${pendingCalls} open) Emission attempts: ${m.turnAttempts.length} (${rejectedAttempts} rejected) Provider requests: ${m.providerRequests.length} (${pendingRequests} open) Log entries: ${m.logEntries.length}`);
|
|
292
312
|
lines.push(`Semantic: body=${m.embeddings.body_entries} attached=${m.embeddings.derivation_complete} (vector=${m.embeddings.vector_complete} lexical=${m.embeddings.lexical} excluded=${m.embeddings.excluded} nonsemantic=${m.embeddings.nonsemantic} failed=${m.embeddings.failed}) unattached=${m.embeddings.unfinished} artifacts=${m.embeddings.derivation_artifacts_complete} complete/${m.embeddings.derivation_artifacts_building} building chunks=${m.embeddings.chunk_rows} models=${m.embeddings.models} token-derivations=${m.embeddings.token_derivations}`);
|
|
293
313
|
if (m.embeddings.dispositions.length > 0) {
|
|
294
314
|
lines.push("Semantic dispositions:");
|
|
@@ -472,59 +492,86 @@ export default class Digest {
|
|
|
472
492
|
return JSON.stringify({
|
|
473
493
|
dbPath: m.dbPath,
|
|
474
494
|
semantic: m.embeddings,
|
|
475
|
-
workspaces: m.workspaces.map((s) => ({
|
|
476
|
-
|
|
495
|
+
workspaces: m.workspaces.map((s) => ({
|
|
496
|
+
id: s.id,
|
|
497
|
+
name: s.name,
|
|
498
|
+
accounting: Digest.#accounting(m.requestsByWorkspace.get(s.id) ?? []),
|
|
499
|
+
})),
|
|
500
|
+
workers: m.workers.map((r) => ({
|
|
501
|
+
id: r.id,
|
|
502
|
+
workspace_id: r.workspace_id,
|
|
503
|
+
name: r.name,
|
|
504
|
+
accounting: Digest.#accounting(m.requestsByWorker.get(r.id) ?? []),
|
|
505
|
+
})),
|
|
477
506
|
loops: m.loops.map((l) => ({
|
|
478
507
|
id: l.id, worker_id: l.worker_id, sequence: l.sequence, status: l.status,
|
|
479
508
|
prompt: l.prompt, flags: Digest.#parseJson(l.flags, {}),
|
|
480
509
|
terminated_by: l.terminated_by,
|
|
481
510
|
result: Digest.#terminalResult(l),
|
|
511
|
+
accounting: Digest.#accounting(m.requestsByLoop.get(l.id) ?? []),
|
|
512
|
+
})),
|
|
513
|
+
turns: m.turns.map((t) => ({
|
|
514
|
+
id: t.id, loop_id: t.loop_id, sequence: t.sequence, status: t.status,
|
|
515
|
+
accounting: Digest.#accounting(m.requestsByTurn.get(t.id) ?? []),
|
|
516
|
+
finish_reason: t.finish_reason, model: t.model,
|
|
517
|
+
attributions: t.packet?.attributions ?? [],
|
|
518
|
+
// Preserve the opaque provider and engine metadata for aggregate
|
|
519
|
+
// tooling. {§meta-passthrough}, {§rail-truth-engine-verdict}
|
|
520
|
+
meta: Digest.#parseJson(t.meta ?? "null", null),
|
|
521
|
+
})),
|
|
522
|
+
model_calls: m.modelCalls.map((call) => ({
|
|
523
|
+
id: call.id,
|
|
524
|
+
turn_id: call.turn_id,
|
|
525
|
+
sequence: call.sequence,
|
|
526
|
+
kind: call.kind,
|
|
527
|
+
state: call.state,
|
|
528
|
+
response: Digest.#parseJson(call.response),
|
|
529
|
+
failure: Digest.#parseJson(call.failure),
|
|
530
|
+
attributions: Digest.#parseJson(call.attributions, []),
|
|
531
|
+
accounting: Digest.#accounting(m.requestsByModelCall.get(call.id) ?? []),
|
|
532
|
+
finish_reason: call.finish_reason,
|
|
533
|
+
model: call.model,
|
|
534
|
+
timestamp: call.timestamp,
|
|
535
|
+
completed_at: call.completed_at,
|
|
536
|
+
turn_attempt_id: call.turn_attempt_id,
|
|
537
|
+
accepted: call.accepted === null ? null : call.accepted === 1,
|
|
538
|
+
parse_errors: Digest.#parseJson(call.parse_errors, []),
|
|
539
|
+
log_entry_id: call.log_entry_id,
|
|
540
|
+
})),
|
|
541
|
+
turn_attempts: m.turnAttempts.map((attempt) => ({
|
|
542
|
+
id: attempt.id,
|
|
543
|
+
turn_id: attempt.turn_id,
|
|
544
|
+
sequence: attempt.sequence,
|
|
545
|
+
state: attempt.state,
|
|
546
|
+
accepted: attempt.accepted === null ? null : attempt.accepted === 1,
|
|
547
|
+
response: Digest.#parseJson(attempt.response),
|
|
548
|
+
failure: Digest.#parseJson(attempt.failure),
|
|
549
|
+
parse_errors: Digest.#parseJson(attempt.parse_errors, []),
|
|
550
|
+
attributions: Digest.#parseJson(attempt.attributions, []),
|
|
551
|
+
accounting: Digest.#accounting(m.requestsByAttempt.get(attempt.id) ?? []),
|
|
552
|
+
finish_reason: attempt.finish_reason,
|
|
553
|
+
model: attempt.model,
|
|
554
|
+
timestamp: attempt.timestamp,
|
|
555
|
+
completed_at: attempt.completed_at,
|
|
556
|
+
})),
|
|
557
|
+
provider_requests: m.providerRequests.map((request) => ({
|
|
558
|
+
id: request.id,
|
|
559
|
+
model_call_id: request.model_call_id,
|
|
560
|
+
turn_attempt_id: request.turn_attempt_id,
|
|
561
|
+
kind: request.kind,
|
|
562
|
+
sequence: request.sequence,
|
|
563
|
+
state: request.state,
|
|
564
|
+
accounting: request.state === "settled"
|
|
565
|
+
? Digest.#requestAccounting(request)
|
|
566
|
+
: null,
|
|
567
|
+
started_at: request.started_at,
|
|
568
|
+
completed_at: request.completed_at,
|
|
482
569
|
})),
|
|
483
|
-
turns: m.turns.map((t) => {
|
|
484
|
-
const costs = Digest.#providerCosts(t.usage_cost, `turn ${t.id}`);
|
|
485
|
-
return {
|
|
486
|
-
id: t.id, loop_id: t.loop_id, sequence: t.sequence, status: t.status,
|
|
487
|
-
usage_prompt: t.usage_prompt, usage_completion: t.usage_completion,
|
|
488
|
-
usage_reasoning: t.usage_reasoning, usage_cached: t.usage_cached,
|
|
489
|
-
usage_cost: costs,
|
|
490
|
-
usage_cost_usd: t.usage_cost_usd,
|
|
491
|
-
finish_reason: t.finish_reason, model: t.model,
|
|
492
|
-
attributions: t.packet?.attributions ?? [],
|
|
493
|
-
// Preserve the opaque provider and engine metadata for aggregate
|
|
494
|
-
// tooling. {§meta-passthrough}, {§rail-truth-engine-verdict}
|
|
495
|
-
meta: Digest.#parseJson(t.meta ?? "null", null),
|
|
496
|
-
};
|
|
497
|
-
}),
|
|
498
|
-
turn_attempts: m.turnAttempts.map((attempt) => {
|
|
499
|
-
const cost = attempt.usage_cost === null
|
|
500
|
-
? null
|
|
501
|
-
: Digest.#providerCost(attempt.usage_cost, `attempt ${attempt.id}`);
|
|
502
|
-
return {
|
|
503
|
-
id: attempt.id,
|
|
504
|
-
turn_id: attempt.turn_id,
|
|
505
|
-
sequence: attempt.sequence,
|
|
506
|
-
state: attempt.state,
|
|
507
|
-
accepted: attempt.accepted === null ? null : attempt.accepted === 1,
|
|
508
|
-
response: Digest.#parseJson(attempt.response),
|
|
509
|
-
failure: Digest.#parseJson(attempt.failure),
|
|
510
|
-
parse_errors: Digest.#parseJson(attempt.parse_errors, []),
|
|
511
|
-
attributions: Digest.#parseJson(attempt.attributions, []),
|
|
512
|
-
usage_prompt: attempt.usage_prompt,
|
|
513
|
-
usage_completion: attempt.usage_completion,
|
|
514
|
-
usage_reasoning: attempt.usage_reasoning,
|
|
515
|
-
usage_cached: attempt.usage_cached,
|
|
516
|
-
usage_cost: cost,
|
|
517
|
-
usage_cost_usd: attempt.usage_cost_usd,
|
|
518
|
-
finish_reason: attempt.finish_reason,
|
|
519
|
-
model: attempt.model,
|
|
520
|
-
timestamp: attempt.timestamp,
|
|
521
|
-
completed_at: attempt.completed_at,
|
|
522
|
-
};
|
|
523
|
-
}),
|
|
524
570
|
log_entries: m.logEntries.map((le) => ({
|
|
525
571
|
id: le.id, worker_id: le.worker_id, loop_id: le.loop_id,
|
|
526
572
|
turn_id: le.turn_id, sequence: le.sequence, origin: le.origin,
|
|
527
|
-
source: le.source,
|
|
573
|
+
source: le.source, model_call_id: le.model_call_id,
|
|
574
|
+
attrs: Digest.#parseJson(le.attrs, {}),
|
|
528
575
|
op: le.op, target: Digest.#renderTarget(le),
|
|
529
576
|
status_rx: le.status_rx, state: le.state, outcome: le.outcome,
|
|
530
577
|
...(Digest.#renderStream(le) === null
|
|
@@ -532,6 +579,11 @@ export default class Digest {
|
|
|
532
579
|
: { stream: Digest.#renderStream(le) }),
|
|
533
580
|
...(le.status_rx >= 400 ? { problem: Digest.#rowProblem(le) } : {}),
|
|
534
581
|
})),
|
|
582
|
+
log_curation_effects: m.curationEffects.map(({ tags_added, tags_removed, ...effect }) => ({
|
|
583
|
+
...effect,
|
|
584
|
+
tags_added: Digest.#parseJson(tags_added, []),
|
|
585
|
+
tags_removed: Digest.#parseJson(tags_removed, []),
|
|
586
|
+
})),
|
|
535
587
|
}, null, 2);
|
|
536
588
|
}
|
|
537
589
|
// Default DB path — mirrors the service (`Service.#expandHome(PLURNK_SERVICE_DB_PATH)`; the
|
|
@@ -648,33 +700,20 @@ export default class Digest {
|
|
|
648
700
|
content: `# Verbatim worker evidence\n\n${JSON.stringify(evidence, null, 2)}\n\n# Audit request\n\n${REQUIEM_PROMPT}`,
|
|
649
701
|
},
|
|
650
702
|
];
|
|
651
|
-
const id =
|
|
703
|
+
const id = worker.provider_identity;
|
|
652
704
|
const report = {
|
|
653
705
|
workerId: worker.id,
|
|
654
706
|
workerName: worker.name,
|
|
655
707
|
messages,
|
|
656
708
|
responses: [],
|
|
657
709
|
calls: [],
|
|
658
|
-
|
|
659
|
-
costs: [],
|
|
660
|
-
costUsd: null,
|
|
710
|
+
accounting: aggregateProviderAccounting([]),
|
|
661
711
|
testimony: null,
|
|
662
712
|
};
|
|
663
713
|
reports.push(report);
|
|
664
714
|
const updateObservedTotals = () => {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
return total;
|
|
668
|
-
return {
|
|
669
|
-
prompt: total.prompt + call.usage.prompt,
|
|
670
|
-
completion: total.completion + call.usage.completion,
|
|
671
|
-
reasoning: total.reasoning + call.usage.reasoning,
|
|
672
|
-
cached: total.cached + call.usage.cached,
|
|
673
|
-
total: total.total + call.usage.total,
|
|
674
|
-
};
|
|
675
|
-
}, { prompt: 0, completion: 0, reasoning: 0, cached: 0, total: 0 });
|
|
676
|
-
report.costs = report.calls.map((call) => call.cost);
|
|
677
|
-
report.costUsd = Digest.#costProjection(report.costs);
|
|
715
|
+
const requests = report.calls.flatMap((call) => call.requests.flatMap((request) => request.accounting === null ? [] : [request.accounting]));
|
|
716
|
+
report.accounting = aggregateProviderAccounting(requests);
|
|
678
717
|
persistReports();
|
|
679
718
|
};
|
|
680
719
|
const issue = async (outputTokens) => {
|
|
@@ -682,25 +721,62 @@ export default class Digest {
|
|
|
682
721
|
openedAt: new Date().toISOString(),
|
|
683
722
|
completedAt: null,
|
|
684
723
|
state: "open",
|
|
685
|
-
|
|
686
|
-
cost: { kind: "unknown", reason: "requiem provider call is open" },
|
|
724
|
+
requests: [],
|
|
687
725
|
failure: null,
|
|
688
726
|
};
|
|
689
727
|
report.calls.push(call);
|
|
690
728
|
updateObservedTotals();
|
|
729
|
+
const observeRequest = async (identity) => {
|
|
730
|
+
if (identity.provider.length === 0 || identity.model.length === 0) {
|
|
731
|
+
throw new TypeError("requiem provider request identity is incomplete");
|
|
732
|
+
}
|
|
733
|
+
const request = {
|
|
734
|
+
provider: identity.provider,
|
|
735
|
+
model: identity.model,
|
|
736
|
+
openedAt: new Date().toISOString(),
|
|
737
|
+
completedAt: null,
|
|
738
|
+
state: "open",
|
|
739
|
+
accounting: null,
|
|
740
|
+
};
|
|
741
|
+
call.requests.push(request);
|
|
742
|
+
updateObservedTotals();
|
|
743
|
+
return async (value) => {
|
|
744
|
+
if (request.state !== "open")
|
|
745
|
+
throw new Error("requiem provider request settled more than once");
|
|
746
|
+
const accounting = validateProviderRequestAccounting(value);
|
|
747
|
+
if (accounting.provider !== identity.provider || accounting.model !== identity.model) {
|
|
748
|
+
throw new TypeError("requiem provider request settlement changed its identity");
|
|
749
|
+
}
|
|
750
|
+
request.state = "settled";
|
|
751
|
+
request.completedAt = new Date().toISOString();
|
|
752
|
+
request.accounting = accounting;
|
|
753
|
+
updateObservedTotals();
|
|
754
|
+
};
|
|
755
|
+
};
|
|
756
|
+
const assertObserved = (expected) => {
|
|
757
|
+
const observedRequests = call.requests.map((request) => {
|
|
758
|
+
if (request.accounting === null) {
|
|
759
|
+
throw new TypeError("requiem provider returned while a physical request remained open");
|
|
760
|
+
}
|
|
761
|
+
return request.accounting;
|
|
762
|
+
});
|
|
763
|
+
if (!isDeepStrictEqual(expected.map(validateProviderRequestAccounting), observedRequests)) {
|
|
764
|
+
throw new TypeError("requiem provider accounting differs from its observed physical requests");
|
|
765
|
+
}
|
|
766
|
+
};
|
|
691
767
|
try {
|
|
692
768
|
const response = await provider.generate({
|
|
693
769
|
messages,
|
|
694
770
|
workerId: id,
|
|
695
771
|
primaryWorkerId: id,
|
|
696
|
-
|
|
772
|
+
maxOutputTokens: outputTokens,
|
|
773
|
+
observeRequest,
|
|
697
774
|
...(opts.signal !== undefined ? { signal: opts.signal } : {}),
|
|
698
775
|
});
|
|
776
|
+
assertObserved(response.accounting);
|
|
699
777
|
call.state = "response";
|
|
700
778
|
call.completedAt = new Date().toISOString();
|
|
701
|
-
|
|
702
|
-
call.cost = providerCostFor(provider, response.assistant.usage, response.charge);
|
|
703
|
-
report.responses.push(response);
|
|
779
|
+
report.responses.push(requiemResponseEvidence(response));
|
|
704
780
|
updateObservedTotals();
|
|
705
781
|
return response;
|
|
706
782
|
}
|
|
@@ -712,16 +788,11 @@ export default class Digest {
|
|
|
712
788
|
: cause instanceof Error
|
|
713
789
|
? { name: cause.name, message: cause.message }
|
|
714
790
|
: String(cause);
|
|
715
|
-
if (cause instanceof ProviderError
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
else {
|
|
721
|
-
call.cost = {
|
|
722
|
-
kind: "unknown",
|
|
723
|
-
reason: "requiem provider call failed without response-bearing charge evidence",
|
|
724
|
-
};
|
|
791
|
+
if (cause instanceof ProviderError) {
|
|
792
|
+
assertObserved(cause.accounting);
|
|
793
|
+
if (cause.attempt !== undefined) {
|
|
794
|
+
report.responses.push(requiemResponseEvidence(cause.attempt));
|
|
795
|
+
}
|
|
725
796
|
}
|
|
726
797
|
updateObservedTotals();
|
|
727
798
|
throw cause;
|
|
@@ -743,13 +814,14 @@ export default class Digest {
|
|
|
743
814
|
if (resp === undefined)
|
|
744
815
|
throw new Error(`requiem worker ${worker.id} completed without a provider response`);
|
|
745
816
|
const testimony = resp.assistant.content.trim()
|
|
746
|
-
|| `(no testimony - ${
|
|
817
|
+
|| `(no testimony - ${report.accounting.usage?.outputTokens ?? "unknown"} output tokens after ${report.calls.length} provider call(s))`;
|
|
747
818
|
report.testimony = testimony;
|
|
748
819
|
persistReports();
|
|
749
|
-
const costSummary = report.costUsd === null
|
|
820
|
+
const costSummary = report.accounting.costUsd === null
|
|
750
821
|
? "cost USD unavailable"
|
|
751
|
-
: `cost USD ${report.costUsd}`;
|
|
752
|
-
|
|
822
|
+
: `cost USD ${report.accounting.costUsd}`;
|
|
823
|
+
const physicalRequests = report.calls.reduce((total, call) => total + call.requests.length, 0);
|
|
824
|
+
out.push(`## Worker #${worker.id} - ${worker.name}`, "", `_(${resp.assistant.model}, ${resp.assistant.finishReason ?? "?"}, provider calls ${report.calls.length}, physical requests ${physicalRequests}, ${Digest.#usageSummary(report.accounting)}, ${costSummary})_`, "", testimony, "");
|
|
753
825
|
}
|
|
754
826
|
const path = join(digestDir, "requiem.md");
|
|
755
827
|
writeFileSync(path, out.join("\n"));
|
|
@@ -782,8 +854,11 @@ export default class Digest {
|
|
|
782
854
|
...turn,
|
|
783
855
|
packet: StoredPacket.parse(turn.packet, `digest turn ${turn.id}`),
|
|
784
856
|
}));
|
|
857
|
+
let modelCalls = db.digest_model_calls.all();
|
|
785
858
|
let turnAttempts = db.digest_turn_attempts.all();
|
|
859
|
+
let providerRequests = db.digest_provider_requests.all();
|
|
786
860
|
let logEntries = db.digest_log_entries.all();
|
|
861
|
+
let curationEffects = [];
|
|
787
862
|
let workerRollupRows = db.digest_worker_rollups.all();
|
|
788
863
|
let opMixRows = db.digest_worker_op_mix.all();
|
|
789
864
|
// The semantic-state analytic (owner ask), feature-detected per table: a HISTORICAL
|
|
@@ -795,6 +870,14 @@ export default class Digest {
|
|
|
795
870
|
const hasColumn = (table, column) => probe.prepare(`SELECT 1 FROM pragma_table_info(?) WHERE name=?`).get(table, column) !== undefined;
|
|
796
871
|
const one = (q) => Number(probe.prepare(q).get().n);
|
|
797
872
|
const semanticStateAvailable = has("entries") && has("entry_channels") && hasColumn("entries", "deep_hash");
|
|
873
|
+
if (has("log_curation_effects")) {
|
|
874
|
+
curationEffects = probe.prepare(`
|
|
875
|
+
SELECT operation_log_entry_id, target_log_entry_id, expanded_before,
|
|
876
|
+
tags_added, tags_removed
|
|
877
|
+
FROM log_curation_effects
|
|
878
|
+
ORDER BY operation_log_entry_id, target_log_entry_id
|
|
879
|
+
`).all();
|
|
880
|
+
}
|
|
798
881
|
const body = semanticStateAvailable
|
|
799
882
|
? "FROM entries e JOIN entry_channels ec ON ec.entry_id=e.id AND ec.name='body'"
|
|
800
883
|
: "";
|
|
@@ -837,8 +920,13 @@ export default class Digest {
|
|
|
837
920
|
const keptLoopIds = new Set(loops.map((l) => l.id));
|
|
838
921
|
turns = turns.filter((t) => keptLoopIds.has(t.loop_id));
|
|
839
922
|
const keptTurnIds = new Set(turns.map((t) => t.id));
|
|
923
|
+
modelCalls = modelCalls.filter((call) => keptTurnIds.has(call.turn_id));
|
|
840
924
|
turnAttempts = turnAttempts.filter((attempt) => keptTurnIds.has(attempt.turn_id));
|
|
925
|
+
providerRequests = providerRequests.filter((request) => keptTurnIds.has(request.turn_id));
|
|
841
926
|
logEntries = logEntries.filter((le) => keptTurnIds.has(le.turn_id));
|
|
927
|
+
const keptLogEntryIds = new Set(logEntries.map((entry) => entry.id));
|
|
928
|
+
curationEffects = curationEffects.filter((effect) => keptLogEntryIds.has(effect.operation_log_entry_id)
|
|
929
|
+
&& keptLogEntryIds.has(effect.target_log_entry_id));
|
|
842
930
|
workerRollupRows = workerRollupRows.filter((r) => keptWorkerIds.has(r.worker_id));
|
|
843
931
|
opMixRows = opMixRows.filter((o) => keptWorkerIds.has(o.worker_id));
|
|
844
932
|
}
|
|
@@ -870,6 +958,27 @@ export default class Digest {
|
|
|
870
958
|
arr.push(attempt);
|
|
871
959
|
attemptsByTurn.set(attempt.turn_id, arr);
|
|
872
960
|
}
|
|
961
|
+
const requestsByModelCall = new Map();
|
|
962
|
+
const requestsByAttempt = new Map();
|
|
963
|
+
const requestsByTurn = new Map();
|
|
964
|
+
const requestsByLoop = new Map();
|
|
965
|
+
const requestsByWorker = new Map();
|
|
966
|
+
const requestsByWorkspace = new Map();
|
|
967
|
+
const appendRequest = (map, id, request) => {
|
|
968
|
+
const rows = map.get(id) ?? [];
|
|
969
|
+
rows.push(request);
|
|
970
|
+
map.set(id, rows);
|
|
971
|
+
};
|
|
972
|
+
for (const request of providerRequests) {
|
|
973
|
+
appendRequest(requestsByModelCall, request.model_call_id, request);
|
|
974
|
+
if (request.turn_attempt_id !== null) {
|
|
975
|
+
appendRequest(requestsByAttempt, request.turn_attempt_id, request);
|
|
976
|
+
}
|
|
977
|
+
appendRequest(requestsByTurn, request.turn_id, request);
|
|
978
|
+
appendRequest(requestsByLoop, request.loop_id, request);
|
|
979
|
+
appendRequest(requestsByWorker, request.worker_id, request);
|
|
980
|
+
appendRequest(requestsByWorkspace, request.workspace_id, request);
|
|
981
|
+
}
|
|
873
982
|
const logEntriesByTurn = new Map();
|
|
874
983
|
for (const le of logEntries) {
|
|
875
984
|
const arr = logEntriesByTurn.get(le.turn_id) ?? [];
|
|
@@ -886,8 +995,10 @@ export default class Digest {
|
|
|
886
995
|
opMixByWorker.set(o.worker_id, arr);
|
|
887
996
|
}
|
|
888
997
|
const m = {
|
|
889
|
-
dbPath, digestDir, workspaces, workers, loops, turns, turnAttempts, logEntries,
|
|
890
|
-
workersByWorkspace, loopsByWorker, turnsByLoop, attemptsByTurn,
|
|
998
|
+
dbPath, digestDir, workspaces, workers, loops, turns, modelCalls, turnAttempts, providerRequests, logEntries, curationEffects,
|
|
999
|
+
workersByWorkspace, loopsByWorker, turnsByLoop, attemptsByTurn,
|
|
1000
|
+
requestsByModelCall, requestsByAttempt, requestsByTurn, requestsByLoop, requestsByWorker, requestsByWorkspace,
|
|
1001
|
+
logEntriesByTurn, loopsById, workersById,
|
|
891
1002
|
workerRollups, opMixByWorker, embeddings,
|
|
892
1003
|
};
|
|
893
1004
|
writeFileSync(join(digestDir, "digest.md"), Digest.#renderWaterfall(m));
|
|
@@ -897,7 +1008,7 @@ export default class Digest {
|
|
|
897
1008
|
const packetIds = [...new Set(packetFiles.map((f) => f.slice(0, f.indexOf("."))))];
|
|
898
1009
|
console.log(`digest: wrote ${digestDir}/{digest.md,digest.json,reasoning.md} + ${packetFiles.length} packet section files (${packetIds.join(", ") || "none"})`);
|
|
899
1010
|
console.log(` source: ${dbPath}`);
|
|
900
|
-
console.log(` workspaces=${workspaces.length} workers=${workers.length} loops=${loops.length} turns=${turns.length} turn_attempts=${turnAttempts.length} log_entries=${logEntries.length}`);
|
|
1011
|
+
console.log(` workspaces=${workspaces.length} workers=${workers.length} loops=${loops.length} turns=${turns.length} model_calls=${modelCalls.length} turn_attempts=${turnAttempts.length} provider_requests=${providerRequests.length} log_entries=${logEntries.length} log_curation_effects=${curationEffects.length}`);
|
|
901
1012
|
}
|
|
902
1013
|
}
|
|
903
1014
|
//# sourceMappingURL=Digest.js.map
|