@code-yeongyu/senpi 2026.9.24-2 → 2026.9.24-3
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 +28 -0
- package/dist/bundle/chunks/{anthropic-messages-UPLQFNTT.js → anthropic-messages-UYDVRFAS.js} +1 -1
- package/dist/bundle/chunks/{app-server-command-UHPJ2C4D.js → app-server-command-OTRHYRIB.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-XAR2E66I.js → azure-openai-responses-DODWR4W6.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
- package/dist/bundle/chunks/{chunk-WISJJQ4K.js → chunk-6Q6DGME2.js} +1 -1
- package/dist/bundle/chunks/{chunk-YWO3OBYK.js → chunk-77ACEMYL.js} +1 -1
- package/dist/bundle/chunks/chunk-ELFCNCBY.js +11 -0
- package/dist/bundle/chunks/{chunk-WTSAB6AE.js → chunk-FD34HSJJ.js} +2 -2
- package/dist/bundle/chunks/{chunk-2PLPSKHD.js → chunk-HZAKOVHN.js} +1 -1
- package/dist/bundle/chunks/chunk-JBOV6VNK.js +8 -0
- package/dist/bundle/chunks/{chunk-YBC274GY.js → chunk-KMJXSXRX.js} +3 -3
- package/dist/bundle/chunks/{chunk-JRQSHZPP.js → chunk-OZCB6BP3.js} +4 -3
- package/dist/bundle/chunks/{chunk-NQAVM5XL.js → chunk-SFYHCFRO.js} +1 -1
- package/dist/bundle/chunks/{chunk-ONR57UMO.js → chunk-TTY5BHCG.js} +1 -1
- package/dist/bundle/chunks/{chunk-YKU45B65.js → chunk-UM43CBL4.js} +156 -98
- package/dist/bundle/chunks/{chunk-NGHOUIPR.js → chunk-WM5FVFAP.js} +2 -2
- package/dist/bundle/chunks/{chunk-NKVUDCGZ.js → chunk-ZKZAATFM.js} +1 -1
- package/dist/bundle/chunks/{cli-main-O5Y3TBID.js → cli-main-TX6I4X4F.js} +1 -1
- package/dist/bundle/chunks/{google-generative-ai-B5QMFONL.js → google-generative-ai-VIEFECKJ.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-O2TGMVWF.js → google-vertex-Q64CKFID.js} +1 -1
- package/dist/bundle/chunks/{help-fast-path-Y33OIZBU.js → help-fast-path-ZGKPSDFO.js} +1 -1
- package/dist/bundle/chunks/{host-command-WJOL27Q7.js → host-command-BMHJ4YUD.js} +1 -1
- package/dist/bundle/chunks/{host-lifecycle-YBFXYFZP.js → host-lifecycle-2GZAGSGW.js} +1 -1
- package/dist/bundle/chunks/{interactive-host-runtime-XVTF3NUD.js → interactive-host-runtime-YI75GFD5.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-OO3NGM4G.js → interactive-mode-UI5Q6FGY.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-6MKBBOKF.js → multi-session-host-D6HMI3RQ.js} +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-CK7T4WNM.js → openai-codex-responses-YSGZZDD5.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-OPQKN7FH.js → openai-completions-4CLXDDHJ.js} +3 -3
- package/dist/bundle/chunks/openai-responses-IBFGBAJP.js +2 -0
- package/dist/bundle/chunks/{package-manager-cli-BMEWLAI2.js → package-manager-cli-3UWH3ZZS.js} +1 -1
- package/dist/bundle/chunks/{rotation-stream-ZFA6ELXJ.js → rotation-stream-NATO6IMN.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-5653CV65.js → rpc-mode-LXIZHJSJ.js} +1 -1
- package/dist/bundle/chunks/{session-picker-PPYK56TA.js → session-picker-BP7THCWF.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +190 -131
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/agent-session.d.ts +3 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +42 -7
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
- package/dist/core/dynamic-prompt/build.js +3 -0
- package/dist/core/dynamic-prompt/build.js.map +1 -1
- package/dist/core/dynamic-prompt/handoff.d.ts +16 -0
- package/dist/core/dynamic-prompt/handoff.d.ts.map +1 -0
- package/dist/core/dynamic-prompt/handoff.js +16 -0
- package/dist/core/dynamic-prompt/handoff.js.map +1 -0
- package/dist/core/dynamic-prompt/index.d.ts +1 -0
- package/dist/core/dynamic-prompt/index.d.ts.map +1 -1
- package/dist/core/dynamic-prompt/index.js +1 -0
- package/dist/core/dynamic-prompt/index.js.map +1 -1
- package/dist/core/dynamic-prompt/policies.d.ts.map +1 -1
- package/dist/core/dynamic-prompt/policies.js +2 -1
- package/dist/core/dynamic-prompt/policies.js.map +1 -1
- package/dist/core/dynamic-prompt/style.js +2 -2
- package/dist/core/dynamic-prompt/style.js.map +1 -1
- package/dist/core/environment-context.d.ts +13 -0
- package/dist/core/environment-context.d.ts.map +1 -1
- package/dist/core/environment-context.js +31 -0
- package/dist/core/environment-context.js.map +1 -1
- package/dist/core/extensions/builtin/anthropic-bash/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/anthropic-bash/index.js +1 -1
- package/dist/core/extensions/builtin/anthropic-bash/index.js.map +1 -1
- package/dist/core/extensions/builtin/anthropic-web-search/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/anthropic-web-search/index.js +1 -1
- package/dist/core/extensions/builtin/anthropic-web-search/index.js.map +1 -1
- package/dist/core/extensions/builtin/bash-timeout/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/bash-timeout/index.js +1 -1
- package/dist/core/extensions/builtin/bash-timeout/index.js.map +1 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.d.ts +1 -0
- package/dist/core/extensions/builtin/cache-keepalive/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cache-keepalive/index.js +4 -0
- package/dist/core/extensions/builtin/cache-keepalive/index.js.map +1 -1
- package/dist/core/extensions/builtin/cache-keepalive/prewarm-entry.d.ts +21 -0
- package/dist/core/extensions/builtin/cache-keepalive/prewarm-entry.d.ts.map +1 -0
- package/dist/core/extensions/builtin/cache-keepalive/prewarm-entry.js +23 -0
- package/dist/core/extensions/builtin/cache-keepalive/prewarm-entry.js.map +1 -0
- package/dist/core/extensions/builtin/cache-keepalive/session-prewarm.d.ts +25 -0
- package/dist/core/extensions/builtin/cache-keepalive/session-prewarm.d.ts.map +1 -0
- package/dist/core/extensions/builtin/cache-keepalive/session-prewarm.js +86 -0
- package/dist/core/extensions/builtin/cache-keepalive/session-prewarm.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +6 -2
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts +3 -1
- package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/todo-bridge.js +6 -3
- package/dist/core/extensions/builtin/compaction/todo-bridge.js.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/continuation.js +1 -1
- package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
- package/dist/core/extensions/builtin/goal/direct-input-lifecycle.d.ts +2 -0
- package/dist/core/extensions/builtin/goal/direct-input-lifecycle.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +2 -0
- package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js.map +1 -1
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +14 -0
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/todo-owed-backstop.d.ts +47 -0
- package/dist/core/extensions/builtin/goal/todo-owed-backstop.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/todo-owed-backstop.js +155 -0
- package/dist/core/extensions/builtin/goal/todo-owed-backstop.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/index.js +6 -2
- package/dist/core/extensions/builtin/hooks/index.js.map +1 -1
- package/dist/core/extensions/builtin/imagegen/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/imagegen/index.js +1 -1
- package/dist/core/extensions/builtin/imagegen/index.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.js +15 -6
- package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
- package/dist/core/extensions/builtin/openai-image-gen/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/openai-image-gen/index.js +13 -3
- package/dist/core/extensions/builtin/openai-image-gen/index.js.map +1 -1
- package/dist/core/extensions/builtin/openai-web-search/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/openai-web-search/index.js +1 -1
- package/dist/core/extensions/builtin/openai-web-search/index.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +12 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +13 -2
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5-5.js +13 -2
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js +14 -3
- package/dist/core/extensions/builtin/prompt-preset/claude-opus-5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js +15 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +17 -5
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +6 -2
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +11 -2
- package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.js +10 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.5.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.6.js +12 -4
- package/dist/core/extensions/builtin/prompt-preset/grok-4.6.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.7.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/grok-4.7.js +45 -31
- package/dist/core/extensions/builtin/prompt-preset/grok-4.7.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/index.js +3 -2
- package/dist/core/extensions/builtin/prompt-preset/index.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-code.js +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k2-code.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +13 -2
- package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-url-widget.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-url-widget.js +4 -3
- package/dist/core/extensions/builtin/prompt-url-widget.js.map +1 -1
- package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/rules/index.js +15 -8
- package/dist/core/extensions/builtin/rules/index.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/commands.d.ts +2 -1
- package/dist/core/extensions/builtin/todotools/commands.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/commands.js +6 -3
- package/dist/core/extensions/builtin/todotools/commands.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/first-turn.d.ts +38 -0
- package/dist/core/extensions/builtin/todotools/first-turn.d.ts.map +1 -0
- package/dist/core/extensions/builtin/todotools/first-turn.js +83 -0
- package/dist/core/extensions/builtin/todotools/first-turn.js.map +1 -0
- package/dist/core/extensions/builtin/todotools/index.d.ts +1 -1
- package/dist/core/extensions/builtin/todotools/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/index.js +69 -14
- package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -2
- package/dist/core/extensions/builtin/todotools/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/prompt.js +2 -3
- package/dist/core/extensions/builtin/todotools/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/state.d.ts +4 -3
- package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/state.js +4 -3
- package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/todo-ask.d.ts +13 -0
- package/dist/core/extensions/builtin/todotools/todo-ask.d.ts.map +1 -0
- package/dist/core/extensions/builtin/todotools/todo-ask.js +61 -0
- package/dist/core/extensions/builtin/todotools/todo-ask.js.map +1 -0
- package/dist/core/extensions/builtin/todotools/todo-format.d.ts +30 -2
- package/dist/core/extensions/builtin/todotools/todo-format.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/todo-format.js +58 -1
- package/dist/core/extensions/builtin/todotools/todo-format.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/todo-storage.d.ts +5 -2
- package/dist/core/extensions/builtin/todotools/todo-storage.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/todo-storage.js +23 -12
- package/dist/core/extensions/builtin/todotools/todo-storage.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/todo-types.d.ts +14 -0
- package/dist/core/extensions/builtin/todotools/todo-types.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/todo-types.js +2 -0
- package/dist/core/extensions/builtin/todotools/todo-types.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/tools/todo.d.ts +3 -1
- package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/tools/todo.js +23 -8
- package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +5 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +7 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +27 -2
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +53 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +10 -2
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-runtime.d.ts +11 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +13 -0
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/prompt-cache-prefix-request.d.ts +45 -0
- package/dist/core/prompt-cache-prefix-request.d.ts.map +1 -0
- package/dist/core/prompt-cache-prefix-request.js +134 -0
- package/dist/core/prompt-cache-prefix-request.js.map +1 -0
- package/dist/core/settings-manager.d.ts +4 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +8 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-shapes.d.ts +5 -0
- package/dist/core/settings-shapes.d.ts.map +1 -1
- package/dist/core/settings-shapes.js.map +1 -1
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js +6 -0
- package/dist/core/usage-totals.js.map +1 -1
- package/docs/extensions.md +22 -0
- package/docs/settings.md +7 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +16 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js +24 -17
- package/node_modules/@earendil-works/pi-ai/dist/api/google-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +57 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-prompt-cache.d.ts +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-prompt-cache.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-prompt-cache.js +62 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-prompt-cache.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +12 -4
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +11 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +63 -9
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.lazy.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.lazy.js +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.lazy.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/prompt-cache-warmers.d.ts +13 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/prompt-cache-warmers.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/prompt-cache-warmers.js +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/prompt-cache-warmers.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/warm-prompt-cache.d.ts +4 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/warm-prompt-cache.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/warm-prompt-cache.js +22 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/warm-prompt-cache.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/google-vertex.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +13 -0
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.js +7 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/tool-choice-fallback.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
- package/dist/bundle/chunks/chunk-J7IUURQ6.js +0 -8
- package/dist/bundle/chunks/chunk-MO2U7YRX.js +0 -11
- package/dist/bundle/chunks/openai-responses-QHWM3KPO.js +0 -2
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { getAnthropicCompat } from "@earendil-works/pi-ai/utils/prompt-cache-ttl";
|
|
2
|
+
export const FIRST_TURN_CUSTOM_TYPE = "senpi.todo-first-turn";
|
|
3
|
+
export const FIRST_TURN_REMINDER = `<system-reminder>
|
|
4
|
+
This is the first request of the session. Before continuing, call the todo tool with op "init" and a phased list covering the whole request end to end: investigation, implementation, verification (diagnostics, tests, build, manual check), and the final report. Give every task a unique 5-10 word label; phase names are short noun phrases. Then continue the request in this same turn - the init is not a turn by itself.
|
|
5
|
+
</system-reminder>`;
|
|
6
|
+
/** One-shot, non-interactive runs; the same set `terminal/notify.ts` never wakes. */
|
|
7
|
+
const NON_INTERACTIVE_MODES = new Set(["print", "json"]);
|
|
8
|
+
const TRAILING_CLOSERS = /[\s"'`\u2018\u2019\u201C\u201D)\]}]+$/u;
|
|
9
|
+
/**
|
|
10
|
+
* Arms the first-turn plan opener only for a session's first real request that asks for work:
|
|
11
|
+
* never in a preview, never once any user message is on the branch (`before_agent_start` fires
|
|
12
|
+
* before the prompt is persisted), never over an existing list, never for a question or an
|
|
13
|
+
* exclamation, and never in print/json runs.
|
|
14
|
+
*/
|
|
15
|
+
export function shouldArmFirstTurn(input) {
|
|
16
|
+
if (input.preview || input.setting === "off" || !input.todoActive)
|
|
17
|
+
return false;
|
|
18
|
+
if (NON_INTERACTIVE_MODES.has(input.mode))
|
|
19
|
+
return false;
|
|
20
|
+
const request = input.prompt.trim().replace(TRAILING_CLOSERS, "");
|
|
21
|
+
if (request === "" || /[?!\uFF1F\uFF01]$/u.test(request))
|
|
22
|
+
return false;
|
|
23
|
+
if (input.branchEntries.some((entry) => entry.type === "message" && entry.message.role === "user"))
|
|
24
|
+
return false;
|
|
25
|
+
return input.phases.every((phase) => phase.tasks.length === 0);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether the request wire can name one tool in `tool_choice`. Anthropic reads the RESOLVED
|
|
29
|
+
* compat (catalog models carry no `compat`, and the resolver applies the Fable / Mythos /
|
|
30
|
+
* Opus 5.5 forced-choice default), never `model.compat` directly.
|
|
31
|
+
*/
|
|
32
|
+
export function supportsNamedToolChoice(model) {
|
|
33
|
+
switch (model?.api) {
|
|
34
|
+
case "anthropic-messages": {
|
|
35
|
+
const compat = getAnthropicCompat(model);
|
|
36
|
+
return compat.supportsToolChoice !== false && compat.supportsForcedToolChoice !== false;
|
|
37
|
+
}
|
|
38
|
+
case "openai-responses":
|
|
39
|
+
case "openai-completions":
|
|
40
|
+
return true;
|
|
41
|
+
default:
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Wire shape of a `tool_choice` that forces `toolName`, or `undefined` for an unsupported api. */
|
|
46
|
+
export function namedToolChoicePayload(api, toolName) {
|
|
47
|
+
switch (api) {
|
|
48
|
+
case "anthropic-messages":
|
|
49
|
+
return { type: "tool", name: toolName };
|
|
50
|
+
case "openai-responses":
|
|
51
|
+
return { type: "function", name: toolName };
|
|
52
|
+
case "openai-completions":
|
|
53
|
+
return { type: "function", function: { name: toolName } };
|
|
54
|
+
default:
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function isRecord(value) {
|
|
59
|
+
return typeof value === "object" && value !== null;
|
|
60
|
+
}
|
|
61
|
+
function declaresTool(tools, toolName) {
|
|
62
|
+
return (Array.isArray(tools) &&
|
|
63
|
+
tools.some((tool) => isRecord(tool) && (tool.name === toolName || (isRecord(tool.function) && tool.function.name === toolName))));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The payload with a forced `todo` tool_choice, or `undefined` to leave it untouched: the
|
|
67
|
+
* request must declare `todo`, carry no tool_choice of its own, and (Anthropic) not run
|
|
68
|
+
* extended thinking, which rejects any forced tool use.
|
|
69
|
+
*/
|
|
70
|
+
export function withForcedTodoChoice(payload, model) {
|
|
71
|
+
if (!supportsNamedToolChoice(model))
|
|
72
|
+
return undefined;
|
|
73
|
+
const toolChoice = namedToolChoicePayload(model?.api, "todo");
|
|
74
|
+
if (!toolChoice || !isRecord(payload) || payload.tool_choice !== undefined)
|
|
75
|
+
return undefined;
|
|
76
|
+
if (!declaresTool(payload.tools, "todo"))
|
|
77
|
+
return undefined;
|
|
78
|
+
const thinking = isRecord(payload.thinking) ? payload.thinking.type : undefined;
|
|
79
|
+
if (model?.api === "anthropic-messages" && (thinking === "enabled" || thinking === "adaptive"))
|
|
80
|
+
return undefined;
|
|
81
|
+
return { ...payload, tool_choice: toolChoice };
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=first-turn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"first-turn.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/first-turn.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { getAnthropicCompat } from \"@earendil-works/pi-ai/utils/prompt-cache-ttl\";\nimport type { SessionEntry } from \"../../../session-manager.ts\";\nimport type { TodoFirstTurnPlan } from \"../../../settings-shapes.ts\";\nimport type { ExtensionMode } from \"../../types.ts\";\nimport type { TodoPhase } from \"./todo-types.ts\";\n\nexport const FIRST_TURN_CUSTOM_TYPE = \"senpi.todo-first-turn\";\n\nexport const FIRST_TURN_REMINDER = `<system-reminder>\nThis is the first request of the session. Before continuing, call the todo tool with op \"init\" and a phased list covering the whole request end to end: investigation, implementation, verification (diagnostics, tests, build, manual check), and the final report. Give every task a unique 5-10 word label; phase names are short noun phrases. Then continue the request in this same turn - the init is not a turn by itself.\n</system-reminder>`;\n\n/** One-shot, non-interactive runs; the same set `terminal/notify.ts` never wakes. */\nconst NON_INTERACTIVE_MODES: ReadonlySet<ExtensionMode> = new Set([\"print\", \"json\"]);\n\nconst TRAILING_CLOSERS = /[\\s\"'`\\u2018\\u2019\\u201C\\u201D)\\]}]+$/u;\n\nexport type FirstTurnGateInput = {\n\tpreview: boolean | undefined;\n\tprompt: string;\n\tbranchEntries: readonly SessionEntry[];\n\tphases: readonly TodoPhase[];\n\ttodoActive: boolean;\n\tsetting: TodoFirstTurnPlan;\n\tmode: ExtensionMode;\n};\n\n/**\n * Arms the first-turn plan opener only for a session's first real request that asks for work:\n * never in a preview, never once any user message is on the branch (`before_agent_start` fires\n * before the prompt is persisted), never over an existing list, never for a question or an\n * exclamation, and never in print/json runs.\n */\nexport function shouldArmFirstTurn(input: FirstTurnGateInput): boolean {\n\tif (input.preview || input.setting === \"off\" || !input.todoActive) return false;\n\tif (NON_INTERACTIVE_MODES.has(input.mode)) return false;\n\tconst request = input.prompt.trim().replace(TRAILING_CLOSERS, \"\");\n\tif (request === \"\" || /[?!\\uFF1F\\uFF01]$/u.test(request)) return false;\n\tif (input.branchEntries.some((entry) => entry.type === \"message\" && entry.message.role === \"user\")) return false;\n\treturn input.phases.every((phase) => phase.tasks.length === 0);\n}\n\n/**\n * Whether the request wire can name one tool in `tool_choice`. Anthropic reads the RESOLVED\n * compat (catalog models carry no `compat`, and the resolver applies the Fable / Mythos /\n * Opus 5.5 forced-choice default), never `model.compat` directly.\n */\nexport function supportsNamedToolChoice(model: Model<Api> | undefined): boolean {\n\tswitch (model?.api) {\n\t\tcase \"anthropic-messages\": {\n\t\t\tconst compat = getAnthropicCompat(model as Model<\"anthropic-messages\">);\n\t\t\treturn compat.supportsToolChoice !== false && compat.supportsForcedToolChoice !== false;\n\t\t}\n\t\tcase \"openai-responses\":\n\t\tcase \"openai-completions\":\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\n/** Wire shape of a `tool_choice` that forces `toolName`, or `undefined` for an unsupported api. */\nexport function namedToolChoicePayload(api: Api | undefined, toolName: string): Record<string, unknown> | undefined {\n\tswitch (api) {\n\t\tcase \"anthropic-messages\":\n\t\t\treturn { type: \"tool\", name: toolName };\n\t\tcase \"openai-responses\":\n\t\t\treturn { type: \"function\", name: toolName };\n\t\tcase \"openai-completions\":\n\t\t\treturn { type: \"function\", function: { name: toolName } };\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction declaresTool(tools: unknown, toolName: string): boolean {\n\treturn (\n\t\tArray.isArray(tools) &&\n\t\ttools.some(\n\t\t\t(tool) =>\n\t\t\t\tisRecord(tool) && (tool.name === toolName || (isRecord(tool.function) && tool.function.name === toolName)),\n\t\t)\n\t);\n}\n\n/**\n * The payload with a forced `todo` tool_choice, or `undefined` to leave it untouched: the\n * request must declare `todo`, carry no tool_choice of its own, and (Anthropic) not run\n * extended thinking, which rejects any forced tool use.\n */\nexport function withForcedTodoChoice(payload: unknown, model: Model<Api> | undefined): unknown {\n\tif (!supportsNamedToolChoice(model)) return undefined;\n\tconst toolChoice = namedToolChoicePayload(model?.api, \"todo\");\n\tif (!toolChoice || !isRecord(payload) || payload.tool_choice !== undefined) return undefined;\n\tif (!declaresTool(payload.tools, \"todo\")) return undefined;\n\tconst thinking = isRecord(payload.thinking) ? payload.thinking.type : undefined;\n\tif (model?.api === \"anthropic-messages\" && (thinking === \"enabled\" || thinking === \"adaptive\")) return undefined;\n\treturn { ...payload, tool_choice: toolChoice };\n}\n"]}
|
|
@@ -3,6 +3,6 @@ export default function todotoolsExtension(pi: ExtensionAPI): void;
|
|
|
3
3
|
export { findPhaseFuzzy, findTaskFuzzy, registerTodoCommand, tokenizeTodoArgs } from "./commands.ts";
|
|
4
4
|
export { markdownToPhases, phasesToMarkdown, resolveTodoMarkdownPath } from "./markdown.ts";
|
|
5
5
|
export { TASK_MANAGEMENT_SECTION } from "./prompt.ts";
|
|
6
|
-
export { appendItems, applyEntry, applyOpsToPhases, applyParams, clonePhases, cloneTask, DEFAULT_INIT_PHASE, findPhaseByName, findTaskByContent, formatSummary, getCompletionTransitions, getLatestPhasesFromBranchEntries, getLatestTodosFromBranchEntries, getTaskTargets, getTodoMarker, getTodoResultLines, getTodoWidgetLines, initPhases, isIncompleteTodo, isTerminalTodoStatus, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, nextActionableTask, normalizeInProgressTask, removeTasks, resolvePhaseOrError, resolveTaskOrError, sanitizeTodoText, TODO_STATE_ENTRY_TYPE, type TodoCompletionTransition, type TodoItem, type TodoOpEntry, type TodoOperation, type TodoPhase, type TodoStateEntry, type TodoStatus, type TodoToolDetails, } from "./state.ts";
|
|
6
|
+
export { appendItems, applyEntry, applyOpsToPhases, applyParams, clonePhases, cloneTask, DEFAULT_INIT_PHASE, describeAskNowNext, findPhaseByName, findTaskByContent, formatSummary, getCompletionTransitions, getLatestPhasesFromBranchEntries, getLatestTodoStateFromBranchEntries, getLatestTodosFromBranchEntries, getTaskTargets, getTodoMarker, getTodoResultLines, getTodoWidgetLines, initPhases, isIncompleteTodo, isTerminalTodoStatus, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, nextActionableTask, normalizeInProgressTask, removeTasks, resolvePhaseOrError, resolveTaskOrError, sanitizeTodoText, TODO_STATE_ENTRY_TYPE, type TodoAsk, type TodoCompletionTransition, type TodoItem, type TodoOpEntry, type TodoOperation, type TodoPhase, type TodoState, type TodoStateEntry, type TodoStatus, type TodoToolDetails, } from "./state.ts";
|
|
7
7
|
export { phaseRomanNumeral } from "./tools/todo.ts";
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAwBrE,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA+GjE;AAED,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,gCAAgC,EAChC,mCAAmC,EACnC,+BAA+B,EAC/B,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,OAAO,EACZ,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,36 +1,58 @@
|
|
|
1
|
+
import { createSessionLogger } from "../../../session-log.js";
|
|
2
|
+
import { SettingsManager } from "../../../settings-manager.js";
|
|
1
3
|
import { registerTodoCommand } from "./commands.js";
|
|
4
|
+
import { FIRST_TURN_CUSTOM_TYPE, FIRST_TURN_REMINDER, shouldArmFirstTurn, withForcedTodoChoice } from "./first-turn.js";
|
|
2
5
|
import { phasesFromCursorTodos } from "./native-todo-mirror.js";
|
|
3
6
|
import { TASK_MANAGEMENT_SECTION } from "./prompt.js";
|
|
4
|
-
import { clonePhases,
|
|
7
|
+
import { clonePhases, getLatestTodoStateFromBranchEntries, } from "./state.js";
|
|
5
8
|
import { TODO_STATE_ENTRY_TYPE } from "./todo-types.js";
|
|
6
9
|
import { getTodoWidgetModel } from "./todo-widget.js";
|
|
7
10
|
import { TodoWidgetComponent } from "./todo-widget-component.js";
|
|
8
11
|
import { registerTodoTool } from "./tools/todo.js";
|
|
9
|
-
function
|
|
10
|
-
return
|
|
12
|
+
function readFirstTurnPlan(ctx) {
|
|
13
|
+
return SettingsManager.create(ctx.cwd, ctx.agentDir, {
|
|
14
|
+
projectTrusted: ctx.isProjectTrusted(),
|
|
15
|
+
}).getTodoFirstTurnPlan();
|
|
11
16
|
}
|
|
12
17
|
export default function todotoolsExtension(pi) {
|
|
13
|
-
let
|
|
14
|
-
|
|
18
|
+
let currentState = { phases: [], ask: undefined };
|
|
19
|
+
// Armed by the first-turn opener; cleared once that run's first assistant message lands.
|
|
20
|
+
let pendingForce;
|
|
21
|
+
let logger;
|
|
22
|
+
const clearPendingForce = () => {
|
|
23
|
+
pendingForce = undefined;
|
|
24
|
+
};
|
|
25
|
+
const getCurrentPhases = () => clonePhases(currentState.phases);
|
|
15
26
|
const setCurrentPhases = (phases) => {
|
|
16
|
-
|
|
27
|
+
currentState = { ...currentState, phases: clonePhases(phases) };
|
|
28
|
+
};
|
|
29
|
+
const getCurrentAsk = () => currentState.ask;
|
|
30
|
+
const setCurrentAsk = (ask) => {
|
|
31
|
+
currentState = { ...currentState, ask };
|
|
17
32
|
};
|
|
18
33
|
const syncWidget = (ctx, completedTasks = []) => {
|
|
19
|
-
const model = getTodoWidgetModel(
|
|
34
|
+
const model = getTodoWidgetModel(currentState.phases);
|
|
20
35
|
ctx.ui.setWidget("todo-sidebar", model ? (tui, theme) => new TodoWidgetComponent(tui, theme, model, completedTasks) : undefined);
|
|
21
36
|
};
|
|
22
37
|
const syncFromSession = (ctx) => {
|
|
23
|
-
|
|
38
|
+
currentState = getLatestTodoStateFromBranchEntries(ctx.sessionManager.getBranch());
|
|
24
39
|
syncWidget(ctx);
|
|
25
40
|
};
|
|
26
41
|
pi.on("session_start", async (_event, ctx) => {
|
|
42
|
+
clearPendingForce();
|
|
27
43
|
syncFromSession(ctx);
|
|
28
44
|
});
|
|
29
45
|
pi.on("session_tree", async (_event, ctx) => {
|
|
46
|
+
clearPendingForce();
|
|
30
47
|
syncFromSession(ctx);
|
|
31
48
|
});
|
|
49
|
+
pi.on("agent_end", clearPendingForce);
|
|
50
|
+
pi.on("session_abort", clearPendingForce);
|
|
51
|
+
pi.on("session_shutdown", clearPendingForce);
|
|
32
52
|
pi.on("message_end", async (event, ctx) => {
|
|
33
53
|
const message = event.message;
|
|
54
|
+
if (message?.role === "assistant")
|
|
55
|
+
clearPendingForce();
|
|
34
56
|
if (message?.role !== "assistant" || !Array.isArray(message.content)) {
|
|
35
57
|
return;
|
|
36
58
|
}
|
|
@@ -43,21 +65,54 @@ export default function todotoolsExtension(pi) {
|
|
|
43
65
|
continue;
|
|
44
66
|
}
|
|
45
67
|
setCurrentPhases(phases);
|
|
46
|
-
|
|
68
|
+
const ask = getCurrentAsk();
|
|
69
|
+
pi.appendEntry(TODO_STATE_ENTRY_TYPE, { schema: "v2", phases, ...(ask ? { ask } : {}) });
|
|
47
70
|
syncWidget(ctx);
|
|
48
71
|
}
|
|
49
72
|
});
|
|
50
|
-
pi.on("before_agent_start", async (event) => {
|
|
73
|
+
pi.on("before_agent_start", async (event, ctx) => {
|
|
74
|
+
const systemPrompt = `${event.systemPrompt}\n${TASK_MANAGEMENT_SECTION}`;
|
|
75
|
+
if (event.preview)
|
|
76
|
+
return { systemPrompt };
|
|
77
|
+
const branchEntries = ctx.sessionManager.getBranch();
|
|
78
|
+
const setting = readFirstTurnPlan(ctx);
|
|
79
|
+
const armed = shouldArmFirstTurn({
|
|
80
|
+
preview: event.preview,
|
|
81
|
+
prompt: event.prompt,
|
|
82
|
+
branchEntries,
|
|
83
|
+
phases: getLatestTodoStateFromBranchEntries(branchEntries).phases,
|
|
84
|
+
todoActive: pi.getActiveTools().includes("todo"),
|
|
85
|
+
setting,
|
|
86
|
+
mode: ctx.mode,
|
|
87
|
+
});
|
|
88
|
+
if (!armed)
|
|
89
|
+
return { systemPrompt };
|
|
90
|
+
pendingForce = { forceNamed: setting === "force", logged: false };
|
|
51
91
|
return {
|
|
52
|
-
systemPrompt
|
|
92
|
+
systemPrompt,
|
|
93
|
+
message: { customType: FIRST_TURN_CUSTOM_TYPE, content: FIRST_TURN_REMINDER, display: false },
|
|
53
94
|
};
|
|
95
|
+
}, { previewSafe: true });
|
|
96
|
+
pi.on("before_provider_request", async (event, ctx) => {
|
|
97
|
+
if (!pendingForce)
|
|
98
|
+
return undefined;
|
|
99
|
+
const forced = pendingForce.forceNamed
|
|
100
|
+
? withForcedTodoChoice(event.payload, event.model ?? ctx.model)
|
|
101
|
+
: undefined;
|
|
102
|
+
if (!pendingForce.logged) {
|
|
103
|
+
pendingForce.logged = true;
|
|
104
|
+
logger ??= createSessionLogger(ctx.agentDir);
|
|
105
|
+
logger.info("todo_first_turn", { mode: forced === undefined ? "reminder-only" : "forced" });
|
|
106
|
+
}
|
|
107
|
+
return forced;
|
|
54
108
|
});
|
|
55
|
-
|
|
56
|
-
|
|
109
|
+
const accessors = { getCurrentPhases, setCurrentPhases, getCurrentAsk, setCurrentAsk, syncWidget };
|
|
110
|
+
registerTodoTool(pi, accessors);
|
|
111
|
+
registerTodoCommand(pi, accessors);
|
|
57
112
|
}
|
|
58
113
|
export { findPhaseFuzzy, findTaskFuzzy, registerTodoCommand, tokenizeTodoArgs } from "./commands.js";
|
|
59
114
|
export { markdownToPhases, phasesToMarkdown, resolveTodoMarkdownPath } from "./markdown.js";
|
|
60
115
|
export { TASK_MANAGEMENT_SECTION } from "./prompt.js";
|
|
61
|
-
export { appendItems, applyEntry, applyOpsToPhases, applyParams, clonePhases, cloneTask, DEFAULT_INIT_PHASE, findPhaseByName, findTaskByContent, formatSummary, getCompletionTransitions, getLatestPhasesFromBranchEntries, getLatestTodosFromBranchEntries, getTaskTargets, getTodoMarker, getTodoResultLines, getTodoWidgetLines, initPhases, isIncompleteTodo, isTerminalTodoStatus, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, nextActionableTask, normalizeInProgressTask, removeTasks, resolvePhaseOrError, resolveTaskOrError, sanitizeTodoText, TODO_STATE_ENTRY_TYPE, } from "./state.js";
|
|
116
|
+
export { appendItems, applyEntry, applyOpsToPhases, applyParams, clonePhases, cloneTask, DEFAULT_INIT_PHASE, describeAskNowNext, findPhaseByName, findTaskByContent, formatSummary, getCompletionTransitions, getLatestPhasesFromBranchEntries, getLatestTodoStateFromBranchEntries, getLatestTodosFromBranchEntries, getTaskTargets, getTodoMarker, getTodoResultLines, getTodoWidgetLines, initPhases, isIncompleteTodo, isTerminalTodoStatus, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, nextActionableTask, normalizeInProgressTask, removeTasks, resolvePhaseOrError, resolveTaskOrError, sanitizeTodoText, TODO_STATE_ENTRY_TYPE, } from "./state.js";
|
|
62
117
|
export { phaseRomanNumeral } from "./tools/todo.js";
|
|
63
118
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { registerTodoCommand } from \"./commands.ts\";\nimport { phasesFromCursorTodos } from \"./native-todo-mirror.ts\";\nimport { TASK_MANAGEMENT_SECTION } from \"./prompt.ts\";\nimport {\n\tclonePhases,\n\tgetLatestPhasesFromBranchEntries,\n\ttype TodoCompletionTransition,\n\ttype TodoPhase,\n} from \"./state.ts\";\nimport { TODO_STATE_ENTRY_TYPE } from \"./todo-types.ts\";\nimport { getTodoWidgetModel } from \"./todo-widget.ts\";\nimport { TodoWidgetComponent } from \"./todo-widget-component.ts\";\nimport { registerTodoTool } from \"./tools/todo.ts\";\n\nfunction getLatestPhases(ctx: ExtensionContext): TodoPhase[] {\n\treturn getLatestPhasesFromBranchEntries(ctx.sessionManager.getBranch());\n}\n\nexport default function todotoolsExtension(pi: ExtensionAPI): void {\n\tlet currentPhases: TodoPhase[] = [];\n\n\tconst getCurrentPhases = (): TodoPhase[] => clonePhases(currentPhases);\n\n\tconst setCurrentPhases = (phases: TodoPhase[]): void => {\n\t\tcurrentPhases = clonePhases(phases);\n\t};\n\n\tconst syncWidget = (ctx: ExtensionContext, completedTasks: readonly TodoCompletionTransition[] = []): void => {\n\t\tconst model = getTodoWidgetModel(currentPhases);\n\t\tctx.ui.setWidget(\n\t\t\t\"todo-sidebar\",\n\t\t\tmodel ? (tui, theme) => new TodoWidgetComponent(tui, theme, model, completedTasks) : undefined,\n\t\t);\n\t};\n\n\tconst syncFromSession = (ctx: ExtensionContext): void => {\n\t\tcurrentPhases = getLatestPhases(ctx);\n\t\tsyncWidget(ctx);\n\t};\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"session_tree\", async (_event, ctx) => {\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"message_end\", async (event, ctx) => {\n\t\tconst message = event.message;\n\t\tif (message?.role !== \"assistant\" || !Array.isArray(message.content)) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const block of message.content) {\n\t\t\tif (block.type !== \"toolCall\" || block.name !== \"todo\" || block.arguments?.op) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst phases = phasesFromCursorTodos(block.arguments?.todos);\n\t\t\tif (phases === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsetCurrentPhases(phases);\n\t\t\tpi.appendEntry(TODO_STATE_ENTRY_TYPE, { schema: \"v2\", phases });\n\t\t\tsyncWidget(ctx);\n\t\t}\n\t});\n\n\tpi.on(\"before_agent_start\", async (event) => {\n\t\treturn {\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n${TASK_MANAGEMENT_SECTION}`,\n\t\t};\n\t});\n\n\tregisterTodoTool(pi, { getCurrentPhases, setCurrentPhases, syncWidget });\n\tregisterTodoCommand(pi, { getCurrentPhases, setCurrentPhases, syncWidget });\n}\n\nexport { findPhaseFuzzy, findTaskFuzzy, registerTodoCommand, tokenizeTodoArgs } from \"./commands.ts\";\nexport { markdownToPhases, phasesToMarkdown, resolveTodoMarkdownPath } from \"./markdown.ts\";\nexport { TASK_MANAGEMENT_SECTION } from \"./prompt.ts\";\nexport {\n\tappendItems,\n\tapplyEntry,\n\tapplyOpsToPhases,\n\tapplyParams,\n\tclonePhases,\n\tcloneTask,\n\tDEFAULT_INIT_PHASE,\n\tfindPhaseByName,\n\tfindTaskByContent,\n\tformatSummary,\n\tgetCompletionTransitions,\n\tgetLatestPhasesFromBranchEntries,\n\tgetLatestTodosFromBranchEntries,\n\tgetTaskTargets,\n\tgetTodoMarker,\n\tgetTodoResultLines,\n\tgetTodoWidgetLines,\n\tinitPhases,\n\tisIncompleteTodo,\n\tisTerminalTodoStatus,\n\tisTodoItem,\n\tisTodoItemArray,\n\tisTodoPhase,\n\tisTodoPhaseArray,\n\tnextActionableTask,\n\tnormalizeInProgressTask,\n\tremoveTasks,\n\tresolvePhaseOrError,\n\tresolveTaskOrError,\n\tsanitizeTodoText,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoCompletionTransition,\n\ttype TodoItem,\n\ttype TodoOpEntry,\n\ttype TodoOperation,\n\ttype TodoPhase,\n\ttype TodoStateEntry,\n\ttype TodoStatus,\n\ttype TodoToolDetails,\n} from \"./state.ts\";\nexport { phaseRomanNumeral } from \"./tools/todo.ts\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSessionLogger, type SessionLogger } from \"../../../session-log.ts\";\nimport { SettingsManager } from \"../../../settings-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { registerTodoCommand } from \"./commands.ts\";\nimport { FIRST_TURN_CUSTOM_TYPE, FIRST_TURN_REMINDER, shouldArmFirstTurn, withForcedTodoChoice } from \"./first-turn.ts\";\nimport { phasesFromCursorTodos } from \"./native-todo-mirror.ts\";\nimport { TASK_MANAGEMENT_SECTION } from \"./prompt.ts\";\nimport {\n\tclonePhases,\n\tgetLatestTodoStateFromBranchEntries,\n\ttype TodoAsk,\n\ttype TodoCompletionTransition,\n\ttype TodoPhase,\n\ttype TodoState,\n} from \"./state.ts\";\nimport { TODO_STATE_ENTRY_TYPE } from \"./todo-types.ts\";\nimport { getTodoWidgetModel } from \"./todo-widget.ts\";\nimport { TodoWidgetComponent } from \"./todo-widget-component.ts\";\nimport { registerTodoTool } from \"./tools/todo.ts\";\n\nfunction readFirstTurnPlan(ctx: ExtensionContext) {\n\treturn SettingsManager.create(ctx.cwd, ctx.agentDir, {\n\t\tprojectTrusted: ctx.isProjectTrusted(),\n\t}).getTodoFirstTurnPlan();\n}\n\nexport default function todotoolsExtension(pi: ExtensionAPI): void {\n\tlet currentState: TodoState = { phases: [], ask: undefined };\n\t// Armed by the first-turn opener; cleared once that run's first assistant message lands.\n\tlet pendingForce: { forceNamed: boolean; logged: boolean } | undefined;\n\tlet logger: SessionLogger | undefined;\n\tconst clearPendingForce = (): void => {\n\t\tpendingForce = undefined;\n\t};\n\n\tconst getCurrentPhases = (): TodoPhase[] => clonePhases(currentState.phases);\n\n\tconst setCurrentPhases = (phases: TodoPhase[]): void => {\n\t\tcurrentState = { ...currentState, phases: clonePhases(phases) };\n\t};\n\n\tconst getCurrentAsk = (): TodoAsk | undefined => currentState.ask;\n\n\tconst setCurrentAsk = (ask: TodoAsk | undefined): void => {\n\t\tcurrentState = { ...currentState, ask };\n\t};\n\n\tconst syncWidget = (ctx: ExtensionContext, completedTasks: readonly TodoCompletionTransition[] = []): void => {\n\t\tconst model = getTodoWidgetModel(currentState.phases);\n\t\tctx.ui.setWidget(\n\t\t\t\"todo-sidebar\",\n\t\t\tmodel ? (tui, theme) => new TodoWidgetComponent(tui, theme, model, completedTasks) : undefined,\n\t\t);\n\t};\n\n\tconst syncFromSession = (ctx: ExtensionContext): void => {\n\t\tcurrentState = getLatestTodoStateFromBranchEntries(ctx.sessionManager.getBranch());\n\t\tsyncWidget(ctx);\n\t};\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tclearPendingForce();\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"session_tree\", async (_event, ctx) => {\n\t\tclearPendingForce();\n\t\tsyncFromSession(ctx);\n\t});\n\n\tpi.on(\"agent_end\", clearPendingForce);\n\tpi.on(\"session_abort\", clearPendingForce);\n\tpi.on(\"session_shutdown\", clearPendingForce);\n\n\tpi.on(\"message_end\", async (event, ctx) => {\n\t\tconst message = event.message;\n\t\tif (message?.role === \"assistant\") clearPendingForce();\n\t\tif (message?.role !== \"assistant\" || !Array.isArray(message.content)) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const block of message.content) {\n\t\t\tif (block.type !== \"toolCall\" || block.name !== \"todo\" || block.arguments?.op) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst phases = phasesFromCursorTodos(block.arguments?.todos);\n\t\t\tif (phases === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tsetCurrentPhases(phases);\n\t\t\tconst ask = getCurrentAsk();\n\t\t\tpi.appendEntry(TODO_STATE_ENTRY_TYPE, { schema: \"v2\", phases, ...(ask ? { ask } : {}) });\n\t\t\tsyncWidget(ctx);\n\t\t}\n\t});\n\n\tpi.on(\n\t\t\"before_agent_start\",\n\t\tasync (event, ctx) => {\n\t\t\tconst systemPrompt = `${event.systemPrompt}\\n${TASK_MANAGEMENT_SECTION}`;\n\t\t\tif (event.preview) return { systemPrompt };\n\t\t\tconst branchEntries = ctx.sessionManager.getBranch();\n\t\t\tconst setting = readFirstTurnPlan(ctx);\n\t\t\tconst armed = shouldArmFirstTurn({\n\t\t\t\tpreview: event.preview,\n\t\t\t\tprompt: event.prompt,\n\t\t\t\tbranchEntries,\n\t\t\t\tphases: getLatestTodoStateFromBranchEntries(branchEntries).phases,\n\t\t\t\ttodoActive: pi.getActiveTools().includes(\"todo\"),\n\t\t\t\tsetting,\n\t\t\t\tmode: ctx.mode,\n\t\t\t});\n\t\t\tif (!armed) return { systemPrompt };\n\t\t\tpendingForce = { forceNamed: setting === \"force\", logged: false };\n\t\t\treturn {\n\t\t\t\tsystemPrompt,\n\t\t\t\tmessage: { customType: FIRST_TURN_CUSTOM_TYPE, content: FIRST_TURN_REMINDER, display: false },\n\t\t\t};\n\t\t},\n\t\t{ previewSafe: true },\n\t);\n\n\tpi.on(\"before_provider_request\", async (event, ctx) => {\n\t\tif (!pendingForce) return undefined;\n\t\tconst forced = pendingForce.forceNamed\n\t\t\t? withForcedTodoChoice(event.payload, event.model ?? ctx.model)\n\t\t\t: undefined;\n\t\tif (!pendingForce.logged) {\n\t\t\tpendingForce.logged = true;\n\t\t\tlogger ??= createSessionLogger(ctx.agentDir);\n\t\t\tlogger.info(\"todo_first_turn\", { mode: forced === undefined ? \"reminder-only\" : \"forced\" });\n\t\t}\n\t\treturn forced;\n\t});\n\n\tconst accessors = { getCurrentPhases, setCurrentPhases, getCurrentAsk, setCurrentAsk, syncWidget };\n\tregisterTodoTool(pi, accessors);\n\tregisterTodoCommand(pi, accessors);\n}\n\nexport { findPhaseFuzzy, findTaskFuzzy, registerTodoCommand, tokenizeTodoArgs } from \"./commands.ts\";\nexport { markdownToPhases, phasesToMarkdown, resolveTodoMarkdownPath } from \"./markdown.ts\";\nexport { TASK_MANAGEMENT_SECTION } from \"./prompt.ts\";\nexport {\n\tappendItems,\n\tapplyEntry,\n\tapplyOpsToPhases,\n\tapplyParams,\n\tclonePhases,\n\tcloneTask,\n\tDEFAULT_INIT_PHASE,\n\tdescribeAskNowNext,\n\tfindPhaseByName,\n\tfindTaskByContent,\n\tformatSummary,\n\tgetCompletionTransitions,\n\tgetLatestPhasesFromBranchEntries,\n\tgetLatestTodoStateFromBranchEntries,\n\tgetLatestTodosFromBranchEntries,\n\tgetTaskTargets,\n\tgetTodoMarker,\n\tgetTodoResultLines,\n\tgetTodoWidgetLines,\n\tinitPhases,\n\tisIncompleteTodo,\n\tisTerminalTodoStatus,\n\tisTodoItem,\n\tisTodoItemArray,\n\tisTodoPhase,\n\tisTodoPhaseArray,\n\tnextActionableTask,\n\tnormalizeInProgressTask,\n\tremoveTasks,\n\tresolvePhaseOrError,\n\tresolveTaskOrError,\n\tsanitizeTodoText,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoAsk,\n\ttype TodoCompletionTransition,\n\ttype TodoItem,\n\ttype TodoOpEntry,\n\ttype TodoOperation,\n\ttype TodoPhase,\n\ttype TodoState,\n\ttype TodoStateEntry,\n\ttype TodoStatus,\n\ttype TodoToolDetails,\n} from \"./state.ts\";\nexport { phaseRomanNumeral } from \"./tools/todo.ts\";\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare const TODO_TOOL_DESCRIPTION = "**Tasks referenced by verbatim content string, NEVER an auto-generated ID \u2014 no \"task-1\"/\"task-N\" exists. Pass the content text in the task field.**\n\nOn each completion the earliest still-open task (in phase order) auto-promotes to in_progress.\nCompleting tasks out of phase order can move this pointer **back** to an earlier phase \u2014 expected; completed tasks are never reverted.\n\n## Operations\n\n| op | Required fields | Effect |\n|---|---|---|\n| init | list: [{phase, items: string[]}] | Initialize full list (replaces existing) |\n| init | items: string[] | Flattened single-phase init |\n| start | task | Mark in progress |\n| done | task or phase | Mark completed |\n| drop | task or phase | Mark abandoned |\n| rm | task or phase (optional) | Remove task or phase; omit both to clear |\n| append | phase?, items: string[] | Append tasks to phase; lazily creates phase |\n| view | \u2014 | Read-only: echo list |\n\nExample: {\"op\":\"init\",\"list\":[{\"phase\":\"Setup\",\"items\":[\"Survey code\",\"Write tests\"]}]}\n\n## Anatomy\n- **Task content**: 5\u201310 words; what, not how. Unique identifier.\n- **Phase name**: short noun phrase (e.g. Foundation, Auth, Verification). Unique identifier. NEVER prefix 1., A), Phase 1:.\n\n## Rules\n- Mark tasks done immediately after finishing, then re-check the list against the newest user message. Complete phases in order.\n- NEVER
|
|
2
|
-
export declare const TASK_MANAGEMENT_SECTION = "\n<Task_Management>\n## Todo Management\n\
|
|
1
|
+
export declare const TODO_TOOL_DESCRIPTION = "**Tasks referenced by verbatim content string, NEVER an auto-generated ID \u2014 no \"task-1\"/\"task-N\" exists. Pass the content text in the task field.**\n\nOn each completion the earliest still-open task (in phase order) auto-promotes to in_progress.\nCompleting tasks out of phase order can move this pointer **back** to an earlier phase \u2014 expected; completed tasks are never reverted.\n\n## Operations\n\n| op | Required fields | Effect |\n|---|---|---|\n| init | list: [{phase, items: string[]}] | Initialize full list (replaces existing) |\n| init | items: string[] | Flattened single-phase init |\n| start | task | Mark in progress |\n| done | task or phase | Mark completed |\n| drop | task or phase | Mark abandoned |\n| rm | task or phase (optional) | Remove task or phase; omit both to clear |\n| append | phase?, items: string[] | Append tasks to phase; lazily creates phase |\n| view | \u2014 | Read-only: echo list |\n\nExample: {\"op\":\"init\",\"list\":[{\"phase\":\"Setup\",\"items\":[\"Survey code\",\"Write tests\"]}]}\n\n## Anatomy\n- **Task content**: 5\u201310 words; what, not how. Unique identifier.\n- **Phase name**: short noun phrase (e.g. Foundation, Auth, Verification). Unique identifier. NEVER prefix 1., A), Phase 1:.\n\n## Rules\n- Mark tasks done immediately after finishing, then re-check the list against the newest user message. Complete phases in order.\n- NEVER end a turn with a todo call as its only tool call - batch it with the real work: init with the first reads/edits, each done/start with the next action.\n- Blocked? append a task to the active phase, or drop.\n- Keep task/phase strings stable once introduced. done/start/drop take the task's EXACT text \u2014 copy it verbatim from the latest todo result; when it is lost, view echoes the list.\n\n## When to create a list\n- User explicitly requests one\n- User provides a set of tasks\n- New instructions arrive mid-task \u2014 reconcile before acting: keep what they don't conflict with, amend what they contradict, append what they add; replace only on explicit redirect\n\n<critical>\nUser hands you a multi-step plan \u2014 phased todo, numbered/bulleted checklist, or \"N bugs/items/tasks\":\n- You MUST init the list with EVERY item as its own task before working.\n- Enumerate all; NEVER summarize into fewer tasks, sample \"the important ones\", drop items, or track the rest from memory.\n</critical>";
|
|
2
|
+
export declare const TASK_MANAGEMENT_SECTION = "\n<Task_Management>\n## Todo Management\n\nA request with three or more distinct steps gets a phased todo before the first edit - investigation, implementation, verification, final report - in the todo tool; its description carries the operations, anatomy, and rules. Mark each item done the moment it finishes and reconcile the list against the newest user message before ending a turn.\n\n## Evidence\n- File edit: inspect the changed files and diagnostics.\n- Build command: require exit code 0.\n- Test run: require passing output, or state the pre-existing failure.\n</Task_Management>\n";
|
|
3
3
|
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/prompt.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/prompt.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,u3EAuCtB,CAAC;AAEb,eAAO,MAAM,uBAAuB,qlBAWnC,CAAC"}
|
|
@@ -28,12 +28,11 @@ Example: {"op":"init","list":[{"phase":"Setup","items":["Survey code","Write tes
|
|
|
28
28
|
|
|
29
29
|
## Rules
|
|
30
30
|
- Mark tasks done immediately after finishing, then re-check the list against the newest user message. Complete phases in order.
|
|
31
|
-
- NEVER
|
|
31
|
+
- NEVER end a turn with a todo call as its only tool call - batch it with the real work: init with the first reads/edits, each done/start with the next action.
|
|
32
32
|
- Blocked? append a task to the active phase, or drop.
|
|
33
33
|
- Keep task/phase strings stable once introduced. done/start/drop take the task's EXACT text — copy it verbatim from the latest todo result; when it is lost, view echoes the list.
|
|
34
34
|
|
|
35
35
|
## When to create a list
|
|
36
|
-
- Task requires 3+ distinct steps
|
|
37
36
|
- User explicitly requests one
|
|
38
37
|
- User provides a set of tasks
|
|
39
38
|
- New instructions arrive mid-task — reconcile before acting: keep what they don't conflict with, amend what they contradict, append what they add; replace only on explicit redirect
|
|
@@ -47,7 +46,7 @@ export const TASK_MANAGEMENT_SECTION = `
|
|
|
47
46
|
<Task_Management>
|
|
48
47
|
## Todo Management
|
|
49
48
|
|
|
50
|
-
|
|
49
|
+
A request with three or more distinct steps gets a phased todo before the first edit - investigation, implementation, verification, final report - in the todo tool; its description carries the operations, anatomy, and rules. Mark each item done the moment it finishes and reconcile the list against the newest user message before ending a turn.
|
|
51
50
|
|
|
52
51
|
## Evidence
|
|
53
52
|
- File edit: inspect the changed files and diagnostics.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/prompt.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,mCAAmC;AACnC,oCAAoC;AACpC,sCAAsC;AAEtC,MAAM,CAAC,MAAM,qBAAqB,GAAG
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/prompt.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,mCAAmC;AACnC,oCAAoC;AACpC,sCAAsC;AAEtC,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAuCzB,CAAC;AAEb,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;CAWtC,CAAC","sourcesContent":["// Adapted from oh-my-pi's todo prompt (MIT License).\n// Copyright (c) 2025 Mario Zechner\n// Copyright (c) 2025-2026 Can Bölük\n// https://github.com/can1357/oh-my-pi\n\nexport const TODO_TOOL_DESCRIPTION = `**Tasks referenced by verbatim content string, NEVER an auto-generated ID — no \"task-1\"/\"task-N\" exists. Pass the content text in the task field.**\n\nOn each completion the earliest still-open task (in phase order) auto-promotes to in_progress.\nCompleting tasks out of phase order can move this pointer **back** to an earlier phase — expected; completed tasks are never reverted.\n\n## Operations\n\n| op | Required fields | Effect |\n|---|---|---|\n| init | list: [{phase, items: string[]}] | Initialize full list (replaces existing) |\n| init | items: string[] | Flattened single-phase init |\n| start | task | Mark in progress |\n| done | task or phase | Mark completed |\n| drop | task or phase | Mark abandoned |\n| rm | task or phase (optional) | Remove task or phase; omit both to clear |\n| append | phase?, items: string[] | Append tasks to phase; lazily creates phase |\n| view | — | Read-only: echo list |\n\nExample: {\"op\":\"init\",\"list\":[{\"phase\":\"Setup\",\"items\":[\"Survey code\",\"Write tests\"]}]}\n\n## Anatomy\n- **Task content**: 5–10 words; what, not how. Unique identifier.\n- **Phase name**: short noun phrase (e.g. Foundation, Auth, Verification). Unique identifier. NEVER prefix 1., A), Phase 1:.\n\n## Rules\n- Mark tasks done immediately after finishing, then re-check the list against the newest user message. Complete phases in order.\n- NEVER end a turn with a todo call as its only tool call - batch it with the real work: init with the first reads/edits, each done/start with the next action.\n- Blocked? append a task to the active phase, or drop.\n- Keep task/phase strings stable once introduced. done/start/drop take the task's EXACT text — copy it verbatim from the latest todo result; when it is lost, view echoes the list.\n\n## When to create a list\n- User explicitly requests one\n- User provides a set of tasks\n- New instructions arrive mid-task — reconcile before acting: keep what they don't conflict with, amend what they contradict, append what they add; replace only on explicit redirect\n\n<critical>\nUser hands you a multi-step plan — phased todo, numbered/bulleted checklist, or \"N bugs/items/tasks\":\n- You MUST init the list with EVERY item as its own task before working.\n- Enumerate all; NEVER summarize into fewer tasks, sample \"the important ones\", drop items, or track the rest from memory.\n</critical>`;\n\nexport const TASK_MANAGEMENT_SECTION = `\n<Task_Management>\n## Todo Management\n\nA request with three or more distinct steps gets a phased todo before the first edit - investigation, implementation, verification, final report - in the todo tool; its description carries the operations, anatomy, and rules. Mark each item done the moment it finishes and reconcile the list against the newest user message before ending a turn.\n\n## Evidence\n- File edit: inspect the changed files and diagnostics.\n- Build command: require exit code 0.\n- Test run: require passing output, or state the pre-existing failure.\n</Task_Management>\n`;\n"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { ASK_TEXT_LIMIT, captureListAsk, truncateAskText } from "./todo-ask.ts";
|
|
2
|
+
export { type AskNowNext, describeAskNowNext, formatAskNowNextHeader, formatHandoffCue, formatSummary, getTodoMarker, getTodoResultLines, HANDOFF_CUES, type HandoffMoment, handoffMomentOf, isIncompleteTodo, isTerminalTodoStatus, sanitizeTodoText, } from "./todo-format.ts";
|
|
2
3
|
export { appendItems, applyEntry, applyOpsToPhases, applyParams, initPhases, removeTasks, } from "./todo-operations.ts";
|
|
3
4
|
export { findPhaseByName, findTaskByContent, getCompletionTransitions, nextActionableTask, normalizeInProgressTask, } from "./todo-query.ts";
|
|
4
5
|
export { getTaskTargets, resolvePhaseOrError, resolveTaskOrError } from "./todo-resolution.ts";
|
|
5
|
-
export { clonePhases, cloneTask, getLatestPhasesFromBranchEntries, getLatestTodosFromBranchEntries, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, } from "./todo-storage.ts";
|
|
6
|
-
export { DEFAULT_INIT_PHASE, TODO_STATE_ENTRY_TYPE, type TodoCompletionTransition, type TodoItem, type TodoOpEntry, type TodoOperation, type TodoPhase, type TodoStateEntry, type TodoStatus, type TodoToolDetails, } from "./todo-types.ts";
|
|
6
|
+
export { clonePhases, cloneTask, getLatestPhasesFromBranchEntries, getLatestTodoStateFromBranchEntries, getLatestTodosFromBranchEntries, isTodoAsk, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, } from "./todo-storage.ts";
|
|
7
|
+
export { DEFAULT_INIT_PHASE, TODO_RESTORE_REQUEST_TYPE, TODO_STATE_ENTRY_TYPE, type TodoAsk, type TodoCompletionTransition, type TodoItem, type TodoOpEntry, type TodoOperation, type TodoPhase, type TodoState, type TodoStateEntry, type TodoStatus, type TodoToolDetails, } from "./todo-types.ts";
|
|
7
8
|
export { getTodoWidgetLines, getTodoWidgetModel, type TodoWidgetModel, type TodoWidgetRow, } from "./todo-widget.ts";
|
|
8
9
|
//# sourceMappingURL=state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAKA,OAAO,EACN,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,WAAW,GACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EACN,WAAW,EACX,SAAS,EACT,gCAAgC,EAChC,+BAA+B,EAC/B,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,GAClB,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EACN,KAAK,UAAU,EACf,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,KAAK,aAAa,EAClB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,WAAW,GACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EACN,WAAW,EACX,SAAS,EACT,gCAAgC,EAChC,mCAAmC,EACnC,+BAA+B,EAC/B,SAAS,EACT,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,OAAO,EACZ,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,eAAe,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,GAClB,MAAM,kBAAkB,CAAC"}
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
// Copyright (c) 2025 Mario Zechner
|
|
3
3
|
// Copyright (c) 2025-2026 Can Bölük
|
|
4
4
|
// https://github.com/can1357/oh-my-pi
|
|
5
|
-
export {
|
|
5
|
+
export { ASK_TEXT_LIMIT, captureListAsk, truncateAskText } from "./todo-ask.js";
|
|
6
|
+
export { describeAskNowNext, formatAskNowNextHeader, formatHandoffCue, formatSummary, getTodoMarker, getTodoResultLines, HANDOFF_CUES, handoffMomentOf, isIncompleteTodo, isTerminalTodoStatus, sanitizeTodoText, } from "./todo-format.js";
|
|
6
7
|
export { appendItems, applyEntry, applyOpsToPhases, applyParams, initPhases, removeTasks, } from "./todo-operations.js";
|
|
7
8
|
export { findPhaseByName, findTaskByContent, getCompletionTransitions, nextActionableTask, normalizeInProgressTask, } from "./todo-query.js";
|
|
8
9
|
export { getTaskTargets, resolvePhaseOrError, resolveTaskOrError } from "./todo-resolution.js";
|
|
9
|
-
export { clonePhases, cloneTask, getLatestPhasesFromBranchEntries, getLatestTodosFromBranchEntries, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, } from "./todo-storage.js";
|
|
10
|
-
export { DEFAULT_INIT_PHASE, TODO_STATE_ENTRY_TYPE, } from "./todo-types.js";
|
|
10
|
+
export { clonePhases, cloneTask, getLatestPhasesFromBranchEntries, getLatestTodoStateFromBranchEntries, getLatestTodosFromBranchEntries, isTodoAsk, isTodoItem, isTodoItemArray, isTodoPhase, isTodoPhaseArray, } from "./todo-storage.js";
|
|
11
|
+
export { DEFAULT_INIT_PHASE, TODO_RESTORE_REQUEST_TYPE, TODO_STATE_ENTRY_TYPE, } from "./todo-types.js";
|
|
11
12
|
export { getTodoWidgetLines, getTodoWidgetModel, } from "./todo-widget.js";
|
|
12
13
|
//# sourceMappingURL=state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,mCAAmC;AACnC,oCAAoC;AACpC,sCAAsC;AAEtC,OAAO,
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/state.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,mCAAmC;AACnC,oCAAoC;AACpC,sCAAsC;AAEtC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAEN,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,YAAY,EAEZ,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,WAAW,GACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EACN,WAAW,EACX,SAAS,EACT,gCAAgC,EAChC,mCAAmC,EACnC,+BAA+B,EAC/B,SAAS,EACT,UAAU,EACV,eAAe,EACf,WAAW,EACX,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,GAWrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,kBAAkB,EAClB,kBAAkB,GAGlB,MAAM,kBAAkB,CAAC","sourcesContent":["// Ported and adapted from oh-my-pi's todo tool (MIT License).\n// Copyright (c) 2025 Mario Zechner\n// Copyright (c) 2025-2026 Can Bölük\n// https://github.com/can1357/oh-my-pi\n\nexport { ASK_TEXT_LIMIT, captureListAsk, truncateAskText } from \"./todo-ask.ts\";\nexport {\n\ttype AskNowNext,\n\tdescribeAskNowNext,\n\tformatAskNowNextHeader,\n\tformatHandoffCue,\n\tformatSummary,\n\tgetTodoMarker,\n\tgetTodoResultLines,\n\tHANDOFF_CUES,\n\ttype HandoffMoment,\n\thandoffMomentOf,\n\tisIncompleteTodo,\n\tisTerminalTodoStatus,\n\tsanitizeTodoText,\n} from \"./todo-format.ts\";\nexport {\n\tappendItems,\n\tapplyEntry,\n\tapplyOpsToPhases,\n\tapplyParams,\n\tinitPhases,\n\tremoveTasks,\n} from \"./todo-operations.ts\";\nexport {\n\tfindPhaseByName,\n\tfindTaskByContent,\n\tgetCompletionTransitions,\n\tnextActionableTask,\n\tnormalizeInProgressTask,\n} from \"./todo-query.ts\";\nexport { getTaskTargets, resolvePhaseOrError, resolveTaskOrError } from \"./todo-resolution.ts\";\nexport {\n\tclonePhases,\n\tcloneTask,\n\tgetLatestPhasesFromBranchEntries,\n\tgetLatestTodoStateFromBranchEntries,\n\tgetLatestTodosFromBranchEntries,\n\tisTodoAsk,\n\tisTodoItem,\n\tisTodoItemArray,\n\tisTodoPhase,\n\tisTodoPhaseArray,\n} from \"./todo-storage.ts\";\nexport {\n\tDEFAULT_INIT_PHASE,\n\tTODO_RESTORE_REQUEST_TYPE,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoAsk,\n\ttype TodoCompletionTransition,\n\ttype TodoItem,\n\ttype TodoOpEntry,\n\ttype TodoOperation,\n\ttype TodoPhase,\n\ttype TodoState,\n\ttype TodoStateEntry,\n\ttype TodoStatus,\n\ttype TodoToolDetails,\n} from \"./todo-types.ts\";\nexport {\n\tgetTodoWidgetLines,\n\tgetTodoWidgetModel,\n\ttype TodoWidgetModel,\n\ttype TodoWidgetRow,\n} from \"./todo-widget.ts\";\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SessionEntry } from "../../../session-manager.ts";
|
|
2
|
+
import { type TodoAsk } from "./todo-types.ts";
|
|
3
|
+
export declare const ASK_TEXT_LIMIT = 200;
|
|
4
|
+
export declare function truncateAskText(text: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* The ask a newly created list anchors to. The first list of a branch anchors to the
|
|
7
|
+
* session's first user request; a later list-creating call is an explicit redirect and
|
|
8
|
+
* anchors to the newest user request. Ask-user answer frames are replies, not requests.
|
|
9
|
+
* A compaction restore request newer than both the last list and the last user request
|
|
10
|
+
* re-emits the ask its snapshot carried; the model never supplies an ask itself.
|
|
11
|
+
*/
|
|
12
|
+
export declare function captureListAsk(entries: readonly SessionEntry[], capturedAt: number): TodoAsk | undefined;
|
|
13
|
+
//# sourceMappingURL=todo-ask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo-ask.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/todo-ask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAIhE,OAAO,EAAoD,KAAK,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAEjG,eAAO,MAAM,cAAc,MAAM,CAAC;AAalC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CA0BxG"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { parseAskUserAnswerFrame } from "../ask-user/format.js";
|
|
2
|
+
import { sanitizeTodoText } from "./todo-format.js";
|
|
3
|
+
import { isTodoAsk } from "./todo-storage.js";
|
|
4
|
+
import { TODO_RESTORE_REQUEST_TYPE, TODO_STATE_ENTRY_TYPE } from "./todo-types.js";
|
|
5
|
+
export const ASK_TEXT_LIMIT = 200;
|
|
6
|
+
function firstTextBlock(content) {
|
|
7
|
+
if (typeof content === "string")
|
|
8
|
+
return content;
|
|
9
|
+
if (!Array.isArray(content))
|
|
10
|
+
return undefined;
|
|
11
|
+
for (const block of content) {
|
|
12
|
+
if (typeof block === "object" && block !== null && block.type === "text" && typeof block.text === "string") {
|
|
13
|
+
return block.text;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
export function truncateAskText(text) {
|
|
19
|
+
const codePoints = Array.from(text);
|
|
20
|
+
if (codePoints.length <= ASK_TEXT_LIMIT)
|
|
21
|
+
return text;
|
|
22
|
+
return `${codePoints.slice(0, ASK_TEXT_LIMIT).join("")}… (+${codePoints.length - ASK_TEXT_LIMIT} chars)`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The ask a newly created list anchors to. The first list of a branch anchors to the
|
|
26
|
+
* session's first user request; a later list-creating call is an explicit redirect and
|
|
27
|
+
* anchors to the newest user request. Ask-user answer frames are replies, not requests.
|
|
28
|
+
* A compaction restore request newer than both the last list and the last user request
|
|
29
|
+
* re-emits the ask its snapshot carried; the model never supplies an ask itself.
|
|
30
|
+
*/
|
|
31
|
+
export function captureListAsk(entries, capturedAt) {
|
|
32
|
+
let lastStateIndex = -1;
|
|
33
|
+
let restore;
|
|
34
|
+
const requests = [];
|
|
35
|
+
entries.forEach((entry, index) => {
|
|
36
|
+
if (entry.type === "custom" && entry.customType === TODO_STATE_ENTRY_TYPE) {
|
|
37
|
+
lastStateIndex = index;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (entry.type === "custom_message" && entry.customType === TODO_RESTORE_REQUEST_TYPE) {
|
|
41
|
+
const ask = entry.details?.ask;
|
|
42
|
+
if (isTodoAsk(ask))
|
|
43
|
+
restore = { index, ask };
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (entry.type !== "message" || entry.message.role !== "user")
|
|
47
|
+
return;
|
|
48
|
+
const raw = firstTextBlock(entry.message.content);
|
|
49
|
+
if (raw === undefined || parseAskUserAnswerFrame(raw))
|
|
50
|
+
return;
|
|
51
|
+
const text = sanitizeTodoText(raw);
|
|
52
|
+
if (text)
|
|
53
|
+
requests.push({ index, entryId: entry.id, text });
|
|
54
|
+
});
|
|
55
|
+
const latest = requests.at(-1);
|
|
56
|
+
if (restore && restore.index > lastStateIndex && restore.index > (latest?.index ?? -1))
|
|
57
|
+
return { ...restore.ask };
|
|
58
|
+
const chosen = lastStateIndex === -1 ? requests[0] : latest;
|
|
59
|
+
return chosen ? { entryId: chosen.entryId, text: truncateAskText(chosen.text), capturedAt } : undefined;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=todo-ask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo-ask.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/todo-ask.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry } from \"../../../session-manager.ts\";\nimport { parseAskUserAnswerFrame } from \"../ask-user/format.ts\";\nimport { sanitizeTodoText } from \"./todo-format.ts\";\nimport { isTodoAsk } from \"./todo-storage.ts\";\nimport { TODO_RESTORE_REQUEST_TYPE, TODO_STATE_ENTRY_TYPE, type TodoAsk } from \"./todo-types.ts\";\n\nexport const ASK_TEXT_LIMIT = 200;\n\nfunction firstTextBlock(content: unknown): string | undefined {\n\tif (typeof content === \"string\") return content;\n\tif (!Array.isArray(content)) return undefined;\n\tfor (const block of content) {\n\t\tif (typeof block === \"object\" && block !== null && block.type === \"text\" && typeof block.text === \"string\") {\n\t\t\treturn block.text;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport function truncateAskText(text: string): string {\n\tconst codePoints = Array.from(text);\n\tif (codePoints.length <= ASK_TEXT_LIMIT) return text;\n\treturn `${codePoints.slice(0, ASK_TEXT_LIMIT).join(\"\")}… (+${codePoints.length - ASK_TEXT_LIMIT} chars)`;\n}\n\n/**\n * The ask a newly created list anchors to. The first list of a branch anchors to the\n * session's first user request; a later list-creating call is an explicit redirect and\n * anchors to the newest user request. Ask-user answer frames are replies, not requests.\n * A compaction restore request newer than both the last list and the last user request\n * re-emits the ask its snapshot carried; the model never supplies an ask itself.\n */\nexport function captureListAsk(entries: readonly SessionEntry[], capturedAt: number): TodoAsk | undefined {\n\tlet lastStateIndex = -1;\n\tlet restore: { index: number; ask: TodoAsk } | undefined;\n\tconst requests: Array<{ index: number; entryId: string; text: string }> = [];\n\n\tentries.forEach((entry, index) => {\n\t\tif (entry.type === \"custom\" && entry.customType === TODO_STATE_ENTRY_TYPE) {\n\t\t\tlastStateIndex = index;\n\t\t\treturn;\n\t\t}\n\t\tif (entry.type === \"custom_message\" && entry.customType === TODO_RESTORE_REQUEST_TYPE) {\n\t\t\tconst ask = (entry.details as { ask?: unknown } | undefined)?.ask;\n\t\t\tif (isTodoAsk(ask)) restore = { index, ask };\n\t\t\treturn;\n\t\t}\n\t\tif (entry.type !== \"message\" || entry.message.role !== \"user\") return;\n\t\tconst raw = firstTextBlock(entry.message.content);\n\t\tif (raw === undefined || parseAskUserAnswerFrame(raw)) return;\n\t\tconst text = sanitizeTodoText(raw);\n\t\tif (text) requests.push({ index, entryId: entry.id, text });\n\t});\n\n\tconst latest = requests.at(-1);\n\tif (restore && restore.index > lastStateIndex && restore.index > (latest?.index ?? -1)) return { ...restore.ask };\n\tconst chosen = lastStateIndex === -1 ? requests[0] : latest;\n\treturn chosen ? { entryId: chosen.entryId, text: truncateAskText(chosen.text), capturedAt } : undefined;\n}\n"]}
|
|
@@ -1,5 +1,33 @@
|
|
|
1
|
-
import type { TodoItem, TodoPhase } from "./todo-types.ts";
|
|
2
|
-
export
|
|
1
|
+
import type { TodoAsk, TodoItem, TodoPhase } from "./todo-types.ts";
|
|
2
|
+
export type AskNowNext = {
|
|
3
|
+
ask: string;
|
|
4
|
+
now: string;
|
|
5
|
+
next: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* The three handoff anchors of a todo state: the captured user request, the task in
|
|
9
|
+
* progress, and the first pending task after it in phase order (it may sit in an earlier
|
|
10
|
+
* phase after an out-of-order start). Task labels are verbatim.
|
|
11
|
+
*/
|
|
12
|
+
export declare function describeAskNowNext(state: {
|
|
13
|
+
phases: readonly TodoPhase[];
|
|
14
|
+
ask?: TodoAsk;
|
|
15
|
+
}): AskNowNext;
|
|
16
|
+
/** The todo transitions at which the user is owed a handoff block (the prompts' `## Handoff` moments). */
|
|
17
|
+
export type HandoffMoment = "list-created" | "phase-closed" | "all-closed";
|
|
18
|
+
/**
|
|
19
|
+
* Which handoff moment a successful mutation produced, if any: the list was just created, the
|
|
20
|
+
* last open task of a phase closed, or the last open task of the whole list closed. The result
|
|
21
|
+
* carries the cue right before the model writes its next text, where a system-prompt rule alone
|
|
22
|
+
* proved unreliable on weaker models (senpi#2121 real-surface QA).
|
|
23
|
+
*/
|
|
24
|
+
export declare function handoffMomentOf(before: readonly TodoPhase[], after: readonly TodoPhase[], createsList: boolean): HandoffMoment | undefined;
|
|
25
|
+
export declare const HANDOFF_CUES: Readonly<Record<HandoffMoment, string>>;
|
|
26
|
+
/** The cue line appended to a todo result, or nothing when no handoff moment was reached. */
|
|
27
|
+
export declare function formatHandoffCue(moment: HandoffMoment | undefined): string;
|
|
28
|
+
/** `Ask:` / `Now:` / `Next:` lines plus a blank separator line. */
|
|
29
|
+
export declare function formatAskNowNextHeader(phases: readonly TodoPhase[], ask: TodoAsk | undefined): string;
|
|
30
|
+
export declare function formatSummary(phases: readonly TodoPhase[], errors: readonly string[], readOnly?: boolean, ask?: TodoAsk): string;
|
|
3
31
|
export declare function sanitizeTodoText(text: string): string;
|
|
4
32
|
export declare function isTerminalTodoStatus(status: string): boolean;
|
|
5
33
|
export declare function isIncompleteTodo(todo: TodoItem): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"todo-format.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/todo-format.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"todo-format.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/todo-format.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEpE,MAAM,MAAM,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,UAAU,CAYrG;AAED,0GAA0G;AAC1G,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,cAAc,GAAG,YAAY,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,WAAW,EAAE,OAAO,GAClB,aAAa,GAAG,SAAS,CAa3B;AAED,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAOhE,CAAC;AAEF,6FAA6F;AAC7F,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,CAE1E;AAED,mEAAmE;AACnE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAGrG;AAED,wBAAgB,aAAa,CAC5B,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,QAAQ,UAAQ,EAChB,GAAG,CAAC,EAAE,OAAO,GACX,MAAM,CAER;AA2DD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAExD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,EAAE,CASzE"}
|