@code-yeongyu/senpi 2026.8.28 → 2026.8.30
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 +140 -0
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +4 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +2 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +50 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +313 -25
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +1 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -0
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +155 -37
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/credential-accounts.d.ts.map +1 -1
- package/dist/core/credential-accounts.js +45 -21
- package/dist/core/credential-accounts.js.map +1 -1
- package/dist/core/credential-pool/classify.d.ts +6 -1
- package/dist/core/credential-pool/classify.d.ts.map +1 -1
- package/dist/core/credential-pool/classify.js +22 -5
- package/dist/core/credential-pool/classify.js.map +1 -1
- package/dist/core/credential-pool/env-slots.d.ts.map +1 -1
- package/dist/core/credential-pool/env-slots.js +2 -0
- package/dist/core/credential-pool/env-slots.js.map +1 -1
- package/dist/core/credential-pool/failover.d.ts +8 -0
- package/dist/core/credential-pool/failover.d.ts.map +1 -1
- package/dist/core/credential-pool/failover.js +24 -6
- package/dist/core/credential-pool/failover.js.map +1 -1
- package/dist/core/credential-pool/rotation-stream.d.ts +13 -2
- package/dist/core/credential-pool/rotation-stream.d.ts.map +1 -1
- package/dist/core/credential-pool/rotation-stream.js +97 -10
- package/dist/core/credential-pool/rotation-stream.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +8 -2
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +160 -47
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/retained-message-safety.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/retained-message-safety.js +31 -8
- package/dist/core/extensions/builtin/compaction/retained-message-safety.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js +8 -28
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js.map +1 -1
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +7 -0
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/external-dir.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/external-dir.js +15 -5
- package/dist/core/extensions/builtin/permission-system/external-dir.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/parsers.js +16 -1
- package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
- package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
- package/dist/core/extensions/builtin/service-tier.js +13 -0
- package/dist/core/extensions/builtin/service-tier.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +4 -2
- package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/manager.d.ts +5 -0
- package/dist/core/extensions/builtin/terminal/manager.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/manager.js +31 -3
- package/dist/core/extensions/builtin/terminal/manager.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-permission.d.ts +8 -0
- package/dist/core/extensions/builtin/terminal/monitor-permission.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/monitor-permission.js +16 -0
- package/dist/core/extensions/builtin/terminal/monitor-permission.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +13 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.js +403 -3
- package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-bundle.js +1 -0
- package/dist/core/extensions/builtin/terminal/session-bundle.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.js +5 -2
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +4 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js +40 -2
- package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
- package/dist/core/model-config-schema.d.ts +4 -4
- package/dist/core/model-resolver.js +2 -2
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +2 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +74 -37
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/retry-fallback/chains.d.ts +23 -1
- package/dist/core/retry-fallback/chains.d.ts.map +1 -1
- package/dist/core/retry-fallback/chains.js +59 -3
- package/dist/core/retry-fallback/chains.js.map +1 -1
- package/dist/core/retry-fallback/controller.d.ts.map +1 -1
- package/dist/core/retry-fallback/controller.js +9 -2
- package/dist/core/retry-fallback/controller.js.map +1 -1
- package/dist/core/retry-fallback/settings.d.ts.map +1 -1
- package/dist/core/retry-fallback/settings.js +9 -0
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/retry-fallback/validate.js +1 -1
- package/dist/core/retry-fallback/validate.js.map +1 -1
- package/dist/core/sdk.js +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +9 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +40 -0
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +7 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +6 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +97 -15
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +8 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +76 -34
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/main.d.ts +7 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +10 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/favorite-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/favorite-models-selector.js +2 -2
- package/dist/modes/interactive/components/favorite-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +7 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +34 -8
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/grok/chrome.d.ts +2 -0
- package/dist/modes/interactive/grok/chrome.d.ts.map +1 -1
- package/dist/modes/interactive/grok/chrome.js.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts +51 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.js +545 -40
- package/dist/modes/interactive/interactive-host-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +7 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +390 -239
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts +8 -1
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +268 -63
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/host-ensure.d.ts +2 -0
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
- package/dist/modes/rpc/host-ensure.js +15 -2
- package/dist/modes/rpc/host-ensure.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +31 -12
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/host-watchdog.d.ts +2 -0
- package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
- package/dist/modes/rpc/host-watchdog.js +23 -12
- package/dist/modes/rpc/host-watchdog.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +20 -8
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +91 -16
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +129 -37
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-input-validation.d.ts +1 -0
- package/dist/modes/rpc/rpc-input-validation.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-input-validation.js +66 -0
- package/dist/modes/rpc/rpc-input-validation.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +3 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +3 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +241 -3
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-binding.d.ts +1 -0
- package/dist/modes/rpc/session-binding.d.ts.map +1 -1
- package/dist/modes/rpc/session-binding.js +21 -1
- package/dist/modes/rpc/session-binding.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts +22 -0
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +148 -16
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-event-writer.d.ts +4 -0
- package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
- package/dist/modes/rpc/session-event-writer.js +58 -7
- package/dist/modes/rpc/session-event-writer.js.map +1 -1
- package/dist/modes/rpc/session-extension-ui-requests.d.ts +1 -0
- package/dist/modes/rpc/session-extension-ui-requests.d.ts.map +1 -1
- package/dist/modes/rpc/session-extension-ui-requests.js +5 -0
- package/dist/modes/rpc/session-extension-ui-requests.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +17 -2
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +67 -4
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/dist/modes/rpc/socket-event-fanout.d.ts +22 -0
- package/dist/modes/rpc/socket-event-fanout.d.ts.map +1 -0
- package/dist/modes/rpc/socket-event-fanout.js +84 -0
- package/dist/modes/rpc/socket-event-fanout.js.map +1 -0
- package/docs/rpc.md +40 -1
- package/docs/settings.md +34 -0
- package/docs/windows.md +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +62 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +139 -90
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +4 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +6 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js +40 -20
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts +3 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.js +28 -9
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/utils/shell-output.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +58 -31
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts +20 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js +443 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/measure.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +7 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +5 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/mux.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/mux.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/mux.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/mux.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +19 -0
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -1,4 +1,70 @@
|
|
|
1
1
|
export const MAX_RPC_MESSAGE_CHARACTERS = 1_000_000;
|
|
2
|
+
function validContent(content) {
|
|
3
|
+
if (typeof content === "string")
|
|
4
|
+
return true;
|
|
5
|
+
return (Array.isArray(content) &&
|
|
6
|
+
content.every((item) => {
|
|
7
|
+
if (typeof item !== "object" || item === null)
|
|
8
|
+
return false;
|
|
9
|
+
const value = item;
|
|
10
|
+
return value.type === "text"
|
|
11
|
+
? typeof value.text === "string"
|
|
12
|
+
: value.type === "image" && typeof value.data === "string" && typeof value.mimeType === "string";
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
function validBaseEntry(entry) {
|
|
16
|
+
return (typeof entry.id === "string" &&
|
|
17
|
+
(entry.parentId === null || typeof entry.parentId === "string") &&
|
|
18
|
+
typeof entry.timestamp === "string");
|
|
19
|
+
}
|
|
20
|
+
function validSessionEntry(entry) {
|
|
21
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
22
|
+
return false;
|
|
23
|
+
const value = entry;
|
|
24
|
+
if (!validBaseEntry(value))
|
|
25
|
+
return false;
|
|
26
|
+
switch (value.type) {
|
|
27
|
+
case "message": {
|
|
28
|
+
const message = value.message;
|
|
29
|
+
if (typeof message !== "object" || message === null)
|
|
30
|
+
return false;
|
|
31
|
+
const item = message;
|
|
32
|
+
return ["user", "assistant", "tool"].includes(item.role) && validContent(item.content);
|
|
33
|
+
}
|
|
34
|
+
case "thinking_level_change":
|
|
35
|
+
return typeof value.thinkingLevel === "string";
|
|
36
|
+
case "model_change":
|
|
37
|
+
return typeof value.provider === "string" && typeof value.modelId === "string";
|
|
38
|
+
case "compaction":
|
|
39
|
+
return (typeof value.summary === "string" &&
|
|
40
|
+
typeof value.firstKeptEntryId === "string" &&
|
|
41
|
+
typeof value.tokensBefore === "number");
|
|
42
|
+
case "branch_summary":
|
|
43
|
+
return typeof value.fromId === "string" && typeof value.summary === "string";
|
|
44
|
+
case "custom":
|
|
45
|
+
return typeof value.customType === "string";
|
|
46
|
+
case "custom_message":
|
|
47
|
+
return (typeof value.customType === "string" && validContent(value.content) && typeof value.display === "boolean");
|
|
48
|
+
case "label":
|
|
49
|
+
return typeof value.targetId === "string" && (value.label === undefined || typeof value.label === "string");
|
|
50
|
+
case "session_info":
|
|
51
|
+
return value.name === undefined || typeof value.name === "string";
|
|
52
|
+
default:
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function rpcCommandPayloadError(command) {
|
|
57
|
+
if (rpcCommandShapeError(command))
|
|
58
|
+
return undefined;
|
|
59
|
+
const value = command;
|
|
60
|
+
if (value.type === "append_user_message" && !validContent(value.content)) {
|
|
61
|
+
return "append_user_message content must be a string or text/image content array.";
|
|
62
|
+
}
|
|
63
|
+
if (value.type === "append_session_entry" && !validSessionEntry(value.entry)) {
|
|
64
|
+
return "append_session_entry entry is malformed.";
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
2
68
|
export function rpcCommandShapeError(command) {
|
|
3
69
|
if (typeof command !== "object" || command === null || Array.isArray(command)) {
|
|
4
70
|
return "RPC command must be a JSON object.";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-input-validation.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-input-validation.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG,SAAS,CAAC;AAOpD,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACpD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/E,OAAO,oCAAoC,CAAC;IAC7C,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACrD,IAAI,oBAAoB,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,MAAM,KAAK,GAAG,OAA0B,CAAC;IACzC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACrF,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,0BAA0B,EAAE,CAAC;QAC7F,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,OAAO,KAAK,CAAC,IAAI,oBAAoB,0BAA0B,cAAc,CAAC;AACtF,CAAC","sourcesContent":["export const MAX_RPC_MESSAGE_CHARACTERS = 1_000_000;\n\ninterface RpcMessageInput {\n\ttype?: unknown;\n\tmessage?: unknown;\n}\n\nexport function rpcCommandShapeError(command: unknown): string | undefined {\n\tif (typeof command !== \"object\" || command === null || Array.isArray(command)) {\n\t\treturn \"RPC command must be a JSON object.\";\n\t}\n\treturn undefined;\n}\n\nexport function rpcMessageLengthError(command: unknown): string | undefined {\n\tif (rpcCommandShapeError(command)) return undefined;\n\tconst input = command as RpcMessageInput;\n\tif (input.type !== \"prompt\" && input.type !== \"steer\" && input.type !== \"follow_up\") {\n\t\treturn undefined;\n\t}\n\tif (typeof input.message !== \"string\" || input.message.length <= MAX_RPC_MESSAGE_CHARACTERS) {\n\t\treturn undefined;\n\t}\n\treturn `RPC ${input.type} message exceeds ${MAX_RPC_MESSAGE_CHARACTERS} characters.`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rpc-input-validation.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-input-validation.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG,SAAS,CAAC;AAOpD,SAAS,YAAY,CAAC,OAAgB;IACrC,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC7C,OAAO,CACN,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE;YACtB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YAC5D,MAAM,KAAK,GAAG,IAA8E,CAAC;YAC7F,OAAO,KAAK,CAAC,IAAI,KAAK,MAAM;gBAC3B,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAChC,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC;QACnG,CAAC,CAAC,CACF,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAA8B;IACrD,OAAO,CACN,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QAC5B,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC;QAC/D,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CACnC,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtF,MAAM,KAAK,GAAG,KAAgC,CAAC;IAC/C,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,SAAS,CAAC,CAAC,CAAC;YAChB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;YAC9B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YAClE,MAAM,IAAI,GAAG,OAAgD,CAAC;YAC9D,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAc,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClG,CAAC;QACD,KAAK,uBAAuB;YAC3B,OAAO,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC;QAChD,KAAK,cAAc;YAClB,OAAO,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC;QAChF,KAAK,YAAY;YAChB,OAAO,CACN,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;gBACjC,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ;gBAC1C,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,CACtC,CAAC;QACH,KAAK,gBAAgB;YACpB,OAAO,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC;QAC9E,KAAK,QAAQ;YACZ,OAAO,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC;QAC7C,KAAK,gBAAgB;YACpB,OAAO,CACN,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,SAAS,CACzG,CAAC;QACH,KAAK,OAAO;YACX,OAAO,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC;QAC7G,KAAK,cAAc;YAClB,OAAO,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;QACnE;YACC,OAAO,KAAK,CAAC;IACf,CAAC;AACF,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACtD,IAAI,oBAAoB,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,MAAM,KAAK,GAAG,OAAkC,CAAC;IACjD,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1E,OAAO,2EAA2E,CAAC;IACpF,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,sBAAsB,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9E,OAAO,0CAA0C,CAAC;IACnD,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACpD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/E,OAAO,oCAAoC,CAAC;IAC7C,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACrD,IAAI,oBAAoB,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,MAAM,KAAK,GAAG,OAA0B,CAAC;IACzC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACrF,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,0BAA0B,EAAE,CAAC;QAC7F,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,OAAO,KAAK,CAAC,IAAI,oBAAoB,0BAA0B,cAAc,CAAC;AACtF,CAAC","sourcesContent":["export const MAX_RPC_MESSAGE_CHARACTERS = 1_000_000;\n\ninterface RpcMessageInput {\n\ttype?: unknown;\n\tmessage?: unknown;\n}\n\nfunction validContent(content: unknown): boolean {\n\tif (typeof content === \"string\") return true;\n\treturn (\n\t\tArray.isArray(content) &&\n\t\tcontent.every((item) => {\n\t\t\tif (typeof item !== \"object\" || item === null) return false;\n\t\t\tconst value = item as { type?: unknown; text?: unknown; data?: unknown; mimeType?: unknown };\n\t\t\treturn value.type === \"text\"\n\t\t\t\t? typeof value.text === \"string\"\n\t\t\t\t: value.type === \"image\" && typeof value.data === \"string\" && typeof value.mimeType === \"string\";\n\t\t})\n\t);\n}\n\nfunction validBaseEntry(entry: Record<string, unknown>): boolean {\n\treturn (\n\t\ttypeof entry.id === \"string\" &&\n\t\t(entry.parentId === null || typeof entry.parentId === \"string\") &&\n\t\ttypeof entry.timestamp === \"string\"\n\t);\n}\n\nfunction validSessionEntry(entry: unknown): boolean {\n\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) return false;\n\tconst value = entry as Record<string, unknown>;\n\tif (!validBaseEntry(value)) return false;\n\tswitch (value.type) {\n\t\tcase \"message\": {\n\t\t\tconst message = value.message;\n\t\t\tif (typeof message !== \"object\" || message === null) return false;\n\t\t\tconst item = message as { role?: unknown; content?: unknown };\n\t\t\treturn [\"user\", \"assistant\", \"tool\"].includes(item.role as string) && validContent(item.content);\n\t\t}\n\t\tcase \"thinking_level_change\":\n\t\t\treturn typeof value.thinkingLevel === \"string\";\n\t\tcase \"model_change\":\n\t\t\treturn typeof value.provider === \"string\" && typeof value.modelId === \"string\";\n\t\tcase \"compaction\":\n\t\t\treturn (\n\t\t\t\ttypeof value.summary === \"string\" &&\n\t\t\t\ttypeof value.firstKeptEntryId === \"string\" &&\n\t\t\t\ttypeof value.tokensBefore === \"number\"\n\t\t\t);\n\t\tcase \"branch_summary\":\n\t\t\treturn typeof value.fromId === \"string\" && typeof value.summary === \"string\";\n\t\tcase \"custom\":\n\t\t\treturn typeof value.customType === \"string\";\n\t\tcase \"custom_message\":\n\t\t\treturn (\n\t\t\t\ttypeof value.customType === \"string\" && validContent(value.content) && typeof value.display === \"boolean\"\n\t\t\t);\n\t\tcase \"label\":\n\t\t\treturn typeof value.targetId === \"string\" && (value.label === undefined || typeof value.label === \"string\");\n\t\tcase \"session_info\":\n\t\t\treturn value.name === undefined || typeof value.name === \"string\";\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nexport function rpcCommandPayloadError(command: unknown): string | undefined {\n\tif (rpcCommandShapeError(command)) return undefined;\n\tconst value = command as Record<string, unknown>;\n\tif (value.type === \"append_user_message\" && !validContent(value.content)) {\n\t\treturn \"append_user_message content must be a string or text/image content array.\";\n\t}\n\tif (value.type === \"append_session_entry\" && !validSessionEntry(value.entry)) {\n\t\treturn \"append_session_entry entry is malformed.\";\n\t}\n\treturn undefined;\n}\n\nexport function rpcCommandShapeError(command: unknown): string | undefined {\n\tif (typeof command !== \"object\" || command === null || Array.isArray(command)) {\n\t\treturn \"RPC command must be a JSON object.\";\n\t}\n\treturn undefined;\n}\n\nexport function rpcMessageLengthError(command: unknown): string | undefined {\n\tif (rpcCommandShapeError(command)) return undefined;\n\tconst input = command as RpcMessageInput;\n\tif (input.type !== \"prompt\" && input.type !== \"steer\" && input.type !== \"follow_up\") {\n\t\treturn undefined;\n\t}\n\tif (typeof input.message !== \"string\" || input.message.length <= MAX_RPC_MESSAGE_CHARACTERS) {\n\t\treturn undefined;\n\t}\n\treturn `RPC ${input.type} message exceeds ${MAX_RPC_MESSAGE_CHARACTERS} characters.`;\n}\n"]}
|
|
@@ -28,9 +28,11 @@
|
|
|
28
28
|
* | Command | Params | Success data | Notes |
|
|
29
29
|
* | ---------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----- |
|
|
30
30
|
* | `get_protocol_info` | - | `{ protocolVersion: 1, serverVersion, capabilities, mode: "classic"|"multi" }` | Answered in BOTH modes; side-effect-free capability probe. |
|
|
31
|
-
* | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState }`
|
|
31
|
+
* | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState, attached?: boolean }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there); `provider`/`modelId` applied only on create (resume restores the session's model); params form the immutable launch profile (D8). |
|
|
32
32
|
* | `close_session` | `sessionId` | `{}` | Aborts active work, awaits agent idle + settled persistence, flushes queued events, detaches subscriptions; its response is the LAST record tagged with that handle — no events after (test-pinned). |
|
|
33
33
|
* | `list_sessions` | - | `{ sessions: [{ sessionId, durableSessionId, sessionPath, cwd, name, status }] }` | Includes `opening`/`closing` entries with their status. |
|
|
34
|
+
* | `get_steering_messages` / `get_follow_up_messages` / `clear_queue` | queue read or clear parameters | host-authoritative queue values | Interactive attach clients must not read bootstrap queues. |
|
|
35
|
+
* | `abort_branch_summary` / `record_bash_result` / `set_label` | narrow mutation payloads | `{}` | Routes interactive runtime mutations to the owning host session. |
|
|
34
36
|
* | every existing command | + `sessionId` (REQUIRED in multi mode) | unchanged | Routed to that session. |
|
|
35
37
|
*
|
|
36
38
|
* Identities (D6): response-level `sessionId` = opaque routing handle, unique per
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rpc-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAe/E,YAAY,EACX,UAAU,EACV,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,eAAe,GACf,MAAM,gBAAgB,CAAC;AAExB;;;GAGG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,KAAK,CAAC,CA0GjF"}
|
|
@@ -28,9 +28,11 @@
|
|
|
28
28
|
* | Command | Params | Success data | Notes |
|
|
29
29
|
* | ---------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----- |
|
|
30
30
|
* | `get_protocol_info` | - | `{ protocolVersion: 1, serverVersion, capabilities, mode: "classic"|"multi" }` | Answered in BOTH modes; side-effect-free capability probe. |
|
|
31
|
-
* | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState }`
|
|
31
|
+
* | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState, attached?: boolean }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there); `provider`/`modelId` applied only on create (resume restores the session's model); params form the immutable launch profile (D8). |
|
|
32
32
|
* | `close_session` | `sessionId` | `{}` | Aborts active work, awaits agent idle + settled persistence, flushes queued events, detaches subscriptions; its response is the LAST record tagged with that handle — no events after (test-pinned). |
|
|
33
33
|
* | `list_sessions` | - | `{ sessions: [{ sessionId, durableSessionId, sessionPath, cwd, name, status }] }` | Includes `opening`/`closing` entries with their status. |
|
|
34
|
+
* | `get_steering_messages` / `get_follow_up_messages` / `clear_queue` | queue read or clear parameters | host-authoritative queue values | Interactive attach clients must not read bootstrap queues. |
|
|
35
|
+
* | `abort_branch_summary` / `record_bash_result` / `set_label` | narrow mutation payloads | `{}` | Routes interactive runtime mutations to the owning host session. |
|
|
34
36
|
* | every existing command | + `sessionId` (REQUIRED in multi mode) | unchanged | Routed to that session. |
|
|
35
37
|
*
|
|
36
38
|
* Identities (D6): response-level `sessionId` = opaque routing handle, unique per
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-mode.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RPC mode: Headless operation with JSON stdin/stdout protocol.\n *\n * Used for embedding the agent in other applications.\n * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.\n *\n * Protocol:\n * - Commands: JSON objects with `type` field, optional `id` for correlation\n * - Responses: JSON objects with `type: \"response\"`, `command`, `success`, and optional `data`/`error`\n * - Events: AgentSessionEvent objects streamed as they occur\n * - Extension UI: Extension UI requests are emitted, client responds with extension_ui_response\n *\n * This is the single-connection stdio host. The RPC command loop, extension-UI\n * bridge, and event subscription live in `connection-handler.ts` so the same\n * logic can also serve a caller-owned RPC transport. This file owns exactly the\n * process-level concerns that a per-connection handler must NOT\n * touch: stdout takeover, stdin wiring, signal handlers, and process exit.\n *\n * ── Multi-session mode (`--multi-session`) ─────────────────────────────────\n *\n * Startup: `senpi --mode rpc --multi-session` → NO default session is constructed\n * (no default `AgentSessionRuntime`, no default extension/watcher load). Classic\n * `senpi --mode rpc` is byte-identical to today. Mode is fixed at process start;\n * there is no runtime transition.\n *\n * D1 normative table (multi-session mode):\n *\n * | Command | Params | Success data | Notes |\n * | ---------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----- |\n * | `get_protocol_info` | - | `{ protocolVersion: 1, serverVersion, capabilities, mode: \"classic\"|\"multi\" }` | Answered in BOTH modes; side-effect-free capability probe. |\n * | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there); `provider`/`modelId` applied only on create (resume restores the session's model); params form the immutable launch profile (D8). |\n * | `close_session` | `sessionId` | `{}` | Aborts active work, awaits agent idle + settled persistence, flushes queued events, detaches subscriptions; its response is the LAST record tagged with that handle — no events after (test-pinned). |\n * | `list_sessions` | - | `{ sessions: [{ sessionId, durableSessionId, sessionPath, cwd, name, status }] }` | Includes `opening`/`closing` entries with their status. |\n * | every existing command | + `sessionId` (REQUIRED in multi mode) | unchanged | Routed to that session. |\n *\n * Identities (D6): response-level `sessionId` = opaque routing handle, unique per\n * process epoch, ephemeral (dies with the child). `state.sessionId` = durable\n * JSONL session identity (what a resume cursor stores today). `list_sessions`\n * exposes both. Clients store both, discard routing handles on child exit, verify\n * only durable ids against cursors.\n *\n * Stable error codes (in the response `error` field, machine-matchable):\n * `unknown_session`, `session_closing`, `session_path_in_use`, `missing_session_id`\n * (session-scoped command without `sessionId` in multi mode), `multi_session_disabled`\n * (`open_session` in classic mode), `invalid_path` (relative `sessionPath`/`cwd`),\n * `open_failed: <detail>`.\n *\n * Tagging: every response/event/`extension_ui_request` belonging to a session\n * carries top-level `sessionId` (routing handle). `get_protocol_info`/\n * `list_sessions` responses are untagged. Classic mode: nothing tagged\n * (byte-identical).\n *\n * Ordering guarantee (D9): strict FIFO per session; one total stdout order;\n * cross-session order unspecified; fair round-robin between sessions' queued\n * complete records; NO cross-session batch coalescing (per-session event buffers;\n * the process-wide single-array coalescer in `event-output-buffer.ts` must not\n * merge records of different sessions into one write). Starvation freedom is NOT\n * promised (single pipe); a giant tool record delays others — bounded only by\n * record completion.\n *\n * Duplicate/idempotency: duplicate `open_session` while a path reservation is\n * held → `session_path_in_use`. `close_session` on unknown/already-closed →\n * `unknown_session` error. Request `id`s are client-owned; the server echoes them\n * without dedup.\n *\n * Full prose docs: `packages/coding-agent/docs/rpc.md` (Multi-session mode).\n */\n\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport { envValue } from \"../../core/brand.ts\";\nimport {\n\tflushRawStdout,\n\ttakeOverStdout,\n\twaitForRawStdoutBackpressure,\n\twriteRawStdout,\n} from \"../../core/output-guard.ts\";\nimport { killTrackedDetachedChildren } from \"../../utils/shell.ts\";\nimport { toJsonEvent } from \"../json-event.ts\";\nimport { createRpcConnectionHandler, type RpcConnectionSink } from \"./connection-handler.ts\";\nimport { parseClientCapabilities } from \"./custom-capability.ts\";\nimport { attachJsonlLineReader, MAX_RPC_LINE_CHARACTERS, serializeJsonLine } from \"./jsonl.ts\";\n\n// Re-export types for consumers\nexport type {\n\tRpcCommand,\n\tRpcExtensionUIRequest,\n\tRpcExtensionUIResponse,\n\tRpcResponse,\n\tRpcSessionState,\n} from \"./rpc-types.ts\";\n\n/**\n * Run in RPC mode.\n * Listens for JSON commands on stdin, outputs events and responses on stdout.\n */\nexport async function runRpcMode(runtimeHost: AgentSessionRuntime): Promise<never> {\n\ttakeOverStdout();\n\n\tconst sink: RpcConnectionSink = {\n\t\twriteRaw: (chunk) => {\n\t\t\tconst linearized = chunk\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.filter((line) => line.length > 0)\n\t\t\t\t.map((line) => {\n\t\t\t\t\tconst value = JSON.parse(line) as { type?: string };\n\t\t\t\t\treturn JSON.stringify(value.type === \"message_update\" ? toJsonEvent(value as AgentSessionEvent) : value);\n\t\t\t\t})\n\t\t\t\t.join(\"\\n\");\n\t\t\twriteRawStdout(linearized.length > 0 ? `${linearized}\\n` : \"\");\n\t\t},\n\t\twaitForBackpressure: waitForRawStdoutBackpressure,\n\t};\n\n\t// Client capability flags reach this single-connection stdio host via the\n\t// SENPI_RPC_CLIENT_CAPABILITIES env var (comma-separated). A launcher can set\n\t// it from a client handshake; a plain stdio client that sets nothing gets\n\t// byte-identical default behavior.\n\tconst capabilities = parseClientCapabilities(envValue(\"RPC_CLIENT_CAPABILITIES\"));\n\tconst handler = createRpcConnectionHandler(runtimeHost, sink, { capabilities });\n\n\tlet shuttingDown = false;\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid shutdown(signal === \"SIGHUP\" ? 129 : 143, signal);\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\tlet detachInput = () => {};\n\n\tasync function shutdown(exitCode = 0, signal?: NodeJS.Signals): Promise<never> {\n\t\tif (shuttingDown) {\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t\tshuttingDown = true;\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait handler.dispose();\n\t\tdetachInput();\n\t\tprocess.stdin.pause();\n\t\tif (signal !== \"SIGTERM\") {\n\t\t\tawait flushRawStdout();\n\t\t}\n\t\tprocess.exit(exitCode);\n\t}\n\n\tconst handleInputLine = async (line: string): Promise<void> => {\n\t\tawait handler.handleInputLine(line);\n\t\tif (handler.isShutdownRequested()) {\n\t\t\tawait shutdown();\n\t\t}\n\t};\n\n\tconst onInputEnd = () => {\n\t\tvoid shutdown();\n\t};\n\tprocess.stdin.on(\"end\", onInputEnd);\n\n\tdetachInput = (() => {\n\t\tconst detachJsonl = attachJsonlLineReader(\n\t\t\tprocess.stdin,\n\t\t\t(line) => {\n\t\t\t\tvoid handleInputLine(line);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmaxLineLength: MAX_RPC_LINE_CHARACTERS,\n\t\t\t\tonOversizedLine: () => {\n\t\t\t\t\twriteRawStdout(\n\t\t\t\t\t\tserializeJsonLine({\n\t\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\t\tcommand: \"parse\",\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: `RPC input line exceeds ${MAX_RPC_LINE_CHARACTERS} characters.`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tvoid waitForRawStdoutBackpressure();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\treturn () => {\n\t\t\tdetachJsonl();\n\t\t\tprocess.stdin.off(\"end\", onInputEnd);\n\t\t};\n\t})();\n\n\t// Keep process alive forever\n\treturn new Promise(() => {});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rpc-mode.js","sourceRoot":"","sources":["../../../src/modes/rpc/rpc-mode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RPC mode: Headless operation with JSON stdin/stdout protocol.\n *\n * Used for embedding the agent in other applications.\n * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.\n *\n * Protocol:\n * - Commands: JSON objects with `type` field, optional `id` for correlation\n * - Responses: JSON objects with `type: \"response\"`, `command`, `success`, and optional `data`/`error`\n * - Events: AgentSessionEvent objects streamed as they occur\n * - Extension UI: Extension UI requests are emitted, client responds with extension_ui_response\n *\n * This is the single-connection stdio host. The RPC command loop, extension-UI\n * bridge, and event subscription live in `connection-handler.ts` so the same\n * logic can also serve a caller-owned RPC transport. This file owns exactly the\n * process-level concerns that a per-connection handler must NOT\n * touch: stdout takeover, stdin wiring, signal handlers, and process exit.\n *\n * ── Multi-session mode (`--multi-session`) ─────────────────────────────────\n *\n * Startup: `senpi --mode rpc --multi-session` → NO default session is constructed\n * (no default `AgentSessionRuntime`, no default extension/watcher load). Classic\n * `senpi --mode rpc` is byte-identical to today. Mode is fixed at process start;\n * there is no runtime transition.\n *\n * D1 normative table (multi-session mode):\n *\n * | Command | Params | Success data | Notes |\n * | ---------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------- | ----- |\n * | `get_protocol_info` | - | `{ protocolVersion: 1, serverVersion, capabilities, mode: \"classic\"|\"multi\" }` | Answered in BOTH modes; side-effect-free capability probe. |\n * | `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState, attached?: boolean }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there); `provider`/`modelId` applied only on create (resume restores the session's model); params form the immutable launch profile (D8). |\n * | `close_session` | `sessionId` | `{}` | Aborts active work, awaits agent idle + settled persistence, flushes queued events, detaches subscriptions; its response is the LAST record tagged with that handle — no events after (test-pinned). |\n * | `list_sessions` | - | `{ sessions: [{ sessionId, durableSessionId, sessionPath, cwd, name, status }] }` | Includes `opening`/`closing` entries with their status. |\n * | `get_steering_messages` / `get_follow_up_messages` / `clear_queue` | queue read or clear parameters | host-authoritative queue values | Interactive attach clients must not read bootstrap queues. |\n * | `abort_branch_summary` / `record_bash_result` / `set_label` | narrow mutation payloads | `{}` | Routes interactive runtime mutations to the owning host session. |\n * | every existing command | + `sessionId` (REQUIRED in multi mode) | unchanged | Routed to that session. |\n *\n * Identities (D6): response-level `sessionId` = opaque routing handle, unique per\n * process epoch, ephemeral (dies with the child). `state.sessionId` = durable\n * JSONL session identity (what a resume cursor stores today). `list_sessions`\n * exposes both. Clients store both, discard routing handles on child exit, verify\n * only durable ids against cursors.\n *\n * Stable error codes (in the response `error` field, machine-matchable):\n * `unknown_session`, `session_closing`, `session_path_in_use`, `missing_session_id`\n * (session-scoped command without `sessionId` in multi mode), `multi_session_disabled`\n * (`open_session` in classic mode), `invalid_path` (relative `sessionPath`/`cwd`),\n * `open_failed: <detail>`.\n *\n * Tagging: every response/event/`extension_ui_request` belonging to a session\n * carries top-level `sessionId` (routing handle). `get_protocol_info`/\n * `list_sessions` responses are untagged. Classic mode: nothing tagged\n * (byte-identical).\n *\n * Ordering guarantee (D9): strict FIFO per session; one total stdout order;\n * cross-session order unspecified; fair round-robin between sessions' queued\n * complete records; NO cross-session batch coalescing (per-session event buffers;\n * the process-wide single-array coalescer in `event-output-buffer.ts` must not\n * merge records of different sessions into one write). Starvation freedom is NOT\n * promised (single pipe); a giant tool record delays others — bounded only by\n * record completion.\n *\n * Duplicate/idempotency: duplicate `open_session` while a path reservation is\n * held → `session_path_in_use`. `close_session` on unknown/already-closed →\n * `unknown_session` error. Request `id`s are client-owned; the server echoes them\n * without dedup.\n *\n * Full prose docs: `packages/coding-agent/docs/rpc.md` (Multi-session mode).\n */\n\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.ts\";\nimport { envValue } from \"../../core/brand.ts\";\nimport {\n\tflushRawStdout,\n\ttakeOverStdout,\n\twaitForRawStdoutBackpressure,\n\twriteRawStdout,\n} from \"../../core/output-guard.ts\";\nimport { killTrackedDetachedChildren } from \"../../utils/shell.ts\";\nimport { toJsonEvent } from \"../json-event.ts\";\nimport { createRpcConnectionHandler, type RpcConnectionSink } from \"./connection-handler.ts\";\nimport { parseClientCapabilities } from \"./custom-capability.ts\";\nimport { attachJsonlLineReader, MAX_RPC_LINE_CHARACTERS, serializeJsonLine } from \"./jsonl.ts\";\n\n// Re-export types for consumers\nexport type {\n\tRpcCommand,\n\tRpcExtensionUIRequest,\n\tRpcExtensionUIResponse,\n\tRpcResponse,\n\tRpcSessionState,\n} from \"./rpc-types.ts\";\n\n/**\n * Run in RPC mode.\n * Listens for JSON commands on stdin, outputs events and responses on stdout.\n */\nexport async function runRpcMode(runtimeHost: AgentSessionRuntime): Promise<never> {\n\ttakeOverStdout();\n\n\tconst sink: RpcConnectionSink = {\n\t\twriteRaw: (chunk) => {\n\t\t\tconst linearized = chunk\n\t\t\t\t.split(\"\\n\")\n\t\t\t\t.filter((line) => line.length > 0)\n\t\t\t\t.map((line) => {\n\t\t\t\t\tconst value = JSON.parse(line) as { type?: string };\n\t\t\t\t\treturn JSON.stringify(value.type === \"message_update\" ? toJsonEvent(value as AgentSessionEvent) : value);\n\t\t\t\t})\n\t\t\t\t.join(\"\\n\");\n\t\t\twriteRawStdout(linearized.length > 0 ? `${linearized}\\n` : \"\");\n\t\t},\n\t\twaitForBackpressure: waitForRawStdoutBackpressure,\n\t};\n\n\t// Client capability flags reach this single-connection stdio host via the\n\t// SENPI_RPC_CLIENT_CAPABILITIES env var (comma-separated). A launcher can set\n\t// it from a client handshake; a plain stdio client that sets nothing gets\n\t// byte-identical default behavior.\n\tconst capabilities = parseClientCapabilities(envValue(\"RPC_CLIENT_CAPABILITIES\"));\n\tconst handler = createRpcConnectionHandler(runtimeHost, sink, { capabilities });\n\n\tlet shuttingDown = false;\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid shutdown(signal === \"SIGHUP\" ? 129 : 143, signal);\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\tlet detachInput = () => {};\n\n\tasync function shutdown(exitCode = 0, signal?: NodeJS.Signals): Promise<never> {\n\t\tif (shuttingDown) {\n\t\t\tprocess.exit(exitCode);\n\t\t}\n\t\tshuttingDown = true;\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait handler.dispose();\n\t\tdetachInput();\n\t\tprocess.stdin.pause();\n\t\tif (signal !== \"SIGTERM\") {\n\t\t\tawait flushRawStdout();\n\t\t}\n\t\tprocess.exit(exitCode);\n\t}\n\n\tconst handleInputLine = async (line: string): Promise<void> => {\n\t\tawait handler.handleInputLine(line);\n\t\tif (handler.isShutdownRequested()) {\n\t\t\tawait shutdown();\n\t\t}\n\t};\n\n\tconst onInputEnd = () => {\n\t\tvoid shutdown();\n\t};\n\tprocess.stdin.on(\"end\", onInputEnd);\n\n\tdetachInput = (() => {\n\t\tconst detachJsonl = attachJsonlLineReader(\n\t\t\tprocess.stdin,\n\t\t\t(line) => {\n\t\t\t\tvoid handleInputLine(line);\n\t\t\t},\n\t\t\t{\n\t\t\t\tmaxLineLength: MAX_RPC_LINE_CHARACTERS,\n\t\t\t\tonOversizedLine: () => {\n\t\t\t\t\twriteRawStdout(\n\t\t\t\t\t\tserializeJsonLine({\n\t\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\t\tcommand: \"parse\",\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: `RPC input line exceeds ${MAX_RPC_LINE_CHARACTERS} characters.`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\t\tvoid waitForRawStdoutBackpressure();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\treturn () => {\n\t\t\tdetachJsonl();\n\t\t\tprocess.stdin.off(\"end\", onInputEnd);\n\t\t};\n\t})();\n\n\t// Keep process alive forever\n\treturn new Promise(() => {});\n}\n"]}
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
* Responses and events are emitted as JSON lines on stdout.
|
|
6
6
|
*/
|
|
7
7
|
import type { AgentMessage, ThinkingLevel } from "@earendil-works/pi-agent-core";
|
|
8
|
-
import type { ImageContent, Model } from "@earendil-works/pi-ai";
|
|
8
|
+
import type { ImageContent, Model, ThinkingSelection } from "@earendil-works/pi-ai";
|
|
9
|
+
import type { AgentAbortSource } from "../../core/agent-abort-provenance.ts";
|
|
9
10
|
import type { PromptDisposition, SessionStats } from "../../core/agent-session.ts";
|
|
10
11
|
import type { BashResult } from "../../core/bash-executor.ts";
|
|
11
12
|
import type { CompactionResult } from "../../core/compaction/index.ts";
|
|
12
13
|
import type { ServiceTier } from "../../core/extensions/builtin/service-tier.ts";
|
|
13
|
-
import type {
|
|
14
|
+
import type { ContextUsage } from "../../core/extensions/types.ts";
|
|
15
|
+
import type { SessionEntry, SessionTreeNode, UsageTotals } from "../../core/session-manager.ts";
|
|
14
16
|
import type { SourceInfo } from "../../core/source-info.ts";
|
|
15
17
|
import type { RpcSlashCommand } from "./rpc-command-surface.ts";
|
|
16
18
|
export type { RpcCommandInvocationEvent } from "./rpc-command-invocation.ts";
|
|
@@ -22,22 +24,62 @@ type RpcSessionCommand = {
|
|
|
22
24
|
images?: ImageContent[];
|
|
23
25
|
streamingBehavior?: "steer" | "followUp";
|
|
24
26
|
thinkingLevel?: ThinkingLevel;
|
|
27
|
+
sessionTitlePrompt?: string | false;
|
|
28
|
+
expandPromptTemplates?: boolean;
|
|
29
|
+
} | {
|
|
30
|
+
id?: string;
|
|
31
|
+
type: "send_custom_message";
|
|
32
|
+
customType: string;
|
|
33
|
+
content: unknown;
|
|
34
|
+
display: boolean;
|
|
35
|
+
details?: unknown;
|
|
36
|
+
triggerTurn?: boolean;
|
|
37
|
+
deliverAs?: "steer" | "followUp" | "nextTurn";
|
|
38
|
+
} | {
|
|
39
|
+
id?: string;
|
|
40
|
+
type: "append_user_message";
|
|
41
|
+
content: unknown;
|
|
42
|
+
} | {
|
|
43
|
+
id?: string;
|
|
44
|
+
type: "append_session_entry";
|
|
45
|
+
entry: SessionEntry;
|
|
25
46
|
} | {
|
|
26
47
|
id?: string;
|
|
27
48
|
type: "steer";
|
|
28
49
|
message: string;
|
|
29
50
|
images?: ImageContent[];
|
|
51
|
+
enqueueOrder?: number;
|
|
30
52
|
} | {
|
|
31
53
|
id?: string;
|
|
32
54
|
type: "follow_up";
|
|
33
55
|
message: string;
|
|
34
56
|
images?: ImageContent[];
|
|
57
|
+
enqueueOrder?: number;
|
|
35
58
|
} | {
|
|
36
59
|
id?: string;
|
|
37
60
|
type: "abort";
|
|
61
|
+
} | {
|
|
62
|
+
id?: string;
|
|
63
|
+
type: "abort_compaction";
|
|
64
|
+
} | {
|
|
65
|
+
id?: string;
|
|
66
|
+
type: "reload";
|
|
67
|
+
} | {
|
|
68
|
+
id?: string;
|
|
69
|
+
type: "check_reload_veto";
|
|
38
70
|
} | {
|
|
39
71
|
id?: string;
|
|
40
72
|
type: "clear_queue";
|
|
73
|
+
abortWillFollow?: boolean;
|
|
74
|
+
} | {
|
|
75
|
+
id?: string;
|
|
76
|
+
type: "get_steering_messages";
|
|
77
|
+
} | {
|
|
78
|
+
id?: string;
|
|
79
|
+
type: "get_follow_up_messages";
|
|
80
|
+
} | {
|
|
81
|
+
id?: string;
|
|
82
|
+
type: "abort_branch_summary";
|
|
41
83
|
} | {
|
|
42
84
|
id?: string;
|
|
43
85
|
type: "new_session";
|
|
@@ -50,9 +92,18 @@ type RpcSessionCommand = {
|
|
|
50
92
|
type: "set_model";
|
|
51
93
|
provider: string;
|
|
52
94
|
modelId: string;
|
|
95
|
+
} | {
|
|
96
|
+
id?: string;
|
|
97
|
+
type: "set_favorite_models";
|
|
98
|
+
models: RpcSessionModelEntry[];
|
|
99
|
+
} | {
|
|
100
|
+
id?: string;
|
|
101
|
+
type: "set_scoped_models";
|
|
102
|
+
models: RpcSessionModelEntry[];
|
|
53
103
|
} | {
|
|
54
104
|
id?: string;
|
|
55
105
|
type: "cycle_model";
|
|
106
|
+
direction?: "forward" | "backward";
|
|
56
107
|
} | {
|
|
57
108
|
id?: string;
|
|
58
109
|
type: "get_available_models";
|
|
@@ -101,10 +152,37 @@ type RpcSessionCommand = {
|
|
|
101
152
|
id?: string;
|
|
102
153
|
type: "bash";
|
|
103
154
|
command: string;
|
|
155
|
+
/** Identifies output chunks to the requesting client. */
|
|
156
|
+
bashId?: string;
|
|
157
|
+
excludeFromContext?: boolean;
|
|
158
|
+
executionId?: string;
|
|
159
|
+
operations?: Record<string, unknown>;
|
|
160
|
+
} | {
|
|
161
|
+
id?: string;
|
|
162
|
+
type: "record_bash_result";
|
|
163
|
+
command: string;
|
|
164
|
+
result: BashResult;
|
|
104
165
|
excludeFromContext?: boolean;
|
|
105
166
|
} | {
|
|
106
167
|
id?: string;
|
|
107
168
|
type: "abort_bash";
|
|
169
|
+
} | {
|
|
170
|
+
id?: string;
|
|
171
|
+
type: "cleanup_bash_output";
|
|
172
|
+
path: string;
|
|
173
|
+
} | {
|
|
174
|
+
id?: string;
|
|
175
|
+
type: "set_label";
|
|
176
|
+
entryId: string;
|
|
177
|
+
label?: string;
|
|
178
|
+
} | {
|
|
179
|
+
id?: string;
|
|
180
|
+
type: "navigate_tree";
|
|
181
|
+
targetId: string;
|
|
182
|
+
summarize?: boolean;
|
|
183
|
+
customInstructions?: string;
|
|
184
|
+
replaceInstructions?: boolean;
|
|
185
|
+
label?: string;
|
|
108
186
|
} | {
|
|
109
187
|
id?: string;
|
|
110
188
|
type: "get_session_stats";
|
|
@@ -112,14 +190,21 @@ type RpcSessionCommand = {
|
|
|
112
190
|
id?: string;
|
|
113
191
|
type: "export_html";
|
|
114
192
|
outputPath?: string;
|
|
193
|
+
themeName?: string;
|
|
194
|
+
} | {
|
|
195
|
+
id?: string;
|
|
196
|
+
type: "export_jsonl";
|
|
197
|
+
outputPath?: string;
|
|
115
198
|
} | {
|
|
116
199
|
id?: string;
|
|
117
200
|
type: "switch_session";
|
|
118
201
|
sessionPath: string;
|
|
202
|
+
cwdOverride?: string;
|
|
119
203
|
} | {
|
|
120
204
|
id?: string;
|
|
121
205
|
type: "fork";
|
|
122
206
|
entryId: string;
|
|
207
|
+
position?: "before" | "at";
|
|
123
208
|
} | {
|
|
124
209
|
id?: string;
|
|
125
210
|
type: "clone";
|
|
@@ -140,6 +225,11 @@ type RpcSessionCommand = {
|
|
|
140
225
|
id?: string;
|
|
141
226
|
type: "set_session_name";
|
|
142
227
|
name: string;
|
|
228
|
+
} | {
|
|
229
|
+
id?: string;
|
|
230
|
+
type: "import_jsonl";
|
|
231
|
+
inputPath: string;
|
|
232
|
+
cwdOverride?: string;
|
|
143
233
|
} | {
|
|
144
234
|
id?: string;
|
|
145
235
|
type: "get_messages";
|
|
@@ -260,9 +350,28 @@ export interface RpcLoadedMcpServer {
|
|
|
260
350
|
status: RpcMcpServerStatus;
|
|
261
351
|
authStatus: "unsupported" | "notLoggedIn" | "bearerToken" | "oAuth";
|
|
262
352
|
}
|
|
353
|
+
export interface RpcSessionModelEntry {
|
|
354
|
+
model: Model<any>;
|
|
355
|
+
thinkingLevel?: ThinkingLevel;
|
|
356
|
+
thinkingSelection?: ThinkingSelection;
|
|
357
|
+
serviceTier?: ServiceTier;
|
|
358
|
+
}
|
|
263
359
|
export interface RpcSessionState {
|
|
264
360
|
model?: Model<any>;
|
|
265
361
|
thinkingLevel: ThinkingLevel;
|
|
362
|
+
/**
|
|
363
|
+
* Explicit selector provenance for `thinkingLevel`, absent for SDK-defaulted
|
|
364
|
+
* effective levels. An attached client cannot distinguish "the user chose high"
|
|
365
|
+
* from "high is simply the effective level" without it.
|
|
366
|
+
*/
|
|
367
|
+
thinkingSelection?: ThinkingSelection;
|
|
368
|
+
/**
|
|
369
|
+
* Abort owner of the most recent aborted turn, or the in-flight one while it is
|
|
370
|
+
* still settling. Retained after settle: the live session getter is transient, so a
|
|
371
|
+
* client that snapshots state after the turn ends would otherwise see nothing and
|
|
372
|
+
* fall back to generic wording instead of "Operation aborted".
|
|
373
|
+
*/
|
|
374
|
+
lastAbortSource?: AgentAbortSource;
|
|
266
375
|
/** Service tier the session resolved for the active model, if any. */
|
|
267
376
|
serviceTier?: ServiceTier;
|
|
268
377
|
/** True when the active model is served at the priority ("fast") tier. */
|
|
@@ -274,9 +383,27 @@ export interface RpcSessionState {
|
|
|
274
383
|
sessionFile?: string;
|
|
275
384
|
sessionId: string;
|
|
276
385
|
sessionName?: string;
|
|
386
|
+
cwd: string;
|
|
387
|
+
/** Whether project-scoped settings and resources are trusted by the host. */
|
|
388
|
+
projectTrusted: boolean;
|
|
389
|
+
/** Authoritative entries for setup-only sessions whose deferred file does not exist yet. */
|
|
390
|
+
entries?: SessionEntry[];
|
|
391
|
+
favoriteModels: RpcSessionModelEntry[];
|
|
392
|
+
scopedModels: RpcSessionModelEntry[];
|
|
393
|
+
steering: string[];
|
|
394
|
+
followUp: string[];
|
|
395
|
+
ordered: Array<{
|
|
396
|
+
text: string;
|
|
397
|
+
mode: "steer" | "followUp";
|
|
398
|
+
enqueueOrder: number;
|
|
399
|
+
}>;
|
|
277
400
|
autoCompactionEnabled: boolean;
|
|
278
401
|
messageCount: number;
|
|
279
402
|
pendingMessageCount: number;
|
|
403
|
+
usageTotals: UsageTotals;
|
|
404
|
+
contextUsage?: ContextUsage;
|
|
405
|
+
retryAttempt: number;
|
|
406
|
+
isBashRunning: boolean;
|
|
280
407
|
}
|
|
281
408
|
export type RpcResponse = {
|
|
282
409
|
id?: string;
|
|
@@ -297,6 +424,7 @@ export type RpcResponse = {
|
|
|
297
424
|
data: {
|
|
298
425
|
sessionId: string;
|
|
299
426
|
state: RpcSessionState;
|
|
427
|
+
attached?: boolean;
|
|
300
428
|
};
|
|
301
429
|
} | {
|
|
302
430
|
id?: string;
|
|
@@ -327,6 +455,21 @@ export type RpcResponse = {
|
|
|
327
455
|
data?: {
|
|
328
456
|
disposition?: PromptDisposition;
|
|
329
457
|
};
|
|
458
|
+
} | {
|
|
459
|
+
id?: string;
|
|
460
|
+
type: "response";
|
|
461
|
+
command: "send_custom_message";
|
|
462
|
+
success: true;
|
|
463
|
+
} | {
|
|
464
|
+
id?: string;
|
|
465
|
+
type: "response";
|
|
466
|
+
command: "append_user_message";
|
|
467
|
+
success: true;
|
|
468
|
+
} | {
|
|
469
|
+
id?: string;
|
|
470
|
+
type: "response";
|
|
471
|
+
command: "append_session_entry";
|
|
472
|
+
success: true;
|
|
330
473
|
} | {
|
|
331
474
|
id?: string;
|
|
332
475
|
type: "response";
|
|
@@ -342,6 +485,29 @@ export type RpcResponse = {
|
|
|
342
485
|
type: "response";
|
|
343
486
|
command: "abort";
|
|
344
487
|
success: true;
|
|
488
|
+
} | {
|
|
489
|
+
id?: string;
|
|
490
|
+
type: "response";
|
|
491
|
+
command: "abort_compaction";
|
|
492
|
+
success: true;
|
|
493
|
+
} | {
|
|
494
|
+
id?: string;
|
|
495
|
+
type: "response";
|
|
496
|
+
command: "reload";
|
|
497
|
+
success: true;
|
|
498
|
+
data: {
|
|
499
|
+
cancelled: boolean;
|
|
500
|
+
reason?: string;
|
|
501
|
+
};
|
|
502
|
+
} | {
|
|
503
|
+
id?: string;
|
|
504
|
+
type: "response";
|
|
505
|
+
command: "check_reload_veto";
|
|
506
|
+
success: true;
|
|
507
|
+
data: {
|
|
508
|
+
cancelled: boolean;
|
|
509
|
+
reason?: string;
|
|
510
|
+
};
|
|
345
511
|
} | {
|
|
346
512
|
id?: string;
|
|
347
513
|
type: "response";
|
|
@@ -350,6 +516,11 @@ export type RpcResponse = {
|
|
|
350
516
|
data: {
|
|
351
517
|
steering: string[];
|
|
352
518
|
followUp: string[];
|
|
519
|
+
ordered: Array<{
|
|
520
|
+
text: string;
|
|
521
|
+
mode: "steer" | "followUp";
|
|
522
|
+
enqueueOrder: number;
|
|
523
|
+
}>;
|
|
353
524
|
};
|
|
354
525
|
} | {
|
|
355
526
|
id?: string;
|
|
@@ -370,7 +541,19 @@ export type RpcResponse = {
|
|
|
370
541
|
type: "response";
|
|
371
542
|
command: "set_model";
|
|
372
543
|
success: true;
|
|
373
|
-
data: Model<any
|
|
544
|
+
data: Model<any> & {
|
|
545
|
+
systemPromptName?: string;
|
|
546
|
+
};
|
|
547
|
+
} | {
|
|
548
|
+
id?: string;
|
|
549
|
+
type: "response";
|
|
550
|
+
command: "set_favorite_models";
|
|
551
|
+
success: true;
|
|
552
|
+
} | {
|
|
553
|
+
id?: string;
|
|
554
|
+
type: "response";
|
|
555
|
+
command: "set_scoped_models";
|
|
556
|
+
success: true;
|
|
374
557
|
} | {
|
|
375
558
|
id?: string;
|
|
376
559
|
type: "response";
|
|
@@ -469,6 +652,17 @@ export type RpcResponse = {
|
|
|
469
652
|
command: "bash";
|
|
470
653
|
success: true;
|
|
471
654
|
data: BashResult;
|
|
655
|
+
} | {
|
|
656
|
+
id?: string;
|
|
657
|
+
type: "response";
|
|
658
|
+
command: "navigate_tree";
|
|
659
|
+
success: true;
|
|
660
|
+
data: {
|
|
661
|
+
cancelled: boolean;
|
|
662
|
+
editorText?: string;
|
|
663
|
+
aborted?: boolean;
|
|
664
|
+
summaryEntry?: unknown;
|
|
665
|
+
};
|
|
472
666
|
} | {
|
|
473
667
|
id?: string;
|
|
474
668
|
type: "response";
|
|
@@ -488,6 +682,14 @@ export type RpcResponse = {
|
|
|
488
682
|
data: {
|
|
489
683
|
path: string;
|
|
490
684
|
};
|
|
685
|
+
} | {
|
|
686
|
+
id?: string;
|
|
687
|
+
type: "response";
|
|
688
|
+
command: "export_jsonl";
|
|
689
|
+
success: true;
|
|
690
|
+
data: {
|
|
691
|
+
path: string;
|
|
692
|
+
};
|
|
491
693
|
} | {
|
|
492
694
|
id?: string;
|
|
493
695
|
type: "response";
|
|
@@ -555,6 +757,14 @@ export type RpcResponse = {
|
|
|
555
757
|
type: "response";
|
|
556
758
|
command: "set_session_name";
|
|
557
759
|
success: true;
|
|
760
|
+
} | {
|
|
761
|
+
id?: string;
|
|
762
|
+
type: "response";
|
|
763
|
+
command: "import_jsonl";
|
|
764
|
+
success: true;
|
|
765
|
+
data: {
|
|
766
|
+
cancelled: boolean;
|
|
767
|
+
};
|
|
558
768
|
} | {
|
|
559
769
|
id?: string;
|
|
560
770
|
type: "response";
|
|
@@ -638,6 +848,8 @@ export type RpcResponse = {
|
|
|
638
848
|
command: string;
|
|
639
849
|
success: false;
|
|
640
850
|
error: string;
|
|
851
|
+
errorCode?: string;
|
|
852
|
+
errorData?: unknown;
|
|
641
853
|
};
|
|
642
854
|
/** Emitted when an extension needs user input */
|
|
643
855
|
export type RpcExtensionUIRequest = {
|
|
@@ -725,6 +937,12 @@ export type RpcExtensionUIResponse = {
|
|
|
725
937
|
export interface RpcThinkingLevelChangedEvent {
|
|
726
938
|
type: "thinking_level_changed";
|
|
727
939
|
level: ThinkingLevel;
|
|
940
|
+
/**
|
|
941
|
+
* Selector provenance in force after the change; absent when the level is an
|
|
942
|
+
* SDK-defaulted effective level rather than an explicit choice. Additive: an old
|
|
943
|
+
* client that does not know the field ignores it.
|
|
944
|
+
*/
|
|
945
|
+
thinkingSelection?: ThinkingSelection;
|
|
728
946
|
}
|
|
729
947
|
export interface RpcHighReasoningWarningEvent {
|
|
730
948
|
type: "high_reasoning_warning";
|
|
@@ -762,6 +980,8 @@ export interface RpcModelChangedEvent {
|
|
|
762
980
|
thinkingLevel: ThinkingLevel;
|
|
763
981
|
/** Why the model changed: "set", "cycle", "restore", "fallback", or "fallback-revert". */
|
|
764
982
|
source: string;
|
|
983
|
+
/** Selector provenance for `thinkingLevel` after the switch, when one was explicit. */
|
|
984
|
+
thinkingSelection?: ThinkingSelection;
|
|
765
985
|
}
|
|
766
986
|
/** Emitted when the effective service tier or fast-mode state of the session changes. */
|
|
767
987
|
export interface RpcServiceTierChangedEvent {
|
|
@@ -769,6 +989,24 @@ export interface RpcServiceTierChangedEvent {
|
|
|
769
989
|
tier?: ServiceTier;
|
|
770
990
|
fastMode: boolean;
|
|
771
991
|
}
|
|
992
|
+
/**
|
|
993
|
+
* Emitted after the host swapped the live session behind this connection (new session,
|
|
994
|
+
* fork, or switch), carrying the new authoritative identity.
|
|
995
|
+
*
|
|
996
|
+
* A replacement can be initiated by ANY attached client. Without this event the other
|
|
997
|
+
* attached clients keep their stale identity and keep routing replacement-dependent
|
|
998
|
+
* actions at the session that no longer exists. Additive: an old client that does not
|
|
999
|
+
* know the type filters it out.
|
|
1000
|
+
*/
|
|
1001
|
+
export interface RpcSessionReplacedEvent {
|
|
1002
|
+
type: "session_replaced";
|
|
1003
|
+
/** Durable session id of the session now bound to this connection. */
|
|
1004
|
+
sessionId: string;
|
|
1005
|
+
/** Session file backing the new session, absent for a deferred setup-only session. */
|
|
1006
|
+
sessionFile?: string;
|
|
1007
|
+
cwd: string;
|
|
1008
|
+
sessionName?: string;
|
|
1009
|
+
}
|
|
772
1010
|
/** Emitted after the loaded skill, extension, or MCP inventory changes. */
|
|
773
1011
|
export interface RpcLoadedSurfacesChangedEvent {
|
|
774
1012
|
type: "loaded_surfaces_changed";
|