one-code-extension 0.4.1 → 0.6.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/README.md +16 -5
- package/agents/general-purpose.md +2 -2
- package/docs/guide/README.md +2 -1
- package/docs/guide/bring-your-claude-code-setup.md +60 -9
- package/docs/guide/configuration.md +48 -14
- package/docs/guide/differences-from-claude-code.md +40 -28
- package/docs/guide/doctor.md +20 -13
- package/docs/guide/hooks.md +18 -3
- package/docs/guide/installation.md +26 -4
- package/docs/guide/permissions-modes-and-auto-mode.md +225 -49
- package/docs/guide/providers-and-models.md +137 -54
- package/docs/guide/reference.md +27 -15
- package/docs/guide/sessions-and-context.md +69 -16
- package/docs/guide/skills-plugins-and-mcp.md +57 -20
- package/docs/guide/subagents-and-workflows.md +95 -29
- package/docs/guide/tasks-and-background-work.md +101 -26
- package/docs/guide/terminal-interface.md +24 -12
- package/docs/guide/tools.md +46 -5
- package/docs/guide/troubleshooting.md +13 -9
- package/docs/guide/windows.md +58 -31
- package/extensions/artifacts/gallery.ts +227 -0
- package/extensions/artifacts/index.ts +288 -0
- package/extensions/artifacts/store.ts +570 -0
- package/extensions/artifacts/viewer.ts +199 -0
- package/extensions/ask-user/description.ts +67 -0
- package/extensions/ask-user/dialogs.ts +80 -0
- package/extensions/ask-user/index.ts +37 -33
- package/extensions/ask-user/questions.ts +32 -7
- package/extensions/ask-user/widget.ts +45 -25
- package/extensions/auto-mode/actions.ts +6 -0
- package/extensions/auto-mode/cache.ts +88 -0
- package/extensions/auto-mode/classifier-prompt.ts +5 -4
- package/extensions/auto-mode/classifier.ts +290 -65
- package/extensions/auto-mode/config.ts +72 -20
- package/extensions/auto-mode/decision-log.ts +2 -0
- package/extensions/auto-mode/defaults.ts +1 -1
- package/extensions/auto-mode/denials.ts +124 -0
- package/extensions/auto-mode/git-checkout-programs.ts +187 -0
- package/extensions/auto-mode/git-status-meta.ts +159 -0
- package/extensions/auto-mode/history.ts +189 -0
- package/extensions/auto-mode/instructions.ts +58 -52
- package/extensions/auto-mode/model-select.ts +159 -134
- package/extensions/auto-mode/paths.ts +57 -5
- package/extensions/auto-mode/pause.ts +57 -2
- package/extensions/auto-mode/prompt.ts +37 -21
- package/extensions/auto-mode/read-only-options.ts +724 -0
- package/extensions/auto-mode/resolved-paths-meta.ts +133 -0
- package/extensions/auto-mode/rules.ts +18 -1
- package/extensions/auto-mode/safety-floor.ts +361 -18
- package/extensions/auto-mode/setup-run.ts +20 -14
- package/extensions/auto-mode/shell-analysis.ts +764 -490
- package/extensions/auto-mode/shell-parse.ts +885 -0
- package/extensions/auto-mode/system-note.ts +33 -0
- package/extensions/auto-mode/transcript.ts +80 -51
- package/extensions/background/cron.ts +642 -0
- package/extensions/background/index.ts +614 -248
- package/extensions/background/loop-fire.ts +173 -0
- package/extensions/background/loop-preamble.ts +59 -0
- package/extensions/background/loop-skill.ts +163 -0
- package/extensions/background/monitor-batch.ts +53 -0
- package/extensions/background/noop-fold.ts +128 -0
- package/extensions/background/switch-guard.ts +56 -0
- package/extensions/background/wakeup.ts +178 -55
- package/extensions/bash/background.ts +53 -17
- package/extensions/bash/child.ts +7 -0
- package/extensions/bash/description.ts +188 -0
- package/extensions/bash/guards.ts +15 -67
- package/extensions/bash/index.ts +66 -35
- package/extensions/branding/compaction-keep.ts +63 -0
- package/extensions/branding/declined.ts +22 -0
- package/extensions/branding/index.ts +133 -9
- package/extensions/branding/prompt-editor.ts +53 -6
- package/extensions/branding/queued-edit.ts +31 -0
- package/extensions/branding/replaced-builtins.ts +68 -0
- package/extensions/branding/startup.ts +33 -71
- package/extensions/btw/index.ts +250 -78
- package/extensions/btw/panel.ts +228 -100
- package/extensions/btw/prompt.ts +41 -4
- package/extensions/cache-marks/index.ts +42 -0
- package/extensions/claude-compat/index.ts +7 -11
- package/extensions/claude-context/index.ts +436 -63
- package/extensions/compaction/cut.ts +157 -0
- package/extensions/compaction/index.ts +219 -75
- package/extensions/compaction/kept-thinking.ts +62 -0
- package/extensions/compaction/prompt.ts +15 -12
- package/extensions/context-budget/budget.ts +16 -2
- package/extensions/context-budget/index.ts +35 -15
- package/extensions/context-management/index.ts +36 -28
- package/extensions/doctor/build.ts +59 -8
- package/extensions/doctor/builtins.ts +84 -0
- package/extensions/doctor/cli.ts +7 -1
- package/extensions/doctor/compat.ts +88 -23
- package/extensions/doctor/dependencies.ts +41 -5
- package/extensions/doctor/fix-prompt.ts +9 -2
- package/extensions/doctor/index.ts +102 -58
- package/extensions/doctor/models.ts +102 -63
- package/extensions/doctor/presets.ts +42 -27
- package/extensions/doctor/report.ts +19 -2
- package/extensions/doctor/viewer.ts +49 -27
- package/extensions/effort/index.ts +141 -25
- package/extensions/effort/settings.ts +21 -0
- package/extensions/effort/slider.ts +24 -20
- package/extensions/exit/index.ts +32 -1
- package/extensions/file-tracker/index.ts +420 -42
- package/extensions/file-tracker/replay.ts +137 -24
- package/extensions/file-tracker/restore.ts +66 -0
- package/extensions/file-tracker/results.ts +66 -0
- package/extensions/file-tracker/shell-reads.ts +211 -0
- package/extensions/file-tracker/tracker.ts +45 -15
- package/extensions/footer/footer-line.ts +45 -24
- package/extensions/footer/index.ts +47 -2
- package/extensions/footer/pr.ts +34 -5
- package/extensions/hooks/compaction.ts +7 -0
- package/extensions/hooks/executor.ts +32 -30
- package/extensions/hooks/index.ts +209 -58
- package/extensions/hooks/matcher.ts +3 -0
- package/extensions/hooks/prompt-context.ts +59 -0
- package/extensions/hooks/protocol.ts +41 -3
- package/extensions/hooks/settings.ts +50 -19
- package/extensions/hooks/subagent-bridge.ts +2 -0
- package/extensions/hooks/trust.ts +26 -12
- package/extensions/idle-compact/index.ts +119 -0
- package/extensions/idle-compact/policy.ts +143 -0
- package/extensions/init/index.ts +11 -10
- package/extensions/init/prompt.ts +25 -32
- package/extensions/interrupted/index.ts +13 -1
- package/extensions/kept-thinking/index.ts +27 -0
- package/extensions/ledger/index.ts +46 -0
- package/extensions/ledger/wire.ts +154 -0
- package/extensions/lib/agent-cron.ts +146 -0
- package/extensions/lib/agent-loader.ts +18 -3
- package/extensions/lib/agent-view.ts +85 -0
- package/extensions/lib/anthropic-auth.ts +98 -0
- package/extensions/lib/anthropic-payload.ts +82 -1
- package/extensions/lib/anthropic-server-call.ts +230 -0
- package/extensions/lib/anthropic-server-tools.ts +485 -0
- package/extensions/lib/app-launch.mjs +94 -0
- package/extensions/lib/argument-hints.ts +190 -0
- package/extensions/lib/atomic-write.ts +6 -2
- package/extensions/lib/auto-memory.ts +75 -0
- package/extensions/lib/bash-parser.ts +84 -0
- package/extensions/lib/btw-fork.ts +93 -0
- package/extensions/lib/child-extensions.ts +52 -0
- package/extensions/lib/child-writes.ts +45 -0
- package/extensions/lib/claude-context.ts +515 -100
- package/extensions/lib/claude-external-includes.ts +68 -0
- package/extensions/lib/claude-id.ts +22 -0
- package/extensions/lib/claude-rules.ts +323 -0
- package/extensions/lib/claude-settings.ts +76 -4
- package/extensions/lib/compaction-boundary.ts +36 -0
- package/extensions/lib/compaction-keep.mjs +83 -0
- package/extensions/lib/config-mode.ts +112 -0
- package/extensions/lib/consent-dialogs.ts +63 -0
- package/extensions/lib/consent-preview.ts +5 -1
- package/extensions/lib/consent-stores.ts +48 -0
- package/extensions/lib/context-facts.ts +97 -0
- package/extensions/lib/covered-messages.ts +23 -0
- package/extensions/lib/deferred.ts +359 -25
- package/extensions/lib/dock-rows.ts +60 -0
- package/extensions/lib/empty-tool-result.ts +27 -0
- package/extensions/lib/environment-block.ts +76 -0
- package/extensions/lib/fetch-timeout.ts +24 -6
- package/extensions/{system-prompt → lib}/git-status.ts +51 -13
- package/extensions/lib/git.ts +75 -13
- package/extensions/lib/grammars/LICENSE-tree-sitter-bash +21 -0
- package/extensions/lib/grammars/README.md +2 -0
- package/extensions/lib/grammars/tree-sitter-bash.wasm +0 -0
- package/extensions/lib/guide-docs.ts +45 -0
- package/extensions/lib/headless-output.ts +46 -0
- package/extensions/lib/hook-gate.ts +7 -7
- package/extensions/lib/interrupt.ts +20 -4
- package/extensions/lib/key-input.ts +455 -0
- package/extensions/lib/keys.ts +14 -1
- package/extensions/lib/ledger/fold-memo.ts +49 -0
- package/extensions/lib/ledger/fold.ts +265 -0
- package/extensions/lib/ledger/layout.ts +72 -0
- package/extensions/lib/ledger/plan.ts +102 -0
- package/extensions/lib/ledger/records.ts +276 -0
- package/extensions/lib/ledger/state.ts +47 -0
- package/extensions/lib/ledger/validate.ts +141 -0
- package/extensions/lib/ledger/wire.ts +632 -0
- package/extensions/lib/local-command.ts +71 -19
- package/extensions/lib/mcp-overrides.ts +1 -1
- package/extensions/lib/mcp-share.ts +46 -0
- package/extensions/lib/memory-content.ts +146 -0
- package/extensions/lib/memory-index.ts +18 -0
- package/extensions/lib/memory.ts +134 -123
- package/extensions/lib/model-catalog/huggingface.json +178 -0
- package/extensions/lib/model-catalog/models-dev.json +18533 -0
- package/extensions/lib/model-catalog/openrouter.json +5050 -0
- package/extensions/lib/model-catalog-data.ts +513 -0
- package/extensions/lib/model-catalog.ts +462 -0
- package/extensions/lib/model-choice-warnings.ts +137 -0
- package/extensions/lib/model-pairings.ts +152 -0
- package/extensions/{auto-mode → lib}/model-picker.ts +26 -43
- package/extensions/lib/model-policy.ts +112 -15
- package/extensions/lib/model-tier.ts +283 -355
- package/extensions/lib/model-unusable.ts +1 -1
- package/extensions/lib/newer-model.ts +100 -0
- package/extensions/lib/notices.ts +87 -0
- package/extensions/lib/notifications.ts +357 -73
- package/extensions/lib/one-code-settings.ts +74 -8
- package/extensions/lib/open-browser.ts +63 -0
- package/extensions/lib/openrouter-generation.ts +94 -0
- package/extensions/lib/operation-deadline.ts +30 -0
- package/extensions/lib/original-command.ts +4 -4
- package/extensions/lib/package-version.ts +1 -1
- package/extensions/lib/panel-focus.ts +134 -0
- package/extensions/lib/paths.ts +17 -2
- package/extensions/lib/permission-gate.ts +72 -6
- package/extensions/lib/persisted-output.ts +60 -8
- package/extensions/lib/pi-ai-estimate.ts +19 -3
- package/extensions/lib/pi-version.ts +38 -2
- package/extensions/lib/plan-mode-channels.ts +42 -5
- package/extensions/lib/plugins.ts +26 -17
- package/extensions/lib/powershell-parse-script.ts +208 -0
- package/extensions/lib/powershell-parser.ts +344 -0
- package/extensions/lib/previous-mark.ts +101 -0
- package/extensions/lib/process-state.ts +48 -0
- package/extensions/lib/process-tree.ts +132 -8
- package/extensions/lib/prompt-options.ts +82 -0
- package/extensions/lib/queued-delivery.ts +44 -0
- package/extensions/lib/reminders.ts +370 -358
- package/extensions/lib/replaced-builtins.mjs +199 -0
- package/extensions/lib/replay-call.ts +70 -0
- package/extensions/lib/request-replay.ts +547 -0
- package/extensions/lib/scratchpad.ts +81 -14
- package/extensions/lib/send-now-channel.ts +7 -0
- package/extensions/lib/session-model-tier.ts +51 -0
- package/extensions/lib/session-work.ts +64 -0
- package/extensions/lib/settings-channels.ts +4 -4
- package/extensions/lib/shell-exit-semantics.ts +170 -0
- package/extensions/lib/shell-quote.ts +11 -0
- package/extensions/lib/shell-result.ts +70 -0
- package/extensions/lib/shell-spawn.ts +70 -6
- package/extensions/lib/shell-tool.ts +75 -25
- package/extensions/lib/side-call-cache.ts +124 -0
- package/extensions/lib/side-call-run.ts +96 -0
- package/extensions/lib/side-call-usage.ts +38 -0
- package/extensions/lib/side-call.ts +24 -1
- package/extensions/lib/single-flight.ts +18 -0
- package/extensions/lib/skill-body.ts +42 -0
- package/extensions/lib/skill-scan.ts +63 -24
- package/extensions/lib/spill-file.ts +140 -0
- package/extensions/lib/subagent-handback.ts +112 -0
- package/extensions/lib/system-role.ts +156 -0
- package/extensions/lib/terminal-text.ts +114 -0
- package/extensions/lib/text-width.ts +47 -16
- package/extensions/lib/timer-ops.ts +20 -0
- package/extensions/lib/tool-additions.ts +129 -0
- package/extensions/lib/tool-call-corruption.ts +134 -0
- package/extensions/lib/tool-path.ts +66 -0
- package/extensions/lib/tool-variants.ts +69 -0
- package/extensions/lib/tui-render.ts +255 -27
- package/extensions/lib/turn-budget-layout.ts +159 -0
- package/extensions/lib/update-check.mjs +15 -2
- package/extensions/lib/usage-bus.ts +1 -1
- package/extensions/lib/user-denial.ts +38 -0
- package/extensions/lib/workspace-channel.ts +16 -0
- package/extensions/lib/worktree-channel.ts +31 -3
- package/extensions/lib/worktree-isolation.ts +40 -10
- package/extensions/lsp/client.ts +8 -9
- package/extensions/lsp/index.ts +76 -12
- package/extensions/lsp/keep-alive.ts +1 -1
- package/extensions/lsp/trust.ts +119 -0
- package/extensions/lsp/watcher.ts +1 -1
- package/extensions/mcp/announce.ts +90 -43
- package/extensions/mcp/client.ts +161 -48
- package/extensions/mcp/config.ts +132 -8
- package/extensions/mcp/discovery.ts +19 -0
- package/extensions/mcp/index.ts +220 -121
- package/extensions/mcp/oauth/browser.ts +38 -17
- package/extensions/mcp/oauth/flow.ts +25 -17
- package/extensions/mcp/oauth/provider.ts +14 -8
- package/extensions/mcp/oauth/store.ts +34 -16
- package/extensions/mcp/panel/keys.ts +12 -11
- package/extensions/mcp/panel/render.ts +9 -6
- package/extensions/mcp/schema.ts +104 -5
- package/extensions/mcp/trust.ts +164 -73
- package/extensions/memory/entries.ts +23 -14
- package/extensions/memory/index.ts +134 -28
- package/extensions/memory/open-external.ts +33 -18
- package/extensions/memory/panel.ts +135 -26
- package/extensions/model-default/index.ts +86 -19
- package/extensions/newer-model/index.ts +31 -0
- package/extensions/notebook/description.ts +18 -0
- package/extensions/notebook/index.ts +6 -5
- package/extensions/notebook/notebook.ts +1 -1
- package/extensions/permissions/index.ts +1426 -398
- package/extensions/permissions/matcher.ts +425 -74
- package/extensions/permissions/modes.ts +11 -4
- package/extensions/permissions/panel/host.ts +130 -0
- package/extensions/permissions/panel/keys.ts +48 -0
- package/extensions/permissions/panel/render.ts +450 -0
- package/extensions/permissions/panel/state.ts +550 -0
- package/extensions/permissions/powershell-cmdlets.ts +198 -0
- package/extensions/permissions/powershell-paths.ts +197 -0
- package/extensions/permissions/powershell-rules.ts +207 -280
- package/extensions/permissions/powershell-tree.ts +557 -0
- package/extensions/permissions/project-trust.ts +27 -11
- package/extensions/permissions/protected-paths.ts +14 -2
- package/extensions/permissions/session-grant.ts +6 -0
- package/extensions/permissions/settings.ts +166 -31
- package/extensions/permissions/subagent-gate.ts +25 -0
- package/extensions/permissions/workspace.ts +78 -0
- package/extensions/plan-mode/index.ts +276 -92
- package/extensions/plan-mode/reminder.ts +89 -21
- package/extensions/plan-mode/run-state.ts +26 -0
- package/extensions/plan-mode/texts.ts +177 -0
- package/extensions/plan-mode/viewer.ts +92 -27
- package/extensions/plugins/counts.ts +3 -3
- package/extensions/plugins/index.ts +64 -46
- package/extensions/plugins/install/install.ts +16 -0
- package/extensions/plugins/marketplace/sync.ts +9 -3
- package/extensions/plugins/marketplace/types.ts +3 -1
- package/extensions/plugins/panel/keys.ts +21 -24
- package/extensions/plugins/panel/render.ts +12 -6
- package/extensions/plugins/shell-expand.ts +107 -0
- package/extensions/plugins/template.ts +32 -15
- package/extensions/powershell/child.ts +7 -0
- package/extensions/powershell/description.ts +38 -6
- package/extensions/powershell/guards.ts +1 -1
- package/extensions/powershell/index.ts +14 -7
- package/extensions/recap/index.ts +73 -71
- package/extensions/recap/prompt.ts +2 -2
- package/extensions/recap/scheduler.ts +3 -5
- package/extensions/search-tools/grep-merge.ts +39 -0
- package/extensions/search-tools/index.ts +0 -0
- package/extensions/send-now/chord.ts +62 -0
- package/extensions/send-now/index.ts +133 -0
- package/extensions/session-title/index.ts +3 -0
- package/extensions/session-title/title.ts +4 -1
- package/extensions/skill/announce.ts +30 -0
- package/extensions/skill/code-review.ts +97 -0
- package/extensions/skill/index.ts +469 -132
- package/extensions/skill/invoke.ts +118 -75
- package/extensions/skill/listing.ts +133 -9
- package/extensions/skill/panel/keys.ts +15 -16
- package/extensions/skill/panel/render.ts +5 -2
- package/extensions/skill/panel/state.ts +12 -1
- package/extensions/subagents/agent-args.ts +39 -0
- package/extensions/subagents/agent-description.ts +132 -0
- package/extensions/subagents/agents.ts +146 -31
- package/extensions/subagents/default-model.ts +2 -3
- package/extensions/subagents/delegation-steer.ts +4 -4
- package/extensions/subagents/fork-cache.ts +82 -0
- package/extensions/subagents/guide-agent.ts +189 -0
- package/extensions/subagents/hand-back-review.ts +3 -0
- package/extensions/subagents/index.ts +1594 -852
- package/extensions/subagents/live-runs.ts +26 -6
- package/extensions/subagents/model-select.ts +38 -25
- package/extensions/subagents/outcome.ts +5 -2
- package/extensions/subagents/panel-keys.ts +73 -31
- package/extensions/subagents/panel-render.ts +120 -96
- package/extensions/subagents/panel-widget.ts +60 -89
- package/extensions/subagents/parent-mode.ts +50 -0
- package/extensions/subagents/pending-claim.ts +18 -1
- package/extensions/subagents/runner.ts +135 -80
- package/extensions/subagents/runs.ts +44 -5
- package/extensions/subagents/send-to-main-tool.ts +1 -1
- package/extensions/subagents/session-turns.ts +32 -8
- package/extensions/subagents/shell-panel.ts +36 -178
- package/extensions/subagents/tasks-dialog.ts +170 -0
- package/extensions/subagents/viewport-mirror.ts +95 -0
- package/extensions/subagents/worktree.ts +57 -13
- package/extensions/system-prompt/environment.ts +19 -19
- package/extensions/system-prompt/idle-turn.ts +65 -0
- package/extensions/system-prompt/index.ts +165 -47
- package/extensions/system-prompt/template.ts +34 -51
- package/extensions/system-prompt/tiers/common.ts +23 -64
- package/extensions/system-prompt/tiers/frontier.ts +32 -11
- package/extensions/system-prompt/tiers/low.ts +67 -45
- package/extensions/system-prompt/tiers/mid.ts +96 -38
- package/extensions/system-reminder/index.ts +204 -70
- package/extensions/tasks/descriptions.ts +190 -0
- package/extensions/tasks/index.ts +120 -41
- package/extensions/tasks/store.ts +83 -16
- package/extensions/tool-call-corruption/child.ts +7 -0
- package/extensions/tool-call-corruption/index.ts +237 -0
- package/extensions/tool-search/index.ts +366 -144
- package/extensions/tool-style/index.ts +68 -10
- package/extensions/tool-style/write-description.ts +40 -0
- package/extensions/tool-style/write-render.ts +237 -0
- package/extensions/turn-duration/index.ts +7 -3
- package/extensions/turn-duration/line.ts +47 -4
- package/extensions/web/backends.ts +6 -9
- package/extensions/web/description.ts +50 -0
- package/extensions/web/index.ts +118 -53
- package/extensions/web/native-call.ts +15 -0
- package/extensions/web/native-results.ts +41 -0
- package/extensions/web-fetch/description.ts +42 -0
- package/extensions/web-fetch/extract.ts +53 -6
- package/extensions/web-fetch/index.ts +125 -76
- package/extensions/web-fetch/page-content.ts +19 -0
- package/extensions/web-fetch/response.ts +49 -0
- package/extensions/web-fetch/summarize.ts +9 -10
- package/extensions/workflow/agent-session.ts +108 -18
- package/extensions/workflow/args.ts +24 -0
- package/extensions/workflow/description.ts +67 -0
- package/extensions/workflow/globals.ts +17 -3
- package/extensions/workflow/index.ts +157 -162
- package/extensions/workflow/records.ts +1 -0
- package/extensions/workflow/run-manager.ts +33 -6
- package/extensions/workflow/saved-workflows.ts +3 -2
- package/extensions/workflow/types.ts +22 -1
- package/extensions/workflow/viewer.ts +54 -24
- package/extensions/workflow/widget.ts +20 -0
- package/extensions/worktree/descriptions.ts +91 -0
- package/extensions/worktree/guards.ts +316 -54
- package/extensions/worktree/index.ts +162 -44
- package/extensions/worktree/powershell-guards.ts +167 -0
- package/extensions/worktree/rewrite.ts +14 -16
- package/package.json +21 -7
- package/skills/artifact-design/SKILL.md +85 -0
- package/skills/code-review/SKILL.md +20 -20
- package/skills/code-review/cells/arguments-and-flags.md +19 -0
- package/skills/code-review/cells/high-3x5-recall-verify.md +137 -0
- package/skills/code-review/cells/high-8-inline.md +122 -0
- package/skills/code-review/cells/low-1-pass-max4.md +27 -0
- package/skills/code-review/cells/low-1-pass-min-files-4.md +28 -0
- package/skills/code-review/cells/max-5x5-verify-sweep.md +162 -0
- package/skills/code-review/cells/medium-3x5-verify.md +132 -0
- package/skills/code-review/cells/minimal-prompt.md +32 -0
- package/skills/code-review/cells/xhigh-10-inline-sweep.md +149 -0
- package/skills/code-review/cells/xhigh-5x5-verify-sweep.md +162 -0
- package/skills/fewer-permission-prompts/SKILL.md +1 -1
- package/skills/loop/SKILL.md +11 -0
- package/skills/security-review/SKILL.md +2 -5
- package/skills/simplify/SKILL.md +7 -5
- package/skills/workflow-authoring/SKILL.md +143 -0
- package/themes/onecode-light.json +1 -1
- package/themes/onecode.json +1 -1
- package/types/app.d.ts +58 -0
- package/types/community-packages.d.ts +26 -1
- package/extensions/auto-mode/recoverability.ts +0 -229
- package/extensions/lib/capability-index.ts +0 -466
- package/extensions/lib/model-facts.generated.json +0 -2675
- package/extensions/lib/model-facts.ts +0 -162
- package/extensions/tool-search/announce.ts +0 -42
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fold: everything the ledger knows, derived from the current branch's
|
|
3
|
+
* entries alone (design.md sections 3 to 5). Resume, `/reload`, `/fork` and
|
|
4
|
+
* `/tree` need no restore code because each folds a different branch.
|
|
5
|
+
*
|
|
6
|
+
* Rules: told facts are a union within the
|
|
7
|
+
* epoch and start empty at its start; pending items are those no request
|
|
8
|
+
* delivered; pi's `usage` entries (a cache warm) are skipped. An epoch starts
|
|
9
|
+
* at the first request, after a compaction entry or an `epoch` record, and at
|
|
10
|
+
* a request whose identity (api, provider, model, auth) differs.
|
|
11
|
+
*
|
|
12
|
+
* Delivered means the model saw it and the branch kept it. A request counts
|
|
13
|
+
* (its consumed pending ids and the told records written with it, and it
|
|
14
|
+
* becomes the base the next request extends) only when its own reply follows
|
|
15
|
+
* it: the first message after the request record, before any other request,
|
|
16
|
+
* epoch or compaction, is an assistant message that did not end in an error
|
|
17
|
+
* or an abort and that pi did not omit later (a `context_edit` with no
|
|
18
|
+
* replacement: a recoverable length stop, a failed attempt before a retry).
|
|
19
|
+
* A request with no reply (the turn in flight, a process that died
|
|
20
|
+
* mid-stream, a re-send that replaced it, a btw fork copied mid-stream)
|
|
21
|
+
* counts nothing, so its pending items are delivered again.
|
|
22
|
+
* A request that does not count takes back what it changed: the `epoch`
|
|
23
|
+
* record written right before it and an identity change it made, so a failed
|
|
24
|
+
* model hop leaves the epoch it left.
|
|
25
|
+
*
|
|
26
|
+
* The rebuilt request shares its elements with the branch's entries: clone
|
|
27
|
+
* before mutating (`spliceRequest` does).
|
|
28
|
+
*
|
|
29
|
+
* Pure: no pi imports.
|
|
30
|
+
*/
|
|
31
|
+
import { type Coverage, type EntryLike, type EpochCause, type PendingRecordData, readRecord, type RequestIdentity, type RequestRecordData, sameIdentity, type ToldFact } from "./records.ts";
|
|
32
|
+
import { declaredToolNames, leadingToolsItem, loadedInList, type RecordedRequest } from "./wire.ts";
|
|
33
|
+
|
|
34
|
+
export type { EpochCause };
|
|
35
|
+
|
|
36
|
+
/** A recorded request as the fold rebuilds it: the wire list and head, the context messages it covered, and where it was routed. */
|
|
37
|
+
export interface FoldedRequest extends RecordedRequest {
|
|
38
|
+
covers?: Coverage;
|
|
39
|
+
routing?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface LedgerFold {
|
|
43
|
+
/** True when the next request opens an epoch: no request yet, a compaction or `epoch` record since, or a changed identity. */
|
|
44
|
+
opensEpoch: boolean;
|
|
45
|
+
/** Why, when `opensEpoch`. */
|
|
46
|
+
cause?: EpochCause;
|
|
47
|
+
/** The last request on the branch that counts (its reply followed it and stayed), rebuilt from its records. */
|
|
48
|
+
lastRequest: FoldedRequest | undefined;
|
|
49
|
+
/** Every element hash already stored on the branch. */
|
|
50
|
+
knownHashes: Set<string>;
|
|
51
|
+
/** Every tool the branch's counted requests declared, in the order of its first declaration: the order an epoch renders (ledger/wire.ts). */
|
|
52
|
+
toolOrder: string[];
|
|
53
|
+
/** Told facts in the current epoch: kind ("tools", "skills", `CALLABLE_TOOLS`) to names. */
|
|
54
|
+
told: Map<string, Set<string>>;
|
|
55
|
+
/** Modes told in the current epoch, by key: on or off as last told. */
|
|
56
|
+
modes: Map<string, boolean>;
|
|
57
|
+
/** Whole-text blocks told in the current epoch, by key: the content hash of the text last told. */
|
|
58
|
+
blocks: Map<string, string>;
|
|
59
|
+
/** Produced and not yet sent, latest per key, in branch order. */
|
|
60
|
+
pending: PendingRecordData[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The told kind of the tools announced by a callable `tool_addition` (also folded under "tools"). */
|
|
64
|
+
export const CALLABLE_TOOLS = "tools:callable";
|
|
65
|
+
|
|
66
|
+
/** What an epoch has told the model, as the fold keeps it and a render reads it. */
|
|
67
|
+
export interface ToldState {
|
|
68
|
+
told: Map<string, Set<string>>;
|
|
69
|
+
modes: Map<string, boolean>;
|
|
70
|
+
blocks: Map<string, string>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Add `facts` to what the epoch told: a mode or block as last told, names as a union (callable tools also under `CALLABLE_TOOLS`), tools told gone taken out. */
|
|
74
|
+
export function tellFacts(into: ToldState, facts: readonly ToldFact[]): void {
|
|
75
|
+
for (const fact of facts) {
|
|
76
|
+
if (fact.kind === "mode") into.modes.set(fact.key, fact.on);
|
|
77
|
+
else if (fact.kind === "block") into.blocks.set(fact.key, fact.hash);
|
|
78
|
+
else if (fact.kind === "tools" && fact.removed) {
|
|
79
|
+
for (const kind of ["tools", CALLABLE_TOOLS]) for (const name of fact.names) into.told.get(kind)?.delete(name);
|
|
80
|
+
} else {
|
|
81
|
+
const kinds = fact.kind === "tools" && fact.callable ? ["tools", CALLABLE_TOOLS] : [fact.kind];
|
|
82
|
+
for (const kind of kinds) {
|
|
83
|
+
const set = into.told.get(kind) ?? new Set<string>();
|
|
84
|
+
for (const name of fact.names) set.add(name);
|
|
85
|
+
into.told.set(kind, set);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** What `facts` tell an epoch that starts empty. */
|
|
92
|
+
export function toldOf(facts: readonly ToldFact[]): ToldState {
|
|
93
|
+
const state: ToldState = { told: new Map(), modes: new Map(), blocks: new Map() };
|
|
94
|
+
tellFacts(state, facts);
|
|
95
|
+
return state;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** The request a record describes, rebuilt on its base; undefined when the branch lacks a body it needs. */
|
|
99
|
+
function rebuild(data: RequestRecordData, base: RecordedRequest | undefined, blobs: ReadonlyMap<string, unknown>): FoldedRequest | undefined {
|
|
100
|
+
const kept = base?.list.length ?? 0;
|
|
101
|
+
if (data.keep > kept || !blobs.has(data.head) || !data.append.every((hash) => blobs.has(hash))) return undefined;
|
|
102
|
+
const head = blobs.get(data.head);
|
|
103
|
+
if (typeof head !== "object" || head === null || Array.isArray(head)) return undefined;
|
|
104
|
+
return {
|
|
105
|
+
identity: data.identity,
|
|
106
|
+
list: [...(base?.list.slice(0, data.keep) ?? []), ...data.append.map((hash) => blobs.get(hash))],
|
|
107
|
+
head: head as Record<string, unknown>,
|
|
108
|
+
hashes: [...(base?.hashes.slice(0, data.keep) ?? []), ...data.append],
|
|
109
|
+
headHash: data.head,
|
|
110
|
+
...(data.covers ? { covers: data.covers } : {}),
|
|
111
|
+
...(data.routing ? { routing: data.routing } : {}),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* What a request that does not count takes back: the told state, the epoch
|
|
117
|
+
* cause and the identity from before it. The told state is held by reference,
|
|
118
|
+
* not copied: nothing tells into it while a checkpoint is live (an epoch or a
|
|
119
|
+
* changed identity replaces it, and told records riding a request wait in its
|
|
120
|
+
* `facts` until it counts, when its checkpoint is dropped).
|
|
121
|
+
*/
|
|
122
|
+
interface FoldCheckpoint {
|
|
123
|
+
told: ToldState;
|
|
124
|
+
resetSinceBase: EpochCause | undefined;
|
|
125
|
+
lastIdentity: RequestIdentity | undefined;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** The ids of the entries pi omitted from the model's view: a `context_edit` with no replacement. */
|
|
129
|
+
function omittedIds(branch: readonly EntryLike[]): Set<string> {
|
|
130
|
+
const ids = new Set<string>();
|
|
131
|
+
for (const entry of branch) if (entry.type === "context_edit" && entry.replacement === null && typeof entry.targetId === "string") ids.add(entry.targetId);
|
|
132
|
+
return ids;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** The tools a request declares at its head: its head's declarations, then a leading Responses `additional_tools` item's (pi 1.4.0 and later). */
|
|
136
|
+
function headToolNames(request: Pick<RecordedRequest, "head" | "list">): string[] {
|
|
137
|
+
const item = leadingToolsItem(request.head.tools, request.list);
|
|
138
|
+
return [...declaredToolNames(request.head), ...(item ? loadedInList([item]) : [])];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Fold the branch (root first, as `getBranch()` returns it). `identity` is the live request identity, for epoch detection. */
|
|
142
|
+
export function foldBranch(branch: readonly EntryLike[], identity?: RequestIdentity): LedgerFold {
|
|
143
|
+
const blobs = new Map<string, unknown>();
|
|
144
|
+
let told = toldOf([]);
|
|
145
|
+
const produced: { item: PendingRecordData; index: number }[] = [];
|
|
146
|
+
const consumed = new Set<string>();
|
|
147
|
+
const omitted = omittedIds(branch);
|
|
148
|
+
/** The index of the last compaction on the branch: an older `untilCompaction` pending item is stale. */
|
|
149
|
+
let lastCompaction = -1;
|
|
150
|
+
let base: FoldedRequest | undefined;
|
|
151
|
+
const toolOrder = new Set<string>();
|
|
152
|
+
/** The head hash of the last counted request, and its first list element's (a leading tools item's), whose declarations `toolOrder` holds. */
|
|
153
|
+
let orderedHead: string | undefined;
|
|
154
|
+
/** A compaction or `epoch` record after the base: the next request renders everything again. */
|
|
155
|
+
let resetSinceBase: EpochCause | undefined;
|
|
156
|
+
let lastIdentity: RequestIdentity | undefined;
|
|
157
|
+
/** The state before the last `epoch` record, while nothing but its own request may follow it. */
|
|
158
|
+
let beforeEpoch: { index: number; checkpoint: FoldCheckpoint } | undefined;
|
|
159
|
+
/** The latest request and what rode it, until its reply settles it. */
|
|
160
|
+
let open: { request: FoldedRequest | undefined; consumed: string[]; facts: ToldFact[]; checkpoint: FoldCheckpoint } | undefined;
|
|
161
|
+
|
|
162
|
+
const tell = (facts: readonly ToldFact[]) => tellFacts(told, facts);
|
|
163
|
+
const checkpoint = (): FoldCheckpoint => ({ told, resetSinceBase, lastIdentity });
|
|
164
|
+
/** A new epoch starts with nothing told: a new state, so a checkpoint keeps the one it holds. */
|
|
165
|
+
const resetTold = () => {
|
|
166
|
+
told = toldOf([]);
|
|
167
|
+
};
|
|
168
|
+
/** Count what the open request carried and make it the base; a request without its reply takes back what it changed. */
|
|
169
|
+
const settle = (counts: boolean) => {
|
|
170
|
+
if (!open) return;
|
|
171
|
+
if (counts) {
|
|
172
|
+
for (const id of open.consumed) consumed.add(id);
|
|
173
|
+
tell(open.facts);
|
|
174
|
+
if (open.request) {
|
|
175
|
+
base = open.request;
|
|
176
|
+
resetSinceBase = undefined;
|
|
177
|
+
// Requests mostly share their head: the last counted one's adds no name.
|
|
178
|
+
const heading = `${open.request.headHash}:${open.request.hashes[0] ?? ""}`;
|
|
179
|
+
if (heading !== orderedHead) for (const name of headToolNames(open.request)) toolOrder.add(name);
|
|
180
|
+
orderedHead = heading;
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
({ told, resetSinceBase, lastIdentity } = open.checkpoint);
|
|
184
|
+
}
|
|
185
|
+
open = undefined;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
branch.forEach((entry, index) => {
|
|
189
|
+
const attached = beforeEpoch?.index === index - 1 ? beforeEpoch : undefined;
|
|
190
|
+
beforeEpoch = undefined;
|
|
191
|
+
if (entry.type === "message") {
|
|
192
|
+
// A request's reply is the first message after its record: pi stores the
|
|
193
|
+
// prompt before the request and the tool results after the reply, so a
|
|
194
|
+
// user message first (a btw fork's side question, copied mid-stream) means
|
|
195
|
+
// no reply. pi drops an errored or aborted reply from the next request
|
|
196
|
+
// (transform-messages.js) and omits a recovered one.
|
|
197
|
+
const message = entry.message;
|
|
198
|
+
settle(message?.role === "assistant" && message.stopReason !== "error" && message.stopReason !== "aborted" && !omitted.has(entry.id));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (entry.type === "compaction") {
|
|
202
|
+
lastCompaction = index;
|
|
203
|
+
settle(false);
|
|
204
|
+
resetTold();
|
|
205
|
+
resetSinceBase = "compaction";
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const record = readRecord(entry);
|
|
209
|
+
if (!record) return;
|
|
210
|
+
switch (record.kind) {
|
|
211
|
+
case "epoch":
|
|
212
|
+
settle(false);
|
|
213
|
+
beforeEpoch = { index, checkpoint: checkpoint() };
|
|
214
|
+
resetTold();
|
|
215
|
+
resetSinceBase = record.data.cause;
|
|
216
|
+
return;
|
|
217
|
+
case "request": {
|
|
218
|
+
settle(false);
|
|
219
|
+
const data = record.data;
|
|
220
|
+
for (const [hash, body] of Object.entries(data.blobs)) if (!blobs.has(hash)) blobs.set(hash, body);
|
|
221
|
+
const before = attached?.checkpoint ?? checkpoint();
|
|
222
|
+
if (lastIdentity && !sameIdentity(lastIdentity, data.identity)) resetTold();
|
|
223
|
+
lastIdentity = data.identity;
|
|
224
|
+
open = { request: rebuild(data, base, blobs), consumed: data.consumed, facts: [], checkpoint: before };
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
case "told":
|
|
228
|
+
if (open) open.facts.push(...record.data.facts);
|
|
229
|
+
else tell(record.data.facts);
|
|
230
|
+
return;
|
|
231
|
+
case "pending":
|
|
232
|
+
produced.push({ item: record.data, index });
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
settle(false);
|
|
237
|
+
|
|
238
|
+
const latestByKey = new Map<string, number>();
|
|
239
|
+
for (const { item, index } of produced) if (item.key !== undefined) latestByKey.set(item.key, index);
|
|
240
|
+
const pending = produced
|
|
241
|
+
.filter(({ item, index }) => item.key === undefined || latestByKey.get(item.key) === index)
|
|
242
|
+
.filter(({ item, index }) => !consumed.has(item.id) && !(item.untilCompaction && index < lastCompaction))
|
|
243
|
+
.map(({ item }) => item);
|
|
244
|
+
|
|
245
|
+
const changed = (b: RequestIdentity, live: RequestIdentity): EpochCause | undefined =>
|
|
246
|
+
b.model !== live.model || b.api !== live.api || b.provider !== live.provider
|
|
247
|
+
? "model"
|
|
248
|
+
: b.auth !== live.auth
|
|
249
|
+
? "auth"
|
|
250
|
+
: b.effortMarkers !== live.effortMarkers
|
|
251
|
+
? "effort"
|
|
252
|
+
: undefined;
|
|
253
|
+
// A compaction with no settled request before it (the only request failed, a
|
|
254
|
+
// session recorded before the ledger) still opens the compaction's epoch.
|
|
255
|
+
const cause: EpochCause | undefined = resetSinceBase ?? (!base ? "first" : identity ? changed(base.identity, identity) : undefined);
|
|
256
|
+
return {
|
|
257
|
+
opensEpoch: cause !== undefined,
|
|
258
|
+
...(cause ? { cause } : {}),
|
|
259
|
+
lastRequest: base,
|
|
260
|
+
knownHashes: new Set(blobs.keys()),
|
|
261
|
+
toolOrder: [...toolOrder],
|
|
262
|
+
...told,
|
|
263
|
+
pending,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The final layout pass over a request's list (findings §52). On Anthropic a
|
|
3
|
+
* system message with content must come after a user message and reach an
|
|
4
|
+
* assistant message, or the end, through system messages only; a request
|
|
5
|
+
* that breaks the rule is a 400, every time, so a session that sends one
|
|
6
|
+
* cannot continue. Several builders put system messages in a list (the
|
|
7
|
+
* stack's system message, `<total_tokens>` countdowns, `tool_addition`
|
|
8
|
+
* notices) and several append to a list built earlier (a side call's prompt
|
|
9
|
+
* after a captured request, a fork's task after its parent's, hook context
|
|
10
|
+
* after a prompt). Instead of each checking what comes after, this pass runs
|
|
11
|
+
* last and makes the layout valid by construction: a run of system messages
|
|
12
|
+
* that a user message follows moves down to just before the next assistant
|
|
13
|
+
* message, or to the end, ahead of the trailing directives pi-ai appends.
|
|
14
|
+
*
|
|
15
|
+
* Only elements from `from` on move (a request's recorded prefix must keep its
|
|
16
|
+
* bytes); the system run that ends the prefix counts as new, since what comes
|
|
17
|
+
* after it is.
|
|
18
|
+
*
|
|
19
|
+
* Pure: no pi imports.
|
|
20
|
+
*/
|
|
21
|
+
import { isObject } from "./records.ts";
|
|
22
|
+
import { appendPoint } from "./wire.ts";
|
|
23
|
+
|
|
24
|
+
const roleOf = (element: unknown) => (isObject(element) ? element.role : undefined);
|
|
25
|
+
|
|
26
|
+
/** A system message that is not the directive-only form, which may sit anywhere. */
|
|
27
|
+
function isContentSystem(element: unknown): boolean {
|
|
28
|
+
if (roleOf(element) !== "system" || !isObject(element)) return false;
|
|
29
|
+
const content = element.content;
|
|
30
|
+
return Array.isArray(content) || typeof content === "string" ? content.length > 0 : content !== undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Whether the system run starting at `index` reaches a non-system element that is not an assistant message. */
|
|
34
|
+
function strandedAt(list: readonly unknown[], index: number): boolean {
|
|
35
|
+
let next = index + 1;
|
|
36
|
+
while (next < list.length && roleOf(list[next]) === "system") next++;
|
|
37
|
+
return next < list.length && roleOf(list[next]) !== "assistant";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** `list` with no stranded system message at or after `from`: the input itself when nothing moves. */
|
|
41
|
+
export function settleSystemMessages<T>(list: readonly T[], api: string, from = 0): readonly T[] {
|
|
42
|
+
if (api !== "anthropic-messages") return list;
|
|
43
|
+
let start = Math.max(0, Math.min(from, list.length));
|
|
44
|
+
while (start > 0 && roleOf(list[start - 1]) === "system") start--;
|
|
45
|
+
if (!list.some((element, index) => index >= start && isContentSystem(element) && strandedAt(list, index))) return list;
|
|
46
|
+
const out = list.slice(0, start);
|
|
47
|
+
let held: T[] = [];
|
|
48
|
+
for (let i = start; i < list.length; i++) {
|
|
49
|
+
const element = list[i];
|
|
50
|
+
if (isContentSystem(element) && strandedAt(list, i)) {
|
|
51
|
+
held.push(element);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (roleOf(element) === "assistant" && held.length > 0) {
|
|
55
|
+
out.push(...held);
|
|
56
|
+
held = [];
|
|
57
|
+
}
|
|
58
|
+
out.push(element);
|
|
59
|
+
}
|
|
60
|
+
if (held.length > 0) {
|
|
61
|
+
out.splice(Math.max(start, appendPoint(out, api)), 0, ...held);
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** `payload` with its list settled from `from` on; the payload itself when nothing moves. */
|
|
67
|
+
export function settlePayload(payload: Record<string, unknown>, api: string, key: string, from = 0): Record<string, unknown> {
|
|
68
|
+
const list = payload[key];
|
|
69
|
+
if (!Array.isArray(list)) return payload;
|
|
70
|
+
const settled = settleSystemMessages(list, api, from);
|
|
71
|
+
return settled === list ? payload : { ...payload, [key]: settled };
|
|
72
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One request's plan, shared over `pi.events` by the three parts of the
|
|
3
|
+
* request path (design.md section 5): the ledger's `context` hook decides it,
|
|
4
|
+
* the renderer (system-reminder) fills in what the request carries, and the
|
|
5
|
+
* ledger's payload hook splices, validates and records by it.
|
|
6
|
+
*
|
|
7
|
+
* The plan object is created once per `context` pass and passed by reference,
|
|
8
|
+
* so the renderer's additions reach the payload hook. A pi cache warm or a
|
|
9
|
+
* provider retry re-runs only the payload hooks; they reuse the last plan.
|
|
10
|
+
*
|
|
11
|
+
* Pure: no pi imports.
|
|
12
|
+
*/
|
|
13
|
+
import type { FoldedRequest, LedgerFold } from "./fold.ts";
|
|
14
|
+
import type { Coverage, EpochCause, ToldFact } from "./records.ts";
|
|
15
|
+
|
|
16
|
+
/** Published by the ledger's `context` hook, once per request. */
|
|
17
|
+
export const LEDGER_PLAN_CHANNEL = "one-code:ledger-plan";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Published by the ledger's payload hook with the request as it goes out
|
|
21
|
+
* (`LedgerSent`): the spliced, validated body, before cache-marks adds its
|
|
22
|
+
* look-back mark. A pi cache warm publishes it again.
|
|
23
|
+
*/
|
|
24
|
+
export const LEDGER_SENT_CHANNEL = "one-code:ledger-sent";
|
|
25
|
+
|
|
26
|
+
export interface LedgerSent {
|
|
27
|
+
payload: Record<string, unknown>;
|
|
28
|
+
model: { api?: string; provider?: string; id?: string } | undefined;
|
|
29
|
+
sessionId: string;
|
|
30
|
+
plan: RequestPlan;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface RequestPlan {
|
|
34
|
+
/** True when the request opens an epoch: the whole conversation goes through pi and the message-1 stack is rendered. */
|
|
35
|
+
epoch: boolean;
|
|
36
|
+
/** Why it opens one; the plan adds "coverage" (the base cannot be extended) and "empty" (nothing new since it) to the fold's causes. */
|
|
37
|
+
cause?: EpochCause;
|
|
38
|
+
/** The request this one extends inside its epoch; undefined on an epoch. */
|
|
39
|
+
base?: FoldedRequest;
|
|
40
|
+
/** The context messages this request covers, for its record. */
|
|
41
|
+
covers: Coverage;
|
|
42
|
+
/** The branch's fold at this request. */
|
|
43
|
+
fold: LedgerFold;
|
|
44
|
+
/** Pending ids this request carries (the renderer fills it). */
|
|
45
|
+
consumed: string[];
|
|
46
|
+
/**
|
|
47
|
+
* Each new block's text with the facts it tells the model, so a repair that
|
|
48
|
+
* drops a block drops its facts (the renderer fills it). The request tells
|
|
49
|
+
* exactly these blocks' facts, in this order.
|
|
50
|
+
*/
|
|
51
|
+
carried: CarriedFacts[];
|
|
52
|
+
/** Every context message pi built for the request, before the cut: what the whole request covers. */
|
|
53
|
+
messages: readonly CoveredMessage[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** A block's text and the facts it tells: they count only while the text is on the wire. */
|
|
57
|
+
export interface CarriedFacts {
|
|
58
|
+
text: string;
|
|
59
|
+
facts: readonly ToldFact[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** A context message as far as coverage reads it. */
|
|
63
|
+
export interface CoveredMessage {
|
|
64
|
+
role: string;
|
|
65
|
+
timestamp?: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** The coverage of a request that sends `messages`. */
|
|
69
|
+
export function coverageOf(messages: readonly CoveredMessage[]): Coverage {
|
|
70
|
+
const last = messages.at(-1);
|
|
71
|
+
return { count: messages.length, role: last?.role ?? "", timestamp: last?.timestamp ?? 0 };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The plan for a request over `messages` (pi's context messages, before any
|
|
76
|
+
* extension injects into them), and the index where the tail this request
|
|
77
|
+
* sends through pi starts: 0 when it opens an epoch. The base is extended only
|
|
78
|
+
* when it covered a prefix of `messages` that is still there, ending in the
|
|
79
|
+
* same message, and something came after it.
|
|
80
|
+
*/
|
|
81
|
+
export function planRequest(fold: LedgerFold, messages: readonly CoveredMessage[]): { plan: RequestPlan; tailStart: number } {
|
|
82
|
+
const covers = coverageOf(messages);
|
|
83
|
+
const plan = (epoch: boolean, cause: EpochCause | undefined, base?: FoldedRequest): RequestPlan => ({
|
|
84
|
+
epoch,
|
|
85
|
+
...(cause ? { cause } : {}),
|
|
86
|
+
...(base ? { base } : {}),
|
|
87
|
+
covers,
|
|
88
|
+
fold,
|
|
89
|
+
consumed: [],
|
|
90
|
+
carried: [],
|
|
91
|
+
messages,
|
|
92
|
+
});
|
|
93
|
+
const base = fold.lastRequest;
|
|
94
|
+
if (fold.opensEpoch || !base) return { plan: plan(true, fold.cause ?? "first"), tailStart: 0 };
|
|
95
|
+
const at = base.covers;
|
|
96
|
+
const last = at && at.count > 0 ? messages[at.count - 1] : undefined;
|
|
97
|
+
if (!at || at.count > messages.length || (at.count > 0 && (last?.role !== at.role || (last?.timestamp ?? 0) !== at.timestamp))) {
|
|
98
|
+
return { plan: plan(true, "coverage"), tailStart: 0 };
|
|
99
|
+
}
|
|
100
|
+
if (at.count === messages.length) return { plan: plan(true, "empty"), tailStart: 0 };
|
|
101
|
+
return { plan: plan(false, undefined, base), tailStart: at.count };
|
|
102
|
+
}
|