@earendil-works/pi-coding-agent 0.84.4 → 0.85.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -5
- package/README.md +3 -1
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +10 -7
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/runtime-setup.d.ts +2 -0
- package/dist/bun/runtime-setup.d.ts.map +1 -0
- package/dist/bun/runtime-setup.js +9 -0
- package/dist/bun/runtime-setup.js.map +1 -0
- package/dist/bundle/chunks/anthropic-messages-QAQLEQIY.js +6 -0
- package/dist/bundle/chunks/{azure-openai-responses-5ENVCQ7U.js → azure-openai-responses-Q7MJBRE6.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
- package/dist/bundle/chunks/chunk-7ZC4UXSL.js +2 -0
- package/dist/bundle/chunks/chunk-EQ6DR6XK.js +5 -0
- package/dist/bundle/chunks/{chunk-MNAIPA3J.js → chunk-IDDQWTHI.js} +1 -1
- package/dist/bundle/chunks/chunk-LZKJTKCT.js +2 -0
- package/dist/bundle/chunks/{chunk-NBBFIJUL.js → chunk-OUXLLA64.js} +2 -2
- package/dist/bundle/chunks/chunk-R7UUJ4C2.js +42 -0
- package/dist/bundle/chunks/chunk-USJZMAIR.js +2 -0
- package/dist/bundle/chunks/chunk-WBE4J4AU.js +9 -0
- package/dist/bundle/chunks/chunk-WZB2R5YO.js +1558 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{google-generative-ai-YMUPJBKR.js → google-generative-ai-BSMTYDAM.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-MPWMV4OF.js → google-vertex-5C3HASOJ.js} +1 -1
- package/dist/bundle/chunks/image-resize-worker.js +1 -1
- package/dist/bundle/chunks/{mistral-conversations-Q3AWZJAZ.js → mistral-conversations-4M6BZBX6.js} +1 -1
- package/dist/bundle/chunks/node-EM5FIVUN.js +16 -0
- package/dist/bundle/chunks/node-TWVVAGPO.js +2 -0
- package/dist/bundle/chunks/openai-codex-responses-YJOO52RW.js +10 -0
- package/dist/bundle/chunks/{openai-completions-ERMU2SS7.js → openai-completions-QOT3QX7D.js} +3 -3
- package/dist/bundle/chunks/openai-responses-U7LNPQN4.js +2 -0
- package/dist/bundle/chunks/{pi-messages-TPFH44NP.js → pi-messages-EGZIFQGG.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/client.js +1 -1
- package/dist/bundle/coordinator.js +3 -0
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +2 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +2 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/experimental/cli.d.ts +7 -3
- package/dist/cli/experimental/cli.d.ts.map +1 -1
- package/dist/cli/experimental/cli.js +6 -2
- package/dist/cli/experimental/cli.js.map +1 -1
- package/dist/cli/experimental/command-options.d.ts +23 -12
- package/dist/cli/experimental/command-options.d.ts.map +1 -1
- package/dist/cli/experimental/command-options.js +69 -20
- package/dist/cli/experimental/command-options.js.map +1 -1
- package/dist/cli/experimental/command.d.ts +10 -3
- package/dist/cli/experimental/command.d.ts.map +1 -1
- package/dist/cli/experimental/command.js +28 -14
- package/dist/cli/experimental/command.js.map +1 -1
- package/dist/cli/experimental/commands/client.d.ts +8 -2
- package/dist/cli/experimental/commands/client.d.ts.map +1 -1
- package/dist/cli/experimental/commands/client.js +43 -5
- package/dist/cli/experimental/commands/client.js.map +1 -1
- package/dist/cli/experimental/commands/server.d.ts +7 -3
- package/dist/cli/experimental/commands/server.d.ts.map +1 -1
- package/dist/cli/experimental/commands/server.js +27 -8
- package/dist/cli/experimental/commands/server.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +23 -14
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts +1 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -2
- package/dist/client/index.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +15 -7
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +14 -6
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +2 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +1 -2
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +8 -2
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +2 -0
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/messages.d.ts +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts +15 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +3 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-runtime.d.ts +1 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +5 -2
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +8 -2
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +40 -13
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +4 -2
- package/dist/core/skills.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +8 -9
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +3 -117
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts +1 -12
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +5 -163
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +4 -55
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +4 -60
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +4 -49
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +4 -120
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts +12 -0
- package/dist/core/tools/renderers/bash.d.ts.map +1 -0
- package/dist/core/tools/renderers/bash.js +130 -0
- package/dist/core/tools/renderers/bash.js.map +1 -0
- package/dist/core/tools/renderers/edit.d.ts +23 -0
- package/dist/core/tools/renderers/edit.d.ts.map +1 -0
- package/dist/core/tools/renderers/edit.js +167 -0
- package/dist/core/tools/renderers/edit.js.map +1 -0
- package/dist/core/tools/renderers/find.d.ts +10 -0
- package/dist/core/tools/renderers/find.d.ts.map +1 -0
- package/dist/core/tools/renderers/find.js +64 -0
- package/dist/core/tools/renderers/find.js.map +1 -0
- package/dist/core/tools/renderers/grep.d.ts +10 -0
- package/dist/core/tools/renderers/grep.d.ts.map +1 -0
- package/dist/core/tools/renderers/grep.js +69 -0
- package/dist/core/tools/renderers/grep.js.map +1 -0
- package/dist/core/tools/renderers/index.d.ts +28 -0
- package/dist/core/tools/renderers/index.d.ts.map +1 -0
- package/dist/core/tools/renderers/index.js +47 -0
- package/dist/core/tools/renderers/index.js.map +1 -0
- package/dist/core/tools/renderers/ls.d.ts +10 -0
- package/dist/core/tools/renderers/ls.d.ts.map +1 -0
- package/dist/core/tools/renderers/ls.js +58 -0
- package/dist/core/tools/renderers/ls.js.map +1 -0
- package/dist/core/tools/renderers/read.d.ts +11 -0
- package/dist/core/tools/renderers/read.d.ts.map +1 -0
- package/dist/core/tools/renderers/read.js +129 -0
- package/dist/core/tools/renderers/read.js.map +1 -0
- package/dist/core/tools/renderers/write.d.ts +10 -0
- package/dist/core/tools/renderers/write.d.ts.map +1 -0
- package/dist/core/tools/renderers/write.js +153 -0
- package/dist/core/tools/renderers/write.js.map +1 -0
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +5 -146
- package/dist/core/tools/write.js.map +1 -1
- package/dist/experimental/client-runtime.d.ts +43 -0
- package/dist/experimental/client-runtime.d.ts.map +1 -0
- package/dist/experimental/client-runtime.js +183 -0
- package/dist/experimental/client-runtime.js.map +1 -0
- package/dist/experimental/client-tui-chat.d.ts +14 -0
- package/dist/experimental/client-tui-chat.d.ts.map +1 -0
- package/dist/experimental/client-tui-chat.js +171 -0
- package/dist/experimental/client-tui-chat.js.map +1 -0
- package/dist/experimental/client-tui.d.ts +37 -0
- package/dist/experimental/client-tui.d.ts.map +1 -0
- package/dist/experimental/client-tui.js +702 -0
- package/dist/experimental/client-tui.js.map +1 -0
- package/dist/experimental/client.d.ts +25 -0
- package/dist/experimental/client.d.ts.map +1 -0
- package/dist/experimental/client.js +99 -0
- package/dist/experimental/client.js.map +1 -0
- package/dist/experimental/coordinator-entry.d.ts +3 -0
- package/dist/experimental/coordinator-entry.d.ts.map +1 -0
- package/dist/experimental/coordinator-entry.js +11 -0
- package/dist/experimental/coordinator-entry.js.map +1 -0
- package/dist/experimental/coordinator.d.ts +38 -0
- package/dist/experimental/coordinator.d.ts.map +1 -0
- package/dist/experimental/coordinator.js +570 -0
- package/dist/experimental/coordinator.js.map +1 -0
- package/dist/experimental/mini/main.d.ts +7 -0
- package/dist/experimental/mini/main.d.ts.map +1 -0
- package/dist/experimental/mini/main.js +21 -0
- package/dist/experimental/mini/main.js.map +1 -0
- package/dist/experimental/mini/server/entry.d.ts +3 -0
- package/dist/experimental/mini/server/entry.d.ts.map +1 -0
- package/dist/experimental/mini/server/entry.js +11 -0
- package/dist/experimental/mini/server/entry.js.map +1 -0
- package/dist/experimental/mini/server/run.d.ts +13 -0
- package/dist/experimental/mini/server/run.d.ts.map +1 -0
- package/dist/experimental/mini/server/run.js +150 -0
- package/dist/experimental/mini/server/run.js.map +1 -0
- package/dist/experimental/mini/shared/protocol.d.ts +127 -0
- package/dist/experimental/mini/shared/protocol.d.ts.map +1 -0
- package/dist/experimental/mini/shared/protocol.js +13 -0
- package/dist/experimental/mini/shared/protocol.js.map +1 -0
- package/dist/experimental/mini/shared/rpc.d.ts +49 -0
- package/dist/experimental/mini/shared/rpc.d.ts.map +1 -0
- package/dist/experimental/mini/shared/rpc.js +171 -0
- package/dist/experimental/mini/shared/rpc.js.map +1 -0
- package/dist/experimental/mini/shared/transport.d.ts +35 -0
- package/dist/experimental/mini/shared/transport.d.ts.map +1 -0
- package/dist/experimental/mini/shared/transport.js +94 -0
- package/dist/experimental/mini/shared/transport.js.map +1 -0
- package/dist/experimental/mini/tui/run.d.ts +9 -0
- package/dist/experimental/mini/tui/run.d.ts.map +1 -0
- package/dist/experimental/mini/tui/run.js +62 -0
- package/dist/experimental/mini/tui/run.js.map +1 -0
- package/dist/experimental/mini/tui/session.d.ts +26 -0
- package/dist/experimental/mini/tui/session.d.ts.map +1 -0
- package/dist/experimental/mini/tui/session.js +94 -0
- package/dist/experimental/mini/tui/session.js.map +1 -0
- package/dist/experimental/mini/tui/view.d.ts +10 -0
- package/dist/experimental/mini/tui/view.d.ts.map +1 -0
- package/dist/experimental/mini/tui/view.js +459 -0
- package/dist/experimental/mini/tui/view.js.map +1 -0
- package/dist/experimental/mini/worker/entry.d.ts +3 -0
- package/dist/experimental/mini/worker/entry.d.ts.map +1 -0
- package/dist/experimental/mini/worker/entry.js +10 -0
- package/dist/experimental/mini/worker/entry.js.map +1 -0
- package/dist/experimental/mini/worker/lane-service.d.ts +44 -0
- package/dist/experimental/mini/worker/lane-service.d.ts.map +1 -0
- package/dist/experimental/mini/worker/lane-service.js +97 -0
- package/dist/experimental/mini/worker/lane-service.js.map +1 -0
- package/dist/experimental/mini/worker/models-service.d.ts +19 -0
- package/dist/experimental/mini/worker/models-service.d.ts.map +1 -0
- package/dist/experimental/mini/worker/models-service.js +136 -0
- package/dist/experimental/mini/worker/models-service.js.map +1 -0
- package/dist/experimental/mini/worker/run.d.ts +14 -0
- package/dist/experimental/mini/worker/run.d.ts.map +1 -0
- package/dist/experimental/mini/worker/run.js +88 -0
- package/dist/experimental/mini/worker/run.js.map +1 -0
- package/dist/experimental/plugin.d.ts +4 -0
- package/dist/experimental/plugin.d.ts.map +1 -0
- package/dist/experimental/plugin.js +4 -0
- package/dist/experimental/plugin.js.map +1 -0
- package/dist/experimental/plugins/bundled.d.ts +7 -0
- package/dist/experimental/plugins/bundled.d.ts.map +1 -0
- package/dist/experimental/plugins/bundled.js +48 -0
- package/dist/experimental/plugins/bundled.js.map +1 -0
- package/dist/experimental/plugins/package.d.ts +18 -0
- package/dist/experimental/plugins/package.d.ts.map +1 -0
- package/dist/experimental/plugins/package.js +113 -0
- package/dist/experimental/plugins/package.js.map +1 -0
- package/dist/experimental/process.d.ts +20 -0
- package/dist/experimental/process.d.ts.map +1 -0
- package/dist/experimental/process.js +85 -0
- package/dist/experimental/process.js.map +1 -0
- package/dist/experimental/radius-auth.d.ts +17 -0
- package/dist/experimental/radius-auth.d.ts.map +1 -0
- package/dist/experimental/radius-auth.js +52 -0
- package/dist/experimental/radius-auth.js.map +1 -0
- package/dist/experimental/radius-relay.d.ts +90 -0
- package/dist/experimental/radius-relay.d.ts.map +1 -0
- package/dist/experimental/radius-relay.js +582 -0
- package/dist/experimental/radius-relay.js.map +1 -0
- package/dist/experimental/server.d.ts +75 -0
- package/dist/experimental/server.d.ts.map +1 -0
- package/dist/experimental/server.js +682 -0
- package/dist/experimental/server.js.map +1 -0
- package/dist/experimental/services/agent-controller-provider.d.ts +4 -0
- package/dist/experimental/services/agent-controller-provider.d.ts.map +1 -0
- package/dist/experimental/services/agent-controller-provider.js +84 -0
- package/dist/experimental/services/agent-controller-provider.js.map +1 -0
- package/dist/experimental/services/agent-controller.d.ts +57 -0
- package/dist/experimental/services/agent-controller.d.ts.map +1 -0
- package/dist/experimental/services/agent-controller.js +3 -0
- package/dist/experimental/services/agent-controller.js.map +1 -0
- package/dist/experimental/services/connection.d.ts +40 -0
- package/dist/experimental/services/connection.d.ts.map +1 -0
- package/dist/experimental/services/connection.js +300 -0
- package/dist/experimental/services/connection.js.map +1 -0
- package/dist/experimental/services/models-provider.d.ts +16 -0
- package/dist/experimental/services/models-provider.d.ts.map +1 -0
- package/dist/experimental/services/models-provider.js +116 -0
- package/dist/experimental/services/models-provider.js.map +1 -0
- package/dist/experimental/services/models.d.ts +36 -0
- package/dist/experimental/services/models.d.ts.map +1 -0
- package/dist/experimental/services/models.js +3 -0
- package/dist/experimental/services/models.js.map +1 -0
- package/dist/experimental/services/plugins.d.ts +16 -0
- package/dist/experimental/services/plugins.d.ts.map +1 -0
- package/dist/experimental/services/plugins.js +4 -0
- package/dist/experimental/services/plugins.js.map +1 -0
- package/dist/experimental/services/presentation-ui.d.ts +13 -0
- package/dist/experimental/services/presentation-ui.d.ts.map +1 -0
- package/dist/experimental/services/presentation-ui.js +3 -0
- package/dist/experimental/services/presentation-ui.js.map +1 -0
- package/dist/experimental/services/server.d.ts +19 -0
- package/dist/experimental/services/server.d.ts.map +1 -0
- package/dist/experimental/services/server.js +104 -0
- package/dist/experimental/services/server.js.map +1 -0
- package/dist/experimental/services/sessions.d.ts +28 -0
- package/dist/experimental/services/sessions.d.ts.map +1 -0
- package/dist/experimental/services/sessions.js +4 -0
- package/dist/experimental/services/sessions.js.map +1 -0
- package/dist/experimental/services/slash-commands-provider.d.ts +14 -0
- package/dist/experimental/services/slash-commands-provider.d.ts.map +1 -0
- package/dist/experimental/services/slash-commands-provider.js +200 -0
- package/dist/experimental/services/slash-commands-provider.js.map +1 -0
- package/dist/experimental/services/slash-commands.d.ts +24 -0
- package/dist/experimental/services/slash-commands.d.ts.map +1 -0
- package/dist/experimental/services/slash-commands.js +3 -0
- package/dist/experimental/services/slash-commands.js.map +1 -0
- package/dist/experimental/services/transcript-provider.d.ts +12 -0
- package/dist/experimental/services/transcript-provider.d.ts.map +1 -0
- package/dist/experimental/services/transcript-provider.js +109 -0
- package/dist/experimental/services/transcript-provider.js.map +1 -0
- package/dist/experimental/services/transcript.d.ts +13 -0
- package/dist/experimental/services/transcript.d.ts.map +1 -0
- package/dist/experimental/services/transcript.js +3 -0
- package/dist/experimental/services/transcript.js.map +1 -0
- package/dist/experimental/services/worker.d.ts +28 -0
- package/dist/experimental/services/worker.d.ts.map +1 -0
- package/dist/experimental/services/worker.js +107 -0
- package/dist/experimental/services/worker.js.map +1 -0
- package/dist/experimental/session-worker-manager.d.ts +24 -0
- package/dist/experimental/session-worker-manager.d.ts.map +1 -0
- package/dist/experimental/session-worker-manager.js +691 -0
- package/dist/experimental/session-worker-manager.js.map +1 -0
- package/dist/experimental/session-worker.d.ts +188 -0
- package/dist/experimental/session-worker.d.ts.map +1 -0
- package/dist/experimental/session-worker.js +785 -0
- package/dist/experimental/session-worker.js.map +1 -0
- package/dist/experimental/source-resolver.d.ts +2 -0
- package/dist/experimental/source-resolver.d.ts.map +1 -0
- package/dist/experimental/source-resolver.js +71 -0
- package/dist/experimental/source-resolver.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +126 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/chat-viewport.d.ts +20 -0
- package/dist/modes/interactive/chat-viewport.d.ts.map +1 -0
- package/dist/modes/interactive/chat-viewport.js +28 -0
- package/dist/modes/interactive/chat-viewport.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +18 -10
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +39 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +5 -14
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +13 -15
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +14 -10
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +10 -3
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +2 -2
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +35 -33
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js +2 -2
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +8 -15
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +95 -80
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts.map +1 -1
- package/dist/modes/interactive/session-share.js +8 -12
- package/dist/modes/interactive/session-share.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +2 -1
- package/dist/modes/interactive/theme/light.json +2 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +5 -0
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-json.d.ts +84 -0
- package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme-json.js +130 -0
- package/dist/modes/interactive/theme/theme-json.js.map +1 -0
- package/dist/modes/interactive/theme/theme-schema.json +6 -2
- package/dist/modes/interactive/theme/theme.d.ts +14 -5
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +18 -119
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/interactive/tui-renderer.d.ts +21 -0
- package/dist/modes/interactive/tui-renderer.d.ts.map +1 -0
- package/dist/modes/interactive/tui-renderer.js +66 -0
- package/dist/modes/interactive/tui-renderer.js.map +1 -0
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js +2 -3
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +41 -19
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/environment-variables.md +2 -0
- package/docs/extensions.md +5 -2
- package/docs/keybindings.md +3 -1
- package/docs/models.md +3 -0
- package/docs/rpc.md +1 -1
- package/docs/sdk.md +5 -0
- package/docs/settings.md +5 -5
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +15 -0
- package/docs/themes.md +8 -6
- package/docs/tui.md +20 -1
- package/examples/README.md +3 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/dynamic-resources/dynamic.json +2 -0
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/plugins/pi-example-plugin/README.md +38 -0
- package/examples/plugins/pi-example-plugin/package.json +10 -0
- package/examples/plugins/pi-example-plugin/src/contract.ts +13 -0
- package/examples/plugins/pi-example-plugin/src/session.ts +23 -0
- package/examples/plugins/pi-example-plugin/src/tui.ts +31 -0
- package/npm-shrinkwrap.json +523 -28
- package/package.json +12 -6
- package/dist/bun/register-bedrock.d.ts +0 -2
- package/dist/bun/register-bedrock.d.ts.map +0 -1
- package/dist/bun/register-bedrock.js +0 -4
- package/dist/bun/register-bedrock.js.map +0 -1
- package/dist/bundle/chunks/anthropic-messages-JWX2WP65.js +0 -45
- package/dist/bundle/chunks/chunk-JUUC5AZY.js +0 -2
- package/dist/bundle/chunks/chunk-OMWWHBTG.js +0 -1548
- package/dist/bundle/chunks/openai-codex-responses-GJVBJXLB.js +0 -8
- package/dist/bundle/chunks/openai-responses-BSOJMSEV.js +0 -2
- package/dist/cli/experimental/auth.d.ts +0 -16
- package/dist/cli/experimental/auth.d.ts.map +0 -1
- package/dist/cli/experimental/auth.js +0 -13
- package/dist/cli/experimental/auth.js.map +0 -1
- package/dist/cli/experimental/commands/pi.d.ts +0 -15
- package/dist/cli/experimental/commands/pi.d.ts.map +0 -1
- package/dist/cli/experimental/commands/pi.js +0 -28
- package/dist/cli/experimental/commands/pi.js.map +0 -1
- package/dist/cli/experimental/transport-address.d.ts +0 -10
- package/dist/cli/experimental/transport-address.d.ts.map +0 -1
- package/dist/cli/experimental/transport-address.js +0 -38
- package/dist/cli/experimental/transport-address.js.map +0 -1
- package/dist/client/remote-session.d.ts +0 -53
- package/dist/client/remote-session.d.ts.map +0 -1
- package/dist/client/remote-session.js +0 -340
- package/dist/client/remote-session.js.map +0 -1
- package/dist/client/transcript.d.ts +0 -12
- package/dist/client/transcript.d.ts.map +0 -1
- package/dist/client/transcript.js +0 -98
- package/dist/client/transcript.js.map +0 -1
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -106
- package/dist/server/create-harness.js.map +0 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Context } from "@earendil-works/chord";
|
|
2
|
+
export interface PresentationSelectItem {
|
|
3
|
+
readonly value: string;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readonly description?: string;
|
|
6
|
+
}
|
|
7
|
+
/** Narrow process-local UI capabilities available to presentation facets. */
|
|
8
|
+
export interface PresentationUI {
|
|
9
|
+
select(title: string, items: readonly PresentationSelectItem[], selectedValue: string | undefined, context: Context): Promise<string | undefined>;
|
|
10
|
+
showStatus(message: string, context: Context): void;
|
|
11
|
+
}
|
|
12
|
+
export declare const PresentationUI: import("@earendil-works/chord").Service<PresentationUI>;
|
|
13
|
+
//# sourceMappingURL=presentation-ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation-ui.d.ts","sourceRoot":"","sources":["../../../src/experimental/services/presentation-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,uBAAuB,CAAC;AAEpE,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC9B,MAAM,CACL,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,SAAS,sBAAsB,EAAE,EACxC,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC/B,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACpD;AAED,eAAO,MAAM,cAAc,yDAA6E,CAAC","sourcesContent":["import { type Context, defineService } from \"@earendil-works/chord\";\n\nexport interface PresentationSelectItem {\n\treadonly value: string;\n\treadonly label: string;\n\treadonly description?: string;\n}\n\n/** Narrow process-local UI capabilities available to presentation facets. */\nexport interface PresentationUI {\n\tselect(\n\t\ttitle: string,\n\t\titems: readonly PresentationSelectItem[],\n\t\tselectedValue: string | undefined,\n\t\tcontext: Context,\n\t): Promise<string | undefined>;\n\tshowStatus(message: string, context: Context): void;\n}\n\nexport const PresentationUI = defineService<PresentationUI>(\"pi.local.presentation-ui\", { local: true });\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation-ui.js","sourceRoot":"","sources":["../../../src/experimental/services/presentation-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAmBpE,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAiB,0BAA0B,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC","sourcesContent":["import { type Context, defineService } from \"@earendil-works/chord\";\n\nexport interface PresentationSelectItem {\n\treadonly value: string;\n\treadonly label: string;\n\treadonly description?: string;\n}\n\n/** Narrow process-local UI capabilities available to presentation facets. */\nexport interface PresentationUI {\n\tselect(\n\t\ttitle: string,\n\t\titems: readonly PresentationSelectItem[],\n\t\tselectedValue: string | undefined,\n\t\tcontext: Context,\n\t): Promise<string | undefined>;\n\tshowStatus(message: string, context: Context): void;\n}\n\nexport const PresentationUI = defineService<PresentationUI>(\"pi.local.presentation-ui\", { local: true });\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Context, type JsonValue } from "@earendil-works/chord";
|
|
2
|
+
import type { RoutedServerServiceHost } from "@earendil-works/pi-server";
|
|
3
|
+
import { type SessionCreateOptions, type SessionSummary } from "./sessions.ts";
|
|
4
|
+
export interface ExperimentalServerServices {
|
|
5
|
+
readonly host: RoutedServerServiceHost;
|
|
6
|
+
refresh(context?: Context): Promise<void>;
|
|
7
|
+
dispose(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare function createExperimentalServerServices(options: {
|
|
10
|
+
list(context: Context): Promise<SessionSummary[]>;
|
|
11
|
+
create(createOptions: SessionCreateOptions, context: Context): Promise<SessionSummary>;
|
|
12
|
+
remove(sessionId: string, context: Context): Promise<void>;
|
|
13
|
+
prepareSessionPlugins(sessionId: string, packagePaths: readonly string[] | undefined, context: Context): Promise<{
|
|
14
|
+
readonly packagePaths: readonly string[];
|
|
15
|
+
readonly presentationPlugins: JsonValue;
|
|
16
|
+
}>;
|
|
17
|
+
reloadPresentationPlugins(packagePaths: readonly string[], context: Context): Promise<JsonValue>;
|
|
18
|
+
}): Promise<ExperimentalServerServices>;
|
|
19
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/experimental/services/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,OAAO,EAEZ,KAAK,SAAS,EAGd,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAiC,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAExG,OAAO,EACN,KAAK,oBAAoB,EAIzB,KAAK,cAAc,EACnB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,wBAAsB,gCAAgC,CAAC,OAAO,EAAE;IAC/D,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAClD,MAAM,CAAC,aAAa,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACvF,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,qBAAqB,CACpB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAC3C,OAAO,EAAE,OAAO,GACd,OAAO,CAAC;QAAE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,mBAAmB,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAClG,yBAAyB,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CACjG,GAAG,OAAO,CAAC,0BAA0B,CAAC,CA8FtC","sourcesContent":["import {\n\ttype Context,\n\tcreateRemoteServiceEndpoint,\n\ttype JsonValue,\n\tRemoteServiceProvider,\n\treplicatedState,\n} from \"@earendil-works/chord\";\nimport { BACKGROUND_CONTEXT } from \"@earendil-works/chord/context\";\nimport type { RoutedServerServiceAttachment, RoutedServerServiceHost } from \"@earendil-works/pi-server\";\nimport { PresentationPlugins } from \"./plugins.ts\";\nimport {\n\ttype SessionCreateOptions,\n\tSessionDirectory,\n\ttype SessionDirectoryState,\n\tSessionManagement,\n\ttype SessionSummary,\n} from \"./sessions.ts\";\n\nexport interface ExperimentalServerServices {\n\treadonly host: RoutedServerServiceHost;\n\trefresh(context?: Context): Promise<void>;\n\tdispose(): Promise<void>;\n}\n\nexport async function createExperimentalServerServices(options: {\n\tlist(context: Context): Promise<SessionSummary[]>;\n\tcreate(createOptions: SessionCreateOptions, context: Context): Promise<SessionSummary>;\n\tremove(sessionId: string, context: Context): Promise<void>;\n\tprepareSessionPlugins(\n\t\tsessionId: string,\n\t\tpackagePaths: readonly string[] | undefined,\n\t\tcontext: Context,\n\t): Promise<{ readonly packagePaths: readonly string[]; readonly presentationPlugins: JsonValue }>;\n\treloadPresentationPlugins(packagePaths: readonly string[], context: Context): Promise<JsonValue>;\n}): Promise<ExperimentalServerServices> {\n\tlet revision = 1;\n\tconst directory = replicatedState<SessionDirectoryState>({\n\t\trevision,\n\t\tsessions: await options.list(BACKGROUND_CONTEXT),\n\t});\n\tconst attachments = new Set<RoutedServerServiceAttachment>();\n\tlet mutationTail = Promise.resolve();\n\n\tconst refreshNow = async (context: Context): Promise<void> => {\n\t\tconst sessions = await options.list(context);\n\t\trevision += 1;\n\t\tdirectory.state.revision = revision;\n\t\tdirectory.state.sessions = sessions;\n\t\tdirectory.publish(context);\n\t};\n\tconst serialize = <T>(operation: () => Promise<T>): Promise<T> => {\n\t\tconst result = mutationTail.catch(() => {}).then(operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t};\n\n\treturn {\n\t\thost: {\n\t\t\tattachClient(presentation) {\n\t\t\t\tlet preparedPluginPackagePaths: readonly string[] | undefined;\n\t\t\t\tconst provider = new RemoteServiceProvider([\n\t\t\t\t\t{ service: SessionDirectory, mode: \"singleton\" },\n\t\t\t\t\t{ service: SessionManagement, mode: \"singleton\" },\n\t\t\t\t\t{ service: PresentationPlugins, mode: \"singleton\" },\n\t\t\t\t]);\n\t\t\t\tprovider.provide(SessionDirectory, { state: directory });\n\t\t\t\tprovider.provide(PresentationPlugins, {\n\t\t\t\t\tprepareSession: ({ sessionId, packagePaths }, context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tconst selected = await options.prepareSessionPlugins(\n\t\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t\tpackagePaths ?? undefined,\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tpreparedPluginPackagePaths = selected.packagePaths;\n\t\t\t\t\t\t\treturn selected.presentationPlugins;\n\t\t\t\t\t\t}),\n\t\t\t\t\treload: (context) =>\n\t\t\t\t\t\tserialize(() => {\n\t\t\t\t\t\t\tif (preparedPluginPackagePaths === undefined) {\n\t\t\t\t\t\t\t\tthrow new Error(\"No Session plugin selection is prepared\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn options.reloadPresentationPlugins(preparedPluginPackagePaths, context);\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\tprovider.provide(SessionManagement, {\n\t\t\t\t\tcreate: (createOptions, context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tconst created = await options.create(createOptions, context);\n\t\t\t\t\t\t\tawait refreshNow(context);\n\t\t\t\t\t\t\treturn created;\n\t\t\t\t\t\t}),\n\t\t\t\t\tremove: (sessionId, context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tawait presentation.prepareSessionRemoval(sessionId, context);\n\t\t\t\t\t\t\tawait options.remove(sessionId, context);\n\t\t\t\t\t\t\tawait refreshNow(context);\n\t\t\t\t\t\t}),\n\t\t\t\t\tattach: (sessionId, context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tawait presentation.attachSession(sessionId, context);\n\t\t\t\t\t\t}),\n\t\t\t\t\tdetach: (context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tawait presentation.detachSession(context);\n\t\t\t\t\t\t\tpreparedPluginPackagePaths = undefined;\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\tconst attachment = createProviderAttachment(provider, () => attachments.delete(attachment));\n\t\t\t\tattachments.add(attachment);\n\t\t\t\treturn attachment;\n\t\t\t},\n\t\t},\n\t\trefresh: (context = BACKGROUND_CONTEXT) => serialize(() => refreshNow(context)),\n\t\tasync dispose() {\n\t\t\tconst releases = await Promise.allSettled(\n\t\t\t\t[...attachments].map((attachment) => attachment.release(BACKGROUND_CONTEXT)),\n\t\t\t);\n\t\t\tattachments.clear();\n\t\t\tawait mutationTail;\n\t\t\tconst errors = releases.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []));\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Failed to release server service attachments\");\n\t\t},\n\t};\n}\n\nfunction createProviderAttachment(\n\tprovider: RemoteServiceProvider,\n\tonRelease: () => void,\n): RoutedServerServiceAttachment {\n\tconst endpoint = createRemoteServiceEndpoint(provider);\n\tlet released = false;\n\treturn {\n\t\tinvokeService(call, publish, context) {\n\t\t\tif (released) return Promise.reject(new Error(\"Server service attachment is released\"));\n\t\t\treturn endpoint.invoke(call, publish, context);\n\t\t},\n\t\trelease() {\n\t\t\tif (released) return;\n\t\t\treleased = true;\n\t\t\tendpoint.dispose();\n\t\t\tprovider.dispose();\n\t\t\tonRelease();\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createRemoteServiceEndpoint, RemoteServiceProvider, replicatedState, } from "@earendil-works/chord";
|
|
2
|
+
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
|
3
|
+
import { PresentationPlugins } from "./plugins.js";
|
|
4
|
+
import { SessionDirectory, SessionManagement, } from "./sessions.js";
|
|
5
|
+
export async function createExperimentalServerServices(options) {
|
|
6
|
+
let revision = 1;
|
|
7
|
+
const directory = replicatedState({
|
|
8
|
+
revision,
|
|
9
|
+
sessions: await options.list(BACKGROUND_CONTEXT),
|
|
10
|
+
});
|
|
11
|
+
const attachments = new Set();
|
|
12
|
+
let mutationTail = Promise.resolve();
|
|
13
|
+
const refreshNow = async (context) => {
|
|
14
|
+
const sessions = await options.list(context);
|
|
15
|
+
revision += 1;
|
|
16
|
+
directory.state.revision = revision;
|
|
17
|
+
directory.state.sessions = sessions;
|
|
18
|
+
directory.publish(context);
|
|
19
|
+
};
|
|
20
|
+
const serialize = (operation) => {
|
|
21
|
+
const result = mutationTail.catch(() => { }).then(operation);
|
|
22
|
+
mutationTail = result.then(() => undefined, () => undefined);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
host: {
|
|
27
|
+
attachClient(presentation) {
|
|
28
|
+
let preparedPluginPackagePaths;
|
|
29
|
+
const provider = new RemoteServiceProvider([
|
|
30
|
+
{ service: SessionDirectory, mode: "singleton" },
|
|
31
|
+
{ service: SessionManagement, mode: "singleton" },
|
|
32
|
+
{ service: PresentationPlugins, mode: "singleton" },
|
|
33
|
+
]);
|
|
34
|
+
provider.provide(SessionDirectory, { state: directory });
|
|
35
|
+
provider.provide(PresentationPlugins, {
|
|
36
|
+
prepareSession: ({ sessionId, packagePaths }, context) => serialize(async () => {
|
|
37
|
+
const selected = await options.prepareSessionPlugins(sessionId, packagePaths ?? undefined, context);
|
|
38
|
+
preparedPluginPackagePaths = selected.packagePaths;
|
|
39
|
+
return selected.presentationPlugins;
|
|
40
|
+
}),
|
|
41
|
+
reload: (context) => serialize(() => {
|
|
42
|
+
if (preparedPluginPackagePaths === undefined) {
|
|
43
|
+
throw new Error("No Session plugin selection is prepared");
|
|
44
|
+
}
|
|
45
|
+
return options.reloadPresentationPlugins(preparedPluginPackagePaths, context);
|
|
46
|
+
}),
|
|
47
|
+
});
|
|
48
|
+
provider.provide(SessionManagement, {
|
|
49
|
+
create: (createOptions, context) => serialize(async () => {
|
|
50
|
+
const created = await options.create(createOptions, context);
|
|
51
|
+
await refreshNow(context);
|
|
52
|
+
return created;
|
|
53
|
+
}),
|
|
54
|
+
remove: (sessionId, context) => serialize(async () => {
|
|
55
|
+
await presentation.prepareSessionRemoval(sessionId, context);
|
|
56
|
+
await options.remove(sessionId, context);
|
|
57
|
+
await refreshNow(context);
|
|
58
|
+
}),
|
|
59
|
+
attach: (sessionId, context) => serialize(async () => {
|
|
60
|
+
await presentation.attachSession(sessionId, context);
|
|
61
|
+
}),
|
|
62
|
+
detach: (context) => serialize(async () => {
|
|
63
|
+
await presentation.detachSession(context);
|
|
64
|
+
preparedPluginPackagePaths = undefined;
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
const attachment = createProviderAttachment(provider, () => attachments.delete(attachment));
|
|
68
|
+
attachments.add(attachment);
|
|
69
|
+
return attachment;
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
refresh: (context = BACKGROUND_CONTEXT) => serialize(() => refreshNow(context)),
|
|
73
|
+
async dispose() {
|
|
74
|
+
const releases = await Promise.allSettled([...attachments].map((attachment) => attachment.release(BACKGROUND_CONTEXT)));
|
|
75
|
+
attachments.clear();
|
|
76
|
+
await mutationTail;
|
|
77
|
+
const errors = releases.flatMap((result) => (result.status === "rejected" ? [result.reason] : []));
|
|
78
|
+
if (errors.length === 1)
|
|
79
|
+
throw errors[0];
|
|
80
|
+
if (errors.length > 1)
|
|
81
|
+
throw new AggregateError(errors, "Failed to release server service attachments");
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function createProviderAttachment(provider, onRelease) {
|
|
86
|
+
const endpoint = createRemoteServiceEndpoint(provider);
|
|
87
|
+
let released = false;
|
|
88
|
+
return {
|
|
89
|
+
invokeService(call, publish, context) {
|
|
90
|
+
if (released)
|
|
91
|
+
return Promise.reject(new Error("Server service attachment is released"));
|
|
92
|
+
return endpoint.invoke(call, publish, context);
|
|
93
|
+
},
|
|
94
|
+
release() {
|
|
95
|
+
if (released)
|
|
96
|
+
return;
|
|
97
|
+
released = true;
|
|
98
|
+
endpoint.dispose();
|
|
99
|
+
provider.dispose();
|
|
100
|
+
onRelease();
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/experimental/services/server.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype Context,\n\tcreateRemoteServiceEndpoint,\n\ttype JsonValue,\n\tRemoteServiceProvider,\n\treplicatedState,\n} from \"@earendil-works/chord\";\nimport { BACKGROUND_CONTEXT } from \"@earendil-works/chord/context\";\nimport type { RoutedServerServiceAttachment, RoutedServerServiceHost } from \"@earendil-works/pi-server\";\nimport { PresentationPlugins } from \"./plugins.ts\";\nimport {\n\ttype SessionCreateOptions,\n\tSessionDirectory,\n\ttype SessionDirectoryState,\n\tSessionManagement,\n\ttype SessionSummary,\n} from \"./sessions.ts\";\n\nexport interface ExperimentalServerServices {\n\treadonly host: RoutedServerServiceHost;\n\trefresh(context?: Context): Promise<void>;\n\tdispose(): Promise<void>;\n}\n\nexport async function createExperimentalServerServices(options: {\n\tlist(context: Context): Promise<SessionSummary[]>;\n\tcreate(createOptions: SessionCreateOptions, context: Context): Promise<SessionSummary>;\n\tremove(sessionId: string, context: Context): Promise<void>;\n\tprepareSessionPlugins(\n\t\tsessionId: string,\n\t\tpackagePaths: readonly string[] | undefined,\n\t\tcontext: Context,\n\t): Promise<{ readonly packagePaths: readonly string[]; readonly presentationPlugins: JsonValue }>;\n\treloadPresentationPlugins(packagePaths: readonly string[], context: Context): Promise<JsonValue>;\n}): Promise<ExperimentalServerServices> {\n\tlet revision = 1;\n\tconst directory = replicatedState<SessionDirectoryState>({\n\t\trevision,\n\t\tsessions: await options.list(BACKGROUND_CONTEXT),\n\t});\n\tconst attachments = new Set<RoutedServerServiceAttachment>();\n\tlet mutationTail = Promise.resolve();\n\n\tconst refreshNow = async (context: Context): Promise<void> => {\n\t\tconst sessions = await options.list(context);\n\t\trevision += 1;\n\t\tdirectory.state.revision = revision;\n\t\tdirectory.state.sessions = sessions;\n\t\tdirectory.publish(context);\n\t};\n\tconst serialize = <T>(operation: () => Promise<T>): Promise<T> => {\n\t\tconst result = mutationTail.catch(() => {}).then(operation);\n\t\tmutationTail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t};\n\n\treturn {\n\t\thost: {\n\t\t\tattachClient(presentation) {\n\t\t\t\tlet preparedPluginPackagePaths: readonly string[] | undefined;\n\t\t\t\tconst provider = new RemoteServiceProvider([\n\t\t\t\t\t{ service: SessionDirectory, mode: \"singleton\" },\n\t\t\t\t\t{ service: SessionManagement, mode: \"singleton\" },\n\t\t\t\t\t{ service: PresentationPlugins, mode: \"singleton\" },\n\t\t\t\t]);\n\t\t\t\tprovider.provide(SessionDirectory, { state: directory });\n\t\t\t\tprovider.provide(PresentationPlugins, {\n\t\t\t\t\tprepareSession: ({ sessionId, packagePaths }, context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tconst selected = await options.prepareSessionPlugins(\n\t\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t\tpackagePaths ?? undefined,\n\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tpreparedPluginPackagePaths = selected.packagePaths;\n\t\t\t\t\t\t\treturn selected.presentationPlugins;\n\t\t\t\t\t\t}),\n\t\t\t\t\treload: (context) =>\n\t\t\t\t\t\tserialize(() => {\n\t\t\t\t\t\t\tif (preparedPluginPackagePaths === undefined) {\n\t\t\t\t\t\t\t\tthrow new Error(\"No Session plugin selection is prepared\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn options.reloadPresentationPlugins(preparedPluginPackagePaths, context);\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\tprovider.provide(SessionManagement, {\n\t\t\t\t\tcreate: (createOptions, context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tconst created = await options.create(createOptions, context);\n\t\t\t\t\t\t\tawait refreshNow(context);\n\t\t\t\t\t\t\treturn created;\n\t\t\t\t\t\t}),\n\t\t\t\t\tremove: (sessionId, context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tawait presentation.prepareSessionRemoval(sessionId, context);\n\t\t\t\t\t\t\tawait options.remove(sessionId, context);\n\t\t\t\t\t\t\tawait refreshNow(context);\n\t\t\t\t\t\t}),\n\t\t\t\t\tattach: (sessionId, context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tawait presentation.attachSession(sessionId, context);\n\t\t\t\t\t\t}),\n\t\t\t\t\tdetach: (context) =>\n\t\t\t\t\t\tserialize(async () => {\n\t\t\t\t\t\t\tawait presentation.detachSession(context);\n\t\t\t\t\t\t\tpreparedPluginPackagePaths = undefined;\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\tconst attachment = createProviderAttachment(provider, () => attachments.delete(attachment));\n\t\t\t\tattachments.add(attachment);\n\t\t\t\treturn attachment;\n\t\t\t},\n\t\t},\n\t\trefresh: (context = BACKGROUND_CONTEXT) => serialize(() => refreshNow(context)),\n\t\tasync dispose() {\n\t\t\tconst releases = await Promise.allSettled(\n\t\t\t\t[...attachments].map((attachment) => attachment.release(BACKGROUND_CONTEXT)),\n\t\t\t);\n\t\t\tattachments.clear();\n\t\t\tawait mutationTail;\n\t\t\tconst errors = releases.flatMap((result) => (result.status === \"rejected\" ? [result.reason] : []));\n\t\t\tif (errors.length === 1) throw errors[0];\n\t\t\tif (errors.length > 1) throw new AggregateError(errors, \"Failed to release server service attachments\");\n\t\t},\n\t};\n}\n\nfunction createProviderAttachment(\n\tprovider: RemoteServiceProvider,\n\tonRelease: () => void,\n): RoutedServerServiceAttachment {\n\tconst endpoint = createRemoteServiceEndpoint(provider);\n\tlet released = false;\n\treturn {\n\t\tinvokeService(call, publish, context) {\n\t\t\tif (released) return Promise.reject(new Error(\"Server service attachment is released\"));\n\t\t\treturn endpoint.invoke(call, publish, context);\n\t\t},\n\t\trelease() {\n\t\t\tif (released) return;\n\t\t\treleased = true;\n\t\t\tendpoint.dispose();\n\t\t\tprovider.dispose();\n\t\t\tonRelease();\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Context, type ReplicatedState } from "@earendil-works/chord";
|
|
2
|
+
import type { ServerId } from "@earendil-works/pi-protocol";
|
|
3
|
+
export interface SessionAddress {
|
|
4
|
+
serverId: ServerId;
|
|
5
|
+
sessionId: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SessionSummary extends SessionAddress {
|
|
8
|
+
createdAt: number;
|
|
9
|
+
}
|
|
10
|
+
export interface SessionCreateOptions {
|
|
11
|
+
id?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SessionDirectoryState {
|
|
14
|
+
revision: number;
|
|
15
|
+
sessions: SessionSummary[];
|
|
16
|
+
}
|
|
17
|
+
export interface SessionDirectory {
|
|
18
|
+
readonly state: ReplicatedState<SessionDirectoryState>;
|
|
19
|
+
}
|
|
20
|
+
export declare const SessionDirectory: import("@earendil-works/chord").Service<SessionDirectory>;
|
|
21
|
+
export interface SessionManagement {
|
|
22
|
+
create(options: SessionCreateOptions, context: Context): Promise<SessionSummary>;
|
|
23
|
+
remove(sessionId: string, context: Context): Promise<void>;
|
|
24
|
+
attach(sessionId: string, context: Context): Promise<void>;
|
|
25
|
+
detach(context: Context): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export declare const SessionManagement: import("@earendil-works/chord").Service<SessionManagement>;
|
|
28
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/experimental/services/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC1F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAe,SAAQ,cAAc;IACrD,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACpC,EAAE,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,qBAAqB,CAAC,CAAC;CACvD;AAED,eAAO,MAAM,gBAAgB,2DAA0D,CAAC;AAExF,MAAM,WAAW,iBAAiB;IACjC,MAAM,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACjF,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED,eAAO,MAAM,iBAAiB,4DAA4D,CAAC","sourcesContent":["import { type Context, defineService, type ReplicatedState } from \"@earendil-works/chord\";\nimport type { ServerId } from \"@earendil-works/pi-protocol\";\n\nexport interface SessionAddress {\n\tserverId: ServerId;\n\tsessionId: string;\n}\n\nexport interface SessionSummary extends SessionAddress {\n\tcreatedAt: number;\n}\n\nexport interface SessionCreateOptions {\n\tid?: string;\n}\n\nexport interface SessionDirectoryState {\n\trevision: number;\n\tsessions: SessionSummary[];\n}\n\nexport interface SessionDirectory {\n\treadonly state: ReplicatedState<SessionDirectoryState>;\n}\n\nexport const SessionDirectory = defineService<SessionDirectory>(\"pi.session-directory\");\n\nexport interface SessionManagement {\n\tcreate(options: SessionCreateOptions, context: Context): Promise<SessionSummary>;\n\tremove(sessionId: string, context: Context): Promise<void>;\n\tattach(sessionId: string, context: Context): Promise<void>;\n\tdetach(context: Context): Promise<void>;\n}\n\nexport const SessionManagement = defineService<SessionManagement>(\"pi.session-management\");\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../src/experimental/services/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,aAAa,EAAwB,MAAM,uBAAuB,CAAC;AAyB1F,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAmB,sBAAsB,CAAC,CAAC;AASxF,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAoB,uBAAuB,CAAC,CAAC","sourcesContent":["import { type Context, defineService, type ReplicatedState } from \"@earendil-works/chord\";\nimport type { ServerId } from \"@earendil-works/pi-protocol\";\n\nexport interface SessionAddress {\n\tserverId: ServerId;\n\tsessionId: string;\n}\n\nexport interface SessionSummary extends SessionAddress {\n\tcreatedAt: number;\n}\n\nexport interface SessionCreateOptions {\n\tid?: string;\n}\n\nexport interface SessionDirectoryState {\n\trevision: number;\n\tsessions: SessionSummary[];\n}\n\nexport interface SessionDirectory {\n\treadonly state: ReplicatedState<SessionDirectoryState>;\n}\n\nexport const SessionDirectory = defineService<SessionDirectory>(\"pi.session-directory\");\n\nexport interface SessionManagement {\n\tcreate(options: SessionCreateOptions, context: Context): Promise<SessionSummary>;\n\tremove(sessionId: string, context: Context): Promise<void>;\n\tattach(sessionId: string, context: Context): Promise<void>;\n\tdetach(context: Context): Promise<void>;\n}\n\nexport const SessionManagement = defineService<SessionManagement>(\"pi.session-management\");\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Facet, type JsonValue } from "@earendil-works/chord";
|
|
2
|
+
import { type SlashCommandContribution, SlashCommands } from "./slash-commands.ts";
|
|
3
|
+
export declare class SlashCommandRegistry implements SlashCommands {
|
|
4
|
+
#private;
|
|
5
|
+
register(command: SlashCommandContribution): () => void;
|
|
6
|
+
replace(command: SlashCommandContribution): () => void;
|
|
7
|
+
list(): readonly SlashCommandContribution[];
|
|
8
|
+
subscribe(listener: (commands: readonly SlashCommandContribution[]) => void): () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function createSlashCommandsRuntimeFacet(registry?: SlashCommandRegistry): Facet;
|
|
11
|
+
export declare function createBuiltInSlashCommandsFacet(options: {
|
|
12
|
+
reloadPresentationPlugins(data: JsonValue): Promise<void>;
|
|
13
|
+
}): Facet;
|
|
14
|
+
//# sourceMappingURL=slash-commands-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slash-commands-provider.d.ts","sourceRoot":"","sources":["../../../src/experimental/services/slash-commands-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAMhF,OAAO,EAAE,KAAK,wBAAwB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAiBnF,qBAAa,oBAAqB,YAAW,aAAa;;IAIzD,QAAQ,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,IAAI,CAItD;IAED,OAAO,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,IAAI,CAGrD;IAED,IAAI,IAAI,SAAS,wBAAwB,EAAE,CAE1C;IAED,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAIvF;CA4BD;AAED,wBAAgB,+BAA+B,CAAC,QAAQ,uBAA6B,GAAG,KAAK,CAO5F;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE;IACxD,yBAAyB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D,GAAG,KAAK,CA+BR","sourcesContent":["import { defineFacet, type Facet, type JsonValue } from \"@earendil-works/chord\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { AgentController } from \"./agent-controller.ts\";\nimport { type ModelSummary, Models, type Models as ModelsService } from \"./models.ts\";\nimport { PresentationPlugins, SessionPlugins } from \"./plugins.ts\";\nimport { PresentationUI } from \"./presentation-ui.ts\";\nimport { type SlashCommandContribution, SlashCommands } from \"./slash-commands.ts\";\n\nconst THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {\n\toff: \"No reasoning\",\n\tminimal: \"Very brief reasoning\",\n\tlow: \"Light reasoning\",\n\tmedium: \"Moderate reasoning\",\n\thigh: \"Deep reasoning\",\n\txhigh: \"Extra-high reasoning\",\n\tmax: \"Maximum reasoning\",\n};\n\ninterface RegisteredSlashCommand {\n\treadonly command: SlashCommandContribution;\n\tclosed: boolean;\n}\n\nexport class SlashCommandRegistry implements SlashCommands {\n\treadonly #commands = new Map<string, RegisteredSlashCommand[]>();\n\treadonly #listeners = new Set<(commands: readonly SlashCommandContribution[]) => void>();\n\n\tregister(command: SlashCommandContribution): () => void {\n\t\tthis.#validate(command);\n\t\tif (this.#commands.has(command.name)) throw new Error(`Slash command /${command.name} is already registered`);\n\t\treturn this.#add(command);\n\t}\n\n\treplace(command: SlashCommandContribution): () => void {\n\t\tthis.#validate(command);\n\t\treturn this.#add(command);\n\t}\n\n\tlist(): readonly SlashCommandContribution[] {\n\t\treturn Object.freeze([...this.#commands.values()].map((entries) => entries[0]!.command));\n\t}\n\n\tsubscribe(listener: (commands: readonly SlashCommandContribution[]) => void): () => void {\n\t\tthis.#listeners.add(listener);\n\t\tlistener(this.list());\n\t\treturn () => this.#listeners.delete(listener);\n\t}\n\n\t#add(command: SlashCommandContribution): () => void {\n\t\tconst entry: RegisteredSlashCommand = { command: Object.freeze({ ...command }), closed: false };\n\t\tconst entries = this.#commands.get(command.name) ?? [];\n\t\tentries.push(entry);\n\t\tthis.#commands.set(command.name, entries);\n\t\tif (entries.length === 1) this.#publish();\n\t\treturn () => {\n\t\t\tif (entry.closed) return;\n\t\t\tentry.closed = true;\n\t\t\tif (entries[0] !== entry) return;\n\t\t\twhile (entries[0]?.closed) entries.shift();\n\t\t\tif (entries.length === 0) this.#commands.delete(command.name);\n\t\t\tthis.#publish();\n\t\t};\n\t}\n\n\t#validate(command: SlashCommandContribution): void {\n\t\tif (!/^[a-z0-9][a-z0-9:-]*$/u.test(command.name)) {\n\t\t\tthrow new TypeError(`Invalid slash command name: ${command.name}`);\n\t\t}\n\t}\n\n\t#publish(): void {\n\t\tconst commands = this.list();\n\t\tfor (const listener of this.#listeners) listener(commands);\n\t}\n}\n\nexport function createSlashCommandsRuntimeFacet(registry = new SlashCommandRegistry()): Facet {\n\treturn defineFacet({\n\t\tid: \"@pi/slash-commands-runtime\",\n\t\tsetup(env) {\n\t\t\tenv.provide(SlashCommands, registry);\n\t\t},\n\t});\n}\n\nexport function createBuiltInSlashCommandsFacet(options: {\n\treloadPresentationPlugins(data: JsonValue): Promise<void>;\n}): Facet {\n\treturn defineFacet({\n\t\tid: \"@pi/slash-commands-builtin\",\n\t\tsetup(env) {\n\t\t\tconst commands = env.use(SlashCommands);\n\t\t\tconst models = env.use(Models);\n\t\t\tconst controller = env.use(AgentController);\n\t\t\tconst ui = env.use(PresentationUI);\n\t\t\tconst presentationPlugins = env.use(PresentationPlugins);\n\t\t\tconst sessionPlugins = env.use(SessionPlugins);\n\t\t\tenv.onActivate(() => {\n\t\t\t\tenv.own(commands.replace(modelCommand(models, ui)));\n\t\t\t\tenv.own(commands.replace(thinkingCommand(models, ui)));\n\t\t\t\tenv.own(commands.replace(compactCommand(controller, ui)));\n\t\t\t\tenv.own(\n\t\t\t\t\tcommands.replace({\n\t\t\t\t\t\tname: \"reload\",\n\t\t\t\t\t\tdescription: \"Reload server-selected plugins\",\n\t\t\t\t\t\tasync run(_args, context) {\n\t\t\t\t\t\t\tui.showStatus(\"Reloading plugins…\", context);\n\t\t\t\t\t\t\tconst data = await presentationPlugins.reload(context);\n\t\t\t\t\t\t\tawait sessionPlugins.reload(context);\n\t\t\t\t\t\t\tawait options.reloadPresentationPlugins(data);\n\t\t\t\t\t\t\tui.showStatus(\"Reloaded plugins.\", context);\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t});\n}\n\nfunction modelCommand(models: ModelsService, ui: PresentationUI): SlashCommandContribution {\n\treturn {\n\t\tname: \"model\",\n\t\tdescription: \"Select model\",\n\t\targumentHint: \"<provider/model>\",\n\t\tgetArgumentCompletions(prefix) {\n\t\t\tconst normalized = prefix.toLowerCase();\n\t\t\treturn (models.state.value?.catalog.availableModels ?? [])\n\t\t\t\t.filter((model) => `${model.provider}/${model.modelId} ${model.name}`.toLowerCase().includes(normalized))\n\t\t\t\t.map((model) => ({\n\t\t\t\t\tvalue: `${model.provider}/${model.modelId}`,\n\t\t\t\t\tlabel: model.modelId,\n\t\t\t\t\tdescription: model.provider,\n\t\t\t\t}));\n\t\t},\n\t\tasync run(args, context) {\n\t\t\tconst state = models.state.value;\n\t\t\tif (state === undefined) throw new Error(\"Models service is not ready\");\n\t\t\tlet selected = exactModel(state.catalog.availableModels, args);\n\t\t\tif (args.length > 0 && selected === undefined) {\n\t\t\t\tthrow new Error(`Unknown model: ${args}`);\n\t\t\t}\n\t\t\tif (selected === undefined) {\n\t\t\t\tconst value = await ui.select(\n\t\t\t\t\t\"Select model:\",\n\t\t\t\t\tstate.catalog.availableModels.map((model) => ({\n\t\t\t\t\t\tvalue: `${model.provider}/${model.modelId}`,\n\t\t\t\t\t\tlabel:\n\t\t\t\t\t\t\tstate.configuration.model?.provider === model.provider &&\n\t\t\t\t\t\t\tstate.configuration.model.modelId === model.modelId\n\t\t\t\t\t\t\t\t? `${model.name} (selected)`\n\t\t\t\t\t\t\t\t: model.name,\n\t\t\t\t\t\tdescription: `${model.provider}/${model.modelId}`,\n\t\t\t\t\t})),\n\t\t\t\t\tstate.configuration.model === null\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: `${state.configuration.model.provider}/${state.configuration.model.modelId}`,\n\t\t\t\t\tcontext,\n\t\t\t\t);\n\t\t\t\tif (value === undefined) return undefined;\n\t\t\t\tselected = exactModel(state.catalog.availableModels, value);\n\t\t\t\tif (selected === undefined) throw new Error(`Unknown model: ${value}`);\n\t\t\t}\n\t\t\tawait models.select({ provider: selected.provider, modelId: selected.modelId }, context);\n\t\t\tui.showStatus(`Selected ${selected.provider}/${selected.modelId}.`, context);\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\nfunction thinkingCommand(models: ModelsService, ui: PresentationUI): SlashCommandContribution {\n\treturn {\n\t\tname: \"thinking\",\n\t\tdescription: \"Set thinking level\",\n\t\targumentHint: \"<level>\",\n\t\tasync run(args, context) {\n\t\t\tconst levels = await models.getThinkingLevels(context);\n\t\t\tlet selected = levels.find((level) => level === args.toLowerCase());\n\t\t\tif (args.length > 0 && selected === undefined) {\n\t\t\t\tthrow new Error(`Unknown thinking level \"${args}\". Available levels: ${levels.join(\", \")}.`);\n\t\t\t}\n\t\t\tif (selected === undefined) {\n\t\t\t\tconst value = await ui.select(\n\t\t\t\t\t\"Select thinking level:\",\n\t\t\t\t\tlevels.map((level) => ({\n\t\t\t\t\t\tvalue: level,\n\t\t\t\t\t\tlabel: models.state.value?.configuration.thinkingLevel === level ? `${level} (selected)` : level,\n\t\t\t\t\t\tdescription: THINKING_DESCRIPTIONS[level],\n\t\t\t\t\t})),\n\t\t\t\t\tmodels.state.value?.configuration.thinkingLevel,\n\t\t\t\t\tcontext,\n\t\t\t\t);\n\t\t\t\tif (value === undefined) return undefined;\n\t\t\t\tselected = levels.find((level) => level === value);\n\t\t\t\tif (selected === undefined) throw new Error(`Unknown thinking level: ${value}`);\n\t\t\t}\n\t\t\tawait models.selectThinking(selected, context);\n\t\t\tui.showStatus(`Thinking level: ${selected}.`, context);\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\nfunction compactCommand(controller: AgentController, ui: PresentationUI): SlashCommandContribution {\n\treturn {\n\t\tname: \"compact\",\n\t\tdescription: \"Manually compact the session context\",\n\t\targumentHint: \"<instructions>\",\n\t\trun(args, context) {\n\t\t\tui.showStatus(\"Compacting…\", context);\n\t\t\treturn controller.compact({ customInstructions: args.length === 0 ? null : args }, context);\n\t\t},\n\t};\n}\n\nfunction exactModel(models: readonly ModelSummary[], query: string): ModelSummary | undefined {\n\tif (query.length === 0) return undefined;\n\tconst normalized = query.toLowerCase();\n\tconst matches = models.filter(\n\t\t(model) =>\n\t\t\t`${model.provider}/${model.modelId}`.toLowerCase() === normalized ||\n\t\t\tmodel.modelId.toLowerCase() === normalized,\n\t);\n\treturn matches.length === 1 ? matches[0] : undefined;\n}\n"]}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { defineFacet } from "@earendil-works/chord";
|
|
2
|
+
import { AgentController } from "./agent-controller.js";
|
|
3
|
+
import { Models } from "./models.js";
|
|
4
|
+
import { PresentationPlugins, SessionPlugins } from "./plugins.js";
|
|
5
|
+
import { PresentationUI } from "./presentation-ui.js";
|
|
6
|
+
import { SlashCommands } from "./slash-commands.js";
|
|
7
|
+
const THINKING_DESCRIPTIONS = {
|
|
8
|
+
off: "No reasoning",
|
|
9
|
+
minimal: "Very brief reasoning",
|
|
10
|
+
low: "Light reasoning",
|
|
11
|
+
medium: "Moderate reasoning",
|
|
12
|
+
high: "Deep reasoning",
|
|
13
|
+
xhigh: "Extra-high reasoning",
|
|
14
|
+
max: "Maximum reasoning",
|
|
15
|
+
};
|
|
16
|
+
export class SlashCommandRegistry {
|
|
17
|
+
#commands = new Map();
|
|
18
|
+
#listeners = new Set();
|
|
19
|
+
register(command) {
|
|
20
|
+
this.#validate(command);
|
|
21
|
+
if (this.#commands.has(command.name))
|
|
22
|
+
throw new Error(`Slash command /${command.name} is already registered`);
|
|
23
|
+
return this.#add(command);
|
|
24
|
+
}
|
|
25
|
+
replace(command) {
|
|
26
|
+
this.#validate(command);
|
|
27
|
+
return this.#add(command);
|
|
28
|
+
}
|
|
29
|
+
list() {
|
|
30
|
+
return Object.freeze([...this.#commands.values()].map((entries) => entries[0].command));
|
|
31
|
+
}
|
|
32
|
+
subscribe(listener) {
|
|
33
|
+
this.#listeners.add(listener);
|
|
34
|
+
listener(this.list());
|
|
35
|
+
return () => this.#listeners.delete(listener);
|
|
36
|
+
}
|
|
37
|
+
#add(command) {
|
|
38
|
+
const entry = { command: Object.freeze({ ...command }), closed: false };
|
|
39
|
+
const entries = this.#commands.get(command.name) ?? [];
|
|
40
|
+
entries.push(entry);
|
|
41
|
+
this.#commands.set(command.name, entries);
|
|
42
|
+
if (entries.length === 1)
|
|
43
|
+
this.#publish();
|
|
44
|
+
return () => {
|
|
45
|
+
if (entry.closed)
|
|
46
|
+
return;
|
|
47
|
+
entry.closed = true;
|
|
48
|
+
if (entries[0] !== entry)
|
|
49
|
+
return;
|
|
50
|
+
while (entries[0]?.closed)
|
|
51
|
+
entries.shift();
|
|
52
|
+
if (entries.length === 0)
|
|
53
|
+
this.#commands.delete(command.name);
|
|
54
|
+
this.#publish();
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
#validate(command) {
|
|
58
|
+
if (!/^[a-z0-9][a-z0-9:-]*$/u.test(command.name)) {
|
|
59
|
+
throw new TypeError(`Invalid slash command name: ${command.name}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
#publish() {
|
|
63
|
+
const commands = this.list();
|
|
64
|
+
for (const listener of this.#listeners)
|
|
65
|
+
listener(commands);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export function createSlashCommandsRuntimeFacet(registry = new SlashCommandRegistry()) {
|
|
69
|
+
return defineFacet({
|
|
70
|
+
id: "@pi/slash-commands-runtime",
|
|
71
|
+
setup(env) {
|
|
72
|
+
env.provide(SlashCommands, registry);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
export function createBuiltInSlashCommandsFacet(options) {
|
|
77
|
+
return defineFacet({
|
|
78
|
+
id: "@pi/slash-commands-builtin",
|
|
79
|
+
setup(env) {
|
|
80
|
+
const commands = env.use(SlashCommands);
|
|
81
|
+
const models = env.use(Models);
|
|
82
|
+
const controller = env.use(AgentController);
|
|
83
|
+
const ui = env.use(PresentationUI);
|
|
84
|
+
const presentationPlugins = env.use(PresentationPlugins);
|
|
85
|
+
const sessionPlugins = env.use(SessionPlugins);
|
|
86
|
+
env.onActivate(() => {
|
|
87
|
+
env.own(commands.replace(modelCommand(models, ui)));
|
|
88
|
+
env.own(commands.replace(thinkingCommand(models, ui)));
|
|
89
|
+
env.own(commands.replace(compactCommand(controller, ui)));
|
|
90
|
+
env.own(commands.replace({
|
|
91
|
+
name: "reload",
|
|
92
|
+
description: "Reload server-selected plugins",
|
|
93
|
+
async run(_args, context) {
|
|
94
|
+
ui.showStatus("Reloading plugins…", context);
|
|
95
|
+
const data = await presentationPlugins.reload(context);
|
|
96
|
+
await sessionPlugins.reload(context);
|
|
97
|
+
await options.reloadPresentationPlugins(data);
|
|
98
|
+
ui.showStatus("Reloaded plugins.", context);
|
|
99
|
+
return undefined;
|
|
100
|
+
},
|
|
101
|
+
}));
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function modelCommand(models, ui) {
|
|
107
|
+
return {
|
|
108
|
+
name: "model",
|
|
109
|
+
description: "Select model",
|
|
110
|
+
argumentHint: "<provider/model>",
|
|
111
|
+
getArgumentCompletions(prefix) {
|
|
112
|
+
const normalized = prefix.toLowerCase();
|
|
113
|
+
return (models.state.value?.catalog.availableModels ?? [])
|
|
114
|
+
.filter((model) => `${model.provider}/${model.modelId} ${model.name}`.toLowerCase().includes(normalized))
|
|
115
|
+
.map((model) => ({
|
|
116
|
+
value: `${model.provider}/${model.modelId}`,
|
|
117
|
+
label: model.modelId,
|
|
118
|
+
description: model.provider,
|
|
119
|
+
}));
|
|
120
|
+
},
|
|
121
|
+
async run(args, context) {
|
|
122
|
+
const state = models.state.value;
|
|
123
|
+
if (state === undefined)
|
|
124
|
+
throw new Error("Models service is not ready");
|
|
125
|
+
let selected = exactModel(state.catalog.availableModels, args);
|
|
126
|
+
if (args.length > 0 && selected === undefined) {
|
|
127
|
+
throw new Error(`Unknown model: ${args}`);
|
|
128
|
+
}
|
|
129
|
+
if (selected === undefined) {
|
|
130
|
+
const value = await ui.select("Select model:", state.catalog.availableModels.map((model) => ({
|
|
131
|
+
value: `${model.provider}/${model.modelId}`,
|
|
132
|
+
label: state.configuration.model?.provider === model.provider &&
|
|
133
|
+
state.configuration.model.modelId === model.modelId
|
|
134
|
+
? `${model.name} (selected)`
|
|
135
|
+
: model.name,
|
|
136
|
+
description: `${model.provider}/${model.modelId}`,
|
|
137
|
+
})), state.configuration.model === null
|
|
138
|
+
? undefined
|
|
139
|
+
: `${state.configuration.model.provider}/${state.configuration.model.modelId}`, context);
|
|
140
|
+
if (value === undefined)
|
|
141
|
+
return undefined;
|
|
142
|
+
selected = exactModel(state.catalog.availableModels, value);
|
|
143
|
+
if (selected === undefined)
|
|
144
|
+
throw new Error(`Unknown model: ${value}`);
|
|
145
|
+
}
|
|
146
|
+
await models.select({ provider: selected.provider, modelId: selected.modelId }, context);
|
|
147
|
+
ui.showStatus(`Selected ${selected.provider}/${selected.modelId}.`, context);
|
|
148
|
+
return undefined;
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function thinkingCommand(models, ui) {
|
|
153
|
+
return {
|
|
154
|
+
name: "thinking",
|
|
155
|
+
description: "Set thinking level",
|
|
156
|
+
argumentHint: "<level>",
|
|
157
|
+
async run(args, context) {
|
|
158
|
+
const levels = await models.getThinkingLevels(context);
|
|
159
|
+
let selected = levels.find((level) => level === args.toLowerCase());
|
|
160
|
+
if (args.length > 0 && selected === undefined) {
|
|
161
|
+
throw new Error(`Unknown thinking level "${args}". Available levels: ${levels.join(", ")}.`);
|
|
162
|
+
}
|
|
163
|
+
if (selected === undefined) {
|
|
164
|
+
const value = await ui.select("Select thinking level:", levels.map((level) => ({
|
|
165
|
+
value: level,
|
|
166
|
+
label: models.state.value?.configuration.thinkingLevel === level ? `${level} (selected)` : level,
|
|
167
|
+
description: THINKING_DESCRIPTIONS[level],
|
|
168
|
+
})), models.state.value?.configuration.thinkingLevel, context);
|
|
169
|
+
if (value === undefined)
|
|
170
|
+
return undefined;
|
|
171
|
+
selected = levels.find((level) => level === value);
|
|
172
|
+
if (selected === undefined)
|
|
173
|
+
throw new Error(`Unknown thinking level: ${value}`);
|
|
174
|
+
}
|
|
175
|
+
await models.selectThinking(selected, context);
|
|
176
|
+
ui.showStatus(`Thinking level: ${selected}.`, context);
|
|
177
|
+
return undefined;
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function compactCommand(controller, ui) {
|
|
182
|
+
return {
|
|
183
|
+
name: "compact",
|
|
184
|
+
description: "Manually compact the session context",
|
|
185
|
+
argumentHint: "<instructions>",
|
|
186
|
+
run(args, context) {
|
|
187
|
+
ui.showStatus("Compacting…", context);
|
|
188
|
+
return controller.compact({ customInstructions: args.length === 0 ? null : args }, context);
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function exactModel(models, query) {
|
|
193
|
+
if (query.length === 0)
|
|
194
|
+
return undefined;
|
|
195
|
+
const normalized = query.toLowerCase();
|
|
196
|
+
const matches = models.filter((model) => `${model.provider}/${model.modelId}`.toLowerCase() === normalized ||
|
|
197
|
+
model.modelId.toLowerCase() === normalized);
|
|
198
|
+
return matches.length === 1 ? matches[0] : undefined;
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=slash-commands-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slash-commands-provider.js","sourceRoot":"","sources":["../../../src/experimental/services/slash-commands-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineFacet, type Facet, type JsonValue } from \"@earendil-works/chord\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { AgentController } from \"./agent-controller.ts\";\nimport { type ModelSummary, Models, type Models as ModelsService } from \"./models.ts\";\nimport { PresentationPlugins, SessionPlugins } from \"./plugins.ts\";\nimport { PresentationUI } from \"./presentation-ui.ts\";\nimport { type SlashCommandContribution, SlashCommands } from \"./slash-commands.ts\";\n\nconst THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {\n\toff: \"No reasoning\",\n\tminimal: \"Very brief reasoning\",\n\tlow: \"Light reasoning\",\n\tmedium: \"Moderate reasoning\",\n\thigh: \"Deep reasoning\",\n\txhigh: \"Extra-high reasoning\",\n\tmax: \"Maximum reasoning\",\n};\n\ninterface RegisteredSlashCommand {\n\treadonly command: SlashCommandContribution;\n\tclosed: boolean;\n}\n\nexport class SlashCommandRegistry implements SlashCommands {\n\treadonly #commands = new Map<string, RegisteredSlashCommand[]>();\n\treadonly #listeners = new Set<(commands: readonly SlashCommandContribution[]) => void>();\n\n\tregister(command: SlashCommandContribution): () => void {\n\t\tthis.#validate(command);\n\t\tif (this.#commands.has(command.name)) throw new Error(`Slash command /${command.name} is already registered`);\n\t\treturn this.#add(command);\n\t}\n\n\treplace(command: SlashCommandContribution): () => void {\n\t\tthis.#validate(command);\n\t\treturn this.#add(command);\n\t}\n\n\tlist(): readonly SlashCommandContribution[] {\n\t\treturn Object.freeze([...this.#commands.values()].map((entries) => entries[0]!.command));\n\t}\n\n\tsubscribe(listener: (commands: readonly SlashCommandContribution[]) => void): () => void {\n\t\tthis.#listeners.add(listener);\n\t\tlistener(this.list());\n\t\treturn () => this.#listeners.delete(listener);\n\t}\n\n\t#add(command: SlashCommandContribution): () => void {\n\t\tconst entry: RegisteredSlashCommand = { command: Object.freeze({ ...command }), closed: false };\n\t\tconst entries = this.#commands.get(command.name) ?? [];\n\t\tentries.push(entry);\n\t\tthis.#commands.set(command.name, entries);\n\t\tif (entries.length === 1) this.#publish();\n\t\treturn () => {\n\t\t\tif (entry.closed) return;\n\t\t\tentry.closed = true;\n\t\t\tif (entries[0] !== entry) return;\n\t\t\twhile (entries[0]?.closed) entries.shift();\n\t\t\tif (entries.length === 0) this.#commands.delete(command.name);\n\t\t\tthis.#publish();\n\t\t};\n\t}\n\n\t#validate(command: SlashCommandContribution): void {\n\t\tif (!/^[a-z0-9][a-z0-9:-]*$/u.test(command.name)) {\n\t\t\tthrow new TypeError(`Invalid slash command name: ${command.name}`);\n\t\t}\n\t}\n\n\t#publish(): void {\n\t\tconst commands = this.list();\n\t\tfor (const listener of this.#listeners) listener(commands);\n\t}\n}\n\nexport function createSlashCommandsRuntimeFacet(registry = new SlashCommandRegistry()): Facet {\n\treturn defineFacet({\n\t\tid: \"@pi/slash-commands-runtime\",\n\t\tsetup(env) {\n\t\t\tenv.provide(SlashCommands, registry);\n\t\t},\n\t});\n}\n\nexport function createBuiltInSlashCommandsFacet(options: {\n\treloadPresentationPlugins(data: JsonValue): Promise<void>;\n}): Facet {\n\treturn defineFacet({\n\t\tid: \"@pi/slash-commands-builtin\",\n\t\tsetup(env) {\n\t\t\tconst commands = env.use(SlashCommands);\n\t\t\tconst models = env.use(Models);\n\t\t\tconst controller = env.use(AgentController);\n\t\t\tconst ui = env.use(PresentationUI);\n\t\t\tconst presentationPlugins = env.use(PresentationPlugins);\n\t\t\tconst sessionPlugins = env.use(SessionPlugins);\n\t\t\tenv.onActivate(() => {\n\t\t\t\tenv.own(commands.replace(modelCommand(models, ui)));\n\t\t\t\tenv.own(commands.replace(thinkingCommand(models, ui)));\n\t\t\t\tenv.own(commands.replace(compactCommand(controller, ui)));\n\t\t\t\tenv.own(\n\t\t\t\t\tcommands.replace({\n\t\t\t\t\t\tname: \"reload\",\n\t\t\t\t\t\tdescription: \"Reload server-selected plugins\",\n\t\t\t\t\t\tasync run(_args, context) {\n\t\t\t\t\t\t\tui.showStatus(\"Reloading plugins…\", context);\n\t\t\t\t\t\t\tconst data = await presentationPlugins.reload(context);\n\t\t\t\t\t\t\tawait sessionPlugins.reload(context);\n\t\t\t\t\t\t\tawait options.reloadPresentationPlugins(data);\n\t\t\t\t\t\t\tui.showStatus(\"Reloaded plugins.\", context);\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t});\n}\n\nfunction modelCommand(models: ModelsService, ui: PresentationUI): SlashCommandContribution {\n\treturn {\n\t\tname: \"model\",\n\t\tdescription: \"Select model\",\n\t\targumentHint: \"<provider/model>\",\n\t\tgetArgumentCompletions(prefix) {\n\t\t\tconst normalized = prefix.toLowerCase();\n\t\t\treturn (models.state.value?.catalog.availableModels ?? [])\n\t\t\t\t.filter((model) => `${model.provider}/${model.modelId} ${model.name}`.toLowerCase().includes(normalized))\n\t\t\t\t.map((model) => ({\n\t\t\t\t\tvalue: `${model.provider}/${model.modelId}`,\n\t\t\t\t\tlabel: model.modelId,\n\t\t\t\t\tdescription: model.provider,\n\t\t\t\t}));\n\t\t},\n\t\tasync run(args, context) {\n\t\t\tconst state = models.state.value;\n\t\t\tif (state === undefined) throw new Error(\"Models service is not ready\");\n\t\t\tlet selected = exactModel(state.catalog.availableModels, args);\n\t\t\tif (args.length > 0 && selected === undefined) {\n\t\t\t\tthrow new Error(`Unknown model: ${args}`);\n\t\t\t}\n\t\t\tif (selected === undefined) {\n\t\t\t\tconst value = await ui.select(\n\t\t\t\t\t\"Select model:\",\n\t\t\t\t\tstate.catalog.availableModels.map((model) => ({\n\t\t\t\t\t\tvalue: `${model.provider}/${model.modelId}`,\n\t\t\t\t\t\tlabel:\n\t\t\t\t\t\t\tstate.configuration.model?.provider === model.provider &&\n\t\t\t\t\t\t\tstate.configuration.model.modelId === model.modelId\n\t\t\t\t\t\t\t\t? `${model.name} (selected)`\n\t\t\t\t\t\t\t\t: model.name,\n\t\t\t\t\t\tdescription: `${model.provider}/${model.modelId}`,\n\t\t\t\t\t})),\n\t\t\t\t\tstate.configuration.model === null\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: `${state.configuration.model.provider}/${state.configuration.model.modelId}`,\n\t\t\t\t\tcontext,\n\t\t\t\t);\n\t\t\t\tif (value === undefined) return undefined;\n\t\t\t\tselected = exactModel(state.catalog.availableModels, value);\n\t\t\t\tif (selected === undefined) throw new Error(`Unknown model: ${value}`);\n\t\t\t}\n\t\t\tawait models.select({ provider: selected.provider, modelId: selected.modelId }, context);\n\t\t\tui.showStatus(`Selected ${selected.provider}/${selected.modelId}.`, context);\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\nfunction thinkingCommand(models: ModelsService, ui: PresentationUI): SlashCommandContribution {\n\treturn {\n\t\tname: \"thinking\",\n\t\tdescription: \"Set thinking level\",\n\t\targumentHint: \"<level>\",\n\t\tasync run(args, context) {\n\t\t\tconst levels = await models.getThinkingLevels(context);\n\t\t\tlet selected = levels.find((level) => level === args.toLowerCase());\n\t\t\tif (args.length > 0 && selected === undefined) {\n\t\t\t\tthrow new Error(`Unknown thinking level \"${args}\". Available levels: ${levels.join(\", \")}.`);\n\t\t\t}\n\t\t\tif (selected === undefined) {\n\t\t\t\tconst value = await ui.select(\n\t\t\t\t\t\"Select thinking level:\",\n\t\t\t\t\tlevels.map((level) => ({\n\t\t\t\t\t\tvalue: level,\n\t\t\t\t\t\tlabel: models.state.value?.configuration.thinkingLevel === level ? `${level} (selected)` : level,\n\t\t\t\t\t\tdescription: THINKING_DESCRIPTIONS[level],\n\t\t\t\t\t})),\n\t\t\t\t\tmodels.state.value?.configuration.thinkingLevel,\n\t\t\t\t\tcontext,\n\t\t\t\t);\n\t\t\t\tif (value === undefined) return undefined;\n\t\t\t\tselected = levels.find((level) => level === value);\n\t\t\t\tif (selected === undefined) throw new Error(`Unknown thinking level: ${value}`);\n\t\t\t}\n\t\t\tawait models.selectThinking(selected, context);\n\t\t\tui.showStatus(`Thinking level: ${selected}.`, context);\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\nfunction compactCommand(controller: AgentController, ui: PresentationUI): SlashCommandContribution {\n\treturn {\n\t\tname: \"compact\",\n\t\tdescription: \"Manually compact the session context\",\n\t\targumentHint: \"<instructions>\",\n\t\trun(args, context) {\n\t\t\tui.showStatus(\"Compacting…\", context);\n\t\t\treturn controller.compact({ customInstructions: args.length === 0 ? null : args }, context);\n\t\t},\n\t};\n}\n\nfunction exactModel(models: readonly ModelSummary[], query: string): ModelSummary | undefined {\n\tif (query.length === 0) return undefined;\n\tconst normalized = query.toLowerCase();\n\tconst matches = models.filter(\n\t\t(model) =>\n\t\t\t`${model.provider}/${model.modelId}`.toLowerCase() === normalized ||\n\t\t\tmodel.modelId.toLowerCase() === normalized,\n\t);\n\treturn matches.length === 1 ? matches[0] : undefined;\n}\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Context } from "@earendil-works/chord";
|
|
2
|
+
import type { AgentOperationResponse, AgentQueueResponse } from "./agent-controller.ts";
|
|
3
|
+
export interface SlashCommandCompletion {
|
|
4
|
+
readonly value: string;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly description?: string;
|
|
7
|
+
}
|
|
8
|
+
export type SlashCommandRunResult = AgentOperationResponse | AgentQueueResponse | undefined;
|
|
9
|
+
export interface SlashCommandContribution {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly description?: string;
|
|
12
|
+
readonly argumentHint?: string;
|
|
13
|
+
getArgumentCompletions?(argumentPrefix: string): readonly SlashCommandCompletion[] | null | Promise<readonly SlashCommandCompletion[] | null>;
|
|
14
|
+
run(args: string, context: Context): SlashCommandRunResult | Promise<SlashCommandRunResult>;
|
|
15
|
+
}
|
|
16
|
+
export interface SlashCommands {
|
|
17
|
+
register(command: SlashCommandContribution): () => void;
|
|
18
|
+
/** Stage a same-name replacement while the previous facet generation retires. */
|
|
19
|
+
replace(command: SlashCommandContribution): () => void;
|
|
20
|
+
list(): readonly SlashCommandContribution[];
|
|
21
|
+
subscribe(listener: (commands: readonly SlashCommandContribution[]) => void): () => void;
|
|
22
|
+
}
|
|
23
|
+
export declare const SlashCommands: import("@earendil-works/chord").Service<SlashCommands>;
|
|
24
|
+
//# sourceMappingURL=slash-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slash-commands.d.ts","sourceRoot":"","sources":["../../../src/experimental/services/slash-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAExF,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,GAAG,kBAAkB,GAAG,SAAS,CAAC;AAE5F,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,sBAAsB,CAAC,CACtB,cAAc,EAAE,MAAM,GACpB,SAAS,sBAAsB,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,sBAAsB,EAAE,GAAG,IAAI,CAAC,CAAC;IAChG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC5F;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,IAAI,CAAC;IACxD,iFAAiF;IACjF,OAAO,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,IAAI,CAAC;IACvD,IAAI,IAAI,SAAS,wBAAwB,EAAE,CAAC;IAC5C,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACzF;AAED,eAAO,MAAM,aAAa,wDAA2E,CAAC","sourcesContent":["import { type Context, defineService } from \"@earendil-works/chord\";\nimport type { AgentOperationResponse, AgentQueueResponse } from \"./agent-controller.ts\";\n\nexport interface SlashCommandCompletion {\n\treadonly value: string;\n\treadonly label: string;\n\treadonly description?: string;\n}\n\nexport type SlashCommandRunResult = AgentOperationResponse | AgentQueueResponse | undefined;\n\nexport interface SlashCommandContribution {\n\treadonly name: string;\n\treadonly description?: string;\n\treadonly argumentHint?: string;\n\tgetArgumentCompletions?(\n\t\targumentPrefix: string,\n\t): readonly SlashCommandCompletion[] | null | Promise<readonly SlashCommandCompletion[] | null>;\n\trun(args: string, context: Context): SlashCommandRunResult | Promise<SlashCommandRunResult>;\n}\n\nexport interface SlashCommands {\n\tregister(command: SlashCommandContribution): () => void;\n\t/** Stage a same-name replacement while the previous facet generation retires. */\n\treplace(command: SlashCommandContribution): () => void;\n\tlist(): readonly SlashCommandContribution[];\n\tsubscribe(listener: (commands: readonly SlashCommandContribution[]) => void): () => void;\n}\n\nexport const SlashCommands = defineService<SlashCommands>(\"pi.local.slash-commands\", { local: true });\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slash-commands.js","sourceRoot":"","sources":["../../../src/experimental/services/slash-commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AA6BpE,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAgB,yBAAyB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC","sourcesContent":["import { type Context, defineService } from \"@earendil-works/chord\";\nimport type { AgentOperationResponse, AgentQueueResponse } from \"./agent-controller.ts\";\n\nexport interface SlashCommandCompletion {\n\treadonly value: string;\n\treadonly label: string;\n\treadonly description?: string;\n}\n\nexport type SlashCommandRunResult = AgentOperationResponse | AgentQueueResponse | undefined;\n\nexport interface SlashCommandContribution {\n\treadonly name: string;\n\treadonly description?: string;\n\treadonly argumentHint?: string;\n\tgetArgumentCompletions?(\n\t\targumentPrefix: string,\n\t): readonly SlashCommandCompletion[] | null | Promise<readonly SlashCommandCompletion[] | null>;\n\trun(args: string, context: Context): SlashCommandRunResult | Promise<SlashCommandRunResult>;\n}\n\nexport interface SlashCommands {\n\tregister(command: SlashCommandContribution): () => void;\n\t/** Stage a same-name replacement while the previous facet generation retires. */\n\treplace(command: SlashCommandContribution): () => void;\n\tlist(): readonly SlashCommandContribution[];\n\tsubscribe(listener: (commands: readonly SlashCommandContribution[]) => void): () => void;\n}\n\nexport const SlashCommands = defineService<SlashCommands>(\"pi.local.slash-commands\", { local: true });\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Facet, type MutableReplicatedState } from "@earendil-works/chord";
|
|
2
|
+
import { type AgentLane } from "@earendil-works/pi-agent-core";
|
|
3
|
+
import { type Transcript as TranscriptService, type TranscriptState } from "./transcript.ts";
|
|
4
|
+
interface TranscriptRuntime {
|
|
5
|
+
readonly service: TranscriptService;
|
|
6
|
+
activate(): Promise<void>;
|
|
7
|
+
dispose(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare function createTranscriptService(lane: AgentLane, createState: (initial: TranscriptState) => MutableReplicatedState<TranscriptState>): TranscriptRuntime;
|
|
10
|
+
export declare function createTranscriptServiceFacet(lane: AgentLane): Facet;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=transcript-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-provider.d.ts","sourceRoot":"","sources":["../../../src/experimental/services/transcript-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,KAAK,EAAE,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE7F,OAAO,EACN,KAAK,SAAS,EAOd,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAc,KAAK,UAAU,IAAI,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEzG,UAAU,iBAAiB;IAC1B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,SAAS,EACf,WAAW,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,sBAAsB,CAAC,eAAe,CAAC,GAChF,iBAAiB,CAoEnB;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,GAAG,KAAK,CAUnE","sourcesContent":["import { defineFacet, type Facet, type MutableReplicatedState } from \"@earendil-works/chord\";\nimport { BACKGROUND_CONTEXT } from \"@earendil-works/chord/context\";\nimport {\n\ttype AgentLane,\n\ttype HarnessEvent,\n\ttype LaneSnapshot,\n\ttype LaneTranscriptSnapshot,\n\ttype LaneWatchEvent,\n\treduceLaneSnapshot,\n\ttype WatchHandle,\n} from \"@earendil-works/pi-agent-core\";\nimport { Transcript, type Transcript as TranscriptService, type TranscriptState } from \"./transcript.ts\";\n\ninterface TranscriptRuntime {\n\treadonly service: TranscriptService;\n\tactivate(): Promise<void>;\n\tdispose(): Promise<void>;\n}\n\nexport function createTranscriptService(\n\tlane: AgentLane,\n\tcreateState: (initial: TranscriptState) => MutableReplicatedState<TranscriptState>,\n): TranscriptRuntime {\n\tconst state = createState({ snapshot: null, event: null });\n\tlet watch: WatchHandle<LaneSnapshot> | undefined;\n\tlet rebase: Promise<void> | undefined;\n\tlet rebaseError: Error | undefined;\n\n\tconst publishSnapshot = (\n\t\tnext: LaneSnapshot,\n\t\tevent: LaneWatchEvent | null,\n\t\tcontext: Parameters<typeof state.publish>[0],\n\t): void => {\n\t\tstate.state.snapshot = next as LaneTranscriptSnapshot;\n\t\tstate.state.event = event;\n\t\tstate.publish(context);\n\t};\n\n\tconst scheduleRebase = (context: Parameters<typeof state.publish>[0]): void => {\n\t\tif (rebase !== undefined) return;\n\t\tconst activeWatch = watch;\n\t\tif (activeWatch === undefined) return;\n\t\tconst pending = (async () => {\n\t\t\tconst refreshed = await activeWatch.resnapshot(context);\n\t\t\tpublishSnapshot(refreshed, null, context);\n\t\t})();\n\t\trebase = pending;\n\t\tvoid pending.then(\n\t\t\t() => {\n\t\t\t\tif (rebase === pending) rebase = undefined;\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\trebaseError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\tif (rebase === pending) rebase = undefined;\n\t\t\t},\n\t\t);\n\t};\n\n\tconst onEvent = (event: HarnessEvent, context: Parameters<typeof state.publish>[0]): void => {\n\t\tif (rebaseError !== undefined) throw rebaseError;\n\t\tconst forwarded = toLaneWatchEvent(event);\n\t\tif (forwarded === undefined) return;\n\t\tconst snapshot = state.state.snapshot;\n\t\tif (snapshot === null) throw new Error(\"Transcript service is not active\");\n\t\tif (reduceLaneSnapshot(snapshot, event) === \"rebase\") scheduleRebase(context);\n\t\tstate.state.event = forwarded;\n\t\tstate.publish(context);\n\t};\n\n\treturn {\n\t\tservice: { state },\n\t\tasync activate() {\n\t\t\tif (watch !== undefined) throw new Error(\"Transcript service is already active\");\n\t\t\tconst opened = await lane.watch(BACKGROUND_CONTEXT);\n\t\t\twatch = opened;\n\t\t\tpublishSnapshot(opened.snapshot, null, BACKGROUND_CONTEXT);\n\t\t\topened.start(onEvent);\n\t\t},\n\t\tasync dispose() {\n\t\t\tlet failure: unknown;\n\t\t\ttry {\n\t\t\t\tawait rebase;\n\t\t\t} catch (error) {\n\t\t\t\tfailure = error;\n\t\t\t}\n\t\t\twatch?.unsubscribe();\n\t\t\twatch = undefined;\n\t\t\tif (failure !== undefined) throw failure;\n\t\t},\n\t};\n}\n\nexport function createTranscriptServiceFacet(lane: AgentLane): Facet {\n\treturn defineFacet({\n\t\tid: \"@pi/transcript\",\n\t\tsetup(env) {\n\t\t\tconst runtime = createTranscriptService(lane, env.replicatedState);\n\t\t\tenv.provide(Transcript, runtime.service);\n\t\t\tenv.onActivate(() => runtime.activate());\n\t\t\tenv.own(() => runtime.dispose());\n\t\t},\n\t});\n}\n\nfunction toLaneWatchEvent(event: HarnessEvent): LaneWatchEvent | undefined {\n\tswitch (event.type) {\n\t\tcase \"handler_error\":\n\t\tcase \"turn_start\":\n\t\tcase \"turn_end\":\n\t\tcase \"value_update\":\n\t\tcase \"lane_created\":\n\t\t\treturn undefined;\n\t\tcase \"config_update\":\n\t\t\tif (event.property !== \"model\" && event.property !== \"thinkingLevel\" && event.property !== \"activeTools\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn event as LaneWatchEvent;\n\t\tcase \"message_update\": {\n\t\t\tif (event.message.role !== \"assistant\") {\n\t\t\t\tthrow new TypeError(\"Harness message_update did not carry an assistant message\");\n\t\t\t}\n\t\t\tconst { event: _providerEvent, ...update } = event;\n\t\t\treturn update as LaneWatchEvent;\n\t\t}\n\t\tdefault:\n\t\t\treturn event as LaneWatchEvent;\n\t}\n}\n"]}
|