@prometheus-ai/agent 0.5.4 → 0.5.8
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/CHANGELOG.md +30 -0
- package/dist/cli.js +25110 -0
- package/dist/types/async/index.d.ts +0 -1
- package/dist/types/async/job-manager.d.ts +33 -0
- package/dist/types/autolearn/controller.d.ts +25 -0
- package/dist/types/autolearn/managed-skills.d.ts +45 -0
- package/dist/types/autoresearch/state.d.ts +1 -1
- package/dist/types/autoresearch/tools/init-experiment.d.ts +1 -1
- package/dist/types/autoresearch/tools/log-experiment.d.ts +1 -1
- package/dist/types/autoresearch/tools/run-experiment.d.ts +1 -1
- package/dist/types/autoresearch/tools/update-notes.d.ts +1 -1
- package/dist/types/autoresearch/types.d.ts +1 -1
- package/dist/types/capability/context-file.d.ts +0 -13
- package/dist/types/capability/mcp.d.ts +1 -0
- package/dist/types/capability/rule-buckets.d.ts +1 -1
- package/dist/types/capability/rule.d.ts +6 -1
- package/dist/types/capability/types.d.ts +0 -4
- package/dist/types/cli/args.d.ts +23 -3
- package/dist/types/cli/bench-cli.d.ts +78 -0
- package/dist/types/cli/claude-trace-cli.d.ts +7 -0
- package/dist/types/cli/dry-balance-cli.d.ts +16 -2
- package/dist/types/cli/gallery-cli.d.ts +43 -0
- package/dist/types/cli/gallery-fixtures/agentic.d.ts +2 -0
- package/dist/types/cli/gallery-fixtures/codeintel.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/edit.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/fs.d.ts +2 -0
- package/dist/types/cli/gallery-fixtures/index.d.ts +4 -0
- package/dist/types/cli/gallery-fixtures/interaction.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/memory.d.ts +2 -0
- package/dist/types/cli/gallery-fixtures/misc.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/search.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/shell.d.ts +3 -0
- package/dist/types/cli/gallery-fixtures/types.d.ts +55 -0
- package/dist/types/cli/gallery-fixtures/web.d.ts +2 -0
- package/dist/types/cli/gallery-screenshot.d.ts +35 -0
- package/dist/types/cli/grievances-cli.d.ts +1 -1
- package/dist/types/cli/list-models.d.ts +6 -14
- package/dist/types/cli/models-cli.d.ts +49 -0
- package/dist/types/cli/session-picker.d.ts +1 -1
- package/dist/types/cli/setup-cli.d.ts +1 -1
- package/dist/types/cli/setup-model-picker.d.ts +14 -0
- package/dist/types/cli/startup-cwd.d.ts +2 -0
- package/dist/types/cli/update-cli.d.ts +13 -40
- package/dist/types/cli/usage-cli.d.ts +81 -0
- package/dist/types/cli-commands.d.ts +12 -0
- package/dist/types/collab/crypto.d.ts +7 -0
- package/dist/types/collab/guest.d.ts +37 -0
- package/dist/types/collab/host.d.ts +29 -0
- package/dist/types/collab/protocol.d.ts +119 -0
- package/dist/types/collab/relay-client.d.ts +22 -0
- package/dist/types/commands/bench.d.ts +29 -0
- package/dist/types/commands/gallery.d.ts +47 -0
- package/dist/types/commands/install.d.ts +1 -1
- package/dist/types/commands/join.d.ts +12 -0
- package/dist/types/commands/launch.d.ts +8 -4
- package/dist/types/commands/models.d.ts +33 -0
- package/dist/types/commands/read.d.ts +1 -1
- package/dist/types/commands/say.d.ts +24 -0
- package/dist/types/commands/token.d.ts +25 -0
- package/dist/types/commands/usage.d.ts +34 -0
- package/dist/types/commit/agentic/tools/analyze-file.d.ts +1 -1
- package/dist/types/commit/agentic/tools/git-file-diff.d.ts +1 -1
- package/dist/types/commit/agentic/tools/git-hunk.d.ts +1 -1
- package/dist/types/commit/agentic/tools/git-overview.d.ts +1 -1
- package/dist/types/commit/agentic/tools/propose-changelog.d.ts +1 -1
- package/dist/types/commit/agentic/tools/propose-commit.d.ts +1 -1
- package/dist/types/commit/agentic/tools/recent-commits.d.ts +1 -1
- package/dist/types/commit/agentic/tools/schemas.d.ts +1 -1
- package/dist/types/commit/agentic/tools/split-commit.d.ts +1 -1
- package/dist/types/commit/analysis/conventional.d.ts +2 -2
- package/dist/types/commit/analysis/summary.d.ts +2 -2
- package/dist/types/commit/changelog/generate.d.ts +3 -3
- package/dist/types/commit/changelog/index.d.ts +2 -2
- package/dist/types/commit/map-reduce/index.d.ts +3 -3
- package/dist/types/commit/map-reduce/map-phase.d.ts +2 -2
- package/dist/types/commit/map-reduce/reduce-phase.d.ts +2 -2
- package/dist/types/commit/model-selection.d.ts +10 -4
- package/dist/types/commit/shared-llm.d.ts +1 -1
- package/dist/types/config/api-key-resolver.d.ts +43 -0
- package/dist/types/config/append-only-context-mode.d.ts +2 -1
- package/dist/types/config/keybindings.d.ts +12 -7
- package/dist/types/config/model-discovery.d.ts +57 -0
- package/dist/types/config/model-equivalence.d.ts +1 -1
- package/dist/types/config/model-registry.d.ts +86 -222
- package/dist/types/config/model-resolver.d.ts +43 -12
- package/dist/types/config/model-roles.d.ts +29 -0
- package/dist/types/config/models-config-schema.d.ts +536 -43
- package/dist/types/config/models-config.d.ts +391 -0
- package/dist/types/config/settings-schema.d.ts +1202 -324
- package/dist/types/config/settings.d.ts +15 -3
- package/dist/types/dap/config.d.ts +14 -1
- package/dist/types/dap/types.d.ts +10 -0
- package/dist/types/debug/log-viewer.d.ts +1 -1
- package/dist/types/debug/raw-sse.d.ts +1 -1
- package/dist/types/debug/report-bundle.d.ts +3 -0
- package/dist/types/debug/terminal-info.d.ts +0 -1
- package/dist/types/discovery/at-imports.d.ts +15 -0
- package/dist/types/discovery/prometheus-extension-roots.d.ts +7 -7
- package/dist/types/edit/diff.d.ts +3 -2
- package/dist/types/edit/file-snapshot-store.d.ts +18 -0
- package/dist/types/edit/hashline/noop-loop-guard.d.ts +72 -0
- package/dist/types/edit/hashline/params.d.ts +1 -1
- package/dist/types/edit/index.d.ts +0 -1
- package/dist/types/edit/modes/apply-patch.d.ts +1 -1
- package/dist/types/edit/modes/patch.d.ts +1 -1
- package/dist/types/edit/modes/replace.d.ts +1 -1
- package/dist/types/edit/renderer.d.ts +1 -0
- package/dist/types/eval/__tests__/completion-bridge.test.d.ts +1 -0
- package/dist/types/eval/__tests__/helpers-local-roots.test.d.ts +1 -0
- package/dist/types/eval/__tests__/js-context-manager.test.d.ts +1 -0
- package/dist/types/eval/backend.d.ts +7 -2
- package/dist/types/eval/bridge-timeout.d.ts +1 -1
- package/dist/types/eval/completion-bridge.d.ts +25 -0
- package/dist/types/eval/idle-timeout.d.ts +1 -5
- package/dist/types/eval/js/context-manager.d.ts +1 -0
- package/dist/types/eval/js/executor.d.ts +2 -0
- package/dist/types/eval/js/index.d.ts +1 -1
- package/dist/types/eval/js/shared/helpers.d.ts +7 -1
- package/dist/types/eval/js/shared/rewrite-imports.d.ts +6 -6
- package/dist/types/eval/js/shared/runtime.d.ts +6 -1
- package/dist/types/eval/js/worker-protocol.d.ts +6 -0
- package/dist/types/eval/py/__tests__/prelude.test.d.ts +1 -0
- package/dist/types/eval/py/executor.d.ts +12 -0
- package/dist/types/eval/py/index.d.ts +1 -1
- package/dist/types/eval/py/kernel.d.ts +6 -1
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exa/index.d.ts +1 -19
- package/dist/types/exa/mcp-client.d.ts +10 -3
- package/dist/types/exa/types.d.ts +0 -83
- package/dist/types/exec/bash-executor.d.ts +7 -0
- package/dist/types/export/custom-share.d.ts +1 -2
- package/dist/types/export/html/index.d.ts +39 -0
- package/dist/types/export/html/template-js.d.ts +2 -0
- package/dist/types/export/share.d.ts +61 -0
- package/dist/types/export/ttsr.d.ts +14 -0
- package/dist/types/extensibility/custom-commands/types.d.ts +9 -4
- package/dist/types/extensibility/custom-tools/loader.d.ts +30 -4
- package/dist/types/extensibility/custom-tools/types.d.ts +16 -8
- package/dist/types/extensibility/extensions/index.d.ts +1 -1
- package/dist/types/extensibility/extensions/loader.d.ts +20 -1
- package/dist/types/extensibility/extensions/model-api.d.ts +17 -0
- package/dist/types/extensibility/extensions/runner.d.ts +5 -2
- package/dist/types/extensibility/extensions/types.d.ts +72 -11
- package/dist/types/extensibility/hooks/index.d.ts +2 -1
- package/dist/types/extensibility/hooks/loader.d.ts +1 -1
- package/dist/types/extensibility/hooks/types.d.ts +11 -5
- package/dist/types/extensibility/{legacy-pi-ai-shim.d.ts → legacy-package-ai-shim.d.ts} +2 -2
- package/dist/types/extensibility/plugins/{legacy-pi-compat.d.ts → legacy-package-compat.d.ts} +20 -3
- package/dist/types/extensibility/plugins/loader.d.ts +11 -0
- package/dist/types/extensibility/plugins/marketplace-auto-update.d.ts +8 -0
- package/dist/types/extensibility/plugins/types.d.ts +2 -2
- package/dist/types/extensibility/shared-events.d.ts +3 -3
- package/dist/types/extensibility/skills.d.ts +10 -0
- package/dist/types/extensibility/slash-commands.d.ts +1 -11
- package/dist/types/goals/guided-setup.d.ts +18 -0
- package/dist/types/goals/state.d.ts +1 -1
- package/dist/types/goals/tools/goal-tool.d.ts +1 -1
- package/dist/types/hindsight/mental-models.d.ts +17 -8
- package/dist/types/hindsight/transcript.d.ts +1 -1
- package/dist/types/index.d.ts +5 -0
- package/dist/types/internal-urls/artifact-protocol.d.ts +2 -2
- package/dist/types/internal-urls/history-protocol.d.ts +14 -0
- package/dist/types/internal-urls/index.d.ts +1 -0
- package/dist/types/internal-urls/local-protocol.d.ts +14 -2
- package/dist/types/internal-urls/types.d.ts +1 -1
- package/dist/types/irc/bus.d.ts +79 -0
- package/dist/types/lib/xai-http.d.ts +1 -1
- package/dist/types/lsp/client.d.ts +10 -0
- package/dist/types/lsp/config.d.ts +2 -2
- package/dist/types/lsp/edits.d.ts +9 -0
- package/dist/types/lsp/format-options.d.ts +32 -0
- package/dist/types/lsp/index.d.ts +2 -7
- package/dist/types/lsp/types.d.ts +13 -1
- package/dist/types/lsp/utils.d.ts +6 -2
- package/dist/types/main.d.ts +23 -8
- package/dist/types/mcp/json-rpc.d.ts +5 -0
- package/dist/types/mcp/manager.d.ts +8 -0
- package/dist/types/mcp/oauth-discovery.d.ts +6 -1
- package/dist/types/mcp/oauth-flow.d.ts +13 -3
- package/dist/types/mcp/startup-events.d.ts +11 -0
- package/dist/types/mcp/tool-bridge.d.ts +2 -0
- package/dist/types/mcp/transports/stdio.d.ts +13 -0
- package/dist/types/mcp/types.d.ts +2 -0
- package/dist/types/memories/index.d.ts +7 -15
- package/dist/types/memories/storage.d.ts +0 -10
- package/dist/types/memory-backend/index.d.ts +3 -1
- package/dist/types/memory-backend/local-backend.d.ts +4 -3
- package/dist/types/memory-backend/resolve.d.ts +2 -2
- package/dist/types/memory-backend/runtime.d.ts +4 -0
- package/dist/types/memory-backend/types.d.ts +67 -2
- package/dist/types/mnemopi/config.d.ts +31 -1
- package/dist/types/mnemopi/state.d.ts +40 -2
- package/dist/types/modes/acp/acp-agent.d.ts +1 -2
- package/dist/types/modes/components/agent-dashboard.d.ts +17 -1
- package/dist/types/modes/components/agent-hub.d.ts +82 -0
- package/dist/types/modes/components/assistant-message.d.ts +5 -12
- package/dist/types/modes/components/bash-execution.d.ts +1 -1
- package/dist/types/modes/components/chat-block.d.ts +64 -0
- package/dist/types/modes/components/collab-prompt-message.d.ts +10 -0
- package/dist/types/modes/components/compaction-summary-message.d.ts +25 -5
- package/dist/types/modes/components/copy-selector.d.ts +1 -1
- package/dist/types/modes/components/custom-editor.d.ts +49 -2
- package/dist/types/modes/components/custom-editor.test.d.ts +1 -0
- package/dist/types/modes/components/dynamic-border.d.ts +1 -1
- package/dist/types/modes/components/extensions/extension-dashboard.d.ts +1 -1
- package/dist/types/modes/components/extensions/extension-list.d.ts +1 -1
- package/dist/types/modes/components/extensions/inspector-panel.d.ts +1 -1
- package/dist/types/modes/components/footer.d.ts +1 -1
- package/dist/types/modes/components/hook-editor.d.ts +5 -0
- package/dist/types/modes/components/hook-input.d.ts +4 -0
- package/dist/types/modes/components/hook-selector.d.ts +5 -7
- package/dist/types/modes/components/index.d.ts +1 -0
- package/dist/types/modes/components/late-diagnostics-message.d.ts +20 -0
- package/dist/types/modes/components/logout-account-selector.d.ts +8 -0
- package/dist/types/modes/components/mcp-add-wizard.d.ts +2 -1
- package/dist/types/modes/components/model-selector.d.ts +1 -1
- package/dist/types/modes/components/oauth-selector.d.ts +10 -1
- package/dist/types/modes/components/overlay-box.d.ts +17 -0
- package/dist/types/modes/components/plan-review-overlay.d.ts +61 -0
- package/dist/types/modes/components/plan-toc.d.ts +41 -0
- package/dist/types/modes/components/read-tool-group.d.ts +8 -0
- package/dist/types/modes/components/reset-usage-selector.d.ts +12 -0
- package/dist/types/modes/components/segment-track.d.ts +11 -6
- package/dist/types/modes/components/session-selector.d.ts +18 -9
- package/dist/types/modes/components/settings-defs.d.ts +9 -2
- package/dist/types/modes/components/settings-selector.d.ts +17 -4
- package/dist/types/modes/components/snapcompact-shape-preview.d.ts +31 -0
- package/dist/types/modes/components/status-line/component.d.ts +61 -0
- package/dist/types/modes/components/status-line/index.d.ts +1 -0
- package/dist/types/modes/components/status-line/types.d.ts +47 -3
- package/dist/types/modes/components/tiny-title-download-progress.d.ts +1 -1
- package/dist/types/modes/components/tool-execution.d.ts +49 -2
- package/dist/types/modes/components/transcript-container.d.ts +76 -26
- package/dist/types/modes/components/tree-selector.d.ts +2 -2
- package/dist/types/modes/components/ttsr-notification.d.ts +5 -1
- package/dist/types/modes/components/usage-row.d.ts +3 -0
- package/dist/types/modes/components/user-message-selector.d.ts +1 -1
- package/dist/types/modes/components/user-message.d.ts +2 -1
- package/dist/types/modes/components/visual-truncate.d.ts +1 -1
- package/dist/types/modes/components/welcome.d.ts +12 -2
- package/dist/types/modes/controllers/command-controller.d.ts +3 -2
- package/dist/types/modes/controllers/event-controller.d.ts +7 -1
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +0 -1
- package/dist/types/modes/controllers/input-controller.d.ts +25 -3
- package/dist/types/modes/controllers/mcp-command-controller.d.ts +8 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +5 -2
- package/dist/types/modes/controllers/session-focus-controller.d.ts +31 -0
- package/dist/types/modes/controllers/streaming-reveal.d.ts +22 -0
- package/dist/types/modes/controllers/tan-command-controller.d.ts +6 -0
- package/dist/types/modes/controllers/tool-args-reveal.d.ts +43 -0
- package/dist/types/modes/gradient-highlight.d.ts +9 -4
- package/dist/types/modes/image-references.d.ts +14 -3
- package/dist/types/modes/index.d.ts +8 -7
- package/dist/types/modes/interactive-mode.d.ts +92 -16
- package/dist/types/modes/magic-keywords.d.ts +14 -2
- package/dist/types/modes/markdown-prose.d.ts +1 -1
- package/dist/types/modes/oauth-manual-input.d.ts +7 -0
- package/dist/types/modes/rpc/rpc-client.d.ts +48 -2
- package/dist/types/modes/rpc/rpc-mode.d.ts +67 -2
- package/dist/types/modes/rpc/rpc-subagents.d.ts +24 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +113 -1
- package/dist/types/modes/runtime-init.d.ts +4 -0
- package/dist/types/modes/session-observer-registry.d.ts +9 -0
- package/dist/types/modes/setup-version.d.ts +11 -0
- package/dist/types/modes/setup-wizard/index.d.ts +7 -2
- package/dist/types/modes/setup-wizard/lazy.d.ts +2 -0
- package/dist/types/modes/setup-wizard/scenes/sign-in.d.ts +4 -1
- package/dist/types/modes/setup-wizard/scenes/types.d.ts +11 -2
- package/dist/types/modes/setup-wizard/scenes/web-search.d.ts +6 -2
- package/dist/types/modes/setup-wizard/wizard-overlay.d.ts +1 -1
- package/dist/types/modes/theme/theme.d.ts +42 -7
- package/dist/types/modes/types.d.ts +62 -13
- package/dist/types/modes/utils/context-usage.d.ts +6 -1
- package/dist/types/modes/utils/copy-targets.d.ts +21 -1
- package/dist/types/modes/utils/ui-helpers.d.ts +4 -4
- package/dist/types/modes/workflow.d.ts +3 -3
- package/dist/types/plan-mode/approved-plan.d.ts +27 -8
- package/dist/types/plan-mode/plan-protection.d.ts +4 -4
- package/dist/types/registry/agent-lifecycle.d.ts +51 -0
- package/dist/types/registry/agent-registry.d.ts +33 -5
- package/dist/types/sdk.d.ts +46 -4
- package/dist/types/secrets/index.d.ts +1 -1
- package/dist/types/secrets/obfuscator.d.ts +9 -3
- package/dist/types/session/agent-session.d.ts +136 -66
- package/dist/types/session/agent-storage.d.ts +2 -1
- package/dist/types/session/auth-broker-config.d.ts +4 -0
- package/dist/types/session/auth-storage.d.ts +1 -1
- package/dist/types/session/codex-auto-reset.d.ts +111 -0
- package/dist/types/session/indexed-session-storage.d.ts +3 -3
- package/dist/types/session/messages.d.ts +26 -15
- package/dist/types/session/session-context.d.ts +39 -0
- package/dist/types/session/session-entries.d.ts +159 -0
- package/dist/types/session/session-history-format.d.ts +12 -0
- package/dist/types/session/session-listing.d.ts +69 -0
- package/dist/types/session/session-loader.d.ts +16 -0
- package/dist/types/session/session-manager.d.ts +107 -440
- package/dist/types/session/session-migrations.d.ts +12 -0
- package/dist/types/session/session-paths.d.ts +25 -0
- package/dist/types/session/session-persistence.d.ts +8 -0
- package/dist/types/session/session-storage.d.ts +11 -7
- package/dist/types/session/snapcompact-inline.d.ts +145 -0
- package/dist/types/session/snapcompact-savings-journal.d.ts +46 -0
- package/dist/types/session/streaming-output.d.ts +46 -0
- package/dist/types/session/tool-choice-queue.d.ts +6 -6
- package/dist/types/session/yield-queue.d.ts +10 -1
- package/dist/types/slash-commands/acp-builtins.d.ts +16 -0
- package/dist/types/slash-commands/available-commands.d.ts +34 -0
- package/dist/types/slash-commands/builtin-registry.d.ts +10 -0
- package/dist/types/slash-commands/helpers/active-oauth-account.d.ts +14 -0
- package/dist/types/slash-commands/helpers/logout.d.ts +15 -0
- package/dist/types/slash-commands/helpers/reset-usage.d.ts +27 -0
- package/dist/types/slash-commands/helpers/stats-dashboard.d.ts +13 -0
- package/dist/types/slash-commands/types.d.ts +5 -9
- package/dist/types/ssh/connection-manager.d.ts +8 -0
- package/dist/types/stt/asr-client.d.ts +90 -0
- package/dist/types/stt/asr-protocol.d.ts +97 -0
- package/dist/types/stt/asr-worker.d.ts +2 -0
- package/dist/types/stt/downloader.d.ts +38 -0
- package/dist/types/stt/endpointer.d.ts +59 -0
- package/dist/types/stt/index.d.ts +5 -1
- package/dist/types/stt/models.d.ts +120 -0
- package/dist/types/stt/recorder.d.ts +17 -0
- package/dist/types/stt/stt-controller.d.ts +6 -0
- package/dist/types/stt/transcriber.d.ts +5 -7
- package/dist/types/stt/wav.d.ts +29 -0
- package/dist/types/system-prompt.d.ts +9 -1
- package/dist/types/task/commands.d.ts +1 -1
- package/dist/types/task/discovery.d.ts +1 -2
- package/dist/types/task/executor.d.ts +61 -2
- package/dist/types/task/index.d.ts +37 -6
- package/dist/types/task/output-manager.d.ts +0 -7
- package/dist/types/task/parallel.d.ts +2 -2
- package/dist/types/task/prometheus-command.d.ts +2 -2
- package/dist/types/task/render.d.ts +20 -7
- package/dist/types/task/repair-args.d.ts +8 -7
- package/dist/types/task/types.d.ts +109 -52
- package/dist/types/task/worktree.d.ts +2 -0
- package/dist/types/telemetry-export.d.ts +2 -2
- package/dist/types/thinking.d.ts +4 -0
- package/dist/types/tiny/models.d.ts +1 -1
- package/dist/types/tiny/title-client.d.ts +12 -1
- package/dist/types/tiny/title-protocol.d.ts +1 -0
- package/dist/types/tools/archive-reader.d.ts +5 -0
- package/dist/types/tools/ask.d.ts +6 -1
- package/dist/types/tools/ast-edit.d.ts +4 -1
- package/dist/types/tools/ast-grep.d.ts +4 -1
- package/dist/types/tools/bash.d.ts +5 -2
- package/dist/types/tools/browser/attach.d.ts +4 -4
- package/dist/types/tools/browser/cmux/cmux-tab.d.ts +202 -0
- package/dist/types/tools/browser/cmux/rpc.d.ts +70 -0
- package/dist/types/tools/browser/cmux/socket-client.d.ts +19 -0
- package/dist/types/tools/browser/registry.d.ts +17 -3
- package/dist/types/tools/browser/render.d.ts +2 -0
- package/dist/types/tools/browser/tab-protocol.d.ts +2 -0
- package/dist/types/tools/browser/tab-supervisor.d.ts +16 -4
- package/dist/types/tools/browser/tab-worker.d.ts +18 -1
- package/dist/types/tools/browser.d.ts +3 -1
- package/dist/types/tools/checkpoint.d.ts +1 -1
- package/dist/types/tools/conflict-detect.d.ts +16 -0
- package/dist/types/tools/debug.d.ts +1 -1
- package/dist/types/tools/eval-render.d.ts +1 -8
- package/dist/types/tools/eval.d.ts +9 -1
- package/dist/types/tools/fetch.d.ts +17 -8
- package/dist/types/tools/find.d.ts +1 -8
- package/dist/types/tools/gh-cache-invalidation.d.ts +6 -0
- package/dist/types/tools/gh.d.ts +4 -1
- package/dist/types/tools/github-cache.d.ts +19 -0
- package/dist/types/tools/grouped-file-output.d.ts +46 -12
- package/dist/types/tools/image-gen.d.ts +1 -1
- package/dist/types/tools/index.d.ts +89 -8
- package/dist/types/tools/inspect-image.d.ts +1 -1
- package/dist/types/tools/irc.d.ts +79 -39
- package/dist/types/tools/job.d.ts +8 -2
- package/dist/types/tools/learn.d.ts +51 -0
- package/dist/types/tools/manage-skill.d.ts +40 -0
- package/dist/types/tools/memory-edit.d.ts +2 -2
- package/dist/types/tools/memory-recall.d.ts +1 -1
- package/dist/types/tools/memory-reflect.d.ts +1 -1
- package/dist/types/tools/memory-render.d.ts +4 -1
- package/dist/types/tools/memory-retain.d.ts +1 -1
- package/dist/types/tools/path-utils.d.ts +17 -5
- package/dist/types/tools/plan-mode-guard.d.ts +18 -9
- package/dist/types/tools/read.d.ts +3 -2
- package/dist/types/tools/render-mermaid.d.ts +1 -1
- package/dist/types/tools/render-utils.d.ts +47 -27
- package/dist/types/tools/renderers.d.ts +10 -2
- package/dist/types/tools/report-tool-issue.d.ts +6 -1
- package/dist/types/tools/resolve.d.ts +1 -1
- package/dist/types/tools/review.d.ts +1 -1
- package/dist/types/tools/search-tool-bm25.d.ts +1 -1
- package/dist/types/tools/search.d.ts +7 -3
- package/dist/types/tools/sqlite-reader.d.ts +4 -0
- package/dist/types/tools/ssh.d.ts +2 -1
- package/dist/types/tools/todo.d.ts +7 -15
- package/dist/types/tools/tool-result.d.ts +2 -0
- package/dist/types/tools/tool-timeouts.d.ts +1 -1
- package/dist/types/tools/tts.d.ts +26 -1
- package/dist/types/tools/write.d.ts +6 -3
- package/dist/types/tools/yield.d.ts +8 -0
- package/dist/types/tts/downloader.d.ts +20 -0
- package/dist/types/tts/index.d.ts +8 -0
- package/dist/types/tts/models.d.ts +82 -0
- package/dist/types/tts/player.d.ts +32 -0
- package/dist/types/tts/runtime.d.ts +6 -0
- package/dist/types/tts/streaming-player.d.ts +41 -0
- package/dist/types/tts/tts-client.d.ts +93 -0
- package/dist/types/tts/tts-protocol.d.ts +95 -0
- package/dist/types/tts/tts-worker.d.ts +2 -0
- package/dist/types/tts/vocalizer.d.ts +41 -0
- package/dist/types/tts/wav.d.ts +8 -0
- package/dist/types/tui/code-cell.d.ts +0 -2
- package/dist/types/tui/hyperlink.d.ts +13 -7
- package/dist/types/tui/output-block.d.ts +16 -22
- package/dist/types/tui/status-line.d.ts +3 -0
- package/dist/types/utils/block-context.d.ts +35 -0
- package/dist/types/utils/changelog.d.ts +8 -0
- package/dist/types/utils/clipboard.d.ts +4 -3
- package/dist/types/utils/enhanced-paste.d.ts +20 -0
- package/dist/types/utils/file-mentions.d.ts +7 -0
- package/dist/types/utils/git.d.ts +22 -3
- package/dist/types/utils/image-loading.d.ts +30 -1
- package/dist/types/utils/session-color.d.ts +15 -3
- package/dist/types/utils/thinking-display.d.ts +17 -0
- package/dist/types/utils/title-generator.d.ts +3 -2
- package/dist/types/utils/tool-choice.d.ts +8 -0
- package/dist/types/utils/tools-manager.d.ts +2 -1
- package/dist/types/web/kagi.d.ts +2 -2
- package/dist/types/web/parallel.d.ts +3 -0
- package/dist/types/web/scrapers/github.d.ts +22 -0
- package/dist/types/web/scrapers/readthedocs.d.ts +3 -0
- package/dist/types/web/scrapers/types.d.ts +12 -0
- package/dist/types/web/search/index.d.ts +1 -1
- package/dist/types/web/search/providers/anthropic.d.ts +2 -1
- package/dist/types/web/search/providers/base.d.ts +2 -1
- package/dist/types/web/search/providers/brave.d.ts +2 -1
- package/dist/types/web/search/providers/codex.d.ts +2 -1
- package/dist/types/web/search/providers/exa.d.ts +2 -1
- package/dist/types/web/search/providers/gemini.d.ts +10 -6
- package/dist/types/web/search/providers/jina.d.ts +7 -2
- package/dist/types/web/search/providers/kagi.d.ts +7 -2
- package/dist/types/web/search/providers/kimi.d.ts +7 -2
- package/dist/types/web/search/providers/parallel.d.ts +2 -1
- package/dist/types/web/search/providers/perplexity.d.ts +10 -2
- package/dist/types/web/search/providers/searxng.d.ts +2 -1
- package/dist/types/web/search/providers/synthetic.d.ts +7 -3
- package/dist/types/web/search/providers/tavily.d.ts +2 -1
- package/dist/types/web/search/providers/zai.d.ts +2 -1
- package/dist/types/web/search/types.d.ts +1 -1
- package/examples/extensions/api-demo.ts +2 -2
- package/package.json +41 -15
- package/scripts/bench-guard.ts +71 -0
- package/scripts/build-binary.ts +24 -25
- package/scripts/bundle-dist.ts +97 -0
- package/scripts/generate-share-viewer.ts +34 -0
- package/scripts/prometheus +42 -0
- package/scripts/prometheus.ts +20 -0
- package/src/async/index.ts +0 -1
- package/src/async/job-manager.ts +106 -3
- package/src/auto-thinking/classifier.ts +2 -1
- package/src/autolearn/controller.ts +139 -0
- package/src/autolearn/managed-skills.ts +257 -0
- package/src/autoresearch/dashboard.ts +1 -1
- package/src/autoresearch/prompt-setup.md +6 -6
- package/src/autoresearch/prompt.md +6 -6
- package/src/autoresearch/state.ts +1 -1
- package/src/autoresearch/storage.ts +2 -1
- package/src/autoresearch/tools/init-experiment.ts +1 -1
- package/src/autoresearch/tools/log-experiment.ts +1 -1
- package/src/autoresearch/tools/run-experiment.ts +1 -1
- package/src/autoresearch/tools/update-notes.ts +1 -1
- package/src/autoresearch/types.ts +1 -1
- package/src/capability/context-file.ts +0 -14
- package/src/capability/fs.ts +10 -0
- package/src/capability/index.ts +1 -6
- package/src/capability/mcp.ts +1 -0
- package/src/capability/rule-buckets.ts +4 -2
- package/src/capability/rule.ts +10 -1
- package/src/capability/types.ts +0 -4
- package/src/cli/args.ts +66 -13
- package/src/cli/auth-broker-cli.ts +6 -7
- package/src/cli/auth-gateway-cli.ts +8 -9
- package/src/cli/bench-cli.ts +437 -0
- package/src/cli/claude-trace-cli.ts +28 -50
- package/src/cli/completion-gen.ts +28 -28
- package/src/cli/dry-balance-cli.ts +56 -23
- package/src/cli/gallery-cli.ts +231 -0
- package/src/cli/gallery-fixtures/agentic.ts +407 -0
- package/src/cli/gallery-fixtures/codeintel.ts +187 -0
- package/src/cli/gallery-fixtures/edit.ts +194 -0
- package/src/cli/gallery-fixtures/fs.ts +220 -0
- package/src/cli/gallery-fixtures/index.ts +40 -0
- package/src/cli/gallery-fixtures/interaction.ts +49 -0
- package/src/cli/gallery-fixtures/memory.ts +81 -0
- package/src/cli/gallery-fixtures/misc.ts +250 -0
- package/src/cli/gallery-fixtures/search.ts +213 -0
- package/src/cli/gallery-fixtures/shell.ts +167 -0
- package/src/cli/gallery-fixtures/types.ts +57 -0
- package/src/cli/gallery-fixtures/web.ts +158 -0
- package/src/cli/gallery-screenshot.ts +279 -0
- package/src/cli/grievances-cli.ts +1 -1
- package/src/cli/list-models.ts +16 -174
- package/src/cli/models-cli.ts +429 -0
- package/src/cli/session-picker.ts +2 -1
- package/src/cli/setup-cli.ts +148 -47
- package/src/cli/setup-model-picker.ts +43 -0
- package/src/cli/startup-cwd.ts +68 -0
- package/src/cli/update-cli.ts +144 -272
- package/src/cli/usage-cli.ts +774 -0
- package/src/cli-commands.ts +36 -0
- package/src/cli.ts +141 -32
- package/src/collab/crypto.ts +63 -0
- package/src/collab/guest.ts +451 -0
- package/src/collab/host.ts +565 -0
- package/src/collab/protocol.ts +241 -0
- package/src/collab/relay-client.ts +216 -0
- package/src/commands/bench.ts +42 -0
- package/src/commands/complete.ts +1 -1
- package/src/commands/gallery.ts +52 -0
- package/src/commands/install.ts +1 -1
- package/src/commands/join.ts +39 -0
- package/src/commands/launch.ts +8 -4
- package/src/commands/models.ts +61 -0
- package/src/commands/read.ts +6 -3
- package/src/commands/say.ts +102 -0
- package/src/commands/setup.ts +1 -1
- package/src/commands/token.ts +89 -0
- package/src/commands/usage.ts +43 -0
- package/src/commit/agentic/agent.ts +2 -1
- package/src/commit/agentic/tools/analyze-file.ts +42 -20
- package/src/commit/agentic/tools/git-file-diff.ts +1 -1
- package/src/commit/agentic/tools/git-hunk.ts +1 -1
- package/src/commit/agentic/tools/git-overview.ts +1 -1
- package/src/commit/agentic/tools/propose-changelog.ts +1 -1
- package/src/commit/agentic/tools/propose-commit.ts +1 -1
- package/src/commit/agentic/tools/recent-commits.ts +1 -1
- package/src/commit/agentic/tools/schemas.ts +1 -1
- package/src/commit/agentic/tools/split-commit.ts +9 -2
- package/src/commit/analysis/conventional.ts +2 -2
- package/src/commit/analysis/summary.ts +3 -3
- package/src/commit/changelog/generate.ts +3 -3
- package/src/commit/changelog/index.ts +2 -2
- package/src/commit/map-reduce/index.ts +3 -3
- package/src/commit/map-reduce/map-phase.ts +2 -2
- package/src/commit/map-reduce/reduce-phase.ts +2 -2
- package/src/commit/model-selection.ts +35 -12
- package/src/commit/pipeline.ts +4 -4
- package/src/commit/shared-llm.ts +1 -1
- package/src/config/api-key-resolver.ts +67 -0
- package/src/config/append-only-context-mode.ts +6 -12
- package/src/config/keybindings.ts +9 -4
- package/src/config/mcp-schema.json +4 -0
- package/src/config/model-discovery.ts +574 -0
- package/src/config/model-equivalence.ts +5 -4
- package/src/config/model-registry.ts +659 -1093
- package/src/config/model-resolver.ts +374 -174
- package/src/config/model-roles.ts +88 -0
- package/src/config/models-config-schema.ts +61 -9
- package/src/config/models-config.ts +130 -0
- package/src/config/settings-schema.ts +1441 -387
- package/src/config/settings.ts +261 -69
- package/src/dap/client.ts +138 -53
- package/src/dap/config.ts +41 -2
- package/src/dap/defaults.json +1 -0
- package/src/dap/session.ts +263 -161
- package/src/dap/types.ts +10 -0
- package/src/debug/index.ts +50 -60
- package/src/debug/log-viewer.ts +1 -1
- package/src/debug/protocol-probe.ts +1 -1
- package/src/debug/raw-sse-buffer.ts +7 -4
- package/src/debug/raw-sse.ts +1 -1
- package/src/debug/report-bundle.ts +9 -0
- package/src/debug/terminal-info.ts +0 -3
- package/src/discovery/agents-md.ts +25 -21
- package/src/discovery/agents.ts +9 -15
- package/src/discovery/at-imports.ts +273 -0
- package/src/discovery/builtin-rules/index.ts +4 -0
- package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
- package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
- package/src/discovery/builtin.ts +45 -23
- package/src/discovery/claude-plugins.ts +44 -5
- package/src/discovery/helpers.ts +50 -9
- package/src/discovery/prometheus-extension-roots.ts +10 -10
- package/src/discovery/prometheus-plugins.ts +10 -10
- package/src/edit/diff.ts +191 -4
- package/src/edit/file-snapshot-store.ts +34 -1
- package/src/edit/hashline/block-resolver.ts +20 -1
- package/src/edit/hashline/diff.ts +123 -2
- package/src/edit/hashline/execute.ts +60 -4
- package/src/edit/hashline/filesystem.ts +2 -1
- package/src/edit/hashline/noop-loop-guard.ts +99 -0
- package/src/edit/hashline/params.ts +1 -1
- package/src/edit/index.ts +47 -18
- package/src/edit/modes/apply-patch.ts +1 -1
- package/src/edit/modes/patch.ts +59 -3
- package/src/edit/modes/replace.ts +58 -24
- package/src/edit/notebook.ts +22 -2
- package/src/edit/renderer.ts +315 -151
- package/src/eval/__tests__/agent-bridge.test.ts +105 -39
- package/src/eval/__tests__/budget-bridge.test.ts +1 -1
- package/src/eval/__tests__/completion-bridge.test.ts +412 -0
- package/src/eval/__tests__/helpers-local-roots.test.ts +58 -0
- package/src/eval/__tests__/js-context-manager.test.ts +241 -0
- package/src/eval/__tests__/llm-bridge.test.ts +6 -4
- package/src/eval/__tests__/shared-executors.test.ts +34 -92
- package/src/eval/agent-bridge.ts +39 -23
- package/src/eval/backend.ts +15 -2
- package/src/eval/bridge-timeout.ts +1 -1
- package/src/eval/completion-bridge.ts +203 -0
- package/src/eval/idle-timeout.ts +3 -10
- package/src/eval/js/context-manager.ts +108 -31
- package/src/eval/js/executor.ts +9 -2
- package/src/eval/js/index.ts +7 -3
- package/src/eval/js/shared/helpers.ts +59 -13
- package/src/eval/js/shared/local-module-loader.ts +2 -2
- package/src/eval/js/shared/prelude.txt +167 -30
- package/src/eval/js/shared/rewrite-imports.ts +58 -34
- package/src/eval/js/shared/runtime.ts +24 -16
- package/src/eval/js/tool-bridge.ts +4 -0
- package/src/eval/js/worker-core.ts +1 -0
- package/src/eval/js/worker-entry.ts +6 -0
- package/src/eval/js/worker-protocol.ts +6 -0
- package/src/eval/llm-bridge.ts +2 -1
- package/src/eval/py/__tests__/prelude.test.ts +19 -0
- package/src/eval/py/executor.ts +70 -26
- package/src/eval/py/index.ts +13 -4
- package/src/eval/py/kernel.ts +48 -9
- package/src/eval/py/prelude.py +73 -24
- package/src/eval/py/runner.py +133 -28
- package/src/eval/py/runtime.ts +38 -1
- package/src/exa/index.ts +1 -26
- package/src/exa/mcp-client.ts +10 -10
- package/src/exa/types.ts +0 -97
- package/src/exec/bash-executor.ts +104 -7
- package/src/export/custom-share.ts +1 -1
- package/src/export/html/index.ts +119 -17
- package/src/export/html/share-loader.js +102 -0
- package/src/export/html/template-js.ts +6 -0
- package/src/export/html/template.css +745 -459
- package/src/export/html/template.css.d.ts +2 -0
- package/src/export/html/template.html +6 -3
- package/src/export/html/template.js +277 -891
- package/src/export/html/tool-views.generated.d.ts +2 -0
- package/src/export/html/tool-views.generated.js +38 -0
- package/src/export/share.ts +269 -0
- package/src/export/ttsr.ts +122 -1
- package/src/extensibility/custom-commands/loader.ts +7 -4
- package/src/extensibility/custom-commands/types.ts +9 -4
- package/src/extensibility/custom-tools/loader.ts +51 -23
- package/src/extensibility/custom-tools/types.ts +16 -8
- package/src/extensibility/extensions/get-commands-handler.ts +2 -1
- package/src/extensibility/extensions/index.ts +1 -0
- package/src/extensibility/extensions/loader.ts +70 -20
- package/src/extensibility/extensions/model-api.ts +41 -0
- package/src/extensibility/extensions/runner.ts +12 -2
- package/src/extensibility/extensions/types.ts +83 -11
- package/src/extensibility/extensions/wrapper.ts +41 -5
- package/src/extensibility/hooks/index.ts +2 -1
- package/src/extensibility/hooks/loader.ts +6 -3
- package/src/extensibility/hooks/types.ts +11 -5
- package/src/extensibility/{legacy-pi-ai-shim.ts → legacy-package-ai-shim.ts} +2 -2
- package/src/extensibility/plugins/doctor.ts +1 -2
- package/src/extensibility/plugins/installer.ts +2 -2
- package/src/extensibility/plugins/{legacy-pi-compat.ts → legacy-package-compat.ts} +165 -77
- package/src/extensibility/plugins/loader.ts +34 -23
- package/src/extensibility/plugins/manager.ts +226 -95
- package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
- package/src/extensibility/plugins/types.ts +3 -3
- package/src/extensibility/shared-events.ts +3 -3
- package/src/extensibility/skills.ts +113 -9
- package/src/extensibility/slash-commands.ts +1 -97
- package/src/goals/guided-setup.ts +133 -0
- package/src/goals/state.ts +1 -1
- package/src/goals/tools/goal-tool.ts +38 -28
- package/src/hindsight/bank.ts +17 -2
- package/src/hindsight/client.ts +27 -2
- package/src/hindsight/mental-models.ts +59 -12
- package/src/hindsight/state.ts +12 -3
- package/src/hindsight/transcript.ts +1 -1
- package/src/index.ts +5 -0
- package/src/internal-urls/artifact-protocol.ts +11 -2
- package/src/internal-urls/docs-index.generated.ts +9 -7
- package/src/internal-urls/history-protocol.ts +113 -0
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/issue-pr-protocol.ts +22 -9
- package/src/internal-urls/local-protocol.ts +42 -7
- package/src/internal-urls/memory-protocol.ts +4 -31
- package/src/internal-urls/router.ts +3 -1
- package/src/internal-urls/types.ts +1 -1
- package/src/irc/bus.ts +303 -0
- package/src/lib/xai-http.ts +3 -3
- package/src/lsp/client.ts +245 -104
- package/src/lsp/clients/biome-client.ts +101 -39
- package/src/lsp/clients/lsp-linter-client.ts +2 -10
- package/src/lsp/config.ts +15 -5
- package/src/lsp/defaults.json +6 -0
- package/src/lsp/edits.ts +143 -95
- package/src/lsp/format-options.ts +119 -0
- package/src/lsp/index.ts +233 -93
- package/src/lsp/render.ts +11 -35
- package/src/lsp/types.ts +13 -1
- package/src/lsp/utils.ts +31 -12
- package/src/main.ts +396 -216
- package/src/mcp/config-writer.ts +7 -3
- package/src/mcp/json-rpc.ts +35 -5
- package/src/mcp/manager.ts +31 -16
- package/src/mcp/oauth-discovery.ts +34 -4
- package/src/mcp/oauth-flow.ts +61 -8
- package/src/mcp/render.ts +7 -1
- package/src/mcp/startup-events.ts +21 -0
- package/src/mcp/tool-bridge.ts +2 -0
- package/src/mcp/transports/stdio.ts +224 -4
- package/src/mcp/types.ts +2 -0
- package/src/memories/index.ts +174 -1128
- package/src/memories/storage.ts +2 -41
- package/src/memory-backend/index.ts +14 -1
- package/src/memory-backend/local-backend.ts +18 -3
- package/src/memory-backend/off-backend.ts +9 -0
- package/src/memory-backend/resolve.ts +4 -6
- package/src/memory-backend/runtime.ts +66 -0
- package/src/memory-backend/types.ts +82 -2
- package/src/mnemopi/backend.ts +220 -28
- package/src/mnemopi/config.ts +138 -33
- package/src/mnemopi/state.ts +91 -11
- package/src/modes/acp/acp-agent.ts +149 -142
- package/src/modes/acp/acp-event-mapper.ts +5 -1
- package/src/modes/components/agent-dashboard.ts +17 -11
- package/src/modes/components/agent-hub.ts +1346 -0
- package/src/modes/components/assistant-message.ts +190 -80
- package/src/modes/components/bash-execution.ts +1 -1
- package/src/modes/components/btw-panel.ts +5 -1
- package/src/modes/components/chat-block.ts +111 -0
- package/src/modes/components/collab-prompt-message.ts +30 -0
- package/src/modes/components/compaction-summary-message.ts +168 -33
- package/src/modes/components/copy-selector.ts +2 -45
- package/src/modes/components/custom-editor.test.ts +96 -0
- package/src/modes/components/custom-editor.ts +405 -118
- package/src/modes/components/custom-message.ts +1 -3
- package/src/modes/components/diff.ts +13 -2
- package/src/modes/components/dynamic-border.ts +12 -3
- package/src/modes/components/execution-shared.ts +1 -2
- package/src/modes/components/extensions/extension-dashboard.ts +8 -5
- package/src/modes/components/extensions/extension-list.ts +1 -1
- package/src/modes/components/extensions/inspector-panel.ts +7 -3
- package/src/modes/components/extensions/state-manager.ts +36 -41
- package/src/modes/components/footer.ts +4 -2
- package/src/modes/components/history-search.ts +1 -1
- package/src/modes/components/hook-editor.ts +8 -0
- package/src/modes/components/hook-input.ts +8 -0
- package/src/modes/components/hook-message.ts +1 -3
- package/src/modes/components/hook-selector.ts +6 -7
- package/src/modes/components/index.ts +1 -0
- package/src/modes/components/late-diagnostics-message.ts +60 -0
- package/src/modes/components/login-dialog.ts +1 -1
- package/src/modes/components/logout-account-selector.ts +130 -0
- package/src/modes/components/mcp-add-wizard.ts +14 -1
- package/src/modes/components/model-selector.ts +177 -75
- package/src/modes/components/oauth-selector.ts +102 -16
- package/src/modes/components/overlay-box.ts +108 -0
- package/src/modes/components/plan-review-overlay.ts +845 -0
- package/src/modes/components/plan-toc.ts +138 -0
- package/src/modes/components/plugin-settings.ts +22 -5
- package/src/modes/components/read-tool-group.ts +442 -39
- package/src/modes/components/reset-usage-selector.ts +161 -0
- package/src/modes/components/segment-track.ts +44 -7
- package/src/modes/components/session-selector.ts +97 -37
- package/src/modes/components/settings-defs.ts +28 -6
- package/src/modes/components/settings-selector.ts +541 -93
- package/src/modes/components/skill-message.ts +0 -1
- package/src/modes/components/snapcompact-shape-preview-doc.md +11 -0
- package/src/modes/components/snapcompact-shape-preview.ts +193 -0
- package/src/modes/components/{status-line.ts → status-line/component.ts} +205 -168
- package/src/modes/components/status-line/index.ts +1 -0
- package/src/modes/components/status-line/presets.ts +3 -3
- package/src/modes/components/status-line/segments.ts +26 -7
- package/src/modes/components/status-line/types.ts +40 -9
- package/src/modes/components/tiny-title-download-progress.ts +1 -1
- package/src/modes/components/tips.txt +7 -3
- package/src/modes/components/todo-reminder.ts +0 -2
- package/src/modes/components/tool-execution.ts +236 -103
- package/src/modes/components/transcript-container.ts +724 -99
- package/src/modes/components/tree-selector.ts +19 -4
- package/src/modes/components/ttsr-notification.ts +72 -30
- package/src/modes/components/usage-row.ts +18 -0
- package/src/modes/components/user-message-selector.ts +1 -1
- package/src/modes/components/user-message.ts +28 -12
- package/src/modes/components/visual-truncate.ts +1 -1
- package/src/modes/components/welcome.ts +80 -22
- package/src/modes/controllers/command-controller-shared.ts +7 -6
- package/src/modes/controllers/command-controller.ts +210 -180
- package/src/modes/controllers/event-controller.ts +352 -142
- package/src/modes/controllers/extension-ui-controller.ts +167 -208
- package/src/modes/controllers/input-controller.ts +778 -162
- package/src/modes/controllers/mcp-command-controller.ts +232 -80
- package/src/modes/controllers/selector-controller.ts +284 -145
- package/src/modes/controllers/session-focus-controller.ts +112 -0
- package/src/modes/controllers/ssh-command-controller.ts +2 -2
- package/src/modes/controllers/streaming-reveal.ts +295 -0
- package/src/modes/controllers/tan-command-controller.ts +173 -0
- package/src/modes/controllers/tool-args-reveal.ts +174 -0
- package/src/modes/gradient-highlight.ts +21 -9
- package/src/modes/image-references.ts +33 -7
- package/src/modes/index.ts +8 -25
- package/src/modes/interactive-mode.ts +840 -186
- package/src/modes/magic-keywords.ts +28 -6
- package/src/modes/markdown-prose.ts +1 -1
- package/src/modes/oauth-manual-input.ts +30 -3
- package/src/modes/rpc/rpc-client.ts +186 -3
- package/src/modes/rpc/rpc-mode.ts +318 -24
- package/src/modes/rpc/rpc-subagents.ts +265 -0
- package/src/modes/rpc/rpc-types.ts +111 -2
- package/src/modes/runtime-init.ts +28 -3
- package/src/modes/session-observer-registry.ts +72 -3
- package/src/modes/setup-version.ts +11 -0
- package/src/modes/setup-wizard/index.ts +16 -4
- package/src/modes/setup-wizard/lazy.ts +16 -0
- package/src/modes/setup-wizard/scenes/glyph.ts +25 -7
- package/src/modes/setup-wizard/scenes/providers.ts +45 -12
- package/src/modes/setup-wizard/scenes/sign-in.ts +14 -13
- package/src/modes/setup-wizard/scenes/splash.ts +1 -1
- package/src/modes/setup-wizard/scenes/theme.ts +29 -2
- package/src/modes/setup-wizard/scenes/types.ts +11 -2
- package/src/modes/setup-wizard/scenes/web-search.ts +26 -9
- package/src/modes/setup-wizard/wizard-overlay.ts +40 -3
- package/src/modes/shared.ts +2 -0
- package/src/modes/theme/defaults/dark-poimandres.json +1 -1
- package/src/modes/theme/defaults/light-poimandres.json +1 -1
- package/src/modes/theme/shimmer.ts +20 -9
- package/src/modes/theme/theme-schema.json +1 -1
- package/src/modes/theme/theme.ts +342 -82
- package/src/modes/types.ts +60 -18
- package/src/modes/utils/context-usage.ts +88 -8
- package/src/modes/utils/copy-targets.ts +133 -27
- package/src/modes/utils/hotkeys-markdown.ts +3 -2
- package/src/modes/utils/ui-helpers.ts +191 -110
- package/src/modes/workflow.ts +10 -10
- package/src/plan-mode/approved-plan.ts +66 -43
- package/src/plan-mode/plan-protection.ts +4 -4
- package/src/priority.json +5 -1
- package/src/prompts/agents/designer.md +1 -1
- package/src/prompts/agents/explore.md +3 -3
- package/src/prompts/agents/librarian.md +2 -3
- package/src/prompts/agents/oracle.md +2 -2
- package/src/prompts/agents/plan.md +6 -6
- package/src/prompts/agents/reviewer.md +1 -1
- package/src/prompts/agents/task.md +6 -5
- package/src/prompts/bench.md +12 -0
- package/src/prompts/ci-green-request.md +5 -7
- package/src/prompts/goals/goal-budget-limit.md +2 -2
- package/src/prompts/goals/goal-continuation.md +4 -4
- package/src/prompts/goals/goal-mode-active.md +1 -1
- package/src/prompts/goals/guided-goal-interview.md +8 -0
- package/src/prompts/goals/guided-goal-system.md +12 -0
- package/src/prompts/memories/consolidation.md +2 -7
- package/src/prompts/memories/consolidation_system.md +4 -0
- package/src/prompts/memories/identity_review.md +2 -2
- package/src/prompts/memories/read-path.md +11 -10
- package/src/prompts/memories/stage_one_system.md +2 -2
- package/src/prompts/review-custom-request.md +1 -1
- package/src/prompts/system/agent-creation-architect.md +2 -2
- package/src/prompts/system/auto-continue.md +1 -1
- package/src/prompts/system/autolearn-guidance-learn.md +1 -0
- package/src/prompts/system/autolearn-guidance.md +7 -0
- package/src/prompts/system/autolearn-nudge.md +3 -0
- package/src/prompts/system/background-tan-dispatch.md +8 -0
- package/src/prompts/system/btw-user.md +2 -2
- package/src/prompts/system/commit-message-system.md +13 -1
- package/src/prompts/system/custom-system-prompt.md +1 -1
- package/src/prompts/system/eager-task.md +7 -0
- package/src/prompts/system/eager-todo.md +11 -6
- package/src/prompts/system/empty-stop-retry.md +4 -6
- package/src/prompts/system/irc-autoreply.md +6 -0
- package/src/prompts/system/irc-incoming.md +3 -4
- package/src/prompts/system/manual-continue.md +7 -0
- package/src/prompts/system/omfg-user.md +3 -4
- package/src/prompts/system/orchestrate-notice.md +10 -10
- package/src/prompts/system/personalities/default.md +26 -0
- package/src/prompts/system/personalities/friendly.md +17 -0
- package/src/prompts/system/personalities/pragmatic.md +15 -0
- package/src/prompts/system/plan-mode-active.md +70 -77
- package/src/prompts/system/plan-mode-approved.md +1 -1
- package/src/prompts/system/plan-mode-subagent.md +4 -5
- package/src/prompts/system/plan-mode-tool-decision-reminder.md +1 -1
- package/src/prompts/system/project-prompt.md +2 -2
- package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
- package/src/prompts/system/snapcompact-context-stub.md +1 -0
- package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
- package/src/prompts/system/snapcompact-system-stub.md +1 -0
- package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
- package/src/prompts/system/subagent-system-prompt.md +7 -8
- package/src/prompts/system/system-prompt.md +28 -57
- package/src/prompts/system/tiny-title-system.md +1 -1
- package/src/prompts/system/title-marker-instruction.md +1 -0
- package/src/prompts/system/title-system-marker.md +16 -0
- package/src/prompts/system/title-system.md +16 -3
- package/src/prompts/system/ttsr-tool-reminder.md +1 -1
- package/src/prompts/system/workflow-notice.md +4 -4
- package/src/prompts/tools/ast-edit.md +1 -1
- package/src/prompts/tools/ast-grep.md +2 -2
- package/src/prompts/tools/bash.md +16 -8
- package/src/prompts/tools/browser.md +33 -43
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/eval.md +31 -51
- package/src/prompts/tools/find.md +0 -1
- package/src/prompts/tools/github.md +8 -7
- package/src/prompts/tools/goal.md +1 -1
- package/src/prompts/tools/image-gen.md +1 -1
- package/src/prompts/tools/inspect-image-system.md +1 -1
- package/src/prompts/tools/irc.md +39 -31
- package/src/prompts/tools/job.md +2 -1
- package/src/prompts/tools/learn.md +7 -0
- package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
- package/src/prompts/tools/lsp.md +2 -2
- package/src/prompts/tools/manage-skill.md +9 -0
- package/src/prompts/tools/memory-edit.md +1 -1
- package/src/prompts/tools/patch.md +2 -2
- package/src/prompts/tools/read.md +31 -39
- package/src/prompts/tools/recall.md +1 -1
- package/src/prompts/tools/reflect.md +1 -1
- package/src/prompts/tools/render-mermaid.md +2 -2
- package/src/prompts/tools/replace.md +4 -10
- package/src/prompts/tools/rewind.md +2 -2
- package/src/prompts/tools/search-tool-bm25.md +1 -9
- package/src/prompts/tools/search.md +0 -1
- package/src/prompts/tools/ssh.md +0 -4
- package/src/prompts/tools/task-summary.md +5 -16
- package/src/prompts/tools/task.md +47 -31
- package/src/prompts/tools/todo.md +6 -3
- package/src/registry/agent-lifecycle.ts +218 -0
- package/src/registry/agent-registry.ts +46 -5
- package/src/sdk.ts +692 -219
- package/src/secrets/index.ts +8 -1
- package/src/secrets/obfuscator.ts +40 -19
- package/src/session/agent-session.ts +1577 -806
- package/src/session/agent-storage.ts +18 -9
- package/src/session/auth-broker-config.ts +30 -1
- package/src/session/auth-storage.ts +6 -0
- package/src/session/codex-auto-reset.ts +202 -0
- package/src/session/history-storage.ts +3 -2
- package/src/session/indexed-session-storage.ts +7 -10
- package/src/session/messages.ts +59 -95
- package/src/session/session-context.ts +352 -0
- package/src/session/session-dump-format.ts +12 -3
- package/src/session/session-entries.ts +194 -0
- package/src/session/session-history-format.ts +246 -0
- package/src/session/session-listing.ts +588 -0
- package/src/session/session-loader.ts +106 -0
- package/src/session/session-manager.ts +1003 -2920
- package/src/session/session-migrations.ts +78 -0
- package/src/session/session-paths.ts +193 -0
- package/src/session/session-persistence.ts +131 -0
- package/src/session/session-storage.ts +91 -30
- package/src/session/snapcompact-inline.ts +542 -0
- package/src/session/snapcompact-savings-journal.ts +113 -0
- package/src/session/streaming-output.ts +248 -11
- package/src/session/tool-choice-queue.ts +23 -11
- package/src/session/yield-queue.ts +20 -2
- package/src/slash-commands/acp-builtins.ts +25 -1
- package/src/slash-commands/available-commands.ts +105 -0
- package/src/slash-commands/builtin-registry.ts +575 -49
- package/src/slash-commands/helpers/active-oauth-account.ts +44 -0
- package/src/slash-commands/helpers/context-report.ts +28 -1
- package/src/slash-commands/helpers/logout.ts +88 -0
- package/src/slash-commands/helpers/reset-usage.ts +66 -0
- package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
- package/src/slash-commands/helpers/usage-report.ts +38 -3
- package/src/slash-commands/types.ts +5 -9
- package/src/ssh/connection-manager.ts +27 -0
- package/src/ssh/ssh-executor.ts +60 -4
- package/src/stt/asr-client.ts +520 -0
- package/src/stt/asr-protocol.ts +65 -0
- package/src/stt/asr-worker.ts +790 -0
- package/src/stt/downloader.ts +107 -47
- package/src/stt/endpointer.ts +259 -0
- package/src/stt/index.ts +5 -1
- package/src/stt/models.ts +150 -0
- package/src/stt/recorder.ts +254 -67
- package/src/stt/stt-controller.ts +201 -22
- package/src/stt/transcriber.ts +37 -68
- package/src/stt/wav.ts +173 -0
- package/src/system-prompt.ts +52 -10
- package/src/task/agents.ts +3 -4
- package/src/task/commands.ts +3 -2
- package/src/task/discovery.ts +17 -24
- package/src/task/executor.ts +1054 -529
- package/src/task/index.ts +862 -757
- package/src/task/output-manager.ts +0 -11
- package/src/task/parallel.ts +3 -3
- package/src/task/prometheus-command.ts +2 -2
- package/src/task/render.ts +529 -182
- package/src/task/repair-args.ts +21 -9
- package/src/task/types.ts +144 -66
- package/src/task/worktree.ts +64 -56
- package/src/telemetry-export.ts +27 -9
- package/src/thinking.ts +9 -7
- package/src/tiny/models.ts +2 -2
- package/src/tiny/text.ts +5 -1
- package/src/tiny/title-client.ts +72 -20
- package/src/tiny/title-protocol.ts +1 -1
- package/src/tiny/worker.ts +23 -99
- package/src/tool-discovery/tool-index.ts +2 -0
- package/src/tools/archive-reader.ts +94 -2
- package/src/tools/ask.ts +234 -177
- package/src/tools/ast-edit.ts +136 -80
- package/src/tools/ast-grep.ts +41 -45
- package/src/tools/auto-generated-guard.ts +20 -3
- package/src/tools/bash-interactive.ts +28 -8
- package/src/tools/bash.ts +198 -35
- package/src/tools/browser/attach.ts +26 -7
- package/src/tools/browser/cmux/cmux-tab.ts +1264 -0
- package/src/tools/browser/cmux/rpc.ts +156 -0
- package/src/tools/browser/cmux/socket-client.ts +309 -0
- package/src/tools/browser/launch.ts +11 -2
- package/src/tools/browser/readable.ts +19 -2
- package/src/tools/browser/registry.ts +52 -5
- package/src/tools/browser/render.ts +13 -5
- package/src/tools/browser/tab-protocol.ts +2 -0
- package/src/tools/browser/tab-supervisor.ts +256 -34
- package/src/tools/browser/tab-worker.ts +259 -91
- package/src/tools/browser.ts +44 -2
- package/src/tools/checkpoint.ts +1 -1
- package/src/tools/conflict-detect.ts +50 -4
- package/src/tools/debug.ts +27 -12
- package/src/tools/eval-render.ts +32 -35
- package/src/tools/eval.ts +26 -12
- package/src/tools/fetch.ts +450 -99
- package/src/tools/find.ts +182 -142
- package/src/tools/gh-cache-invalidation.ts +255 -0
- package/src/tools/gh-renderer.ts +104 -51
- package/src/tools/gh.ts +232 -37
- package/src/tools/github-cache.ts +97 -7
- package/src/tools/grouped-file-output.ts +159 -52
- package/src/tools/image-gen.ts +237 -132
- package/src/tools/index.ts +147 -26
- package/src/tools/inspect-image-renderer.ts +74 -45
- package/src/tools/inspect-image.ts +12 -6
- package/src/tools/irc.ts +626 -173
- package/src/tools/job.ts +106 -29
- package/src/tools/learn.ts +144 -0
- package/src/tools/manage-skill.ts +104 -0
- package/src/tools/memory-edit.ts +4 -4
- package/src/tools/memory-recall.ts +7 -9
- package/src/tools/memory-reflect.ts +5 -9
- package/src/tools/memory-render.ts +23 -6
- package/src/tools/memory-retain.ts +4 -4
- package/src/tools/path-utils.ts +102 -48
- package/src/tools/plan-mode-guard.ts +101 -40
- package/src/tools/read.ts +475 -120
- package/src/tools/render-mermaid.ts +1 -1
- package/src/tools/render-utils.ts +132 -76
- package/src/tools/renderers.ts +12 -1
- package/src/tools/report-tool-issue.ts +14 -6
- package/src/tools/resolve.ts +20 -3
- package/src/tools/review.ts +2 -2
- package/src/tools/search-tool-bm25.ts +37 -24
- package/src/tools/search.ts +233 -115
- package/src/tools/sqlite-reader.ts +26 -17
- package/src/tools/ssh.ts +20 -14
- package/src/tools/todo.ts +197 -191
- package/src/tools/tool-result.ts +8 -0
- package/src/tools/tool-timeouts.ts +1 -1
- package/src/tools/tts.ts +205 -74
- package/src/tools/write.ts +291 -155
- package/src/tools/yield.ts +10 -1
- package/src/tts/downloader.ts +64 -0
- package/src/tts/index.ts +8 -0
- package/src/tts/models.ts +137 -0
- package/src/tts/player.ts +137 -0
- package/src/tts/runtime.ts +21 -0
- package/src/tts/streaming-player.ts +266 -0
- package/src/tts/tts-client.ts +647 -0
- package/src/tts/tts-protocol.ts +60 -0
- package/src/tts/tts-worker.ts +505 -0
- package/src/tts/vocalizer.ts +162 -0
- package/src/tts/wav.ts +58 -0
- package/src/tui/code-cell.ts +2 -7
- package/src/tui/hyperlink.ts +40 -26
- package/src/tui/output-block.ts +60 -108
- package/src/tui/status-line.ts +5 -1
- package/src/utils/block-context.ts +312 -0
- package/src/utils/changelog.ts +27 -1
- package/src/utils/clipboard.ts +91 -22
- package/src/utils/commit-message-generator.ts +8 -3
- package/src/utils/enhanced-paste.ts +230 -0
- package/src/utils/file-mentions.ts +3 -1
- package/src/utils/git.ts +315 -15
- package/src/utils/image-loading.ts +65 -4
- package/src/utils/session-color.ts +83 -9
- package/src/utils/thinking-display.ts +37 -0
- package/src/utils/title-generator.ts +73 -10
- package/src/utils/tool-choice.ts +16 -0
- package/src/utils/tools-manager.ts +19 -1
- package/src/web/kagi.ts +28 -26
- package/src/web/parallel.ts +7 -3
- package/src/web/scrapers/arxiv.ts +1 -1
- package/src/web/scrapers/github.ts +351 -3
- package/src/web/scrapers/go-pkg.ts +1 -1
- package/src/web/scrapers/iacr.ts +1 -1
- package/src/web/scrapers/readthedocs.ts +1 -1
- package/src/web/scrapers/twitter.ts +2 -1
- package/src/web/scrapers/types.ts +87 -8
- package/src/web/scrapers/wikipedia.ts +1 -1
- package/src/web/scrapers/youtube.ts +9 -3
- package/src/web/search/index.ts +15 -2
- package/src/web/search/providers/anthropic.ts +62 -21
- package/src/web/search/providers/base.ts +2 -1
- package/src/web/search/providers/brave.ts +5 -2
- package/src/web/search/providers/codex.ts +87 -51
- package/src/web/search/providers/exa.ts +101 -10
- package/src/web/search/providers/gemini.ts +49 -24
- package/src/web/search/providers/jina.ts +15 -5
- package/src/web/search/providers/kagi.ts +9 -2
- package/src/web/search/providers/kimi.ts +45 -20
- package/src/web/search/providers/parallel.ts +39 -24
- package/src/web/search/providers/perplexity.ts +226 -63
- package/src/web/search/providers/searxng.ts +19 -3
- package/src/web/search/providers/synthetic.ts +16 -11
- package/src/web/search/providers/tavily.ts +12 -9
- package/src/web/search/providers/zai.ts +22 -9
- package/src/web/search/render.ts +59 -64
- package/src/web/search/types.ts +5 -1
- package/dist/types/discovery/context-files.d.ts +0 -17
- package/dist/types/exa/factory.d.ts +0 -13
- package/dist/types/exa/render.d.ts +0 -19
- package/dist/types/exa/researcher.d.ts +0 -9
- package/dist/types/exa/search.d.ts +0 -9
- package/dist/types/exa/websets.d.ts +0 -9
- package/dist/types/export/html/template.generated.d.ts +0 -1
- package/dist/types/modes/components/session-observer-overlay.d.ts +0 -11
- package/dist/types/modes/components/status-line.d.ts +0 -77
- package/dist/types/slash-commands/headless-plan.d.ts +0 -3
- package/dist/types/stt/setup.d.ts +0 -18
- package/scripts/generate-template.ts +0 -33
- package/src/discovery/context-files.ts +0 -49
- package/src/exa/factory.ts +0 -60
- package/src/exa/render.ts +0 -244
- package/src/exa/researcher.ts +0 -36
- package/src/exa/search.ts +0 -47
- package/src/exa/websets.ts +0 -248
- package/src/export/html/template.generated.ts +0 -2
- package/src/modes/components/session-observer-overlay.ts +0 -852
- package/src/slash-commands/headless-plan.ts +0 -142
- package/src/stt/setup.ts +0 -52
- package/src/stt/transcribe.py +0 -70
- /package/dist/types/extensibility/{legacy-pi-coding-agent-shim.d.ts → legacy-package-agent-shim.d.ts} +0 -0
- /package/src/extensibility/{legacy-pi-coding-agent-shim.ts → legacy-package-agent-shim.ts} +0 -0
package/src/memories/index.ts
CHANGED
|
@@ -3,16 +3,16 @@ import type * as fsNode from "node:fs";
|
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import type { AgentMessage } from "@prometheus-ai/agent-core";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { type ApiKey, completeSimple, Effort, type Model } from "@prometheus-ai/ai";
|
|
7
|
+
import { clampThinkingLevelForModel } from "@prometheus-ai/catalog/model-thinking";
|
|
8
|
+
import { getAgentDbPath, getMemoriesDir, isEnoent, logger, parseJsonlLenient, prompt } from "@prometheus-ai/utils";
|
|
9
|
+
|
|
9
10
|
import type { ModelRegistry } from "../config/model-registry";
|
|
10
|
-
import { resolveModelRoleValue } from "../config/model-resolver";
|
|
11
|
+
import { getModelMatchPreferences, resolveModelRoleValue } from "../config/model-resolver";
|
|
11
12
|
import type { Settings } from "../config/settings";
|
|
12
|
-
import {
|
|
13
|
+
import type { MemoryBackendSaveInput, MemoryBackendSaveResult } from "../memory-backend/types";
|
|
13
14
|
import consolidationTemplate from "../prompts/memories/consolidation.md" with { type: "text" };
|
|
14
|
-
import
|
|
15
|
-
import postTurnReviewTemplate from "../prompts/memories/post_turn_review.md" with { type: "text" };
|
|
15
|
+
import consolidationSystemTemplate from "../prompts/memories/consolidation_system.md" with { type: "text" };
|
|
16
16
|
import readPathTemplate from "../prompts/memories/read-path.md" with { type: "text" };
|
|
17
17
|
import stageOneInputTemplate from "../prompts/memories/stage_one_input.md" with { type: "text" };
|
|
18
18
|
import stageOneSystemTemplate from "../prompts/memories/stage_one_system.md" with { type: "text" };
|
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
markStage1SucceededNoOutput,
|
|
33
33
|
markStage1SucceededWithOutput,
|
|
34
34
|
openMemoryDb,
|
|
35
|
-
recordBackgroundStage1Output,
|
|
36
35
|
type Stage1Claim,
|
|
37
36
|
type Stage1OutputRow,
|
|
38
37
|
tryClaimGlobalPhase2Job,
|
|
@@ -41,13 +40,6 @@ import {
|
|
|
41
40
|
|
|
42
41
|
interface MemoryRuntimeConfig {
|
|
43
42
|
enabled: boolean;
|
|
44
|
-
selfImprovementMode: "memory-and-skills" | "off";
|
|
45
|
-
backgroundReviewMode: "memory-and-skills" | "off";
|
|
46
|
-
backgroundReviewEveryNTurns: number;
|
|
47
|
-
identityReviewMode: "propose" | "off";
|
|
48
|
-
curatorMode: "dry-run" | "off";
|
|
49
|
-
generatedSkillStaleAfterDays: number;
|
|
50
|
-
generatedSkillArchiveAfterDays: number;
|
|
51
43
|
maxRolloutsPerStartup: number;
|
|
52
44
|
maxRolloutAgeDays: number;
|
|
53
45
|
minRolloutIdleHours: number;
|
|
@@ -67,13 +59,6 @@ interface MemoryRuntimeConfig {
|
|
|
67
59
|
|
|
68
60
|
const DEFAULTS: MemoryRuntimeConfig = {
|
|
69
61
|
enabled: false,
|
|
70
|
-
selfImprovementMode: "memory-and-skills",
|
|
71
|
-
backgroundReviewMode: "memory-and-skills",
|
|
72
|
-
backgroundReviewEveryNTurns: 10,
|
|
73
|
-
identityReviewMode: "propose",
|
|
74
|
-
curatorMode: "dry-run",
|
|
75
|
-
generatedSkillStaleAfterDays: 30,
|
|
76
|
-
generatedSkillArchiveAfterDays: 90,
|
|
77
62
|
maxRolloutsPerStartup: 64,
|
|
78
63
|
maxRolloutAgeDays: 30,
|
|
79
64
|
minRolloutIdleHours: 12,
|
|
@@ -91,8 +76,6 @@ const DEFAULTS: MemoryRuntimeConfig = {
|
|
|
91
76
|
summaryInjectionTokenLimit: 5_000,
|
|
92
77
|
};
|
|
93
78
|
|
|
94
|
-
const GENERATED_MEMORY_SKILL_INDEX_LIMIT = 50;
|
|
95
|
-
|
|
96
79
|
interface Stage1Stats {
|
|
97
80
|
claimed: number;
|
|
98
81
|
succeeded: number;
|
|
@@ -114,11 +97,6 @@ interface Stage1OutputSchema {
|
|
|
114
97
|
rollout_slug: string | null;
|
|
115
98
|
}
|
|
116
99
|
|
|
117
|
-
interface PostTurnReviewMessage {
|
|
118
|
-
role: "user" | "assistant";
|
|
119
|
-
content: string;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
100
|
interface ConsolidationSkillFileSchema {
|
|
123
101
|
path: string;
|
|
124
102
|
content: string;
|
|
@@ -133,94 +111,10 @@ interface ConsolidationSkillSchema {
|
|
|
133
111
|
}
|
|
134
112
|
interface ConsolidationOutputSchema {
|
|
135
113
|
memory_md: string;
|
|
136
|
-
user_md: string;
|
|
137
114
|
memory_summary: string;
|
|
138
115
|
skills: ConsolidationSkillSchema[];
|
|
139
116
|
}
|
|
140
117
|
|
|
141
|
-
type GeneratedMemorySkillState = "active" | "stale" | "archived";
|
|
142
|
-
type GeneratedMemorySkillEvent = "use" | "view" | "patch";
|
|
143
|
-
|
|
144
|
-
interface GeneratedMemorySkillUsageRecord {
|
|
145
|
-
schemaVersion: 1;
|
|
146
|
-
name: string;
|
|
147
|
-
source: "memory-consolidation";
|
|
148
|
-
state: GeneratedMemorySkillState;
|
|
149
|
-
pinned: boolean;
|
|
150
|
-
createdAt: string;
|
|
151
|
-
updatedAt: string;
|
|
152
|
-
lastSeenInConsolidationAt: string | null;
|
|
153
|
-
archivedAt: string | null;
|
|
154
|
-
archiveReason: string | null;
|
|
155
|
-
useCount: number;
|
|
156
|
-
viewCount: number;
|
|
157
|
-
patchCount: number;
|
|
158
|
-
lastUsedAt: string | null;
|
|
159
|
-
lastViewedAt: string | null;
|
|
160
|
-
lastPatchedAt: string | null;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
interface GeneratedMemorySkillUsageFile {
|
|
164
|
-
schemaVersion: 1;
|
|
165
|
-
skills: Record<string, GeneratedMemorySkillUsageRecord>;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
interface IdentityReviewResult {
|
|
169
|
-
soulProposal: string;
|
|
170
|
-
nativeSoulPath: string | null;
|
|
171
|
-
error?: string;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
interface SkillCurationResult {
|
|
175
|
-
usage: GeneratedMemorySkillUsageFile;
|
|
176
|
-
active: string[];
|
|
177
|
-
pinnedStale: string[];
|
|
178
|
-
archived: string[];
|
|
179
|
-
staleCandidates: string[];
|
|
180
|
-
archiveCandidates: string[];
|
|
181
|
-
markedStale: string[];
|
|
182
|
-
reactivated: string[];
|
|
183
|
-
report: string;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
export const MEMORY_ARTIFACTS = {
|
|
187
|
-
summary: "memory_summary.md",
|
|
188
|
-
memory: "MEMORY.md",
|
|
189
|
-
user: "USER.md",
|
|
190
|
-
selfImprovementReport: "self_improvement_report.md",
|
|
191
|
-
skillUsage: "skill_usage.json",
|
|
192
|
-
skillCuratorReport: "skill_curator_report.md",
|
|
193
|
-
soulProposal: "SOUL.proposed.md",
|
|
194
|
-
} as const;
|
|
195
|
-
|
|
196
|
-
const USER_PROFILE_OPEN_TAG = '<user_profile role="durable_user_context">';
|
|
197
|
-
const USER_PROFILE_CLOSE_TAG = "</user_profile>";
|
|
198
|
-
const POST_TURN_REVIEW_THREAD_PREFIX = "post-turn-review";
|
|
199
|
-
const postTurnReviewStates = new WeakMap<
|
|
200
|
-
AgentSession,
|
|
201
|
-
{ lastReviewedUserTurns: number; running: boolean; unsubscribe: () => void }
|
|
202
|
-
>();
|
|
203
|
-
|
|
204
|
-
const FORBIDDEN_IDENTITY_ARTIFACT_PATTERNS: ReadonlyArray<{ label: string; pattern: RegExp }> = [
|
|
205
|
-
{ label: "soul_md", pattern: /\bsoul_md\b/i },
|
|
206
|
-
{ label: "SOUL.md", pattern: /\bSOUL\.md\b/i },
|
|
207
|
-
{ label: "SOUL.proposed.md", pattern: /\bSOUL\.proposed\.md\b/i },
|
|
208
|
-
{ label: "<soul>", pattern: /<\s*\/?\s*soul\b/i },
|
|
209
|
-
{ label: "<soul_proposal>", pattern: /<\s*\/?\s*soul[_-]?proposal\b/i },
|
|
210
|
-
{ label: "<soul_proposed>", pattern: /<\s*\/?\s*soul[_-]?proposed\b/i },
|
|
211
|
-
{ label: "<identity>", pattern: /<\s*\/?\s*identity\b/i },
|
|
212
|
-
{ label: "<personality>", pattern: /<\s*\/?\s*personality\b/i },
|
|
213
|
-
{ label: "agent_identity", pattern: /\bagent_identity\b/i },
|
|
214
|
-
{ label: "assistant_identity", pattern: /\bassistant_identity\b/i },
|
|
215
|
-
{ label: "prometheus_identity", pattern: /\bprometheus_identity\b/i },
|
|
216
|
-
{ label: "identity_md", pattern: /\bidentity_md\b/i },
|
|
217
|
-
{ label: "persona_md", pattern: /\bpersona_md\b/i },
|
|
218
|
-
{ label: "personality_md", pattern: /\bpersonality_md\b/i },
|
|
219
|
-
{ label: "agent_personality", pattern: /\bagent_personality\b/i },
|
|
220
|
-
{ label: "assistant_personality", pattern: /\bassistant_personality\b/i },
|
|
221
|
-
{ label: "prometheus_personality", pattern: /\bprometheus_personality\b/i },
|
|
222
|
-
];
|
|
223
|
-
|
|
224
118
|
/**
|
|
225
119
|
* Start the background memory startup pipeline.
|
|
226
120
|
*
|
|
@@ -248,8 +142,6 @@ export function startMemoryStartupTask(options: {
|
|
|
248
142
|
return;
|
|
249
143
|
}
|
|
250
144
|
|
|
251
|
-
attachPostTurnBackgroundReview({ session, settings, modelRegistry, agentDir, config: cfg });
|
|
252
|
-
|
|
253
145
|
void runMemoryStartup({ session, settings, modelRegistry, agentDir, config: cfg }).catch(error => {
|
|
254
146
|
logger.warn("Memory startup failed", { error: String(error) });
|
|
255
147
|
});
|
|
@@ -265,47 +157,31 @@ export async function buildMemoryToolDeveloperInstructions(
|
|
|
265
157
|
const cfg = loadMemoryConfig(settings);
|
|
266
158
|
if (!cfg.enabled) return undefined;
|
|
267
159
|
const memoryRoot = getMemoryRoot(agentDir, settings.getCwd());
|
|
268
|
-
const summaryPath = path.join(memoryRoot, MEMORY_ARTIFACTS.summary);
|
|
269
160
|
|
|
270
|
-
let
|
|
161
|
+
let summary = "";
|
|
271
162
|
try {
|
|
272
|
-
|
|
163
|
+
summary = (await Bun.file(path.join(memoryRoot, "memory_summary.md")).text()).trim();
|
|
273
164
|
} catch {
|
|
274
|
-
|
|
165
|
+
// Missing or unreadable summary: injection is best-effort; fall through
|
|
166
|
+
// so any captured lessons still surface on their own.
|
|
275
167
|
}
|
|
168
|
+
const learned = await readLearnedLessons(memoryRoot);
|
|
169
|
+
if (!summary && !learned) return undefined;
|
|
276
170
|
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const
|
|
171
|
+
const summaryOut = summary ? truncateByApproxTokens(summary, cfg.summaryInjectionTokenLimit).trim() : "";
|
|
172
|
+
// Lessons share one injection budget with the summary so the combined block
|
|
173
|
+
// stays within `summaryInjectionTokenLimit` (~4 chars/token, matching
|
|
174
|
+
// truncateByApproxTokens). With no summary, lessons get the whole budget.
|
|
175
|
+
const learnedBudget = Math.max(0, cfg.summaryInjectionTokenLimit - Math.ceil(summaryOut.length / 4));
|
|
176
|
+
const learnedOut = learned && learnedBudget > 0 ? truncateByApproxTokens(learned, learnedBudget).trim() : "";
|
|
177
|
+
if (!summaryOut && !learnedOut) return undefined;
|
|
282
178
|
|
|
283
179
|
return prompt.render(readPathTemplate, {
|
|
284
|
-
memory_summary:
|
|
285
|
-
|
|
180
|
+
memory_summary: summaryOut,
|
|
181
|
+
learned: learnedOut,
|
|
286
182
|
});
|
|
287
183
|
}
|
|
288
184
|
|
|
289
|
-
async function buildGeneratedMemorySkillIndex(memoryRoot: string): Promise<string> {
|
|
290
|
-
const skillsDir = path.join(memoryRoot, "skills");
|
|
291
|
-
const dirents = await fs.readdir(skillsDir, { withFileTypes: true }).catch(() => []);
|
|
292
|
-
const names: string[] = [];
|
|
293
|
-
for (const dirent of dirents) {
|
|
294
|
-
if (!dirent.isDirectory()) continue;
|
|
295
|
-
const skillPath = path.join(skillsDir, dirent.name, "SKILL.md");
|
|
296
|
-
if (await Bun.file(skillPath).exists()) names.push(dirent.name);
|
|
297
|
-
}
|
|
298
|
-
names.sort((a, b) => a.localeCompare(b));
|
|
299
|
-
if (names.length === 0) return "None yet.";
|
|
300
|
-
const visible = names.slice(0, GENERATED_MEMORY_SKILL_INDEX_LIMIT);
|
|
301
|
-
const lines = visible.map(name => `- memory://root/skills/${name}/SKILL.md`);
|
|
302
|
-
const hidden = names.length - visible.length;
|
|
303
|
-
if (hidden > 0) {
|
|
304
|
-
lines.push(`- ... ${hidden} more generated memory skill${hidden === 1 ? "" : "s"} not listed`);
|
|
305
|
-
}
|
|
306
|
-
return lines.join("\n");
|
|
307
|
-
}
|
|
308
|
-
|
|
309
185
|
/**
|
|
310
186
|
* Clear all persisted memory state and generated artifacts.
|
|
311
187
|
*/
|
|
@@ -343,107 +219,6 @@ async function runMemoryStartup(options: {
|
|
|
343
219
|
await options.session.refreshBaseSystemPrompt?.();
|
|
344
220
|
}
|
|
345
221
|
|
|
346
|
-
function attachPostTurnBackgroundReview(options: {
|
|
347
|
-
session: AgentSession;
|
|
348
|
-
settings: Settings;
|
|
349
|
-
modelRegistry: ModelRegistry;
|
|
350
|
-
agentDir: string;
|
|
351
|
-
config: MemoryRuntimeConfig;
|
|
352
|
-
}): void {
|
|
353
|
-
const { session, config } = options;
|
|
354
|
-
if (config.backgroundReviewMode === "off") return;
|
|
355
|
-
if (config.backgroundReviewEveryNTurns <= 0) return;
|
|
356
|
-
if (postTurnReviewStates.has(session)) return;
|
|
357
|
-
if (typeof session.subscribe !== "function") return;
|
|
358
|
-
|
|
359
|
-
const state = { lastReviewedUserTurns: 0, running: false, unsubscribe: () => {} };
|
|
360
|
-
state.unsubscribe = session.subscribe(event => {
|
|
361
|
-
if (event.type !== "agent_end") return;
|
|
362
|
-
void maybeRunPostTurnBackgroundReview(options);
|
|
363
|
-
});
|
|
364
|
-
postTurnReviewStates.set(session, state);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
async function maybeRunPostTurnBackgroundReview(options: {
|
|
368
|
-
session: AgentSession;
|
|
369
|
-
settings: Settings;
|
|
370
|
-
modelRegistry: ModelRegistry;
|
|
371
|
-
agentDir: string;
|
|
372
|
-
config: MemoryRuntimeConfig;
|
|
373
|
-
}): Promise<void> {
|
|
374
|
-
const { session, modelRegistry, agentDir, config } = options;
|
|
375
|
-
const state = postTurnReviewStates.get(session);
|
|
376
|
-
if (!state || state.running) return;
|
|
377
|
-
|
|
378
|
-
const messages = extractPostTurnReviewMessages(session);
|
|
379
|
-
const userTurns = messages.filter(message => message.role === "user").length;
|
|
380
|
-
if (userTurns <= 0) return;
|
|
381
|
-
if (userTurns - state.lastReviewedUserTurns < config.backgroundReviewEveryNTurns) return;
|
|
382
|
-
|
|
383
|
-
state.running = true;
|
|
384
|
-
try {
|
|
385
|
-
const model = await resolveMemoryModel({ modelRegistry, session, fallbackRole: "default" });
|
|
386
|
-
if (!model) {
|
|
387
|
-
logger.debug("Post-turn memory review skipped: no model available");
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
const apiKey = await modelRegistry.getApiKey(model, session.sessionId);
|
|
391
|
-
if (!apiKey) {
|
|
392
|
-
logger.debug("Post-turn memory review skipped: no API key", {
|
|
393
|
-
provider: model.provider,
|
|
394
|
-
model: model.id,
|
|
395
|
-
});
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
const result = await runPostTurnReviewModel({
|
|
400
|
-
session,
|
|
401
|
-
messages,
|
|
402
|
-
userTurns,
|
|
403
|
-
model,
|
|
404
|
-
apiKey,
|
|
405
|
-
modelMaxTokens: computeModelTokenBudget(model, config),
|
|
406
|
-
config,
|
|
407
|
-
metadata: session.agent?.metadataForProvider(model.provider),
|
|
408
|
-
});
|
|
409
|
-
if (result.kind === "failed") {
|
|
410
|
-
logger.warn("Post-turn memory review failed", { reason: result.reason });
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
if (result.kind === "no_output") {
|
|
414
|
-
state.lastReviewedUserTurns = userTurns;
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
const sourceUpdatedAt = unixNow();
|
|
419
|
-
const threadId = buildPostTurnReviewThreadId(session.sessionManager.getSessionId(), userTurns);
|
|
420
|
-
const db = openMemoryDb(getAgentDbPath(agentDir));
|
|
421
|
-
try {
|
|
422
|
-
recordBackgroundStage1Output(db, {
|
|
423
|
-
threadId,
|
|
424
|
-
sourceUpdatedAt,
|
|
425
|
-
rolloutPath: session.sessionManager.getSessionFile() ?? threadId,
|
|
426
|
-
cwd: session.sessionManager.getCwd(),
|
|
427
|
-
rawMemory: result.output.rawMemory,
|
|
428
|
-
rolloutSummary: result.output.rolloutSummary,
|
|
429
|
-
rolloutSlug: result.output.rolloutSlug,
|
|
430
|
-
nowSec: sourceUpdatedAt,
|
|
431
|
-
});
|
|
432
|
-
} finally {
|
|
433
|
-
closeMemoryDb(db);
|
|
434
|
-
}
|
|
435
|
-
state.lastReviewedUserTurns = userTurns;
|
|
436
|
-
|
|
437
|
-
await runPhase2(options);
|
|
438
|
-
await session.refreshBaseSystemPrompt?.();
|
|
439
|
-
session.emitNotice("info", "Self-improvement review captured durable memory.", "Memory");
|
|
440
|
-
} catch (error) {
|
|
441
|
-
logger.warn("Post-turn memory review failed", { error: String(error) });
|
|
442
|
-
} finally {
|
|
443
|
-
state.running = false;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
222
|
async function runPhase1(options: {
|
|
448
223
|
session: AgentSession;
|
|
449
224
|
settings: Settings;
|
|
@@ -506,7 +281,7 @@ async function runPhase1(options: {
|
|
|
506
281
|
const result = await runStage1Job({
|
|
507
282
|
claim,
|
|
508
283
|
model: phase1Model,
|
|
509
|
-
apiKey:
|
|
284
|
+
apiKey: modelRegistry.resolver(phase1Model, session.sessionId),
|
|
510
285
|
modelMaxTokens: computeModelTokenBudget(phase1Model, config),
|
|
511
286
|
config,
|
|
512
287
|
metadata: session.agent?.metadataForProvider(phase1Model.provider),
|
|
@@ -663,24 +438,10 @@ async function runPhase2(options: {
|
|
|
663
438
|
const consolidated = await runConsolidationModel({
|
|
664
439
|
memoryRoot,
|
|
665
440
|
model: phase2Model,
|
|
666
|
-
apiKey:
|
|
667
|
-
metadata: session.agent?.metadataForProvider(phase2Model.provider),
|
|
668
|
-
});
|
|
669
|
-
const identityReview = await runIdentityReviewModel({
|
|
670
|
-
cwd,
|
|
671
|
-
memoryRoot,
|
|
672
|
-
model: phase2Model,
|
|
673
|
-
apiKey: phase2ApiKey,
|
|
441
|
+
apiKey: modelRegistry.resolver(phase2Model, session.sessionId),
|
|
674
442
|
metadata: session.agent?.metadataForProvider(phase2Model.provider),
|
|
675
|
-
consolidated,
|
|
676
|
-
enabled: config.identityReviewMode === "propose",
|
|
677
|
-
});
|
|
678
|
-
await applyConsolidation(memoryRoot, consolidated, {
|
|
679
|
-
identityReview,
|
|
680
|
-
curatorMode: config.curatorMode,
|
|
681
|
-
generatedSkillStaleAfterDays: config.generatedSkillStaleAfterDays,
|
|
682
|
-
generatedSkillArchiveAfterDays: config.generatedSkillArchiveAfterDays,
|
|
683
443
|
});
|
|
444
|
+
await applyConsolidation(memoryRoot, consolidated);
|
|
684
445
|
if (heartbeatLostOwnership) {
|
|
685
446
|
throw new Error("Phase2 lease ownership lost before completion");
|
|
686
447
|
}
|
|
@@ -820,87 +581,10 @@ function extractPersistableMessages(payload: string): AgentMessage[] {
|
|
|
820
581
|
return messages;
|
|
821
582
|
}
|
|
822
583
|
|
|
823
|
-
async function runPostTurnReviewModel(options: {
|
|
824
|
-
session: AgentSession;
|
|
825
|
-
messages: PostTurnReviewMessage[];
|
|
826
|
-
userTurns: number;
|
|
827
|
-
model: Model;
|
|
828
|
-
apiKey: string;
|
|
829
|
-
modelMaxTokens: number;
|
|
830
|
-
config: MemoryRuntimeConfig;
|
|
831
|
-
metadata?: Record<string, unknown>;
|
|
832
|
-
}): Promise<
|
|
833
|
-
| {
|
|
834
|
-
kind: "output";
|
|
835
|
-
output: { rawMemory: string; rolloutSummary: string; rolloutSlug: string | null };
|
|
836
|
-
}
|
|
837
|
-
| { kind: "no_output" }
|
|
838
|
-
| { kind: "failed"; reason: string }
|
|
839
|
-
> {
|
|
840
|
-
const { session, messages, userTurns, model, apiKey, modelMaxTokens, config } = options;
|
|
841
|
-
try {
|
|
842
|
-
const budgetTokens = Math.min(
|
|
843
|
-
config.phase1InputTokenLimit,
|
|
844
|
-
Math.floor(modelMaxTokens * config.rolloutPayloadPercent),
|
|
845
|
-
);
|
|
846
|
-
const input = prompt.render(postTurnReviewTemplate, {
|
|
847
|
-
thread_id: session.sessionManager.getSessionId() ?? "unknown",
|
|
848
|
-
cwd: session.sessionManager.getCwd(),
|
|
849
|
-
user_turns: String(userTurns),
|
|
850
|
-
review_every_n_turns: String(config.backgroundReviewEveryNTurns),
|
|
851
|
-
conversation_json: truncateByApproxTokens(JSON.stringify(messages), budgetTokens),
|
|
852
|
-
});
|
|
853
|
-
const response = await completeSimple(
|
|
854
|
-
model,
|
|
855
|
-
{
|
|
856
|
-
messages: [{ role: "user", content: [{ type: "text", text: input }], timestamp: Date.now() }],
|
|
857
|
-
},
|
|
858
|
-
{
|
|
859
|
-
apiKey,
|
|
860
|
-
metadata: options.metadata,
|
|
861
|
-
maxTokens: Math.max(1024, Math.min(4096, Math.floor(modelMaxTokens * 0.2))),
|
|
862
|
-
reasoning: clampThinkingLevelForModel(model, Effort.Low),
|
|
863
|
-
},
|
|
864
|
-
);
|
|
865
|
-
|
|
866
|
-
if (response.stopReason === "error") {
|
|
867
|
-
return { kind: "failed", reason: response.errorMessage || "post-turn review model error" };
|
|
868
|
-
}
|
|
869
|
-
const text = response.content
|
|
870
|
-
.filter((c): c is { type: "text"; text: string } => c.type === "text")
|
|
871
|
-
.map(c => c.text)
|
|
872
|
-
.join("\n")
|
|
873
|
-
.trim();
|
|
874
|
-
const parsed = parseJsonObject(text);
|
|
875
|
-
if (!parsed) {
|
|
876
|
-
return { kind: "failed", reason: "post-turn review JSON parse failure" };
|
|
877
|
-
}
|
|
878
|
-
const schemaOutput = parseStage1OutputSchema(parsed);
|
|
879
|
-
if (!schemaOutput) {
|
|
880
|
-
return { kind: "failed", reason: "post-turn review JSON schema validation failure" };
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
const rawMemory = redactSecrets(schemaOutput.raw_memory).trim();
|
|
884
|
-
const rolloutSummary = redactSecrets(schemaOutput.rollout_summary).trim();
|
|
885
|
-
const rolloutSlug = schemaOutput.rollout_slug === null ? null : redactSecrets(schemaOutput.rollout_slug).trim();
|
|
886
|
-
if (!rawMemory || !rolloutSummary) return { kind: "no_output" };
|
|
887
|
-
return {
|
|
888
|
-
kind: "output",
|
|
889
|
-
output: {
|
|
890
|
-
rawMemory,
|
|
891
|
-
rolloutSummary,
|
|
892
|
-
rolloutSlug: rolloutSlug || null,
|
|
893
|
-
},
|
|
894
|
-
};
|
|
895
|
-
} catch (error) {
|
|
896
|
-
return { kind: "failed", reason: String(error) };
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
|
|
900
584
|
async function runStage1Job(options: {
|
|
901
585
|
claim: Stage1Claim;
|
|
902
586
|
model: Model;
|
|
903
|
-
apiKey:
|
|
587
|
+
apiKey: ApiKey;
|
|
904
588
|
modelMaxTokens: number;
|
|
905
589
|
config: MemoryRuntimeConfig;
|
|
906
590
|
metadata?: Record<string, unknown>;
|
|
@@ -1006,12 +690,8 @@ async function syncPhase2Artifacts(memoryRoot: string, outputs: Stage1OutputRow[
|
|
|
1006
690
|
}
|
|
1007
691
|
|
|
1008
692
|
async function cleanupConsolidatedArtifacts(memoryRoot: string): Promise<void> {
|
|
1009
|
-
await fs.rm(path.join(memoryRoot,
|
|
1010
|
-
await fs.rm(path.join(memoryRoot,
|
|
1011
|
-
await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.summary), { force: true });
|
|
1012
|
-
await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.selfImprovementReport), { force: true });
|
|
1013
|
-
await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.skillUsage), { force: true });
|
|
1014
|
-
await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.skillCuratorReport), { force: true });
|
|
693
|
+
await fs.rm(path.join(memoryRoot, "MEMORY.md"), { force: true });
|
|
694
|
+
await fs.rm(path.join(memoryRoot, "memory_summary.md"), { force: true });
|
|
1015
695
|
await fs.rm(path.join(memoryRoot, "skills"), { recursive: true, force: true });
|
|
1016
696
|
}
|
|
1017
697
|
|
|
@@ -1048,11 +728,10 @@ async function readRolloutSummaries(memoryRoot: string): Promise<string> {
|
|
|
1048
728
|
async function runConsolidationModel(options: {
|
|
1049
729
|
memoryRoot: string;
|
|
1050
730
|
model: Model;
|
|
1051
|
-
apiKey:
|
|
731
|
+
apiKey: ApiKey;
|
|
1052
732
|
metadata?: Record<string, unknown>;
|
|
1053
733
|
}): Promise<{
|
|
1054
734
|
memoryMd: string;
|
|
1055
|
-
userMd: string;
|
|
1056
735
|
memorySummary: string;
|
|
1057
736
|
skills: Array<{
|
|
1058
737
|
name: string;
|
|
@@ -1073,6 +752,7 @@ async function runConsolidationModel(options: {
|
|
|
1073
752
|
const response = await completeSimple(
|
|
1074
753
|
model,
|
|
1075
754
|
{
|
|
755
|
+
systemPrompt: [consolidationSystemTemplate],
|
|
1076
756
|
messages: [{ role: "user", content: [{ type: "text", text: input }], timestamp: Date.now() }],
|
|
1077
757
|
},
|
|
1078
758
|
{
|
|
@@ -1094,29 +774,7 @@ async function runConsolidationModel(options: {
|
|
|
1094
774
|
if (!parsed) throw new Error("phase2 JSON parse failure");
|
|
1095
775
|
const schemaOutput = parseConsolidationOutputSchema(parsed);
|
|
1096
776
|
if (!schemaOutput) throw new Error("phase2 JSON schema validation failure");
|
|
1097
|
-
assertNoIdentityArtifactLeak([
|
|
1098
|
-
{ field: "memory_md", value: schemaOutput.memory_md },
|
|
1099
|
-
{ field: "user_md", value: schemaOutput.user_md },
|
|
1100
|
-
{ field: "memory_summary", value: schemaOutput.memory_summary },
|
|
1101
|
-
...schemaOutput.skills.flatMap((skill, index) => [
|
|
1102
|
-
{ field: `skills[${index}].name`, value: skill.name },
|
|
1103
|
-
{ field: `skills[${index}].content`, value: skill.content ?? "" },
|
|
1104
|
-
...(skill.scripts ?? []).map(file => ({
|
|
1105
|
-
field: `skills[${index}].scripts.${file.path}`,
|
|
1106
|
-
value: `${file.path}\n${file.content}`,
|
|
1107
|
-
})),
|
|
1108
|
-
...(skill.templates ?? []).map(file => ({
|
|
1109
|
-
field: `skills[${index}].templates.${file.path}`,
|
|
1110
|
-
value: `${file.path}\n${file.content}`,
|
|
1111
|
-
})),
|
|
1112
|
-
...(skill.examples ?? []).map(file => ({
|
|
1113
|
-
field: `skills[${index}].examples.${file.path}`,
|
|
1114
|
-
value: `${file.path}\n${file.content}`,
|
|
1115
|
-
})),
|
|
1116
|
-
]),
|
|
1117
|
-
]);
|
|
1118
777
|
const memoryMd = redactSecrets(schemaOutput.memory_md).trim();
|
|
1119
|
-
const userMd = normalizeConsolidatedUserProfile(redactSecrets(schemaOutput.user_md));
|
|
1120
778
|
const memorySummary = redactSecrets(schemaOutput.memory_summary).trim();
|
|
1121
779
|
const skills = schemaOutput.skills
|
|
1122
780
|
.map(item => {
|
|
@@ -1142,117 +800,16 @@ async function runConsolidationModel(options: {
|
|
|
1142
800
|
examples: ConsolidationSkillFileSchema[];
|
|
1143
801
|
} => item !== null,
|
|
1144
802
|
);
|
|
1145
|
-
assertNoIdentityArtifactLeak([
|
|
1146
|
-
{ field: "memory_md", value: memoryMd },
|
|
1147
|
-
{ field: "user_md", value: userMd },
|
|
1148
|
-
{ field: "memory_summary", value: memorySummary },
|
|
1149
|
-
...skills.flatMap(skill => [
|
|
1150
|
-
{ field: `skills.${skill.name}.name`, value: skill.name },
|
|
1151
|
-
{ field: `skills.${skill.name}.content`, value: skill.content },
|
|
1152
|
-
...skill.scripts.map(file => ({
|
|
1153
|
-
field: `skills.${skill.name}.scripts.${file.path}`,
|
|
1154
|
-
value: `${file.path}\n${file.content}`,
|
|
1155
|
-
})),
|
|
1156
|
-
...skill.templates.map(file => ({
|
|
1157
|
-
field: `skills.${skill.name}.templates.${file.path}`,
|
|
1158
|
-
value: `${file.path}\n${file.content}`,
|
|
1159
|
-
})),
|
|
1160
|
-
...skill.examples.map(file => ({
|
|
1161
|
-
field: `skills.${skill.name}.examples.${file.path}`,
|
|
1162
|
-
value: `${file.path}\n${file.content}`,
|
|
1163
|
-
})),
|
|
1164
|
-
]),
|
|
1165
|
-
]);
|
|
1166
803
|
if (!memoryMd || !memorySummary) {
|
|
1167
804
|
throw new Error("phase2 returned empty consolidated memory");
|
|
1168
805
|
}
|
|
1169
|
-
return { memoryMd,
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
async function runIdentityReviewModel(options: {
|
|
1173
|
-
cwd: string;
|
|
1174
|
-
memoryRoot: string;
|
|
1175
|
-
model: Model;
|
|
1176
|
-
apiKey: string;
|
|
1177
|
-
metadata?: Record<string, unknown>;
|
|
1178
|
-
enabled: boolean;
|
|
1179
|
-
consolidated: {
|
|
1180
|
-
userMd: string;
|
|
1181
|
-
memorySummary: string;
|
|
1182
|
-
skills: Array<{ name: string }>;
|
|
1183
|
-
};
|
|
1184
|
-
}): Promise<IdentityReviewResult> {
|
|
1185
|
-
const nativeSoul = await readNativeSoulContext(options.cwd);
|
|
1186
|
-
if (!options.enabled) {
|
|
1187
|
-
return { soulProposal: "", nativeSoulPath: nativeSoul.path };
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
try {
|
|
1191
|
-
const input = prompt.render(identityReviewTemplate, {
|
|
1192
|
-
native_soul_path: nativeSoul.path ?? "No native SOUL.md found.",
|
|
1193
|
-
native_soul: truncateByApproxTokens(nativeSoul.content || "No native SOUL.md found.", 8_000),
|
|
1194
|
-
user_md: truncateByApproxTokens(options.consolidated.userMd || "No durable USER.md profile.", 4_000),
|
|
1195
|
-
memory_summary: truncateByApproxTokens(options.consolidated.memorySummary, 4_000),
|
|
1196
|
-
generated_skills:
|
|
1197
|
-
options.consolidated.skills.length === 0
|
|
1198
|
-
? "None."
|
|
1199
|
-
: options.consolidated.skills
|
|
1200
|
-
.map(skill => `- memory://root/skills/${skill.name}/SKILL.md`)
|
|
1201
|
-
.sort((a, b) => a.localeCompare(b))
|
|
1202
|
-
.join("\n"),
|
|
1203
|
-
});
|
|
1204
|
-
|
|
1205
|
-
const response = await completeSimple(
|
|
1206
|
-
options.model,
|
|
1207
|
-
{
|
|
1208
|
-
messages: [{ role: "user", content: [{ type: "text", text: input }], timestamp: Date.now() }],
|
|
1209
|
-
},
|
|
1210
|
-
{
|
|
1211
|
-
apiKey: options.apiKey,
|
|
1212
|
-
metadata: options.metadata,
|
|
1213
|
-
maxTokens: 4096,
|
|
1214
|
-
reasoning: clampThinkingLevelForModel(options.model, Effort.Low),
|
|
1215
|
-
},
|
|
1216
|
-
);
|
|
1217
|
-
if (response.stopReason === "error") {
|
|
1218
|
-
return {
|
|
1219
|
-
soulProposal: "",
|
|
1220
|
-
nativeSoulPath: nativeSoul.path,
|
|
1221
|
-
error: response.errorMessage || "identity review model error",
|
|
1222
|
-
};
|
|
1223
|
-
}
|
|
1224
|
-
const text = response.content
|
|
1225
|
-
.filter((c): c is { type: "text"; text: string } => c.type === "text")
|
|
1226
|
-
.map(c => c.text)
|
|
1227
|
-
.join("\n")
|
|
1228
|
-
.trim();
|
|
1229
|
-
const parsed = parseJsonObject(text);
|
|
1230
|
-
if (!parsed) {
|
|
1231
|
-
return { soulProposal: "", nativeSoulPath: nativeSoul.path, error: "identity review JSON parse failure" };
|
|
1232
|
-
}
|
|
1233
|
-
const proposal = parseIdentityReviewOutputSchema(parsed);
|
|
1234
|
-
if (proposal === undefined) {
|
|
1235
|
-
return { soulProposal: "", nativeSoulPath: nativeSoul.path, error: "identity review JSON schema failure" };
|
|
1236
|
-
}
|
|
1237
|
-
return { soulProposal: proposal, nativeSoulPath: nativeSoul.path };
|
|
1238
|
-
} catch (error) {
|
|
1239
|
-
return { soulProposal: "", nativeSoulPath: nativeSoul.path, error: String(error) };
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
async function readNativeSoulContext(cwd: string): Promise<{ path: string | null; content: string }> {
|
|
1244
|
-
const projectConfigDir = await walkUp(cwd, SOURCE_PATHS.native.projectDir, { file: false, dir: true });
|
|
1245
|
-
if (!projectConfigDir) return { path: null, content: "" };
|
|
1246
|
-
const soulPath = path.join(projectConfigDir, "SOUL.md");
|
|
1247
|
-
const content = await readFile(soulPath);
|
|
1248
|
-
return { path: soulPath, content: content ?? "" };
|
|
806
|
+
return { memoryMd, memorySummary, skills };
|
|
1249
807
|
}
|
|
1250
808
|
|
|
1251
809
|
async function applyConsolidation(
|
|
1252
810
|
memoryRoot: string,
|
|
1253
811
|
consolidated: {
|
|
1254
812
|
memoryMd: string;
|
|
1255
|
-
userMd: string;
|
|
1256
813
|
memorySummary: string;
|
|
1257
814
|
skills: Array<{
|
|
1258
815
|
name: string;
|
|
@@ -1262,146 +819,30 @@ async function applyConsolidation(
|
|
|
1262
819
|
examples: ConsolidationSkillFileSchema[];
|
|
1263
820
|
}>;
|
|
1264
821
|
},
|
|
1265
|
-
options: {
|
|
1266
|
-
identityReview: IdentityReviewResult;
|
|
1267
|
-
curatorMode: "dry-run" | "off";
|
|
1268
|
-
generatedSkillStaleAfterDays: number;
|
|
1269
|
-
generatedSkillArchiveAfterDays: number;
|
|
1270
|
-
},
|
|
1271
822
|
): Promise<void> {
|
|
1272
|
-
await Bun.write(path.join(memoryRoot,
|
|
1273
|
-
await Bun.write(path.join(memoryRoot,
|
|
1274
|
-
await Bun.write(path.join(memoryRoot, MEMORY_ARTIFACTS.summary), `${consolidated.memorySummary.trim()}\n`);
|
|
1275
|
-
const curation = await applyGeneratedMemorySkills(memoryRoot, consolidated.skills, {
|
|
1276
|
-
curatorMode: options.curatorMode,
|
|
1277
|
-
staleAfterDays: options.generatedSkillStaleAfterDays,
|
|
1278
|
-
archiveAfterDays: options.generatedSkillArchiveAfterDays,
|
|
1279
|
-
});
|
|
1280
|
-
|
|
1281
|
-
if (options.identityReview.soulProposal.trim()) {
|
|
1282
|
-
await Bun.write(
|
|
1283
|
-
path.join(memoryRoot, MEMORY_ARTIFACTS.soulProposal),
|
|
1284
|
-
`${options.identityReview.soulProposal.trim()}\n`,
|
|
1285
|
-
);
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
await Bun.write(
|
|
1289
|
-
path.join(memoryRoot, MEMORY_ARTIFACTS.selfImprovementReport),
|
|
1290
|
-
buildSelfImprovementReport(consolidated, {
|
|
1291
|
-
identityReview: options.identityReview,
|
|
1292
|
-
curation,
|
|
1293
|
-
}),
|
|
1294
|
-
);
|
|
1295
|
-
}
|
|
1296
|
-
|
|
1297
|
-
function buildSelfImprovementReport(
|
|
1298
|
-
consolidated: {
|
|
1299
|
-
memoryMd: string;
|
|
1300
|
-
userMd: string;
|
|
1301
|
-
memorySummary: string;
|
|
1302
|
-
skills: Array<{ name: string }>;
|
|
1303
|
-
},
|
|
1304
|
-
options: {
|
|
1305
|
-
identityReview: IdentityReviewResult;
|
|
1306
|
-
curation: SkillCurationResult;
|
|
1307
|
-
},
|
|
1308
|
-
): string {
|
|
1309
|
-
const skillNames = consolidated.skills.map(skill => skill.name).sort((a, b) => a.localeCompare(b));
|
|
1310
|
-
const generatedSkills = skillNames.length === 0 ? "- None" : skillNames.map(name => `- ${name}`).join("\n");
|
|
1311
|
-
const userProfileState = consolidated.userMd.trim() ? "updated" : "empty";
|
|
1312
|
-
const identityLines = options.identityReview.soulProposal.trim()
|
|
1313
|
-
? [
|
|
1314
|
-
"- SOUL proposal: written to memory://root/SOUL.proposed.md",
|
|
1315
|
-
`- Native SOUL source: ${options.identityReview.nativeSoulPath ?? "none"}`,
|
|
1316
|
-
]
|
|
1317
|
-
: ["- SOUL proposal: none written", `- Native SOUL source: ${options.identityReview.nativeSoulPath ?? "none"}`];
|
|
1318
|
-
if (options.identityReview.error) {
|
|
1319
|
-
identityLines.push(`- Identity review warning: ${options.identityReview.error}`);
|
|
1320
|
-
}
|
|
1321
|
-
const curatorLines = options.curation.report.trim()
|
|
1322
|
-
? [`- Skill curator dry-run report: memory://root/${MEMORY_ARTIFACTS.skillCuratorReport}`]
|
|
1323
|
-
: ["- Skill curator: off"];
|
|
1324
|
-
|
|
1325
|
-
return [
|
|
1326
|
-
"# Self-Improvement Report",
|
|
1327
|
-
"",
|
|
1328
|
-
"Trajectory: Hermes-style native Prometheus learning.",
|
|
1329
|
-
"",
|
|
1330
|
-
"Automatic write scope:",
|
|
1331
|
-
"- MEMORY.md: project and operational memory",
|
|
1332
|
-
"- USER.md: durable user profile",
|
|
1333
|
-
"- skills/: generated procedural playbooks",
|
|
1334
|
-
"",
|
|
1335
|
-
"Stable identity boundary:",
|
|
1336
|
-
"- SOUL.md is not generated or rewritten by memory consolidation.",
|
|
1337
|
-
"- SOUL.proposed.md is reserved for an explicit identity-review flow.",
|
|
1338
|
-
"- Do not present memory artifacts as Prometheus identity.",
|
|
1339
|
-
"",
|
|
1340
|
-
"Dry-run review:",
|
|
1341
|
-
"- Memory/profile/skill consolidation completed through the native Prometheus memory pipeline.",
|
|
1342
|
-
...identityLines,
|
|
1343
|
-
...curatorLines,
|
|
1344
|
-
"",
|
|
1345
|
-
"Current artifacts:",
|
|
1346
|
-
`- MEMORY.md chars: ${consolidated.memoryMd.trim().length}`,
|
|
1347
|
-
`- USER.md state: ${userProfileState}`,
|
|
1348
|
-
`- memory_summary.md chars: ${consolidated.memorySummary.trim().length}`,
|
|
1349
|
-
`- skill_usage.json records: ${Object.keys(options.curation.usage.skills).length}`,
|
|
1350
|
-
"",
|
|
1351
|
-
"Generated skills:",
|
|
1352
|
-
generatedSkills,
|
|
1353
|
-
"",
|
|
1354
|
-
"Skill lifecycle:",
|
|
1355
|
-
`- Active generated skills: ${options.curation.active.length}`,
|
|
1356
|
-
`- Pinned stale skills preserved: ${options.curation.pinnedStale.length}`,
|
|
1357
|
-
`- Archived stale skills: ${options.curation.archived.length}`,
|
|
1358
|
-
`- Dry-run stale candidates: ${options.curation.staleCandidates.length}`,
|
|
1359
|
-
`- Dry-run archive candidates: ${options.curation.archiveCandidates.length}`,
|
|
1360
|
-
"",
|
|
1361
|
-
].join("\n");
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
async function applyGeneratedMemorySkills(
|
|
1365
|
-
memoryRoot: string,
|
|
1366
|
-
skills: Array<{
|
|
1367
|
-
name: string;
|
|
1368
|
-
content: string;
|
|
1369
|
-
scripts: ConsolidationSkillFileSchema[];
|
|
1370
|
-
templates: ConsolidationSkillFileSchema[];
|
|
1371
|
-
examples: ConsolidationSkillFileSchema[];
|
|
1372
|
-
}>,
|
|
1373
|
-
options: {
|
|
1374
|
-
curatorMode: "dry-run" | "off";
|
|
1375
|
-
staleAfterDays: number;
|
|
1376
|
-
archiveAfterDays: number;
|
|
1377
|
-
},
|
|
1378
|
-
): Promise<SkillCurationResult> {
|
|
823
|
+
await Bun.write(path.join(memoryRoot, "MEMORY.md"), `${consolidated.memoryMd.trim()}\n`);
|
|
824
|
+
await Bun.write(path.join(memoryRoot, "memory_summary.md"), `${consolidated.memorySummary.trim()}\n`);
|
|
1379
825
|
const skillsDir = path.join(memoryRoot, "skills");
|
|
1380
826
|
await fs.mkdir(skillsDir, { recursive: true });
|
|
1381
|
-
const usage = await readGeneratedMemorySkillUsage(memoryRoot);
|
|
1382
|
-
const now = new Date().toISOString();
|
|
1383
827
|
const keep = new Set<string>();
|
|
1384
|
-
const
|
|
1385
|
-
const pinnedStale: string[] = [];
|
|
1386
|
-
const archived: string[] = [];
|
|
1387
|
-
const staleCandidates: string[] = [];
|
|
1388
|
-
const archiveCandidates: string[] = [];
|
|
1389
|
-
const markedStale: string[] = [];
|
|
1390
|
-
const reactivated: string[] = [];
|
|
1391
|
-
|
|
1392
|
-
for (const skill of skills) {
|
|
828
|
+
for (const skill of consolidated.skills) {
|
|
1393
829
|
const dir = path.join(skillsDir, skill.name);
|
|
1394
|
-
const files = buildSkillFileMap(skill);
|
|
1395
|
-
const existed = await Bun.file(path.join(dir, "SKILL.md")).exists();
|
|
1396
|
-
const changed = await skillFilesChanged(dir, files);
|
|
1397
830
|
keep.add(skill.name);
|
|
1398
|
-
active.push(skill.name);
|
|
1399
|
-
|
|
1400
831
|
await fs.mkdir(dir, { recursive: true });
|
|
832
|
+
const files = new Map<string, string>();
|
|
833
|
+
files.set("SKILL.md", `${skill.content.trim()}\n`);
|
|
834
|
+
for (const item of skill.scripts) {
|
|
835
|
+
files.set(path.posix.join("scripts", item.path), `${item.content.trim()}\n`);
|
|
836
|
+
}
|
|
837
|
+
for (const item of skill.templates) {
|
|
838
|
+
files.set(path.posix.join("templates", item.path), `${item.content.trim()}\n`);
|
|
839
|
+
}
|
|
840
|
+
for (const item of skill.examples) {
|
|
841
|
+
files.set(path.posix.join("examples", item.path), `${item.content.trim()}\n`);
|
|
842
|
+
}
|
|
843
|
+
|
|
1401
844
|
for (const [relativePath, content] of [...files.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
1402
|
-
|
|
1403
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
1404
|
-
await Bun.write(filePath, content);
|
|
845
|
+
await Bun.write(path.join(dir, ...relativePath.split("/")), content);
|
|
1405
846
|
}
|
|
1406
847
|
|
|
1407
848
|
const keepFiles = new Set(files.keys());
|
|
@@ -1411,436 +852,12 @@ async function applyGeneratedMemorySkills(
|
|
|
1411
852
|
await fs.rm(path.join(dir, ...relativePath.split("/")), { force: true });
|
|
1412
853
|
}
|
|
1413
854
|
await pruneEmptyDirectories(dir);
|
|
1414
|
-
await fs.rm(path.join(skillsDir, ".archive", skill.name), { recursive: true, force: true });
|
|
1415
|
-
|
|
1416
|
-
const record = normalizeGeneratedMemorySkillRecord(usage.skills[skill.name], skill.name, now);
|
|
1417
|
-
record.state = "active";
|
|
1418
|
-
record.updatedAt = now;
|
|
1419
|
-
record.lastSeenInConsolidationAt = now;
|
|
1420
|
-
record.archivedAt = null;
|
|
1421
|
-
record.archiveReason = null;
|
|
1422
|
-
if (existed && changed) {
|
|
1423
|
-
record.patchCount += 1;
|
|
1424
|
-
record.lastPatchedAt = now;
|
|
1425
|
-
}
|
|
1426
|
-
usage.skills[skill.name] = record;
|
|
1427
855
|
}
|
|
1428
|
-
|
|
1429
856
|
const dirs = await fs.readdir(skillsDir, { withFileTypes: true }).catch(() => []);
|
|
1430
857
|
for (const dirent of dirs) {
|
|
1431
858
|
if (!dirent.isDirectory()) continue;
|
|
1432
|
-
if (dirent.name === ".archive") continue;
|
|
1433
859
|
if (keep.has(dirent.name)) continue;
|
|
1434
|
-
|
|
1435
|
-
const record = normalizeGeneratedMemorySkillRecord(usage.skills[dirent.name], dirent.name, now);
|
|
1436
|
-
record.updatedAt = now;
|
|
1437
|
-
if (record.pinned) {
|
|
1438
|
-
record.state = "stale";
|
|
1439
|
-
pinnedStale.push(dirent.name);
|
|
1440
|
-
usage.skills[dirent.name] = record;
|
|
1441
|
-
continue;
|
|
1442
|
-
}
|
|
1443
|
-
|
|
1444
|
-
await archiveGeneratedMemorySkillDir(skillsDir, dirent.name);
|
|
1445
|
-
record.state = "archived";
|
|
1446
|
-
record.archivedAt = record.archivedAt ?? now;
|
|
1447
|
-
record.archiveReason = record.archiveReason ?? "Omitted by memory consolidation; archived instead of deleted.";
|
|
1448
|
-
archived.push(dirent.name);
|
|
1449
|
-
usage.skills[dirent.name] = record;
|
|
1450
|
-
}
|
|
1451
|
-
|
|
1452
|
-
if (options.curatorMode === "dry-run") {
|
|
1453
|
-
applyGeneratedSkillDryRunClassification(usage, {
|
|
1454
|
-
now,
|
|
1455
|
-
staleAfterDays: options.staleAfterDays,
|
|
1456
|
-
archiveAfterDays: options.archiveAfterDays,
|
|
1457
|
-
staleCandidates,
|
|
1458
|
-
archiveCandidates,
|
|
1459
|
-
markedStale,
|
|
1460
|
-
reactivated,
|
|
1461
|
-
});
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
const sortedUsage = sortGeneratedMemorySkillUsage(usage);
|
|
1465
|
-
await writeGeneratedMemorySkillUsage(memoryRoot, sortedUsage);
|
|
1466
|
-
const report =
|
|
1467
|
-
options.curatorMode === "dry-run"
|
|
1468
|
-
? buildSkillCuratorReport(sortedUsage, {
|
|
1469
|
-
active,
|
|
1470
|
-
pinnedStale,
|
|
1471
|
-
archived,
|
|
1472
|
-
staleCandidates,
|
|
1473
|
-
archiveCandidates,
|
|
1474
|
-
markedStale,
|
|
1475
|
-
reactivated,
|
|
1476
|
-
curatorMode: options.curatorMode,
|
|
1477
|
-
staleAfterDays: options.staleAfterDays,
|
|
1478
|
-
archiveAfterDays: options.archiveAfterDays,
|
|
1479
|
-
})
|
|
1480
|
-
: "";
|
|
1481
|
-
if (report.trim()) {
|
|
1482
|
-
await Bun.write(path.join(memoryRoot, MEMORY_ARTIFACTS.skillCuratorReport), report);
|
|
1483
|
-
} else {
|
|
1484
|
-
await fs.rm(path.join(memoryRoot, MEMORY_ARTIFACTS.skillCuratorReport), { force: true });
|
|
1485
|
-
}
|
|
1486
|
-
return {
|
|
1487
|
-
usage: sortedUsage,
|
|
1488
|
-
active: active.sort((a, b) => a.localeCompare(b)),
|
|
1489
|
-
pinnedStale: pinnedStale.sort((a, b) => a.localeCompare(b)),
|
|
1490
|
-
archived: archived.sort((a, b) => a.localeCompare(b)),
|
|
1491
|
-
staleCandidates: staleCandidates.sort((a, b) => a.localeCompare(b)),
|
|
1492
|
-
archiveCandidates: archiveCandidates.sort((a, b) => a.localeCompare(b)),
|
|
1493
|
-
markedStale: markedStale.sort((a, b) => a.localeCompare(b)),
|
|
1494
|
-
reactivated: reactivated.sort((a, b) => a.localeCompare(b)),
|
|
1495
|
-
report,
|
|
1496
|
-
};
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
function buildSkillFileMap(skill: {
|
|
1500
|
-
content: string;
|
|
1501
|
-
scripts: ConsolidationSkillFileSchema[];
|
|
1502
|
-
templates: ConsolidationSkillFileSchema[];
|
|
1503
|
-
examples: ConsolidationSkillFileSchema[];
|
|
1504
|
-
}): Map<string, string> {
|
|
1505
|
-
const files = new Map<string, string>();
|
|
1506
|
-
files.set("SKILL.md", `${skill.content.trim()}\n`);
|
|
1507
|
-
for (const item of skill.scripts) {
|
|
1508
|
-
files.set(path.posix.join("scripts", item.path), `${item.content.trim()}\n`);
|
|
1509
|
-
}
|
|
1510
|
-
for (const item of skill.templates) {
|
|
1511
|
-
files.set(path.posix.join("templates", item.path), `${item.content.trim()}\n`);
|
|
1512
|
-
}
|
|
1513
|
-
for (const item of skill.examples) {
|
|
1514
|
-
files.set(path.posix.join("examples", item.path), `${item.content.trim()}\n`);
|
|
1515
|
-
}
|
|
1516
|
-
return files;
|
|
1517
|
-
}
|
|
1518
|
-
|
|
1519
|
-
async function skillFilesChanged(dir: string, desired: Map<string, string>): Promise<boolean> {
|
|
1520
|
-
const existing = await listRelativeFiles(dir);
|
|
1521
|
-
if (existing.length !== desired.size) return true;
|
|
1522
|
-
for (const relativePath of existing) {
|
|
1523
|
-
const wanted = desired.get(relativePath);
|
|
1524
|
-
if (wanted === undefined) return true;
|
|
1525
|
-
const current = await Bun.file(path.join(dir, ...relativePath.split("/")))
|
|
1526
|
-
.text()
|
|
1527
|
-
.catch(() => undefined);
|
|
1528
|
-
if (current !== wanted) return true;
|
|
1529
|
-
}
|
|
1530
|
-
return false;
|
|
1531
|
-
}
|
|
1532
|
-
|
|
1533
|
-
async function readGeneratedMemorySkillUsage(memoryRoot: string): Promise<GeneratedMemorySkillUsageFile> {
|
|
1534
|
-
const fallback: GeneratedMemorySkillUsageFile = { schemaVersion: 1, skills: {} };
|
|
1535
|
-
const text = await Bun.file(path.join(memoryRoot, MEMORY_ARTIFACTS.skillUsage))
|
|
1536
|
-
.text()
|
|
1537
|
-
.catch(() => "");
|
|
1538
|
-
if (!text.trim()) return fallback;
|
|
1539
|
-
try {
|
|
1540
|
-
const parsed = JSON.parse(text) as unknown;
|
|
1541
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fallback;
|
|
1542
|
-
const data = parsed as Record<string, unknown>;
|
|
1543
|
-
if (data.schemaVersion !== 1 || !data.skills || typeof data.skills !== "object" || Array.isArray(data.skills)) {
|
|
1544
|
-
return fallback;
|
|
1545
|
-
}
|
|
1546
|
-
const skills: Record<string, GeneratedMemorySkillUsageRecord> = {};
|
|
1547
|
-
const now = new Date().toISOString();
|
|
1548
|
-
for (const [name, record] of Object.entries(data.skills as Record<string, unknown>)) {
|
|
1549
|
-
const sanitized = sanitizeSkillName(name);
|
|
1550
|
-
if (!sanitized) continue;
|
|
1551
|
-
skills[sanitized] = normalizeGeneratedMemorySkillRecord(record, sanitized, now);
|
|
1552
|
-
}
|
|
1553
|
-
return { schemaVersion: 1, skills };
|
|
1554
|
-
} catch {
|
|
1555
|
-
return fallback;
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
|
|
1559
|
-
async function writeGeneratedMemorySkillUsage(memoryRoot: string, usage: GeneratedMemorySkillUsageFile): Promise<void> {
|
|
1560
|
-
await Bun.write(
|
|
1561
|
-
path.join(memoryRoot, MEMORY_ARTIFACTS.skillUsage),
|
|
1562
|
-
`${JSON.stringify(sortGeneratedMemorySkillUsage(usage), null, 2)}\n`,
|
|
1563
|
-
);
|
|
1564
|
-
}
|
|
1565
|
-
|
|
1566
|
-
function sortGeneratedMemorySkillUsage(usage: GeneratedMemorySkillUsageFile): GeneratedMemorySkillUsageFile {
|
|
1567
|
-
const sorted: Record<string, GeneratedMemorySkillUsageRecord> = {};
|
|
1568
|
-
for (const name of Object.keys(usage.skills).sort((a, b) => a.localeCompare(b))) {
|
|
1569
|
-
sorted[name] = usage.skills[name]!;
|
|
1570
|
-
}
|
|
1571
|
-
return { schemaVersion: 1, skills: sorted };
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
|
-
function normalizeGeneratedMemorySkillRecord(
|
|
1575
|
-
value: unknown,
|
|
1576
|
-
name: string,
|
|
1577
|
-
now: string,
|
|
1578
|
-
): GeneratedMemorySkillUsageRecord {
|
|
1579
|
-
const input = value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : {};
|
|
1580
|
-
const state = parseGeneratedMemorySkillState(input.state) ?? "active";
|
|
1581
|
-
return {
|
|
1582
|
-
schemaVersion: 1,
|
|
1583
|
-
name,
|
|
1584
|
-
source: "memory-consolidation",
|
|
1585
|
-
state,
|
|
1586
|
-
pinned: input.pinned === true,
|
|
1587
|
-
createdAt: parseString(input.createdAt) ?? now,
|
|
1588
|
-
updatedAt: parseString(input.updatedAt) ?? now,
|
|
1589
|
-
lastSeenInConsolidationAt: parseString(input.lastSeenInConsolidationAt),
|
|
1590
|
-
archivedAt: parseString(input.archivedAt),
|
|
1591
|
-
archiveReason: parseString(input.archiveReason),
|
|
1592
|
-
useCount: parseNonNegativeInteger(input.useCount),
|
|
1593
|
-
viewCount: parseNonNegativeInteger(input.viewCount),
|
|
1594
|
-
patchCount: parseNonNegativeInteger(input.patchCount),
|
|
1595
|
-
lastUsedAt: parseString(input.lastUsedAt),
|
|
1596
|
-
lastViewedAt: parseString(input.lastViewedAt),
|
|
1597
|
-
lastPatchedAt: parseString(input.lastPatchedAt),
|
|
1598
|
-
};
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
|
-
function parseGeneratedMemorySkillState(value: unknown): GeneratedMemorySkillState | undefined {
|
|
1602
|
-
return value === "active" || value === "stale" || value === "archived" ? value : undefined;
|
|
1603
|
-
}
|
|
1604
|
-
|
|
1605
|
-
function parseString(value: unknown): string | null {
|
|
1606
|
-
if (typeof value !== "string") return null;
|
|
1607
|
-
const trimmed = value.trim();
|
|
1608
|
-
return trimmed || null;
|
|
1609
|
-
}
|
|
1610
|
-
|
|
1611
|
-
function parseNonNegativeInteger(value: unknown): number {
|
|
1612
|
-
const parsed = typeof value === "number" ? value : Number(value);
|
|
1613
|
-
if (!Number.isFinite(parsed) || parsed < 0) return 0;
|
|
1614
|
-
return Math.floor(parsed);
|
|
1615
|
-
}
|
|
1616
|
-
|
|
1617
|
-
function applyGeneratedSkillDryRunClassification(
|
|
1618
|
-
usage: GeneratedMemorySkillUsageFile,
|
|
1619
|
-
options: {
|
|
1620
|
-
now: string;
|
|
1621
|
-
staleAfterDays: number;
|
|
1622
|
-
archiveAfterDays: number;
|
|
1623
|
-
staleCandidates: string[];
|
|
1624
|
-
archiveCandidates: string[];
|
|
1625
|
-
markedStale: string[];
|
|
1626
|
-
reactivated: string[];
|
|
1627
|
-
},
|
|
1628
|
-
): void {
|
|
1629
|
-
const nowMs = Date.parse(options.now);
|
|
1630
|
-
const staleCutoff = nowMs - options.staleAfterDays * 24 * 60 * 60 * 1000;
|
|
1631
|
-
const archiveCutoff = nowMs - options.archiveAfterDays * 24 * 60 * 60 * 1000;
|
|
1632
|
-
for (const record of Object.values(usage.skills)) {
|
|
1633
|
-
if (record.state === "archived" || record.pinned) continue;
|
|
1634
|
-
const anchor = Date.parse(latestGeneratedMemorySkillActivity(record) ?? record.createdAt);
|
|
1635
|
-
if (!Number.isFinite(anchor)) continue;
|
|
1636
|
-
if (anchor <= archiveCutoff) {
|
|
1637
|
-
options.archiveCandidates.push(record.name);
|
|
1638
|
-
if (record.state === "active") {
|
|
1639
|
-
options.markedStale.push(record.name);
|
|
1640
|
-
}
|
|
1641
|
-
continue;
|
|
1642
|
-
}
|
|
1643
|
-
if (anchor <= staleCutoff) {
|
|
1644
|
-
options.staleCandidates.push(record.name);
|
|
1645
|
-
if (record.state === "active") {
|
|
1646
|
-
options.markedStale.push(record.name);
|
|
1647
|
-
}
|
|
1648
|
-
continue;
|
|
1649
|
-
}
|
|
1650
|
-
if (record.state === "stale") {
|
|
1651
|
-
options.reactivated.push(record.name);
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
|
-
function latestGeneratedMemorySkillActivity(record: GeneratedMemorySkillUsageRecord): string | null {
|
|
1657
|
-
const values = [record.lastUsedAt, record.lastViewedAt, record.lastPatchedAt].filter(
|
|
1658
|
-
(value): value is string => typeof value === "string" && value.length > 0,
|
|
1659
|
-
);
|
|
1660
|
-
values.sort((a, b) => b.localeCompare(a));
|
|
1661
|
-
return values[0] ?? record.lastSeenInConsolidationAt ?? null;
|
|
1662
|
-
}
|
|
1663
|
-
|
|
1664
|
-
function buildSkillCuratorReport(
|
|
1665
|
-
usage: GeneratedMemorySkillUsageFile,
|
|
1666
|
-
options: {
|
|
1667
|
-
active: string[];
|
|
1668
|
-
pinnedStale: string[];
|
|
1669
|
-
archived: string[];
|
|
1670
|
-
staleCandidates: string[];
|
|
1671
|
-
archiveCandidates: string[];
|
|
1672
|
-
markedStale: string[];
|
|
1673
|
-
reactivated: string[];
|
|
1674
|
-
curatorMode: "dry-run" | "off";
|
|
1675
|
-
staleAfterDays: number;
|
|
1676
|
-
archiveAfterDays: number;
|
|
1677
|
-
},
|
|
1678
|
-
): string {
|
|
1679
|
-
const records = Object.values(usage.skills).sort((a, b) => a.name.localeCompare(b.name));
|
|
1680
|
-
const recordLines =
|
|
1681
|
-
records.length === 0
|
|
1682
|
-
? ["- None"]
|
|
1683
|
-
: records.map(
|
|
1684
|
-
record =>
|
|
1685
|
-
`- ${record.name}: state=${record.state}, pinned=${record.pinned ? "yes" : "no"}, ` +
|
|
1686
|
-
`use=${record.useCount}, view=${record.viewCount}, patch=${record.patchCount}`,
|
|
1687
|
-
);
|
|
1688
|
-
|
|
1689
|
-
return [
|
|
1690
|
-
"# Generated Skill Curator Report",
|
|
1691
|
-
"",
|
|
1692
|
-
`Mode: ${options.curatorMode}`,
|
|
1693
|
-
"Scope: generated memory skills only.",
|
|
1694
|
-
"Mutation boundary: dry-run curation reports suggestions; stale skills removed by consolidation are archived, not deleted.",
|
|
1695
|
-
`Stale threshold days: ${options.staleAfterDays}`,
|
|
1696
|
-
`Archive threshold days: ${options.archiveAfterDays}`,
|
|
1697
|
-
"",
|
|
1698
|
-
"Current pass:",
|
|
1699
|
-
`- Active generated skills: ${options.active.length ? options.active.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
|
|
1700
|
-
`- Pinned stale skills preserved: ${
|
|
1701
|
-
options.pinnedStale.length ? options.pinnedStale.sort((a, b) => a.localeCompare(b)).join(", ") : "none"
|
|
1702
|
-
}`,
|
|
1703
|
-
`- Archived stale skills: ${options.archived.length ? options.archived.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
|
|
1704
|
-
"",
|
|
1705
|
-
"Dry-run candidates:",
|
|
1706
|
-
`- Would mark stale: ${options.markedStale.length ? options.markedStale.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
|
|
1707
|
-
`- Would reactivate: ${options.reactivated.length ? options.reactivated.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
|
|
1708
|
-
`- Stale candidates: ${options.staleCandidates.length ? options.staleCandidates.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
|
|
1709
|
-
`- Archive candidates: ${options.archiveCandidates.length ? options.archiveCandidates.sort((a, b) => a.localeCompare(b)).join(", ") : "none"}`,
|
|
1710
|
-
"",
|
|
1711
|
-
"Lifecycle policy:",
|
|
1712
|
-
"- pinned=true prevents automatic archive.",
|
|
1713
|
-
"- state=stale means omitted by latest consolidation while pinned, or inactive past the stale threshold.",
|
|
1714
|
-
"- state=archived means moved to memory://root/skills/.archive/<name>/ for recoverable restore.",
|
|
1715
|
-
"",
|
|
1716
|
-
"Usage records:",
|
|
1717
|
-
...recordLines,
|
|
1718
|
-
"",
|
|
1719
|
-
].join("\n");
|
|
1720
|
-
}
|
|
1721
|
-
|
|
1722
|
-
async function archiveGeneratedMemorySkillDir(skillsDir: string, name: string): Promise<void> {
|
|
1723
|
-
const source = path.join(skillsDir, name);
|
|
1724
|
-
if (!(await Bun.file(path.join(source, "SKILL.md")).exists())) return;
|
|
1725
|
-
const archiveRoot = path.join(skillsDir, ".archive");
|
|
1726
|
-
const target = path.join(archiveRoot, name);
|
|
1727
|
-
await fs.mkdir(archiveRoot, { recursive: true });
|
|
1728
|
-
await fs.rm(target, { recursive: true, force: true });
|
|
1729
|
-
await fs.rename(source, target);
|
|
1730
|
-
}
|
|
1731
|
-
|
|
1732
|
-
export async function recordGeneratedMemorySkillEvent(
|
|
1733
|
-
memoryRoot: string,
|
|
1734
|
-
rawName: string,
|
|
1735
|
-
event: GeneratedMemorySkillEvent,
|
|
1736
|
-
): Promise<boolean> {
|
|
1737
|
-
const name = sanitizeSkillName(rawName);
|
|
1738
|
-
if (!name) return false;
|
|
1739
|
-
const usage = await readGeneratedMemorySkillUsage(memoryRoot);
|
|
1740
|
-
const now = new Date().toISOString();
|
|
1741
|
-
const record = normalizeGeneratedMemorySkillRecord(usage.skills[name], name, now);
|
|
1742
|
-
const activeSkillPath = path.join(memoryRoot, "skills", name, "SKILL.md");
|
|
1743
|
-
if (!(await Bun.file(activeSkillPath).exists()) && record.state !== "archived") return false;
|
|
1744
|
-
record.updatedAt = now;
|
|
1745
|
-
if (event === "use") {
|
|
1746
|
-
record.useCount += 1;
|
|
1747
|
-
record.lastUsedAt = now;
|
|
1748
|
-
} else if (event === "view") {
|
|
1749
|
-
record.viewCount += 1;
|
|
1750
|
-
record.lastViewedAt = now;
|
|
1751
|
-
} else {
|
|
1752
|
-
record.patchCount += 1;
|
|
1753
|
-
record.lastPatchedAt = now;
|
|
1754
|
-
}
|
|
1755
|
-
usage.skills[name] = record;
|
|
1756
|
-
await writeGeneratedMemorySkillUsage(memoryRoot, usage);
|
|
1757
|
-
return true;
|
|
1758
|
-
}
|
|
1759
|
-
|
|
1760
|
-
export async function pinGeneratedMemorySkill(memoryRoot: string, rawName: string, pinned = true): Promise<boolean> {
|
|
1761
|
-
const name = sanitizeSkillName(rawName);
|
|
1762
|
-
if (!name) return false;
|
|
1763
|
-
const usage = await readGeneratedMemorySkillUsage(memoryRoot);
|
|
1764
|
-
const now = new Date().toISOString();
|
|
1765
|
-
const record = normalizeGeneratedMemorySkillRecord(usage.skills[name], name, now);
|
|
1766
|
-
const activeSkillPath = path.join(memoryRoot, "skills", name, "SKILL.md");
|
|
1767
|
-
const archivedSkillPath = path.join(memoryRoot, "skills", ".archive", name, "SKILL.md");
|
|
1768
|
-
if (!(await Bun.file(activeSkillPath).exists()) && !(await Bun.file(archivedSkillPath).exists())) return false;
|
|
1769
|
-
record.pinned = pinned;
|
|
1770
|
-
record.updatedAt = now;
|
|
1771
|
-
usage.skills[name] = record;
|
|
1772
|
-
await writeGeneratedMemorySkillUsage(memoryRoot, usage);
|
|
1773
|
-
return true;
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
|
-
export async function archiveGeneratedMemorySkill(
|
|
1777
|
-
memoryRoot: string,
|
|
1778
|
-
rawName: string,
|
|
1779
|
-
reason: string,
|
|
1780
|
-
): Promise<boolean> {
|
|
1781
|
-
const name = sanitizeSkillName(rawName);
|
|
1782
|
-
if (!name) return false;
|
|
1783
|
-
const skillsDir = path.join(memoryRoot, "skills");
|
|
1784
|
-
const sourceSkillPath = path.join(skillsDir, name, "SKILL.md");
|
|
1785
|
-
if (!(await Bun.file(sourceSkillPath).exists())) return false;
|
|
1786
|
-
const usage = await readGeneratedMemorySkillUsage(memoryRoot);
|
|
1787
|
-
const now = new Date().toISOString();
|
|
1788
|
-
const existingRecord = normalizeGeneratedMemorySkillRecord(usage.skills[name], name, now);
|
|
1789
|
-
if (existingRecord.pinned) return false;
|
|
1790
|
-
await archiveGeneratedMemorySkillDir(skillsDir, name);
|
|
1791
|
-
const record = existingRecord;
|
|
1792
|
-
record.state = "archived";
|
|
1793
|
-
record.updatedAt = now;
|
|
1794
|
-
record.archivedAt = now;
|
|
1795
|
-
record.archiveReason = reason.trim() || "Archived by native generated-skill lifecycle.";
|
|
1796
|
-
usage.skills[name] = record;
|
|
1797
|
-
await writeGeneratedMemorySkillUsage(memoryRoot, usage);
|
|
1798
|
-
return true;
|
|
1799
|
-
}
|
|
1800
|
-
|
|
1801
|
-
export async function restoreGeneratedMemorySkill(memoryRoot: string, rawName: string): Promise<boolean> {
|
|
1802
|
-
const name = sanitizeSkillName(rawName);
|
|
1803
|
-
if (!name) return false;
|
|
1804
|
-
const skillsDir = path.join(memoryRoot, "skills");
|
|
1805
|
-
const source = path.join(skillsDir, ".archive", name);
|
|
1806
|
-
const target = path.join(skillsDir, name);
|
|
1807
|
-
if (!(await Bun.file(path.join(source, "SKILL.md")).exists())) return false;
|
|
1808
|
-
if (await Bun.file(path.join(target, "SKILL.md")).exists()) return false;
|
|
1809
|
-
await fs.mkdir(skillsDir, { recursive: true });
|
|
1810
|
-
await fs.rename(source, target);
|
|
1811
|
-
const usage = await readGeneratedMemorySkillUsage(memoryRoot);
|
|
1812
|
-
const now = new Date().toISOString();
|
|
1813
|
-
const record = normalizeGeneratedMemorySkillRecord(usage.skills[name], name, now);
|
|
1814
|
-
record.state = "active";
|
|
1815
|
-
record.updatedAt = now;
|
|
1816
|
-
record.archivedAt = null;
|
|
1817
|
-
record.archiveReason = null;
|
|
1818
|
-
usage.skills[name] = record;
|
|
1819
|
-
await writeGeneratedMemorySkillUsage(memoryRoot, usage);
|
|
1820
|
-
return true;
|
|
1821
|
-
}
|
|
1822
|
-
|
|
1823
|
-
function normalizeConsolidatedUserProfile(input: string): string {
|
|
1824
|
-
const trimmed = input.trim();
|
|
1825
|
-
if (!trimmed) return "";
|
|
1826
|
-
if (!trimmed.startsWith(USER_PROFILE_OPEN_TAG) || !trimmed.endsWith(USER_PROFILE_CLOSE_TAG)) {
|
|
1827
|
-
throw new Error(
|
|
1828
|
-
`phase2 user_md must be empty or a complete ${USER_PROFILE_OPEN_TAG}...${USER_PROFILE_CLOSE_TAG} block`,
|
|
1829
|
-
);
|
|
1830
|
-
}
|
|
1831
|
-
return trimmed;
|
|
1832
|
-
}
|
|
1833
|
-
|
|
1834
|
-
function assertNoIdentityArtifactLeak(fields: ReadonlyArray<{ field: string; value: string }>): void {
|
|
1835
|
-
for (const { field, value } of fields) {
|
|
1836
|
-
for (const { label, pattern } of FORBIDDEN_IDENTITY_ARTIFACT_PATTERNS) {
|
|
1837
|
-
if (pattern.test(value)) {
|
|
1838
|
-
throw new Error(
|
|
1839
|
-
`phase2 attempted to write approval-gated identity artifact ${label} in ${field}; ` +
|
|
1840
|
-
`${MEMORY_ARTIFACTS.soulProposal} must be proposed only by an explicit identity-review flow`,
|
|
1841
|
-
);
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
860
|
+
await fs.rm(path.join(skillsDir, dirent.name), { recursive: true, force: true });
|
|
1844
861
|
}
|
|
1845
862
|
}
|
|
1846
863
|
|
|
@@ -1922,9 +939,8 @@ function parseStage1OutputSchema(value: Record<string, unknown>): Stage1OutputSc
|
|
|
1922
939
|
}
|
|
1923
940
|
|
|
1924
941
|
function parseConsolidationOutputSchema(value: Record<string, unknown>): ConsolidationOutputSchema | undefined {
|
|
1925
|
-
if (!hasExactKeys(value, ["memory_md", "
|
|
942
|
+
if (!hasExactKeys(value, ["memory_md", "memory_summary", "skills"])) return undefined;
|
|
1926
943
|
if (typeof value.memory_md !== "string") return undefined;
|
|
1927
|
-
if (!(value.user_md === undefined || typeof value.user_md === "string")) return undefined;
|
|
1928
944
|
if (typeof value.memory_summary !== "string") return undefined;
|
|
1929
945
|
if (!Array.isArray(value.skills)) return undefined;
|
|
1930
946
|
const skills: ConsolidationSkillSchema[] = [];
|
|
@@ -1948,24 +964,11 @@ function parseConsolidationOutputSchema(value: Record<string, unknown>): Consoli
|
|
|
1948
964
|
}
|
|
1949
965
|
return {
|
|
1950
966
|
memory_md: value.memory_md,
|
|
1951
|
-
user_md: value.user_md ?? "",
|
|
1952
967
|
memory_summary: value.memory_summary,
|
|
1953
968
|
skills,
|
|
1954
969
|
};
|
|
1955
970
|
}
|
|
1956
971
|
|
|
1957
|
-
function parseIdentityReviewOutputSchema(value: Record<string, unknown>): string | undefined {
|
|
1958
|
-
if (!hasExactKeys(value, ["soul_proposal"])) return undefined;
|
|
1959
|
-
if (typeof value.soul_proposal !== "string") return undefined;
|
|
1960
|
-
const proposal = redactSecrets(value.soul_proposal).trim();
|
|
1961
|
-
if (!proposal) return "";
|
|
1962
|
-
if (!proposal.startsWith("<soul_proposal") || !proposal.endsWith("</soul_proposal>")) return undefined;
|
|
1963
|
-
if (/<\s*\/?\s*soul\b/i.test(proposal)) return undefined;
|
|
1964
|
-
if (/<\s*\/?\s*identity\b/i.test(proposal)) return undefined;
|
|
1965
|
-
if (/<\s*\/?\s*personality\b/i.test(proposal)) return undefined;
|
|
1966
|
-
return proposal;
|
|
1967
|
-
}
|
|
1968
|
-
|
|
1969
972
|
function hasExactKeys(value: Record<string, unknown>, expectedKeys: string[], allowMissing = false): boolean {
|
|
1970
973
|
const sortedKeys = Object.keys(value).sort();
|
|
1971
974
|
const sortedExpected = [...expectedKeys].sort();
|
|
@@ -1986,6 +989,12 @@ function redactSecrets(input: string): string {
|
|
|
1986
989
|
/(?:sk|pk|rk|tok|key|secret|token|password)[-_A-Za-z0-9]{12,}/g,
|
|
1987
990
|
/[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}/g,
|
|
1988
991
|
/(?:AKIA|ASIA)[A-Z0-9]{16}/g,
|
|
992
|
+
// Common provider token prefixes (GitHub, npm, Slack, Google).
|
|
993
|
+
/(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}/g,
|
|
994
|
+
/github_pat_[A-Za-z0-9_]{20,}/g,
|
|
995
|
+
/npm_[A-Za-z0-9]{30,}/g,
|
|
996
|
+
/xox[baprs]-[A-Za-z0-9-]{10,}/g,
|
|
997
|
+
/AIza[A-Za-z0-9_-]{30,}/g,
|
|
1989
998
|
];
|
|
1990
999
|
for (const pattern of patterns) {
|
|
1991
1000
|
out = out.replace(pattern, "[REDACTED]");
|
|
@@ -2064,65 +1073,6 @@ function extractMessageText(message: AgentMessage): string {
|
|
|
2064
1073
|
.join("\n");
|
|
2065
1074
|
}
|
|
2066
1075
|
|
|
2067
|
-
function extractPostTurnReviewMessages(session: AgentSession): PostTurnReviewMessage[] {
|
|
2068
|
-
const manager = session.sessionManager as {
|
|
2069
|
-
getEntries?: () => Array<{ type?: string; message?: { role?: unknown; content?: unknown } }>;
|
|
2070
|
-
};
|
|
2071
|
-
const entries = manager.getEntries?.();
|
|
2072
|
-
if (!entries) return [];
|
|
2073
|
-
const messages: PostTurnReviewMessage[] = [];
|
|
2074
|
-
for (const entry of entries) {
|
|
2075
|
-
if (entry.type !== "message") continue;
|
|
2076
|
-
const message = entry.message;
|
|
2077
|
-
if (!message) continue;
|
|
2078
|
-
const role = message.role;
|
|
2079
|
-
if (role !== "user" && role !== "assistant") continue;
|
|
2080
|
-
const content =
|
|
2081
|
-
role === "user" ? extractPostTurnUserText(message.content) : extractPostTurnAssistantText(message.content);
|
|
2082
|
-
const trimmed = content.trim();
|
|
2083
|
-
if (!trimmed) continue;
|
|
2084
|
-
messages.push({ role, content: trimmed });
|
|
2085
|
-
}
|
|
2086
|
-
return messages;
|
|
2087
|
-
}
|
|
2088
|
-
|
|
2089
|
-
function extractPostTurnUserText(content: unknown): string {
|
|
2090
|
-
if (typeof content === "string") return content;
|
|
2091
|
-
if (!Array.isArray(content)) return "";
|
|
2092
|
-
const parts: string[] = [];
|
|
2093
|
-
for (const item of content) {
|
|
2094
|
-
if (!item || typeof item !== "object") continue;
|
|
2095
|
-
const block = item as { type?: unknown; text?: unknown };
|
|
2096
|
-
if (block.type === "text" && typeof block.text === "string") {
|
|
2097
|
-
parts.push(block.text);
|
|
2098
|
-
}
|
|
2099
|
-
}
|
|
2100
|
-
return parts.join("\n");
|
|
2101
|
-
}
|
|
2102
|
-
|
|
2103
|
-
function extractPostTurnAssistantText(content: unknown): string {
|
|
2104
|
-
if (!Array.isArray(content)) return "";
|
|
2105
|
-
const parts: string[] = [];
|
|
2106
|
-
for (const item of content) {
|
|
2107
|
-
if (!item || typeof item !== "object") continue;
|
|
2108
|
-
const block = item as { type?: unknown; text?: unknown };
|
|
2109
|
-
if (block.type === "text" && typeof block.text === "string") {
|
|
2110
|
-
parts.push(block.text);
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2113
|
-
return parts.join("\n");
|
|
2114
|
-
}
|
|
2115
|
-
|
|
2116
|
-
function buildPostTurnReviewThreadId(sessionId: string | undefined, userTurns: number): string {
|
|
2117
|
-
const rawId = sessionId?.trim() || "unknown-session";
|
|
2118
|
-
const safeSessionId =
|
|
2119
|
-
rawId
|
|
2120
|
-
.replace(/[^A-Za-z0-9_-]+/g, "_")
|
|
2121
|
-
.replace(/^_+|_+$/g, "")
|
|
2122
|
-
.slice(0, 80) || "unknown-session";
|
|
2123
|
-
return `${POST_TURN_REVIEW_THREAD_PREFIX}-${safeSessionId}-${userTurns}`;
|
|
2124
|
-
}
|
|
2125
|
-
|
|
2126
1076
|
function truncateByApproxTokens(text: string, tokenLimit: number): string {
|
|
2127
1077
|
if (tokenLimit <= 0) return "";
|
|
2128
1078
|
const maxChars = tokenLimit * 4;
|
|
@@ -2134,7 +1084,9 @@ function truncateByApproxTokens(text: string, tokenLimit: number): string {
|
|
|
2134
1084
|
|
|
2135
1085
|
function computeModelTokenBudget(model: Model, config: MemoryRuntimeConfig): number {
|
|
2136
1086
|
const maxTokens =
|
|
2137
|
-
Number.isFinite(model.contextWindow) && model.contextWindow > 0
|
|
1087
|
+
model.contextWindow !== null && Number.isFinite(model.contextWindow) && model.contextWindow > 0
|
|
1088
|
+
? model.contextWindow
|
|
1089
|
+
: config.fallbackTokenLimit;
|
|
2138
1090
|
return Math.max(2048, Math.floor(maxTokens));
|
|
2139
1091
|
}
|
|
2140
1092
|
|
|
@@ -2148,7 +1100,7 @@ async function resolveMemoryModel(options: {
|
|
|
2148
1100
|
if (requestedModel) {
|
|
2149
1101
|
const resolved = resolveModelRoleValue(requestedModel, modelRegistry.getAll(), {
|
|
2150
1102
|
settings: session.settings,
|
|
2151
|
-
matchPreferences:
|
|
1103
|
+
matchPreferences: getModelMatchPreferences(session.settings),
|
|
2152
1104
|
modelRegistry,
|
|
2153
1105
|
});
|
|
2154
1106
|
if (resolved.model) return resolved.model;
|
|
@@ -2157,28 +1109,8 @@ async function resolveMemoryModel(options: {
|
|
|
2157
1109
|
}
|
|
2158
1110
|
|
|
2159
1111
|
function loadMemoryConfig(settings: Settings): MemoryRuntimeConfig {
|
|
2160
|
-
const selfImprovementMode = settings.get("selfImprovement.mode") ?? DEFAULTS.selfImprovementMode;
|
|
2161
|
-
const backgroundReviewMode = settings.get("selfImprovement.backgroundReviewMode") ?? DEFAULTS.backgroundReviewMode;
|
|
2162
|
-
const backgroundReviewEveryNTurns =
|
|
2163
|
-
settings.get("selfImprovement.backgroundReviewEveryNTurns") ?? DEFAULTS.backgroundReviewEveryNTurns;
|
|
2164
|
-
const identityReviewMode = settings.get("selfImprovement.identityReviewMode") ?? DEFAULTS.identityReviewMode;
|
|
2165
|
-
const curatorMode = settings.get("selfImprovement.curatorMode") ?? DEFAULTS.curatorMode;
|
|
2166
|
-
const generatedSkillStaleAfterDays =
|
|
2167
|
-
settings.get("selfImprovement.generatedSkillStaleAfterDays") ?? DEFAULTS.generatedSkillStaleAfterDays;
|
|
2168
|
-
const generatedSkillArchiveAfterDays =
|
|
2169
|
-
settings.get("selfImprovement.generatedSkillArchiveAfterDays") ?? DEFAULTS.generatedSkillArchiveAfterDays;
|
|
2170
|
-
const localMemoryRequested = settings.get("memory.backend") === "local" || settings.get("memories.enabled") === true;
|
|
2171
1112
|
return {
|
|
2172
|
-
enabled:
|
|
2173
|
-
selfImprovementMode,
|
|
2174
|
-
backgroundReviewMode,
|
|
2175
|
-
backgroundReviewEveryNTurns: Number.isFinite(backgroundReviewEveryNTurns)
|
|
2176
|
-
? Math.max(0, Math.floor(backgroundReviewEveryNTurns))
|
|
2177
|
-
: DEFAULTS.backgroundReviewEveryNTurns,
|
|
2178
|
-
identityReviewMode,
|
|
2179
|
-
curatorMode,
|
|
2180
|
-
generatedSkillStaleAfterDays,
|
|
2181
|
-
generatedSkillArchiveAfterDays,
|
|
1113
|
+
enabled: settings.get("memory.backend") === "local" || settings.get("memories.enabled") === true,
|
|
2182
1114
|
maxRolloutsPerStartup: settings.get("memories.maxRolloutsPerStartup") ?? DEFAULTS.maxRolloutsPerStartup,
|
|
2183
1115
|
maxRolloutAgeDays: settings.get("memories.maxRolloutAgeDays") ?? DEFAULTS.maxRolloutAgeDays,
|
|
2184
1116
|
minRolloutIdleHours: settings.get("memories.minRolloutIdleHours") ?? DEFAULTS.minRolloutIdleHours,
|
|
@@ -2202,6 +1134,120 @@ export function getMemoryRoot(agentDir: string, cwd: string): string {
|
|
|
2202
1134
|
return path.join(getMemoriesDir(agentDir), encodeProjectPath(cwd));
|
|
2203
1135
|
}
|
|
2204
1136
|
|
|
1137
|
+
/**
|
|
1138
|
+
* Filename of the captured-lessons file under a project's memory root.
|
|
1139
|
+
*
|
|
1140
|
+
* Written by the `learn` tool via {@link saveLearnedLesson} and read back by
|
|
1141
|
+
* {@link buildMemoryToolDeveloperInstructions}. Deliberately distinct from the
|
|
1142
|
+
* consolidation artifacts (`MEMORY.md`, `memory_summary.md`, `skills/`) so a
|
|
1143
|
+
* consolidation pass never clobbers manually captured lessons.
|
|
1144
|
+
*/
|
|
1145
|
+
const LEARNED_LESSONS_FILE = "learned.md";
|
|
1146
|
+
/** Newest-first cap on retained lessons, bounding file growth by entry count. */
|
|
1147
|
+
const MAX_LEARNED_LESSONS = 100;
|
|
1148
|
+
/** Per-field char caps so a single huge capture can't bloat learned.md. */
|
|
1149
|
+
const MAX_LEARNED_CONTENT_CHARS = 2000;
|
|
1150
|
+
const MAX_LEARNED_CONTEXT_CHARS = 400;
|
|
1151
|
+
|
|
1152
|
+
/**
|
|
1153
|
+
* Strip prompt-injection vectors from a single line of lesson text: control/
|
|
1154
|
+
* format chars, angle brackets (`</skills>`), backticks, and `~~~` fences, then
|
|
1155
|
+
* collapse whitespace. Applied on BOTH write and read (the block renders
|
|
1156
|
+
* unescaped into the system prompt), mirroring managed-skill descriptions.
|
|
1157
|
+
*/
|
|
1158
|
+
function neutralizeInjection(text: string): string {
|
|
1159
|
+
return text
|
|
1160
|
+
.replace(/[\p{Cc}\p{Cf}]/gu, " ")
|
|
1161
|
+
.replace(/[<>`]/g, "")
|
|
1162
|
+
.replace(/~{2,}/g, "~")
|
|
1163
|
+
.replace(/\s+/g, " ")
|
|
1164
|
+
.trim();
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/** Slice to `maxChars`, dropping a trailing unpaired high surrogate. */
|
|
1168
|
+
function boundChars(text: string, maxChars: number): string {
|
|
1169
|
+
if (text.length <= maxChars) return text;
|
|
1170
|
+
const sliced = text.slice(0, maxChars);
|
|
1171
|
+
return /[\uD800-\uDBFF]$/.test(sliced) ? sliced.slice(0, -1) : sliced;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
/**
|
|
1175
|
+
* Normalize one lesson field for storage: neutralize injection delimiters
|
|
1176
|
+
* first, then redact secrets, then bound the length.
|
|
1177
|
+
*/
|
|
1178
|
+
function normalizeLearnedText(text: string, maxChars: number): string {
|
|
1179
|
+
return boundChars(redactSecrets(neutralizeInjection(text)).trim(), maxChars);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
/** Per-path write chains serializing `learned.md` read-modify-write. */
|
|
1183
|
+
const learnedWriteChains = new Map<string, Promise<unknown>>();
|
|
1184
|
+
|
|
1185
|
+
/**
|
|
1186
|
+
* Append one lesson to the project's `learned.md` (newest-first, deduped,
|
|
1187
|
+
* capped, secret-redacted, injection-neutralized). The file backs the `learn`
|
|
1188
|
+
* tool when `memory.backend` is `local`.
|
|
1189
|
+
*/
|
|
1190
|
+
export async function saveLearnedLesson(
|
|
1191
|
+
agentDir: string,
|
|
1192
|
+
cwd: string,
|
|
1193
|
+
input: MemoryBackendSaveInput,
|
|
1194
|
+
): Promise<MemoryBackendSaveResult> {
|
|
1195
|
+
const content = normalizeLearnedText(input.content, MAX_LEARNED_CONTENT_CHARS);
|
|
1196
|
+
if (!content) {
|
|
1197
|
+
return { backend: "local", stored: 0, message: "Empty lesson; nothing stored." };
|
|
1198
|
+
}
|
|
1199
|
+
const context = input.context ? normalizeLearnedText(input.context, MAX_LEARNED_CONTEXT_CHARS) : "";
|
|
1200
|
+
const line = context ? `- ${content} _(context: ${context})_` : `- ${content}`;
|
|
1201
|
+
const filePath = path.join(getMemoryRoot(agentDir, cwd), LEARNED_LESSONS_FILE);
|
|
1202
|
+
|
|
1203
|
+
// Serialize the read-modify-write per file: parallel `learn` calls (sibling
|
|
1204
|
+
// subagents, or two shared tool calls in one turn) share the project memory
|
|
1205
|
+
// root, so an unguarded RMW would let the last writer drop the other's lesson.
|
|
1206
|
+
const run = (learnedWriteChains.get(filePath) ?? Promise.resolve()).then(() => appendLearnedLine(filePath, line));
|
|
1207
|
+
const guarded = run.catch(() => {});
|
|
1208
|
+
learnedWriteChains.set(filePath, guarded);
|
|
1209
|
+
try {
|
|
1210
|
+
await run;
|
|
1211
|
+
} finally {
|
|
1212
|
+
if (learnedWriteChains.get(filePath) === guarded) learnedWriteChains.delete(filePath);
|
|
1213
|
+
}
|
|
1214
|
+
return { backend: "local", stored: 1, message: `Lesson saved to ${LEARNED_LESSONS_FILE}.` };
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
async function appendLearnedLine(filePath: string, line: string): Promise<void> {
|
|
1218
|
+
let existing = "";
|
|
1219
|
+
try {
|
|
1220
|
+
existing = await Bun.file(filePath).text();
|
|
1221
|
+
} catch (err) {
|
|
1222
|
+
if (!isEnoent(err)) throw err;
|
|
1223
|
+
}
|
|
1224
|
+
const prior = existing
|
|
1225
|
+
.split("\n")
|
|
1226
|
+
.map(l => l.trim())
|
|
1227
|
+
.filter(l => l.startsWith("- ") && l !== line);
|
|
1228
|
+
const lessons = [line, ...prior].slice(0, MAX_LEARNED_LESSONS);
|
|
1229
|
+
await Bun.write(filePath, `${lessons.join("\n")}\n`);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
/**
|
|
1233
|
+
* Read `learned.md`, neutralizing each line on read too — a hand-edited or
|
|
1234
|
+
* pre-existing file bypasses write-time normalization and the block renders
|
|
1235
|
+
* unescaped into the system prompt. Returns "" when absent/unreadable.
|
|
1236
|
+
*/
|
|
1237
|
+
async function readLearnedLessons(memoryRoot: string): Promise<string> {
|
|
1238
|
+
let raw = "";
|
|
1239
|
+
try {
|
|
1240
|
+
raw = (await Bun.file(path.join(memoryRoot, LEARNED_LESSONS_FILE)).text()).trim();
|
|
1241
|
+
} catch {
|
|
1242
|
+
return "";
|
|
1243
|
+
}
|
|
1244
|
+
if (!raw) return "";
|
|
1245
|
+
return raw
|
|
1246
|
+
.split("\n")
|
|
1247
|
+
.map(line => redactSecrets(neutralizeInjection(line)))
|
|
1248
|
+
.join("\n");
|
|
1249
|
+
}
|
|
1250
|
+
|
|
2205
1251
|
function encodeProjectPath(cwd: string): string {
|
|
2206
1252
|
return `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
|
|
2207
1253
|
}
|