@inhuman.tools/turn 0.0.0-stage → 0.2.0
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/LICENSE.md +7 -0
- package/dist/agent-calls/acceptance.d.ts +12 -0
- package/dist/agent-calls/acceptance.d.ts.map +1 -0
- package/dist/agent-calls/acceptance.js +64 -0
- package/dist/agent-calls/acceptance.js.map +1 -0
- package/dist/agent-calls/callbacks.d.ts +14 -0
- package/dist/agent-calls/callbacks.d.ts.map +1 -0
- package/dist/agent-calls/callbacks.js +59 -0
- package/dist/agent-calls/callbacks.js.map +1 -0
- package/dist/agent-calls/delivery.d.ts +7 -0
- package/dist/agent-calls/delivery.d.ts.map +1 -0
- package/dist/agent-calls/delivery.js +16 -0
- package/dist/agent-calls/delivery.js.map +1 -0
- package/dist/agent-calls/index.d.ts +7 -0
- package/dist/agent-calls/index.d.ts.map +1 -0
- package/dist/agent-calls/index.js +6 -0
- package/dist/agent-calls/index.js.map +1 -0
- package/dist/agent-calls/operator.d.ts +21 -0
- package/dist/agent-calls/operator.d.ts.map +1 -0
- package/dist/agent-calls/operator.js +78 -0
- package/dist/agent-calls/operator.js.map +1 -0
- package/dist/agent-calls/runtime.d.ts +99 -0
- package/dist/agent-calls/runtime.d.ts.map +1 -0
- package/dist/agent-calls/runtime.js +245 -0
- package/dist/agent-calls/runtime.js.map +1 -0
- package/dist/agent-calls/types.d.ts +31 -0
- package/dist/agent-calls/types.d.ts.map +1 -0
- package/dist/agent-calls/types.js +2 -0
- package/dist/agent-calls/types.js.map +1 -0
- package/dist/context/compact-floors.d.ts +43 -0
- package/dist/context/compact-floors.d.ts.map +1 -0
- package/dist/context/compact-floors.js +52 -0
- package/dist/context/compact-floors.js.map +1 -0
- package/dist/context/compact.d.ts +42 -0
- package/dist/context/compact.d.ts.map +1 -0
- package/dist/context/compact.js +155 -0
- package/dist/context/compact.js.map +1 -0
- package/dist/context/delivery.d.ts +13 -0
- package/dist/context/delivery.d.ts.map +1 -0
- package/dist/context/delivery.js +6 -0
- package/dist/context/delivery.js.map +1 -0
- package/dist/context/history.d.ts +66 -0
- package/dist/context/history.d.ts.map +1 -0
- package/dist/context/history.js +573 -0
- package/dist/context/history.js.map +1 -0
- package/dist/context/index.d.ts +10 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +10 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/observations.d.ts +7 -0
- package/dist/context/observations.d.ts.map +1 -0
- package/dist/context/observations.js +11 -0
- package/dist/context/observations.js.map +1 -0
- package/dist/context/retention/defaults.d.ts +10 -0
- package/dist/context/retention/defaults.d.ts.map +1 -0
- package/dist/context/retention/defaults.js +47 -0
- package/dist/context/retention/defaults.js.map +1 -0
- package/dist/context/retention/index.d.ts +14 -0
- package/dist/context/retention/index.d.ts.map +1 -0
- package/dist/context/retention/index.js +21 -0
- package/dist/context/retention/index.js.map +1 -0
- package/dist/context/retention/narrow.d.ts +22 -0
- package/dist/context/retention/narrow.d.ts.map +1 -0
- package/dist/context/retention/narrow.js +140 -0
- package/dist/context/retention/narrow.js.map +1 -0
- package/dist/context/retention/render.d.ts +37 -0
- package/dist/context/retention/render.d.ts.map +1 -0
- package/dist/context/retention/render.js +149 -0
- package/dist/context/retention/render.js.map +1 -0
- package/dist/context/retention/resolve.d.ts +51 -0
- package/dist/context/retention/resolve.d.ts.map +1 -0
- package/dist/context/retention/resolve.js +254 -0
- package/dist/context/retention/resolve.js.map +1 -0
- package/dist/context/retention/schema.d.ts +345 -0
- package/dist/context/retention/schema.d.ts.map +1 -0
- package/dist/context/retention/schema.js +149 -0
- package/dist/context/retention/schema.js.map +1 -0
- package/dist/context/retention/stamp.d.ts +25 -0
- package/dist/context/retention/stamp.d.ts.map +1 -0
- package/dist/context/retention/stamp.js +103 -0
- package/dist/context/retention/stamp.js.map +1 -0
- package/dist/context/retention/step.d.ts +33 -0
- package/dist/context/retention/step.d.ts.map +1 -0
- package/dist/context/retention/step.js +74 -0
- package/dist/context/retention/step.js.map +1 -0
- package/dist/context/retention/view.d.ts +57 -0
- package/dist/context/retention/view.d.ts.map +1 -0
- package/dist/context/retention/view.js +121 -0
- package/dist/context/retention/view.js.map +1 -0
- package/dist/context/squeeze.d.ts +45 -0
- package/dist/context/squeeze.d.ts.map +1 -0
- package/dist/context/squeeze.js +182 -0
- package/dist/context/squeeze.js.map +1 -0
- package/dist/context/tools.d.ts +16 -0
- package/dist/context/tools.d.ts.map +1 -0
- package/dist/context/tools.js +73 -0
- package/dist/context/tools.js.map +1 -0
- package/dist/context/transcript.d.ts +151 -0
- package/dist/context/transcript.d.ts.map +1 -0
- package/dist/context/transcript.js +659 -0
- package/dist/context/transcript.js.map +1 -0
- package/dist/policy-processor/bypass.d.ts +95 -0
- package/dist/policy-processor/bypass.d.ts.map +1 -0
- package/dist/policy-processor/bypass.js +188 -0
- package/dist/policy-processor/bypass.js.map +1 -0
- package/dist/policy-processor/classifier.d.ts +47 -0
- package/dist/policy-processor/classifier.d.ts.map +1 -0
- package/dist/policy-processor/classifier.js +671 -0
- package/dist/policy-processor/classifier.js.map +1 -0
- package/dist/policy-processor/cluster.d.ts +7 -0
- package/dist/policy-processor/cluster.d.ts.map +1 -0
- package/dist/policy-processor/cluster.js +32 -0
- package/dist/policy-processor/cluster.js.map +1 -0
- package/dist/policy-processor/evidence.d.ts +26 -0
- package/dist/policy-processor/evidence.d.ts.map +1 -0
- package/dist/policy-processor/evidence.js +204 -0
- package/dist/policy-processor/evidence.js.map +1 -0
- package/dist/policy-processor/explain.d.ts +59 -0
- package/dist/policy-processor/explain.d.ts.map +1 -0
- package/dist/policy-processor/explain.js +224 -0
- package/dist/policy-processor/explain.js.map +1 -0
- package/dist/policy-processor/index.d.ts +6 -0
- package/dist/policy-processor/index.d.ts.map +1 -0
- package/dist/policy-processor/index.js +6 -0
- package/dist/policy-processor/index.js.map +1 -0
- package/dist/policy-processor/license.d.ts +23 -0
- package/dist/policy-processor/license.d.ts.map +1 -0
- package/dist/policy-processor/license.js +47 -0
- package/dist/policy-processor/license.js.map +1 -0
- package/dist/policy-processor/peel-cwd.d.ts +2 -0
- package/dist/policy-processor/peel-cwd.d.ts.map +1 -0
- package/dist/policy-processor/peel-cwd.js +2 -0
- package/dist/policy-processor/peel-cwd.js.map +1 -0
- package/dist/policy-processor/real-path.d.ts +7 -0
- package/dist/policy-processor/real-path.d.ts.map +1 -0
- package/dist/policy-processor/real-path.js +42 -0
- package/dist/policy-processor/real-path.js.map +1 -0
- package/dist/policy-processor/scope.d.ts +111 -0
- package/dist/policy-processor/scope.d.ts.map +1 -0
- package/dist/policy-processor/scope.js +629 -0
- package/dist/policy-processor/scope.js.map +1 -0
- package/dist/policy-processor/self-protect.d.ts +10 -0
- package/dist/policy-processor/self-protect.d.ts.map +1 -0
- package/dist/policy-processor/self-protect.js +48 -0
- package/dist/policy-processor/self-protect.js.map +1 -0
- package/dist/policy-processor/soft-deny.d.ts +75 -0
- package/dist/policy-processor/soft-deny.d.ts.map +1 -0
- package/dist/policy-processor/soft-deny.js +185 -0
- package/dist/policy-processor/soft-deny.js.map +1 -0
- package/dist/policy-processor/unattended-guard.d.ts +28 -0
- package/dist/policy-processor/unattended-guard.d.ts.map +1 -0
- package/dist/policy-processor/unattended-guard.js +145 -0
- package/dist/policy-processor/unattended-guard.js.map +1 -0
- package/dist/session/cancel.d.ts +14 -0
- package/dist/session/cancel.d.ts.map +1 -0
- package/dist/session/cancel.js +32 -0
- package/dist/session/cancel.js.map +1 -0
- package/dist/session/commands.d.ts +41 -0
- package/dist/session/commands.d.ts.map +1 -0
- package/dist/session/commands.js +241 -0
- package/dist/session/commands.js.map +1 -0
- package/dist/session/compact-actor.d.ts +23 -0
- package/dist/session/compact-actor.d.ts.map +1 -0
- package/dist/session/compact-actor.js +91 -0
- package/dist/session/compact-actor.js.map +1 -0
- package/dist/session/compact-env.d.ts +54 -0
- package/dist/session/compact-env.d.ts.map +1 -0
- package/dist/session/compact-env.js +345 -0
- package/dist/session/compact-env.js.map +1 -0
- package/dist/session/compact.d.ts +42 -0
- package/dist/session/compact.d.ts.map +1 -0
- package/dist/session/compact.js +68 -0
- package/dist/session/compact.js.map +1 -0
- package/dist/session/index.d.ts +9 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +8 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/park.d.ts +16 -0
- package/dist/session/park.d.ts.map +1 -0
- package/dist/session/park.js +73 -0
- package/dist/session/park.js.map +1 -0
- package/dist/session/side-channel-reminder.d.ts +41 -0
- package/dist/session/side-channel-reminder.d.ts.map +1 -0
- package/dist/session/side-channel-reminder.js +132 -0
- package/dist/session/side-channel-reminder.js.map +1 -0
- package/dist/session/types.d.ts +44 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +2 -0
- package/dist/session/types.js.map +1 -0
- package/dist/tool-catalog/catalog.d.ts +77 -0
- package/dist/tool-catalog/catalog.d.ts.map +1 -0
- package/dist/tool-catalog/catalog.js +380 -0
- package/dist/tool-catalog/catalog.js.map +1 -0
- package/dist/tool-catalog/index.d.ts +4 -0
- package/dist/tool-catalog/index.d.ts.map +1 -0
- package/dist/tool-catalog/index.js +3 -0
- package/dist/tool-catalog/index.js.map +1 -0
- package/dist/tool-catalog/recipes.d.ts +36 -0
- package/dist/tool-catalog/recipes.d.ts.map +1 -0
- package/dist/tool-catalog/recipes.js +121 -0
- package/dist/tool-catalog/recipes.js.map +1 -0
- package/dist/tool-catalog/types.d.ts +103 -0
- package/dist/tool-catalog/types.d.ts.map +1 -0
- package/dist/tool-catalog/types.js +5 -0
- package/dist/tool-catalog/types.js.map +1 -0
- package/dist/tool-runtime/approval/approved.d.ts +13 -0
- package/dist/tool-runtime/approval/approved.d.ts.map +1 -0
- package/dist/tool-runtime/approval/approved.js +20 -0
- package/dist/tool-runtime/approval/approved.js.map +1 -0
- package/dist/tool-runtime/approval/dist.d.ts +6 -0
- package/dist/tool-runtime/approval/dist.d.ts.map +1 -0
- package/dist/tool-runtime/approval/dist.js +28 -0
- package/dist/tool-runtime/approval/dist.js.map +1 -0
- package/dist/tool-runtime/approval/inbound.d.ts +7 -0
- package/dist/tool-runtime/approval/inbound.d.ts.map +1 -0
- package/dist/tool-runtime/approval/inbound.js +48 -0
- package/dist/tool-runtime/approval/inbound.js.map +1 -0
- package/dist/tool-runtime/approval/unattended.d.ts +8 -0
- package/dist/tool-runtime/approval/unattended.d.ts.map +1 -0
- package/dist/tool-runtime/approval/unattended.js +23 -0
- package/dist/tool-runtime/approval/unattended.js.map +1 -0
- package/dist/tool-runtime/blob-port.d.ts +46 -0
- package/dist/tool-runtime/blob-port.d.ts.map +1 -0
- package/dist/tool-runtime/blob-port.js +47 -0
- package/dist/tool-runtime/blob-port.js.map +1 -0
- package/dist/tool-runtime/extra-root.d.ts +3 -0
- package/dist/tool-runtime/extra-root.d.ts.map +1 -0
- package/dist/tool-runtime/extra-root.js +14 -0
- package/dist/tool-runtime/extra-root.js.map +1 -0
- package/dist/tool-runtime/handler.d.ts +29 -0
- package/dist/tool-runtime/handler.d.ts.map +1 -0
- package/dist/tool-runtime/handler.js +460 -0
- package/dist/tool-runtime/handler.js.map +1 -0
- package/dist/tool-runtime/index.d.ts +14 -0
- package/dist/tool-runtime/index.d.ts.map +1 -0
- package/dist/tool-runtime/index.js +14 -0
- package/dist/tool-runtime/index.js.map +1 -0
- package/dist/tool-runtime/peel.d.ts +19 -0
- package/dist/tool-runtime/peel.d.ts.map +1 -0
- package/dist/tool-runtime/peel.js +74 -0
- package/dist/tool-runtime/peel.js.map +1 -0
- package/dist/tool-runtime/plugin-context.d.ts +13 -0
- package/dist/tool-runtime/plugin-context.d.ts.map +1 -0
- package/dist/tool-runtime/plugin-context.js +55 -0
- package/dist/tool-runtime/plugin-context.js.map +1 -0
- package/dist/tool-runtime/recall.d.ts +18 -0
- package/dist/tool-runtime/recall.d.ts.map +1 -0
- package/dist/tool-runtime/recall.js +100 -0
- package/dist/tool-runtime/recall.js.map +1 -0
- package/dist/tool-runtime/run-system-tool.d.ts +13 -0
- package/dist/tool-runtime/run-system-tool.d.ts.map +1 -0
- package/dist/tool-runtime/run-system-tool.js +230 -0
- package/dist/tool-runtime/run-system-tool.js.map +1 -0
- package/dist/tool-runtime/tool-error.d.ts +6 -0
- package/dist/tool-runtime/tool-error.d.ts.map +1 -0
- package/dist/tool-runtime/tool-error.js +6 -0
- package/dist/tool-runtime/tool-error.js.map +1 -0
- package/dist/tool-runtime/worker-tools.d.ts +8 -0
- package/dist/tool-runtime/worker-tools.d.ts.map +1 -0
- package/dist/tool-runtime/worker-tools.js +65 -0
- package/dist/tool-runtime/worker-tools.js.map +1 -0
- package/dist/tool-runtime/write-admit.d.ts +21 -0
- package/dist/tool-runtime/write-admit.d.ts.map +1 -0
- package/dist/tool-runtime/write-admit.js +89 -0
- package/dist/tool-runtime/write-admit.js.map +1 -0
- package/package.json +114 -3
- package/policy/auto-mode-ask.scm +201 -0
- package/policy/bypass-detect.prompt +55 -0
- package/policy/classifier-bash-incomplete.prompt +46 -0
- package/policy/classifier-bash.prompt +45 -0
- package/policy/classifier-mcp.prompt +45 -0
- package/policy/classifier-read.prompt +44 -0
- package/policy/classifier-write-outside.prompt +46 -0
- package/policy/classifier-write-risky.prompt +45 -0
- package/policy/classifier-write-workspace.prompt +46 -0
- package/policy/classifier-write.prompt +45 -0
- package/policy/soft-deny-round1.prompt +51 -0
- package/policy/soft-deny-round2.prompt +60 -0
- package/src/agent-calls/acceptance.ts +71 -0
- package/src/agent-calls/callbacks.ts +75 -0
- package/src/agent-calls/delivery.ts +15 -0
- package/src/agent-calls/index.ts +16 -0
- package/src/agent-calls/operator.ts +99 -0
- package/src/agent-calls/runtime.ts +310 -0
- package/src/agent-calls/types.ts +33 -0
- package/src/context/compact-floors.ts +76 -0
- package/src/context/compact.ts +176 -0
- package/src/context/delivery.ts +15 -0
- package/src/context/history.ts +725 -0
- package/src/context/index.ts +35 -0
- package/src/context/observations.ts +13 -0
- package/src/context/retention/defaults.ts +58 -0
- package/src/context/retention/index.ts +45 -0
- package/src/context/retention/narrow.ts +123 -0
- package/src/context/retention/render.ts +177 -0
- package/src/context/retention/resolve.ts +306 -0
- package/src/context/retention/schema.ts +173 -0
- package/src/context/retention/stamp.ts +121 -0
- package/src/context/retention/step.ts +85 -0
- package/src/context/retention/view.ts +161 -0
- package/src/context/squeeze.ts +218 -0
- package/src/context/tools.ts +92 -0
- package/src/context/transcript.ts +705 -0
- package/src/policy-processor/README.md +43 -0
- package/src/policy-processor/bypass.ts +246 -0
- package/src/policy-processor/classifier.ts +711 -0
- package/src/policy-processor/cluster.ts +31 -0
- package/src/policy-processor/evidence.ts +214 -0
- package/src/policy-processor/explain.ts +310 -0
- package/src/policy-processor/index.ts +6 -0
- package/src/policy-processor/license.ts +45 -0
- package/src/policy-processor/peel-cwd.ts +1 -0
- package/src/policy-processor/real-path.ts +41 -0
- package/src/policy-processor/scope.ts +655 -0
- package/src/policy-processor/self-protect.ts +46 -0
- package/src/policy-processor/soft-deny.ts +225 -0
- package/src/policy-processor/unattended-guard.ts +158 -0
- package/src/session/cancel.ts +34 -0
- package/src/session/commands.ts +292 -0
- package/src/session/compact-actor.ts +132 -0
- package/src/session/compact-env.ts +539 -0
- package/src/session/compact.ts +95 -0
- package/src/session/index.ts +18 -0
- package/src/session/park.ts +73 -0
- package/src/session/side-channel-reminder.ts +148 -0
- package/src/session/types.ts +50 -0
- package/src/tool-catalog/catalog.ts +282 -0
- package/src/tool-catalog/index.ts +26 -0
- package/src/tool-catalog/recipes.ts +154 -0
- package/src/tool-catalog/types.ts +110 -0
- package/src/tool-runtime/approval/approved.ts +20 -0
- package/src/tool-runtime/approval/dist.ts +29 -0
- package/src/tool-runtime/approval/inbound.ts +50 -0
- package/src/tool-runtime/approval/unattended.ts +24 -0
- package/src/tool-runtime/blob-port.ts +64 -0
- package/src/tool-runtime/extra-root.ts +16 -0
- package/src/tool-runtime/handler.ts +576 -0
- package/src/tool-runtime/index.ts +21 -0
- package/src/tool-runtime/peel.ts +91 -0
- package/src/tool-runtime/plugin-context.ts +68 -0
- package/src/tool-runtime/recall.ts +104 -0
- package/src/tool-runtime/run-system-tool.ts +273 -0
- package/src/tool-runtime/tool-error.ts +6 -0
- package/src/tool-runtime/worker-tools.ts +76 -0
- package/src/tool-runtime/write-admit.ts +90 -0
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery.js","sourceRoot":"","sources":["../../src/context/delivery.ts"],"names":[],"mappings":"AAUA,6DAA6D;AAC7D,MAAM,UAAU,2BAA2B,CAAC,IAA+B,EAAE,OAAwB;IACnG,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IACvD,OAAO,IAAI,EAAE,IAAI,KAAK,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Completion input projection: history, compact lead, notifications, tool results.
|
|
3
|
+
* Vendor Chat Completions / Responses encoding stays in the protocol actor.
|
|
4
|
+
*
|
|
5
|
+
* Model input is a pure projection of the graph; nothing is deleted. What an
|
|
6
|
+
* earlier item leaves behind is decided by the recorded retention facts
|
|
7
|
+
* (R1 turn policy, R2 job rule, R3 clock) — see `./retention`.
|
|
8
|
+
*/
|
|
9
|
+
import { CompletionExpectation, type CompletionMessage, type ToolTextPart } from "@inhuman.tools/harness-model";
|
|
10
|
+
import { type ViewOptions } from "./retention/view.js";
|
|
11
|
+
import type { KernelToolCatalog } from "../tool-catalog/index.js";
|
|
12
|
+
export type HistoryToolCall = {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly argsJson: string;
|
|
16
|
+
};
|
|
17
|
+
export type HistoryUserPart = {
|
|
18
|
+
readonly type: "text";
|
|
19
|
+
readonly text: string;
|
|
20
|
+
} | {
|
|
21
|
+
readonly type: "image";
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly mime: string;
|
|
24
|
+
readonly width: number;
|
|
25
|
+
readonly height: number;
|
|
26
|
+
readonly resizedFrom: {
|
|
27
|
+
readonly width: number;
|
|
28
|
+
readonly height: number;
|
|
29
|
+
} | null;
|
|
30
|
+
readonly sourcePath: string | null;
|
|
31
|
+
readonly bytes: Uint8Array | null;
|
|
32
|
+
};
|
|
33
|
+
export type HistoryMessage = {
|
|
34
|
+
readonly role: "system" | "user" | "assistant" | "tool";
|
|
35
|
+
readonly content: string | null | readonly ToolTextPart[] | readonly HistoryUserPart[];
|
|
36
|
+
readonly toolCallId?: string;
|
|
37
|
+
readonly toolCalls?: readonly HistoryToolCall[];
|
|
38
|
+
readonly thought?: string;
|
|
39
|
+
readonly thoughtEncrypted?: string;
|
|
40
|
+
};
|
|
41
|
+
export type ProjectHistoryOptions = {
|
|
42
|
+
readonly catalog?: KernelToolCatalog;
|
|
43
|
+
/** Emit an empty assistant shell when the dialect echoes empty thought. */
|
|
44
|
+
readonly echoEmptyThought?: boolean;
|
|
45
|
+
/** Bytes for a seated picture. Missing reader or missing blob omits that picture by name. */
|
|
46
|
+
readonly readVisual?: (id: string) => Uint8Array | null;
|
|
47
|
+
/**
|
|
48
|
+
* Bytes of a body stored beside the document, by content hash (an isolated completion's prompt message, a
|
|
49
|
+
* session round's stored line). A missing reader or a missing blob falls back to the head the document kept.
|
|
50
|
+
*/
|
|
51
|
+
readonly readBlob?: (sha256: string) => Uint8Array | null;
|
|
52
|
+
/** Key into `contextRetention.dialects` (e.g. `anthropic`). Defaults from the tip's model id. */
|
|
53
|
+
readonly dialect?: string;
|
|
54
|
+
} & Pick<ViewOptions, "clockAt">;
|
|
55
|
+
/**
|
|
56
|
+
* A round's prelude: the cells in its `messages` after the last completion
|
|
57
|
+
* ref. `messages` is cumulative (every earlier round's cells ride in it), so
|
|
58
|
+
* anything before that ref belongs to an earlier round and was emitted there.
|
|
59
|
+
*/
|
|
60
|
+
export declare function preludeCells(expectation: CompletionExpectation): CompletionMessage[];
|
|
61
|
+
export declare function notificationMessagesOf(expectation: CompletionExpectation): HistoryMessage[];
|
|
62
|
+
export declare function approvalNoteMessagesOf(expectation: CompletionExpectation): HistoryMessage[];
|
|
63
|
+
export declare function steerMessagesOf(expectation: CompletionExpectation): HistoryMessage[];
|
|
64
|
+
/** History before vendor wire encoding. */
|
|
65
|
+
export declare function projectHistory(tip: CompletionExpectation, options?: ProjectHistoryOptions): Generator<HistoryMessage>;
|
|
66
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/context/history.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAGL,qBAAqB,EACrB,KAAK,iBAAiB,EAYtB,KAAK,YAAY,EAMlB,MAAM,8BAA8B,CAAC;AAQtC,OAAO,EAA2D,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAWhH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjF,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CACnC,CAAC;AAEN,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,YAAY,EAAE,GAAG,SAAS,eAAe,EAAE,CAAC;IACvF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,6FAA6F;IAC7F,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,UAAU,GAAG,IAAI,CAAC;IACxD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,UAAU,GAAG,IAAI,CAAC;IAC1D,iGAAiG;IACjG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;AA6CjC;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,qBAAqB,GAAG,iBAAiB,EAAE,CAUpF;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,qBAAqB,GAAG,cAAc,EAAE,CAQ3F;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,qBAAqB,GAAG,cAAc,EAAE,CAQ3F;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,qBAAqB,GAAG,cAAc,EAAE,CAQpF;AA6bD,2CAA2C;AAC3C,wBAAiB,cAAc,CAC7B,GAAG,EAAE,qBAAqB,EAC1B,OAAO,GAAE,qBAA0B,GAClC,SAAS,CAAC,cAAc,CAAC,CA6F3B"}
|
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Completion input projection: history, compact lead, notifications, tool results.
|
|
3
|
+
* Vendor Chat Completions / Responses encoding stays in the protocol actor.
|
|
4
|
+
*
|
|
5
|
+
* Model input is a pure projection of the graph; nothing is deleted. What an
|
|
6
|
+
* earlier item leaves behind is decided by the recorded retention facts
|
|
7
|
+
* (R1 turn policy, R2 job rule, R3 clock) — see `./retention`.
|
|
8
|
+
*/
|
|
9
|
+
import { CallJob, CompactJob, CompletionExpectation, ContextNeedToolJob, latestCompactCutoff, owningTurn, ProgrammaticJob, PromptMessage, ReACTChunk, SessionRoot, systemPartsOf, tapeCompletion, ToolCallJob, TurnApprovalNoteChunk, TurnNotificationChunk, TurnPromptChunk, TurnSteerChunk, } from "@inhuman.tools/harness-model";
|
|
10
|
+
import invariant from "tiny-invariant";
|
|
11
|
+
import { usesGenericSilentProjection } from "./delivery.js";
|
|
12
|
+
import { BACKGROUND_TOOL, IN_FLIGHT_TOOL, NO_TOOLS_SYSTEM } from "./observations.js";
|
|
13
|
+
import { elideArgs, refOfNode, textRemainder, toolRemainder, visualRef } from "./retention/render.js";
|
|
14
|
+
import { effectiveRule, kindRule } from "./retention/resolve.js";
|
|
15
|
+
import { parseJobStamp } from "./retention/stamp.js";
|
|
16
|
+
import { buildView, horizonExpired, newestOf } from "./retention/view.js";
|
|
17
|
+
import { liftToolImages, paintObservation, squeezeProgrammaticText, squeezeToolCall, toolImageLine, } from "./squeeze.js";
|
|
18
|
+
import { liveCatalogOf, selectCompletionTools } from "./tools.js";
|
|
19
|
+
import { compactLeadRows } from "./transcript.js";
|
|
20
|
+
// --- stored bodies --------------------------------------------------------------------------
|
|
21
|
+
/** Keeps a leading byte-order mark: the text is what was stored, character for character. */
|
|
22
|
+
const UTF8 = new TextDecoder("utf-8", { ignoreBOM: true });
|
|
23
|
+
/**
|
|
24
|
+
* The text a stored body stands for: the inline text, the blob's bytes read as UTF-8, or the head the document
|
|
25
|
+
* kept when the blob cannot be read. The model sees a truncated prompt rather than a failed round; the daemon
|
|
26
|
+
* that binds the reader is the one that can say a blob is missing.
|
|
27
|
+
*/
|
|
28
|
+
function bodyText(body, readBlob) {
|
|
29
|
+
if (body.kind === "inline")
|
|
30
|
+
return body.text;
|
|
31
|
+
const bytes = readBlob?.(body.blob.sha256) ?? null;
|
|
32
|
+
return bytes === null ? body.blob.head : UTF8.decode(bytes);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* {@link CompletionExpectation.userPrompt} with every body read in full: the same rule (authored user messages
|
|
36
|
+
* win; with none, the stored line), but a body stored beside the document comes back through `readBlob`
|
|
37
|
+
* instead of as its head.
|
|
38
|
+
*/
|
|
39
|
+
function userPromptOf(expectation, readBlob) {
|
|
40
|
+
const users = expectation.promptMessages.filter((row) => row.role === "user");
|
|
41
|
+
if (users.length === 0)
|
|
42
|
+
return bodyText(expectation.promptTextBody, readBlob);
|
|
43
|
+
return users.map((row) => bodyText(row.body, readBlob)).join("\n\n");
|
|
44
|
+
}
|
|
45
|
+
// --- prelude --------------------------------------------------------------------------------
|
|
46
|
+
function completionOfCell(cell) {
|
|
47
|
+
return tapeCompletion(cell) ?? (cell instanceof CompletionExpectation ? cell : null);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A round's prelude: the cells in its `messages` after the last completion
|
|
51
|
+
* ref. `messages` is cumulative (every earlier round's cells ride in it), so
|
|
52
|
+
* anything before that ref belongs to an earlier round and was emitted there.
|
|
53
|
+
*/
|
|
54
|
+
export function preludeCells(expectation) {
|
|
55
|
+
const messages = expectation.messages;
|
|
56
|
+
let start = 0;
|
|
57
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
58
|
+
if (completionOfCell(messages[index]) != null) {
|
|
59
|
+
start = index + 1;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return messages.slice(start);
|
|
64
|
+
}
|
|
65
|
+
export function notificationMessagesOf(expectation) {
|
|
66
|
+
const out = [];
|
|
67
|
+
for (const cell of preludeCells(expectation)) {
|
|
68
|
+
if (!(cell instanceof TurnNotificationChunk))
|
|
69
|
+
continue;
|
|
70
|
+
const content = cell.notificationText();
|
|
71
|
+
if (content !== "")
|
|
72
|
+
out.push({ role: "system", content });
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
export function approvalNoteMessagesOf(expectation) {
|
|
77
|
+
const out = [];
|
|
78
|
+
for (const cell of preludeCells(expectation)) {
|
|
79
|
+
if (!(cell instanceof TurnApprovalNoteChunk))
|
|
80
|
+
continue;
|
|
81
|
+
const content = cell.approvalNoteText();
|
|
82
|
+
if (content !== "")
|
|
83
|
+
out.push({ role: "user", content });
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
export function steerMessagesOf(expectation) {
|
|
88
|
+
const out = [];
|
|
89
|
+
for (const cell of preludeCells(expectation)) {
|
|
90
|
+
if (!(cell instanceof TurnSteerChunk))
|
|
91
|
+
continue;
|
|
92
|
+
const content = cell.completionMessage;
|
|
93
|
+
if (content !== "")
|
|
94
|
+
out.push({ role: "user", content });
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
/** A prelude cell's text, or what it leaves once its horizon has passed. `null` leaves nothing. */
|
|
99
|
+
function retainedText(kind, text, completion, ctx) {
|
|
100
|
+
const rule = kindRule(ctx.view.policyOf(completion), kind);
|
|
101
|
+
if (text.length < rule.minChars)
|
|
102
|
+
return text;
|
|
103
|
+
if (!horizonExpired(rule.keep, ctx.view, { consumer: completion, owner: completion }))
|
|
104
|
+
return text;
|
|
105
|
+
return textRemainder(rule.leave, kind, text);
|
|
106
|
+
}
|
|
107
|
+
/** The tool jobs on the tape between `completion` and the next completion or cutoff. */
|
|
108
|
+
function roundOf(completion, catalog) {
|
|
109
|
+
const turn = owningTurn(completion);
|
|
110
|
+
const tape = turn == null ? [] : [...turn.doneWork, ...turn.queue];
|
|
111
|
+
const start = tapeIndexOf(tape, completion);
|
|
112
|
+
const round = { tools: [], suppressed: new Set(), silent: new Set() };
|
|
113
|
+
if (start === -1)
|
|
114
|
+
return round;
|
|
115
|
+
for (let index = start + 1; index < tape.length; index += 1) {
|
|
116
|
+
const cell = tape[index];
|
|
117
|
+
if (tapeCompletion(cell) != null || cell instanceof CompactJob)
|
|
118
|
+
break;
|
|
119
|
+
if (!(cell instanceof ToolCallJob || cell instanceof ProgrammaticJob))
|
|
120
|
+
continue;
|
|
121
|
+
if (cell instanceof ContextNeedToolJob) {
|
|
122
|
+
round.suppressed.add(cell.toolCallId);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (cell instanceof CallJob && catalog != null && usesGenericSilentProjection(cell, catalog)) {
|
|
126
|
+
round.silent.add(cell.toolCallId);
|
|
127
|
+
}
|
|
128
|
+
round.tools.push(cell);
|
|
129
|
+
}
|
|
130
|
+
return round;
|
|
131
|
+
}
|
|
132
|
+
function sealedText(job) {
|
|
133
|
+
if (job instanceof ToolCallJob)
|
|
134
|
+
return paintObservation(liftToolImages(job.observationPayload()).payload);
|
|
135
|
+
const text = job.resultText();
|
|
136
|
+
return text !== "" ? text : (job.receiptJson ?? "");
|
|
137
|
+
}
|
|
138
|
+
function stubFacts(job, kind, snap) {
|
|
139
|
+
return {
|
|
140
|
+
tool: job instanceof ToolCallJob ? job.name : job.toolName,
|
|
141
|
+
kind,
|
|
142
|
+
ref: refOfNode(job) ?? "job:?",
|
|
143
|
+
args: job.args,
|
|
144
|
+
full: sealedText(job),
|
|
145
|
+
ok: snap?.ok !== false,
|
|
146
|
+
value: job instanceof ToolCallJob ? job.observationPayload() : snap?.value,
|
|
147
|
+
code: snap?.code,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function toolContent(job, silentResult, producer, ctx) {
|
|
151
|
+
if (silentResult)
|
|
152
|
+
return "";
|
|
153
|
+
if (!job.completed)
|
|
154
|
+
return job.background ? BACKGROUND_TOOL : IN_FLIGHT_TOOL;
|
|
155
|
+
const stamp = parseJobStamp(job.retentionJson);
|
|
156
|
+
const consumer = ctx.view.nextOf(producer);
|
|
157
|
+
const snap = job.outcomeSnap;
|
|
158
|
+
const failed = snap?.ok === false;
|
|
159
|
+
if (stamp !== null && consumer !== null) {
|
|
160
|
+
const rule = effectiveRule(stamp.rule, failed);
|
|
161
|
+
const text = sealedText(job);
|
|
162
|
+
if (text.length >= rule.minChars && horizonExpired(rule.keep, ctx.view, { consumer, owner: producer })) {
|
|
163
|
+
return toolRemainder(rule.leave, stubFacts(job, stamp.kind, snap), failed);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (job instanceof ToolCallJob) {
|
|
167
|
+
const visible = imageVisible(ctx.images, producer, job.toolCallId);
|
|
168
|
+
return squeezeToolCall(job, "compact", (image) => visible.has(image.index)
|
|
169
|
+
? toolImageLine(image, "shown")
|
|
170
|
+
: toolImageLine(image, "elided", refOfNode(job) ?? "job:?"));
|
|
171
|
+
}
|
|
172
|
+
const parts = job.resultParts();
|
|
173
|
+
if (parts !== undefined)
|
|
174
|
+
return parts.length === 0 ? "" : parts.map((part) => ({ ...part, text: squeezeProgrammaticText(job, part.text) }));
|
|
175
|
+
const text = job.resultText();
|
|
176
|
+
if (text !== "")
|
|
177
|
+
return squeezeProgrammaticText(job, text);
|
|
178
|
+
const receipt = job.receiptJson;
|
|
179
|
+
return receipt == null ? IN_FLIGHT_TOOL : squeezeProgrammaticText(job, receipt);
|
|
180
|
+
}
|
|
181
|
+
// --- pictures -------------------------------------------------------------------------------
|
|
182
|
+
function tapeIndexOf(tape, pew) {
|
|
183
|
+
for (let i = 0; i < tape.length; i += 1) {
|
|
184
|
+
const cell = tape[i];
|
|
185
|
+
if (cell === pew || tapeCompletion(cell) === pew)
|
|
186
|
+
return i;
|
|
187
|
+
}
|
|
188
|
+
return -1;
|
|
189
|
+
}
|
|
190
|
+
function pictureLine(index, visual, omitted) {
|
|
191
|
+
if (omitted)
|
|
192
|
+
return `[Image #${index} omitted: ${visual.mime}, ${visual.width}x${visual.height}]`;
|
|
193
|
+
const resized = visual.resizedFrom == null ? "" : `, resized from ${visual.resizedFrom.width}x${visual.resizedFrom.height}`;
|
|
194
|
+
const path = visual.sourcePath == null || visual.sourcePath === "" ? "" : `, ${visual.sourcePath}`;
|
|
195
|
+
return `[Image #${index}: ${visual.mime}, ${visual.width}x${visual.height}${resized}${path}]`;
|
|
196
|
+
}
|
|
197
|
+
function elidedPictureLine(index, visual) {
|
|
198
|
+
const path = visual.sourcePath == null || visual.sourcePath === "" ? "" : `, ${visual.sourcePath}`;
|
|
199
|
+
return `[Image #${index} elided: ${visual.mime} ${visual.width}x${visual.height}${path} — recall ${visualRef(visual.id)}]`;
|
|
200
|
+
}
|
|
201
|
+
function picturedPrompt(expectation) {
|
|
202
|
+
const turn = owningTurn(expectation);
|
|
203
|
+
if (turn == null || turn.visuals.length === 0)
|
|
204
|
+
return false;
|
|
205
|
+
const tape = [...turn.doneWork, ...turn.queue];
|
|
206
|
+
const index = tapeIndexOf(tape, expectation);
|
|
207
|
+
if (index < 0)
|
|
208
|
+
return false;
|
|
209
|
+
for (let cursor = index - 1; cursor >= 0; cursor -= 1) {
|
|
210
|
+
const cell = tape[cursor];
|
|
211
|
+
if (cell instanceof TurnPromptChunk)
|
|
212
|
+
return true;
|
|
213
|
+
if (cell instanceof ReACTChunk || tapeCompletion(cell) != null)
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
function planImages(view, catalog, readVisual) {
|
|
219
|
+
const items = [];
|
|
220
|
+
for (const completion of view.order) {
|
|
221
|
+
if (completion === view.tip && !picturedPrompt(completion))
|
|
222
|
+
continue;
|
|
223
|
+
const turn = owningTurn(completion);
|
|
224
|
+
if (turn != null && picturedPrompt(completion)) {
|
|
225
|
+
for (let index = 0; index < turn.visuals.length; index += 1) {
|
|
226
|
+
items.push({ kind: "image.user", completion, index });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (completion === view.tip)
|
|
230
|
+
continue;
|
|
231
|
+
for (const job of roundOf(completion, catalog).tools) {
|
|
232
|
+
if (!(job instanceof ToolCallJob) || !job.completed)
|
|
233
|
+
continue;
|
|
234
|
+
for (const image of liftToolImages(job.observationPayload()).images) {
|
|
235
|
+
if (image.bytes !== null) {
|
|
236
|
+
items.push({ kind: "image.tool", completion, callId: job.toolCallId, index: image.index });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const survivors = new Map();
|
|
242
|
+
const user = new Map();
|
|
243
|
+
const tool = new Map();
|
|
244
|
+
for (let cursor = items.length - 1; cursor >= 0; cursor -= 1) {
|
|
245
|
+
const item = items[cursor];
|
|
246
|
+
const rule = kindRule(view.policyOf(item.completion), item.kind);
|
|
247
|
+
const consumer = item.kind === "image.user" ? item.completion : view.nextOf(item.completion);
|
|
248
|
+
let visible = consumer === null || !horizonExpired(rule.keep, view, { consumer, owner: item.completion, againstTip: true });
|
|
249
|
+
if (visible && item.kind === "image.user" && readVisual == null)
|
|
250
|
+
visible = true;
|
|
251
|
+
const cap = newestOf(rule.keep);
|
|
252
|
+
if (visible && cap !== null) {
|
|
253
|
+
const seen = survivors.get(item.kind) ?? 0;
|
|
254
|
+
survivors.set(item.kind, seen + 1);
|
|
255
|
+
if (seen >= cap)
|
|
256
|
+
visible = false;
|
|
257
|
+
}
|
|
258
|
+
if (item.kind === "image.user") {
|
|
259
|
+
const flags = user.get(item.completion) ?? [];
|
|
260
|
+
flags[item.index] = visible;
|
|
261
|
+
user.set(item.completion, flags);
|
|
262
|
+
}
|
|
263
|
+
else if (visible) {
|
|
264
|
+
const calls = tool.get(item.completion) ?? new Map();
|
|
265
|
+
const set = calls.get(item.callId) ?? new Set();
|
|
266
|
+
set.add(item.index);
|
|
267
|
+
calls.set(item.callId, set);
|
|
268
|
+
tool.set(item.completion, calls);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return { user, tool };
|
|
272
|
+
}
|
|
273
|
+
const NO_INDEXES = new Set();
|
|
274
|
+
function imageVisible(plan, producer, callId) {
|
|
275
|
+
return plan.tool.get(producer)?.get(callId) ?? NO_INDEXES;
|
|
276
|
+
}
|
|
277
|
+
function userPictureParts(text, visuals, visible, readVisual) {
|
|
278
|
+
const parts = [];
|
|
279
|
+
if (text !== "")
|
|
280
|
+
parts.push({ type: "text", text });
|
|
281
|
+
for (let index = 0; index < visuals.length; index += 1) {
|
|
282
|
+
const visual = visuals[index];
|
|
283
|
+
if (visual == null)
|
|
284
|
+
continue;
|
|
285
|
+
const number = index + 1;
|
|
286
|
+
if (visible[index] === false) {
|
|
287
|
+
parts.push({ type: "text", text: elidedPictureLine(number, visual) });
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const bytes = readVisual == null ? null : readVisual(visual.id);
|
|
291
|
+
// One line per picture: the descriptive line when the bytes ride, the omitted line when they cannot.
|
|
292
|
+
if (bytes == null) {
|
|
293
|
+
parts.push({ type: "text", text: pictureLine(number, visual, true) });
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
parts.push({ type: "text", text: pictureLine(number, visual, false) }, {
|
|
297
|
+
type: "image",
|
|
298
|
+
id: visual.id,
|
|
299
|
+
mime: visual.mime,
|
|
300
|
+
width: visual.width,
|
|
301
|
+
height: visual.height,
|
|
302
|
+
resizedFrom: visual.resizedFrom,
|
|
303
|
+
sourcePath: visual.sourcePath,
|
|
304
|
+
bytes,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
return parts;
|
|
308
|
+
}
|
|
309
|
+
function toolImageRow(job, images, visible) {
|
|
310
|
+
const parts = [];
|
|
311
|
+
for (const image of images) {
|
|
312
|
+
if (!visible.has(image.index) || image.bytes === null)
|
|
313
|
+
continue;
|
|
314
|
+
parts.push({ type: "text", text: `[Image ${image.index} from ${job.name} ${refOfNode(job) ?? "job:?"}]` });
|
|
315
|
+
parts.push({
|
|
316
|
+
type: "image",
|
|
317
|
+
id: `${refOfNode(job) ?? "job:?"}:${image.index}`,
|
|
318
|
+
mime: image.mime,
|
|
319
|
+
width: 0,
|
|
320
|
+
height: 0,
|
|
321
|
+
resizedFrom: null,
|
|
322
|
+
sourcePath: null,
|
|
323
|
+
bytes: image.bytes,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
return parts.length === 0 ? null : { role: "user", content: parts };
|
|
327
|
+
}
|
|
328
|
+
/** A `context_recall visual:<id>` result: the bytes ride in a user row (Chat tool rows are text-only). */
|
|
329
|
+
function recalledVisual(job, ctx) {
|
|
330
|
+
if (job.name !== "context_recall" || ctx.readVisual == null)
|
|
331
|
+
return null;
|
|
332
|
+
const json = job.outcomeSnap?.json;
|
|
333
|
+
const id = json != null && typeof json === "object" ? json.visualId : undefined;
|
|
334
|
+
if (typeof id !== "string")
|
|
335
|
+
return null;
|
|
336
|
+
const bytes = ctx.readVisual(id);
|
|
337
|
+
if (bytes == null)
|
|
338
|
+
return null;
|
|
339
|
+
const visual = owningTurnVisuals(ctx, id);
|
|
340
|
+
return {
|
|
341
|
+
role: "user",
|
|
342
|
+
content: [
|
|
343
|
+
{ type: "text", text: `[Image recalled: ${visualRef(id)}]` },
|
|
344
|
+
{
|
|
345
|
+
type: "image",
|
|
346
|
+
id,
|
|
347
|
+
mime: visual?.mime ?? "image/png",
|
|
348
|
+
width: visual?.width ?? 0,
|
|
349
|
+
height: visual?.height ?? 0,
|
|
350
|
+
resizedFrom: visual?.resizedFrom ?? null,
|
|
351
|
+
sourcePath: visual?.sourcePath ?? null,
|
|
352
|
+
bytes,
|
|
353
|
+
},
|
|
354
|
+
],
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
function owningTurnVisuals(ctx, id) {
|
|
358
|
+
for (const c of ctx.view.order) {
|
|
359
|
+
const found = owningTurn(c)?.visuals.find((v) => v.id === id);
|
|
360
|
+
if (found !== undefined)
|
|
361
|
+
return found;
|
|
362
|
+
}
|
|
363
|
+
return undefined;
|
|
364
|
+
}
|
|
365
|
+
// --- one completion -------------------------------------------------------------------------
|
|
366
|
+
function promptMessages(expectation, ctx) {
|
|
367
|
+
const messages = [];
|
|
368
|
+
const note = expectation.systemNote?.trim() ?? "";
|
|
369
|
+
if (note !== "") {
|
|
370
|
+
const kept = retainedText("system-note", note, expectation, ctx);
|
|
371
|
+
if (kept !== null)
|
|
372
|
+
messages.push({ role: "system", content: kept });
|
|
373
|
+
}
|
|
374
|
+
const rules = [
|
|
375
|
+
["notification", notificationMessagesOf(expectation)],
|
|
376
|
+
["approval-note", approvalNoteMessagesOf(expectation)],
|
|
377
|
+
["steer", steerMessagesOf(expectation)],
|
|
378
|
+
];
|
|
379
|
+
for (const [kind, rows] of rules) {
|
|
380
|
+
for (const row of rows) {
|
|
381
|
+
const text = typeof row.content === "string" ? row.content : "";
|
|
382
|
+
const kept = retainedText(kind, text, expectation, ctx);
|
|
383
|
+
if (kept !== null)
|
|
384
|
+
messages.push({ ...row, content: kept });
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
const text = userPromptOf(expectation, ctx.readBlob);
|
|
388
|
+
const turn = owningTurn(expectation);
|
|
389
|
+
const visuals = turn != null && picturedPrompt(expectation) ? turn.visuals : [];
|
|
390
|
+
if (text === "" && visuals.length === 0)
|
|
391
|
+
return messages;
|
|
392
|
+
messages.push({
|
|
393
|
+
role: "user",
|
|
394
|
+
content: visuals.length === 0
|
|
395
|
+
? text
|
|
396
|
+
: userPictureParts(text, visuals, ctx.images.user.get(expectation) ?? [], ctx.readVisual),
|
|
397
|
+
});
|
|
398
|
+
return messages;
|
|
399
|
+
}
|
|
400
|
+
function historyToolCall(call, job, producer, ctx) {
|
|
401
|
+
const base = { id: call.toolCallId, name: call.name };
|
|
402
|
+
const args = call.args ?? {};
|
|
403
|
+
const stamp = job === undefined ? null : parseJobStamp(job.retentionJson);
|
|
404
|
+
const consumer = ctx.view.nextOf(producer);
|
|
405
|
+
if (job !== undefined &&
|
|
406
|
+
stamp?.args !== undefined &&
|
|
407
|
+
consumer !== null &&
|
|
408
|
+
horizonExpired(stamp.args.keep, ctx.view, { consumer, owner: producer })) {
|
|
409
|
+
const elided = elideArgs(args, `${refOfNode(job) ?? "job:?"}#args`, stamp.args.minChars);
|
|
410
|
+
if (elided.elided)
|
|
411
|
+
return { ...base, argsJson: elided.json };
|
|
412
|
+
}
|
|
413
|
+
return { ...base, argsJson: JSON.stringify(args) };
|
|
414
|
+
}
|
|
415
|
+
function thinkingExpired(completion, ctx) {
|
|
416
|
+
const rule = kindRule(ctx.view.policyOf(completion), "thinking", ctx.view.dialect);
|
|
417
|
+
return horizonExpired(rule.keep, ctx.view, { consumer: completion, owner: completion });
|
|
418
|
+
}
|
|
419
|
+
function* emitCompletionOnTape(completion, ctx) {
|
|
420
|
+
const round = roundOf(completion, ctx.catalog);
|
|
421
|
+
const prior = promptMessages(completion, ctx);
|
|
422
|
+
const byId = new Map(round.tools.filter((job) => job.toolCallId !== "").map((job) => [job.toolCallId, job]));
|
|
423
|
+
const stored = completion.responseCalls.map((call) => historyToolCall({ toolCallId: call.toolCallId, name: call.name, args: call.args }, byId.get(call.toolCallId), completion, ctx));
|
|
424
|
+
const calls = stored.filter((call) => !round.suppressed.has(call.id));
|
|
425
|
+
const allSuppressed = stored.length > 0 && calls.length === 0;
|
|
426
|
+
const dropThinking = thinkingExpired(completion, ctx);
|
|
427
|
+
const thought = dropThinking ? "" : completion.responseThought;
|
|
428
|
+
const encrypted = dropThinking ? "" : (completion.responseReasoningEncrypted?.trim() ?? "");
|
|
429
|
+
if (completion.responseText !== "" ||
|
|
430
|
+
calls.length > 0 ||
|
|
431
|
+
thought !== "" ||
|
|
432
|
+
encrypted !== "" ||
|
|
433
|
+
allSuppressed ||
|
|
434
|
+
ctx.echoEmptyThought) {
|
|
435
|
+
prior.push({
|
|
436
|
+
role: "assistant",
|
|
437
|
+
// Strict OpenAI-compatible providers reject null content without tool calls.
|
|
438
|
+
content: completion.responseText === "" ? (calls.length > 0 ? null : "") : completion.responseText,
|
|
439
|
+
...(calls.length > 0 ? { toolCalls: calls } : {}),
|
|
440
|
+
thought,
|
|
441
|
+
...(encrypted === "" ? {} : { thoughtEncrypted: encrypted }),
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
// A tool row answers a call in this same projection, or it is not emitted: no orphan results.
|
|
445
|
+
const imageRows = [];
|
|
446
|
+
for (const call of calls) {
|
|
447
|
+
const job = byId.get(call.id);
|
|
448
|
+
prior.push({
|
|
449
|
+
role: "tool",
|
|
450
|
+
toolCallId: call.id,
|
|
451
|
+
content: job === undefined ? IN_FLIGHT_TOOL : toolContent(job, round.silent.has(call.id), completion, ctx),
|
|
452
|
+
});
|
|
453
|
+
if (job instanceof ToolCallJob && job.completed) {
|
|
454
|
+
const row = toolImageRow(job, liftToolImages(job.observationPayload()).images, imageVisible(ctx.images, completion, call.id));
|
|
455
|
+
if (row !== null)
|
|
456
|
+
imageRows.push(row);
|
|
457
|
+
const recalled = recalledVisual(job, ctx);
|
|
458
|
+
if (recalled !== null)
|
|
459
|
+
imageRows.push(recalled);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
prior.push(...imageRows);
|
|
463
|
+
for (const row of prior)
|
|
464
|
+
yield row;
|
|
465
|
+
}
|
|
466
|
+
function dialectOf(tip, given) {
|
|
467
|
+
if (given !== undefined)
|
|
468
|
+
return given;
|
|
469
|
+
return /claude|anthropic/i.test(tip.model) ? "anthropic" : undefined;
|
|
470
|
+
}
|
|
471
|
+
/** History before vendor wire encoding. */
|
|
472
|
+
export function* projectHistory(tip, options = {}) {
|
|
473
|
+
if (tip.completionMode === "isolated") {
|
|
474
|
+
for (const message of tip.promptMessages) {
|
|
475
|
+
invariant(message instanceof PromptMessage, "invalid isolated prompt message");
|
|
476
|
+
yield {
|
|
477
|
+
role: message.role,
|
|
478
|
+
content: bodyText(message.body, options.readBlob),
|
|
479
|
+
...(message.role === "assistant" ? { thought: "" } : {}),
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
const catalog = liveCatalogOf(tip, options.catalog);
|
|
485
|
+
const tools = selectCompletionTools(tip, catalog);
|
|
486
|
+
const echoEmptyThought = options.echoEmptyThought === true;
|
|
487
|
+
const tipTurn = owningTurn(tip);
|
|
488
|
+
const parts = tipTurn === null ? null : systemPartsOf(tipTurn);
|
|
489
|
+
// The addendum frozen with the turn's tool set wins over the live catalog: a catalog edit
|
|
490
|
+
// between rounds must not rewrite the cached prefix.
|
|
491
|
+
const frozenAddendum = tipTurn?.tools.addendum ?? "";
|
|
492
|
+
yield {
|
|
493
|
+
role: "system",
|
|
494
|
+
content: [
|
|
495
|
+
parts?.constitution ?? "",
|
|
496
|
+
tools.length === 0
|
|
497
|
+
? NO_TOOLS_SYSTEM
|
|
498
|
+
: frozenAddendum !== ""
|
|
499
|
+
? frozenAddendum
|
|
500
|
+
: (catalog?.TOOLS_SYSTEM_ADDENDUM ?? NO_TOOLS_SYSTEM),
|
|
501
|
+
]
|
|
502
|
+
.filter((part) => part !== "")
|
|
503
|
+
.join("\n\n"),
|
|
504
|
+
};
|
|
505
|
+
const root = tip.plexus?.root;
|
|
506
|
+
const env = parts?.env ?? {};
|
|
507
|
+
const envLines = [];
|
|
508
|
+
if (root instanceof SessionRoot && root.path !== "")
|
|
509
|
+
envLines.push(`Workspace: ${root.path}`);
|
|
510
|
+
for (const key of Object.keys(env).toSorted()) {
|
|
511
|
+
const value = env[key] ?? "";
|
|
512
|
+
if (value !== "")
|
|
513
|
+
envLines.push(`${key}: ${value}`);
|
|
514
|
+
}
|
|
515
|
+
if (envLines.length > 0)
|
|
516
|
+
yield { role: "system", content: envLines.join("\n") };
|
|
517
|
+
const note = tipTurn?.derivation?.note.trim() ?? "";
|
|
518
|
+
if (note !== "")
|
|
519
|
+
yield { role: "system", content: note };
|
|
520
|
+
const cutoff = tipTurn == null ? null : latestCompactCutoff(tipTurn);
|
|
521
|
+
const leadRows = [];
|
|
522
|
+
if (cutoff != null) {
|
|
523
|
+
const kv = root instanceof SessionRoot ? root.kvs : {};
|
|
524
|
+
for (const row of compactLeadRows(cutoff.turn, cutoff.job, {
|
|
525
|
+
kv,
|
|
526
|
+
configFloor: cutoff.job.keepTurns ?? undefined,
|
|
527
|
+
})) {
|
|
528
|
+
leadRows.push(row);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
const lead = [];
|
|
532
|
+
for (const row of leadRows) {
|
|
533
|
+
if (row.kind === "user" || row.kind === "assistant")
|
|
534
|
+
continue;
|
|
535
|
+
const kept = completionOfCell(row.cell);
|
|
536
|
+
if (kept != null && kept !== tip)
|
|
537
|
+
lead.push(kept);
|
|
538
|
+
}
|
|
539
|
+
const view = buildView(tip, [...lead, ...tip.spine()], {
|
|
540
|
+
...(options.clockAt === undefined ? {} : { clockAt: options.clockAt }),
|
|
541
|
+
dialect: dialectOf(tip, options.dialect),
|
|
542
|
+
});
|
|
543
|
+
const ctx = {
|
|
544
|
+
catalog,
|
|
545
|
+
echoEmptyThought,
|
|
546
|
+
readVisual: options.readVisual,
|
|
547
|
+
readBlob: options.readBlob,
|
|
548
|
+
view,
|
|
549
|
+
images: planImages(view, catalog, options.readVisual),
|
|
550
|
+
};
|
|
551
|
+
for (const row of leadRows) {
|
|
552
|
+
if (row.kind === "user") {
|
|
553
|
+
yield { role: "user", content: row.text };
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
if (row.kind === "assistant") {
|
|
557
|
+
yield { role: "assistant", content: row.text };
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
const kept = completionOfCell(row.cell);
|
|
561
|
+
if (kept == null || kept === tip)
|
|
562
|
+
continue;
|
|
563
|
+
yield* emitCompletionOnTape(kept, ctx);
|
|
564
|
+
}
|
|
565
|
+
for (const completion of tip.spine()) {
|
|
566
|
+
if (completion === tip) {
|
|
567
|
+
yield* promptMessages(completion, ctx);
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
yield* emitCompletionOnTape(completion, ctx);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
//# sourceMappingURL=history.js.map
|