@inhuman.tools/turn 0.0.0-stage → 0.1.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,35 @@
|
|
|
1
|
+
export {
|
|
2
|
+
contentTokensOf,
|
|
3
|
+
type EatCell,
|
|
4
|
+
historyBehind,
|
|
5
|
+
MessageChunk,
|
|
6
|
+
payloadSuffix,
|
|
7
|
+
projectCompactRows,
|
|
8
|
+
sliceCompactEat,
|
|
9
|
+
sliceCompactZones,
|
|
10
|
+
textOfCell,
|
|
11
|
+
Transcript,
|
|
12
|
+
} from "./transcript.js";
|
|
13
|
+
export { keepFloors, keepFloorsOfJob, kvKeepTurnsOf, stampCompactInputs } from "./compact-floors.js";
|
|
14
|
+
export { compactDecision, compactDue, compactRejectReason, needFeasible, tailCompactCandidate } from "./compact.js";
|
|
15
|
+
export {
|
|
16
|
+
SQUEEZE_COMPACT_CHARS,
|
|
17
|
+
SQUEEZE_MICRO_MIN_CHARS,
|
|
18
|
+
liftToolImages,
|
|
19
|
+
squeezeProgrammaticText,
|
|
20
|
+
squeezeToolCall,
|
|
21
|
+
toolImagesOf,
|
|
22
|
+
toolCallRepresentation,
|
|
23
|
+
} from "./squeeze.js";
|
|
24
|
+
export * from "./retention/index.js";
|
|
25
|
+
export { usesGenericSilentProjection } from "./delivery.js";
|
|
26
|
+
export { selectCompletionTools } from "./tools.js";
|
|
27
|
+
export { BACKGROUND_TOOL, IN_FLIGHT_TOOL, NO_TOOLS_SYSTEM } from "./observations.js";
|
|
28
|
+
export {
|
|
29
|
+
approvalNoteMessagesOf,
|
|
30
|
+
type HistoryMessage,
|
|
31
|
+
type HistoryUserPart,
|
|
32
|
+
notificationMessagesOf,
|
|
33
|
+
projectHistory,
|
|
34
|
+
steerMessagesOf,
|
|
35
|
+
} from "./history.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-facing copy for completion input. Vendor HTTP errors are not here.
|
|
3
|
+
*/
|
|
4
|
+
import { prompt } from "@inhuman.tools/harness-commons";
|
|
5
|
+
|
|
6
|
+
/** No-tools face: unhomed completion, empty catalog, or Approvable parent (judge). */
|
|
7
|
+
export const NO_TOOLS_SYSTEM = prompt.system`Reply in prose. You do not have tools.`;
|
|
8
|
+
|
|
9
|
+
/** Unresolved foreground tool row. */
|
|
10
|
+
export const IN_FLIGHT_TOOL = "in-flight";
|
|
11
|
+
|
|
12
|
+
/** Unresolved background tool row. */
|
|
13
|
+
export const BACKGROUND_TOOL = "running in background";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dist defaults for `contextRetention` (design §4.3). A turn minted before
|
|
3
|
+
* retention existed resolves to {@link LEGACY_CONTEXT_RETENTION}: everything
|
|
4
|
+
* lives until compaction, except what the owner fixed regardless of config —
|
|
5
|
+
* pictures live only through their own turn, a system note only for its round.
|
|
6
|
+
*/
|
|
7
|
+
import type { ContextRetention } from "./schema.js";
|
|
8
|
+
|
|
9
|
+
export const DEFAULT_CONTEXT_RETENTION: ContextRetention = {
|
|
10
|
+
version: 1,
|
|
11
|
+
defaults: { minChars: 800 },
|
|
12
|
+
step: { turnBoundary: true, everyRounds: 4, minFreedTokens: 8000, whenCacheCold: true, atCompaction: true },
|
|
13
|
+
kinds: {
|
|
14
|
+
"image.user": { keep: ["turn", { newest: 4 }], leave: "stub", minChars: 0 },
|
|
15
|
+
"image.tool": { keep: ["turn", { newest: 2 }], leave: "stub", minChars: 0 },
|
|
16
|
+
"tool.read": { keep: ["turn", { rounds: 10 }], leave: "stub" },
|
|
17
|
+
"tool.search": { keep: { rounds: 2 }, leave: "stub" },
|
|
18
|
+
"tool.shell": { keep: { rounds: 3 }, leave: "summary" },
|
|
19
|
+
"tool.web.search": { keep: { rounds: 2 }, leave: "stub" },
|
|
20
|
+
"tool.web.fetch": { keep: "turn", leave: "stub" },
|
|
21
|
+
"tool.mcp": { keep: "turn", leave: "stub" },
|
|
22
|
+
"tool.program": { keep: "turn", leave: { head: 400 } },
|
|
23
|
+
"tool.agent": { keep: "compaction" },
|
|
24
|
+
"tool.comm": { keep: "round", leave: "stub", minChars: 200 },
|
|
25
|
+
"tool.write": { keep: "compaction" },
|
|
26
|
+
"tool.other": { keep: "compaction" },
|
|
27
|
+
"tool.args.write": { keep: "turn", leave: "stub", minChars: 2000 },
|
|
28
|
+
thinking: { keep: "turn", leave: "none", minChars: 0 },
|
|
29
|
+
steer: { keep: "compaction" },
|
|
30
|
+
"approval-note": { keep: "compaction" },
|
|
31
|
+
notification: { keep: "turn", leave: "summary" },
|
|
32
|
+
"system-note": { keep: "round", leave: "none", minChars: 0 },
|
|
33
|
+
error: { keep: "turn", leave: "summary", minChars: 0 },
|
|
34
|
+
},
|
|
35
|
+
tools: {},
|
|
36
|
+
dialects: { anthropic: { keep: "forever" } },
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const LEGACY_KINDS: ContextRetention["kinds"] = Object.fromEntries(
|
|
40
|
+
Object.keys(DEFAULT_CONTEXT_RETENTION.kinds).map((kind) => [
|
|
41
|
+
kind,
|
|
42
|
+
{ keep: "compaction", leave: "stub", minChars: 0 },
|
|
43
|
+
]),
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
export const LEGACY_CONTEXT_RETENTION: ContextRetention = {
|
|
47
|
+
version: 1,
|
|
48
|
+
defaults: { minChars: 0 },
|
|
49
|
+
step: { turnBoundary: true, everyRounds: null, minFreedTokens: 0, whenCacheCold: false, atCompaction: true },
|
|
50
|
+
kinds: {
|
|
51
|
+
...LEGACY_KINDS,
|
|
52
|
+
"image.user": { keep: ["turn", { newest: 4 }], leave: "stub", minChars: 0 },
|
|
53
|
+
"image.tool": { keep: ["turn", { newest: 2 }], leave: "stub", minChars: 0 },
|
|
54
|
+
"system-note": { keep: "round", leave: "none", minChars: 0 },
|
|
55
|
+
},
|
|
56
|
+
tools: {},
|
|
57
|
+
dialects: {},
|
|
58
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { resolveRetention, serializePolicy, sessionRetentionLayer } from "./resolve.js";
|
|
2
|
+
|
|
3
|
+
export { DEFAULT_CONTEXT_RETENTION, LEGACY_CONTEXT_RETENTION } from "./defaults.js";
|
|
4
|
+
export { canonicalKeep, narrowRule } from "./narrow.js";
|
|
5
|
+
export {
|
|
6
|
+
effectiveRule,
|
|
7
|
+
kindRule,
|
|
8
|
+
LEGACY_POLICY,
|
|
9
|
+
parsePolicy,
|
|
10
|
+
resolveRetention,
|
|
11
|
+
ruleFor,
|
|
12
|
+
serializePolicy,
|
|
13
|
+
sessionRetentionLayer,
|
|
14
|
+
type ResolvedPolicy,
|
|
15
|
+
type ResolveInput,
|
|
16
|
+
type ResolveResult,
|
|
17
|
+
} from "./resolve.js";
|
|
18
|
+
export { REF_CHARS, jobRef, visualRef } from "./render.js";
|
|
19
|
+
export {
|
|
20
|
+
contextRetentionSchema,
|
|
21
|
+
parseRetentionLayer,
|
|
22
|
+
RETENTION_KINDS,
|
|
23
|
+
type ConcreteRule,
|
|
24
|
+
type ContextRetention,
|
|
25
|
+
type Horizon,
|
|
26
|
+
type Leave,
|
|
27
|
+
type RetentionKind,
|
|
28
|
+
type RetentionLayer,
|
|
29
|
+
type RuleInput,
|
|
30
|
+
} from "./schema.js";
|
|
31
|
+
export { decideRetentionStep, stampRetentionClock, type StepFacts } from "./step.js";
|
|
32
|
+
export { kindOfJob, parseJobStamp, stampJobRetention, type JobStamp } from "./stamp.js";
|
|
33
|
+
export { buildView, parseClock, policyOfTurn, type RetentionClock, type RetentionView } from "./view.js";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* R1: the policy JSON a turn is stamped with at mint. `userConfigJson` is
|
|
37
|
+
* `KernelRoot.contextRetentionJson`; session kv may only narrow it.
|
|
38
|
+
*/
|
|
39
|
+
export function turnRetentionJson(userConfigJson: string, kvs: Readonly<Record<string, string>>): string {
|
|
40
|
+
const { policy } = resolveRetention({
|
|
41
|
+
...(userConfigJson === "" ? {} : { user: userConfigJson }),
|
|
42
|
+
session: sessionRetentionLayer(kvs),
|
|
43
|
+
});
|
|
44
|
+
return serializePolicy(policy);
|
|
45
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Narrowing algebra. A narrowing layer appends conditions to `keep` ("whichever
|
|
3
|
+
* comes first"), may replace `leave` with a shorter remainder, and may lower
|
|
4
|
+
* `minChars`. It cannot lengthen anything: a source that tries is ignored for
|
|
5
|
+
* that key and reported.
|
|
6
|
+
*/
|
|
7
|
+
import { horizonList, NONE_FORBIDDEN_KINDS, type Horizon, type Leave, type RuleInput } from "./schema.js";
|
|
8
|
+
|
|
9
|
+
/** How long a single condition keeps an item, as a comparable number. */
|
|
10
|
+
export function horizonRank(h: Horizon): number {
|
|
11
|
+
if (h === "round") return 1;
|
|
12
|
+
if (h === "turn") return 1000;
|
|
13
|
+
if (h === "compaction") return 1_000_000;
|
|
14
|
+
if (h === "forever") return 10_000_000;
|
|
15
|
+
if ("rounds" in h) return h.rounds;
|
|
16
|
+
if ("turns" in h) return 1000 * h.turns;
|
|
17
|
+
return Number.POSITIVE_INFINITY; // `newest` bounds a count, not a span
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Any-of semantics: the shortest condition decides how long an item lives. */
|
|
21
|
+
export function keepRank(keep: readonly Horizon[]): number {
|
|
22
|
+
if (keep.length === 0) return 1_000_000;
|
|
23
|
+
return Math.min(...keep.map(horizonRank));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Canonical form of an any-of condition list: the tightest of each type, in a fixed order. */
|
|
27
|
+
export function canonicalKeep(keep: readonly Horizon[]): Horizon[] {
|
|
28
|
+
let turns = Number.POSITIVE_INFINITY;
|
|
29
|
+
let rounds = Number.POSITIVE_INFINITY;
|
|
30
|
+
let newest = Number.POSITIVE_INFINITY;
|
|
31
|
+
let compaction = false;
|
|
32
|
+
let forever = false;
|
|
33
|
+
for (const h of keep) {
|
|
34
|
+
switch (h) {
|
|
35
|
+
case "round": {
|
|
36
|
+
rounds = Math.min(rounds, 1);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case "turn": {
|
|
40
|
+
turns = Math.min(turns, 1);
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
case "compaction": {
|
|
44
|
+
compaction = true;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case "forever": {
|
|
48
|
+
forever = true;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
default:
|
|
52
|
+
if ("rounds" in h) rounds = Math.min(rounds, h.rounds);
|
|
53
|
+
else if ("turns" in h) turns = Math.min(turns, h.turns);
|
|
54
|
+
else newest = Math.min(newest, h.newest);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const out: Horizon[] = [];
|
|
58
|
+
if (Number.isFinite(turns)) out.push(turns === 1 ? "turn" : { turns });
|
|
59
|
+
if (Number.isFinite(rounds)) out.push(rounds === 1 ? "round" : { rounds });
|
|
60
|
+
if (Number.isFinite(newest)) out.push({ newest });
|
|
61
|
+
// `compaction` and `forever` only matter when nothing else bounds the item.
|
|
62
|
+
if (out.every((h): boolean => typeof h === "object" && "newest" in h)) {
|
|
63
|
+
if (compaction) out.push("compaction");
|
|
64
|
+
else if (forever) out.push("forever");
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function narrowKeep(base: readonly Horizon[], over: readonly Horizon[]): Horizon[] {
|
|
70
|
+
return canonicalKeep([...base, ...over]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Remainder size, smallest first: none, a one-line stub, a summary, then `head` by length. */
|
|
74
|
+
export function leaveRank(leave: Leave): number {
|
|
75
|
+
if (leave === "none") return 0;
|
|
76
|
+
if (leave === "stub") return 80;
|
|
77
|
+
if (leave === "summary") return 400;
|
|
78
|
+
return leave.head;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function narrowLeave(base: Leave | undefined, over: Leave | undefined, kind: string | null): Leave | undefined {
|
|
82
|
+
if (over === undefined) return base;
|
|
83
|
+
if (over === "none" && kind !== null && NONE_FORBIDDEN_KINDS.has(kind)) return base;
|
|
84
|
+
if (base === undefined) return over;
|
|
85
|
+
return leaveRank(over) < leaveRank(base) ? over : base;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** True when `over` shortens `base` in at least one respect. */
|
|
89
|
+
export function narrows(base: RuleInput, over: RuleInput, kind: string | null): boolean {
|
|
90
|
+
const overKeep = horizonList(over.keep);
|
|
91
|
+
if (overKeep.length > 0) {
|
|
92
|
+
const baseKeep = horizonList(base.keep);
|
|
93
|
+
if (baseKeep.length === 0 || keepRank(overKeep) < keepRank(baseKeep)) return true;
|
|
94
|
+
if (overKeep.some((h) => typeof h === "object" && "newest" in h)) return true;
|
|
95
|
+
}
|
|
96
|
+
if (over.leave !== undefined && narrowLeave(base.leave, over.leave, kind) !== base.leave) return true;
|
|
97
|
+
if (over.minChars !== undefined && (base.minChars === undefined || over.minChars < base.minChars)) return true;
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** `base ∧ over`. The result never lives longer than `base`. */
|
|
102
|
+
export function narrowRule(base: RuleInput, over: RuleInput, kind: string | null): RuleInput {
|
|
103
|
+
const keep = narrowKeep(horizonList(base.keep), horizonList(over.keep));
|
|
104
|
+
const leave = narrowLeave(base.leave, over.leave, kind);
|
|
105
|
+
const minChars =
|
|
106
|
+
over.minChars === undefined ? base.minChars : Math.min(base.minChars ?? Number.POSITIVE_INFINITY, over.minChars);
|
|
107
|
+
let onError = base.onError;
|
|
108
|
+
if (over.onError != null) {
|
|
109
|
+
onError =
|
|
110
|
+
base.onError == null
|
|
111
|
+
? over.onError
|
|
112
|
+
: {
|
|
113
|
+
keep: narrowKeep(horizonList(base.onError.keep), horizonList(over.onError.keep)),
|
|
114
|
+
leave: narrowLeave(base.onError.leave, over.onError.leave, "error") ?? base.onError.leave,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
...(keep.length === 0 ? {} : { keep: keep.length === 1 ? keep[0]! : keep }),
|
|
119
|
+
...(leave === undefined ? {} : { leave }),
|
|
120
|
+
...(minChars === undefined || !Number.isFinite(minChars) ? {} : { minChars }),
|
|
121
|
+
...(onError === undefined ? {} : { onError }),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an expired item leaves behind. Every remainder is deterministic: the
|
|
3
|
+
* same sealed receipt always renders to the same bytes (no timestamps, no
|
|
4
|
+
* ordering-dependent JSON), so a stub never moves the cached prefix.
|
|
5
|
+
*/
|
|
6
|
+
import type { Leave } from "./schema.js";
|
|
7
|
+
|
|
8
|
+
export const REF_CHARS = 8;
|
|
9
|
+
|
|
10
|
+
export function jobRef(uuid: string): string {
|
|
11
|
+
return `job:${uuid.slice(0, REF_CHARS)}`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** A node that is not yet materialized in a document has no uuid; it simply has no ref. */
|
|
15
|
+
export function refOfNode(node: { readonly uuid: string }): string | undefined {
|
|
16
|
+
try {
|
|
17
|
+
return jobRef(node.uuid);
|
|
18
|
+
} catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function visualRef(id: string): string {
|
|
24
|
+
return `visual:${id}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function humanSize(chars: number): string {
|
|
28
|
+
if (chars < 1024) return `${chars} B`;
|
|
29
|
+
if (chars < 1024 * 1024) return `${(chars / 1024).toFixed(1)} KB`;
|
|
30
|
+
return `${(chars / (1024 * 1024)).toFixed(1)} MB`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function oneLine(text: string, max: number): string {
|
|
34
|
+
const flat = text.replaceAll(/\s+/g, " ").trim();
|
|
35
|
+
return flat.length <= max ? flat : `${flat.slice(0, max)}…`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type StubFacts = {
|
|
39
|
+
/** Wire or program name. */
|
|
40
|
+
readonly tool: string;
|
|
41
|
+
readonly kind: string;
|
|
42
|
+
readonly ref: string;
|
|
43
|
+
readonly args: Readonly<Record<string, unknown>> | null;
|
|
44
|
+
/** The full painted observation the elision replaces. */
|
|
45
|
+
readonly full: string;
|
|
46
|
+
readonly ok: boolean;
|
|
47
|
+
readonly value: unknown;
|
|
48
|
+
readonly code: string | undefined;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function argString(args: StubFacts["args"], ...keys: string[]): string {
|
|
52
|
+
for (const key of keys) {
|
|
53
|
+
const value = args?.[key];
|
|
54
|
+
if (typeof value === "string" && value !== "") return value;
|
|
55
|
+
}
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function lineCount(text: string): number {
|
|
60
|
+
if (text === "") return 0;
|
|
61
|
+
return text.split("\n").length;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function identityOf(f: StubFacts): string {
|
|
65
|
+
const size = humanSize(f.full.length);
|
|
66
|
+
switch (f.kind) {
|
|
67
|
+
case "tool.read": {
|
|
68
|
+
const target = argString(f.args, "path", "file_path", "pattern") || "?";
|
|
69
|
+
return `${oneLine(target, 120)}, ${lineCount(f.full)} lines, ${size}`;
|
|
70
|
+
}
|
|
71
|
+
case "tool.search": {
|
|
72
|
+
const needle = argString(f.args, "pattern", "query");
|
|
73
|
+
const where = argString(f.args, "path", "cwd");
|
|
74
|
+
return `"${oneLine(needle, 80)}"${where === "" ? "" : ` in ${oneLine(where, 80)}`}, ${lineCount(f.full)} lines`;
|
|
75
|
+
}
|
|
76
|
+
case "tool.web.search": {
|
|
77
|
+
const urls = [...f.full.matchAll(/https?:\/\/[^\s"'<>)\]]+/g)].map((m) => m[0]);
|
|
78
|
+
const unique = [...new Set(urls)];
|
|
79
|
+
const shown = unique.slice(0, 3).join(", ");
|
|
80
|
+
return `"${oneLine(argString(f.args, "query"), 80)}", ${unique.length} urls${shown === "" ? "" : `: ${shown}${unique.length > 3 ? "…" : ""}`}`;
|
|
81
|
+
}
|
|
82
|
+
case "tool.web.fetch":
|
|
83
|
+
return `${oneLine(argString(f.args, "url"), 160)}, ${size}`;
|
|
84
|
+
case "tool.program":
|
|
85
|
+
return `${oneLine(argString(f.args, "expr", "code", "program"), 80)} → ${size}`;
|
|
86
|
+
default: {
|
|
87
|
+
const target = argString(f.args, "path", "file_path", "pattern", "query", "command", "url", "name");
|
|
88
|
+
return target === "" ? size : `${oneLine(target, 80)}, ${size}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function recallHint(f: StubFacts): string {
|
|
94
|
+
return f.kind === "tool.read" ? `re-read or recall ${f.ref}` : `recall ${f.ref}`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function stubLine(f: StubFacts): string {
|
|
98
|
+
return `[${f.tool} elided: ${identityOf(f)} — ${recallHint(f)}]`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function exitCodeOf(value: unknown): number | null {
|
|
102
|
+
if (value == null || typeof value !== "object") return null;
|
|
103
|
+
const code = (value as Record<string, unknown>).exitCode;
|
|
104
|
+
return typeof code === "number" ? code : null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function tailLines(f: StubFacts, count: number): string {
|
|
108
|
+
const rec = f.value != null && typeof f.value === "object" ? (f.value as Record<string, unknown>) : null;
|
|
109
|
+
const stdout = typeof rec?.stdout === "string" ? rec.stdout : "";
|
|
110
|
+
const stderr = typeof rec?.stderr === "string" ? rec.stderr : "";
|
|
111
|
+
const text = rec === null || (stdout === "" && stderr === "") ? f.full : `${stdout}\n${stderr}`;
|
|
112
|
+
const lines = text
|
|
113
|
+
.split("\n")
|
|
114
|
+
.map((line) => line.trimEnd())
|
|
115
|
+
.filter((line) => line !== "");
|
|
116
|
+
return lines
|
|
117
|
+
.slice(-count)
|
|
118
|
+
.map((line) => oneLine(line, 160))
|
|
119
|
+
.join(" | ");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function shellSummary(f: StubFacts): string {
|
|
123
|
+
const command = oneLine(argString(f.args, "command"), 80);
|
|
124
|
+
const exit = exitCodeOf(f.value);
|
|
125
|
+
const status = exit === null ? (f.ok ? "ok" : "failed") : `exit ${exit}`;
|
|
126
|
+
const tail = tailLines(f, 5);
|
|
127
|
+
return `[shell \`${command}\` ${status}, ${humanSize(f.full.length)} elided${tail === "" ? "" : `; tail: ${tail}`} — recall ${f.ref}]`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function errorSummary(f: StubFacts): string {
|
|
131
|
+
const first = oneLine(f.full.split("\n").find((line) => line.trim() !== "") ?? "", 200);
|
|
132
|
+
const code = f.code === undefined || f.code === "" ? "" : ` (${f.code})`;
|
|
133
|
+
return `[${f.tool} failed${code}: ${first} — recall ${f.ref}]`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function genericSummary(f: StubFacts): string {
|
|
137
|
+
return `${oneLine(f.full, 200)} [${f.tool} elided, ${humanSize(f.full.length)} — recall ${f.ref}]`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** The remainder of a tool result whose horizon has passed. */
|
|
141
|
+
export function toolRemainder(leave: Leave, f: StubFacts, failed: boolean): string {
|
|
142
|
+
if (leave === "none" || leave === "stub") return stubLine(f);
|
|
143
|
+
if (leave === "summary") {
|
|
144
|
+
if (f.kind === "tool.shell") return shellSummary(f);
|
|
145
|
+
if (failed) return errorSummary(f);
|
|
146
|
+
return genericSummary(f);
|
|
147
|
+
}
|
|
148
|
+
return `${f.full.slice(0, leave.head)}\n${stubLine(f)}`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** The remainder of a prelude cell (steer, note, notification, system note). `null` leaves nothing. */
|
|
152
|
+
export function textRemainder(leave: Leave, kind: string, text: string): string | null {
|
|
153
|
+
if (leave === "none") return null;
|
|
154
|
+
if (leave === "stub") return `[${kind} elided: ${text.length} chars]`;
|
|
155
|
+
if (leave === "summary") return `${oneLine(text, 200)} [${kind} elided, ${text.length} chars]`;
|
|
156
|
+
return `${text.slice(0, leave.head)} [${kind} elided, ${text.length} chars]`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Large string fields of a call's arguments become a stub; the JSON stays valid. */
|
|
160
|
+
export function elideArgs(
|
|
161
|
+
args: Readonly<Record<string, unknown>>,
|
|
162
|
+
ref: string,
|
|
163
|
+
minChars: number,
|
|
164
|
+
): { readonly json: string; readonly elided: boolean } {
|
|
165
|
+
const out: Record<string, unknown> = {};
|
|
166
|
+
let elided = false;
|
|
167
|
+
const total = JSON.stringify(args).length;
|
|
168
|
+
for (const [key, value] of Object.entries(args)) {
|
|
169
|
+
if (total >= minChars && typeof value === "string" && value.length > 200) {
|
|
170
|
+
out[key] = `[elided: ${lineCount(value)} lines, ${humanSize(value.length)} — recall ${ref}]`;
|
|
171
|
+
elided = true;
|
|
172
|
+
} else {
|
|
173
|
+
out[key] = value;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return { json: JSON.stringify(out), elided };
|
|
177
|
+
}
|