@getpaseo/server 0.1.78 → 0.1.80

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.
Files changed (192) hide show
  1. package/dist/scripts/dev-runner.js +1 -13
  2. package/dist/scripts/dev-runner.js.map +1 -1
  3. package/dist/scripts/supervisor-entrypoint.js +17 -3
  4. package/dist/scripts/supervisor-entrypoint.js.map +1 -1
  5. package/dist/server/client/daemon-client.d.ts +34 -2
  6. package/dist/server/client/daemon-client.d.ts.map +1 -1
  7. package/dist/server/client/daemon-client.js +138 -1
  8. package/dist/server/client/daemon-client.js.map +1 -1
  9. package/dist/server/server/agent/agent-manager.d.ts +6 -0
  10. package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
  11. package/dist/server/server/agent/agent-manager.js +40 -5
  12. package/dist/server/server/agent/agent-manager.js.map +1 -1
  13. package/dist/server/server/agent/agent-metadata-generator.js +1 -1
  14. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
  15. package/dist/server/server/agent/agent-sdk-types.d.ts +5 -0
  16. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
  17. package/dist/server/server/agent/agent-storage.d.ts +3 -0
  18. package/dist/server/server/agent/agent-storage.d.ts.map +1 -1
  19. package/dist/server/server/agent/agent-storage.js +58 -22
  20. package/dist/server/server/agent/agent-storage.js.map +1 -1
  21. package/dist/server/server/agent/create-agent-lifecycle-dispatch.d.ts +51 -0
  22. package/dist/server/server/agent/create-agent-lifecycle-dispatch.d.ts.map +1 -0
  23. package/dist/server/server/agent/create-agent-lifecycle-dispatch.js +140 -0
  24. package/dist/server/server/agent/create-agent-lifecycle-dispatch.js.map +1 -0
  25. package/dist/server/server/agent/import-sessions.js +2 -2
  26. package/dist/server/server/agent/import-sessions.js.map +1 -1
  27. package/dist/server/server/agent/mcp-server.d.ts.map +1 -1
  28. package/dist/server/server/agent/mcp-server.js +202 -99
  29. package/dist/server/server/agent/mcp-server.js.map +1 -1
  30. package/dist/server/server/agent/provider-registry.js +2 -2
  31. package/dist/server/server/agent/provider-registry.js.map +1 -1
  32. package/dist/server/server/agent/providers/acp-agent.d.ts +3 -0
  33. package/dist/server/server/agent/providers/acp-agent.d.ts.map +1 -1
  34. package/dist/server/server/agent/providers/acp-agent.js +44 -4
  35. package/dist/server/server/agent/providers/acp-agent.js.map +1 -1
  36. package/dist/server/server/agent/providers/claude/agent.d.ts.map +1 -1
  37. package/dist/server/server/agent/providers/claude/agent.js +17 -9
  38. package/dist/server/server/agent/providers/claude/agent.js.map +1 -1
  39. package/dist/server/server/agent/providers/claude/project-dir.d.ts +5 -0
  40. package/dist/server/server/agent/providers/claude/project-dir.d.ts.map +1 -0
  41. package/dist/server/server/agent/providers/claude/project-dir.js +40 -0
  42. package/dist/server/server/agent/providers/claude/project-dir.js.map +1 -0
  43. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -1
  44. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +13 -2
  45. package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
  46. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +4 -0
  47. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
  48. package/dist/server/server/agent/providers/codex-app-server-agent.js +57 -19
  49. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
  50. package/dist/server/server/agent/providers/cursor-acp-agent.d.ts.map +1 -1
  51. package/dist/server/server/agent/providers/cursor-acp-agent.js +11 -1
  52. package/dist/server/server/agent/providers/cursor-acp-agent.js.map +1 -1
  53. package/dist/server/server/agent/providers/generic-acp-agent.d.ts +2 -0
  54. package/dist/server/server/agent/providers/generic-acp-agent.d.ts.map +1 -1
  55. package/dist/server/server/agent/providers/generic-acp-agent.js +2 -0
  56. package/dist/server/server/agent/providers/generic-acp-agent.js.map +1 -1
  57. package/dist/server/server/agent/providers/opencode/runtime.d.ts +1 -0
  58. package/dist/server/server/agent/providers/opencode/runtime.d.ts.map +1 -1
  59. package/dist/server/server/agent/providers/opencode/runtime.js.map +1 -1
  60. package/dist/server/server/agent/providers/opencode/server-manager.d.ts +4 -0
  61. package/dist/server/server/agent/providers/opencode/server-manager.d.ts.map +1 -1
  62. package/dist/server/server/agent/providers/opencode/server-manager.js +18 -2
  63. package/dist/server/server/agent/providers/opencode/server-manager.js.map +1 -1
  64. package/dist/server/server/agent/providers/opencode/test-server-manager.d.ts +2 -0
  65. package/dist/server/server/agent/providers/opencode/test-server-manager.d.ts.map +1 -1
  66. package/dist/server/server/agent/providers/opencode/test-server-manager.js +1 -0
  67. package/dist/server/server/agent/providers/opencode/test-server-manager.js.map +1 -1
  68. package/dist/server/server/agent/providers/opencode/test-utils/test-opencode-runtime.d.ts +2 -0
  69. package/dist/server/server/agent/providers/opencode/test-utils/test-opencode-runtime.d.ts.map +1 -1
  70. package/dist/server/server/agent/providers/opencode/test-utils/test-opencode-runtime.js +1 -1
  71. package/dist/server/server/agent/providers/opencode/test-utils/test-opencode-runtime.js.map +1 -1
  72. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
  73. package/dist/server/server/agent/providers/opencode-agent.js +7 -2
  74. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
  75. package/dist/server/server/agent/providers/{pi-direct-agent.d.ts → pi/agent.d.ts} +38 -29
  76. package/dist/server/server/agent/providers/pi/agent.d.ts.map +1 -0
  77. package/dist/server/server/agent/providers/pi/agent.js +829 -0
  78. package/dist/server/server/agent/providers/pi/agent.js.map +1 -0
  79. package/dist/server/server/agent/providers/pi/cli-runtime.d.ts +18 -0
  80. package/dist/server/server/agent/providers/pi/cli-runtime.d.ts.map +1 -0
  81. package/dist/server/server/agent/providers/pi/cli-runtime.js +218 -0
  82. package/dist/server/server/agent/providers/pi/cli-runtime.js.map +1 -0
  83. package/dist/server/server/agent/providers/pi/history-mapper.d.ts +5 -0
  84. package/dist/server/server/agent/providers/pi/history-mapper.d.ts.map +1 -0
  85. package/dist/server/server/agent/providers/pi/history-mapper.js +139 -0
  86. package/dist/server/server/agent/providers/pi/history-mapper.js.map +1 -0
  87. package/dist/server/server/agent/providers/pi/rpc-types.d.ts +185 -0
  88. package/dist/server/server/agent/providers/pi/rpc-types.d.ts.map +1 -0
  89. package/dist/server/server/agent/providers/pi/rpc-types.js +2 -0
  90. package/dist/server/server/agent/providers/pi/rpc-types.js.map +1 -0
  91. package/dist/server/server/agent/providers/pi/runtime.d.ts +48 -0
  92. package/dist/server/server/agent/providers/pi/runtime.d.ts.map +1 -0
  93. package/dist/server/server/agent/providers/pi/runtime.js +52 -0
  94. package/dist/server/server/agent/providers/pi/runtime.js.map +1 -0
  95. package/dist/server/server/agent/providers/pi/session-descriptor.d.ts +10 -0
  96. package/dist/server/server/agent/providers/pi/session-descriptor.d.ts.map +1 -0
  97. package/dist/server/server/agent/providers/pi/session-descriptor.js +300 -0
  98. package/dist/server/server/agent/providers/pi/session-descriptor.js.map +1 -0
  99. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.d.ts +52 -0
  100. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.d.ts.map +1 -0
  101. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.js +109 -0
  102. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.js.map +1 -0
  103. package/dist/server/server/agent/providers/pi/tool-call-mapper.d.ts +112 -0
  104. package/dist/server/server/agent/providers/pi/tool-call-mapper.d.ts.map +1 -0
  105. package/dist/server/server/agent/providers/pi/tool-call-mapper.js +284 -0
  106. package/dist/server/server/agent/providers/pi/tool-call-mapper.js.map +1 -0
  107. package/dist/server/server/agent/system-prompt.d.ts +2 -0
  108. package/dist/server/server/agent/system-prompt.d.ts.map +1 -0
  109. package/dist/server/server/agent/system-prompt.js +8 -0
  110. package/dist/server/server/agent/system-prompt.js.map +1 -0
  111. package/dist/server/server/bootstrap.d.ts +1 -0
  112. package/dist/server/server/bootstrap.d.ts.map +1 -1
  113. package/dist/server/server/bootstrap.js +15 -1
  114. package/dist/server/server/bootstrap.js.map +1 -1
  115. package/dist/server/server/config.d.ts.map +1 -1
  116. package/dist/server/server/config.js +6 -1
  117. package/dist/server/server/config.js.map +1 -1
  118. package/dist/server/server/daemon-config-store.js +1 -0
  119. package/dist/server/server/daemon-config-store.js.map +1 -1
  120. package/dist/server/server/persisted-config.d.ts +51 -44
  121. package/dist/server/server/persisted-config.d.ts.map +1 -1
  122. package/dist/server/server/persisted-config.js +1 -0
  123. package/dist/server/server/persisted-config.js.map +1 -1
  124. package/dist/server/server/pid-lock.d.ts +2 -2
  125. package/dist/server/server/session.d.ts +21 -0
  126. package/dist/server/server/session.d.ts.map +1 -1
  127. package/dist/server/server/session.js +232 -10
  128. package/dist/server/server/session.js.map +1 -1
  129. package/dist/server/server/websocket-server.d.ts +11 -1
  130. package/dist/server/server/websocket-server.d.ts.map +1 -1
  131. package/dist/server/server/websocket-server.js +10 -2
  132. package/dist/server/server/websocket-server.js.map +1 -1
  133. package/dist/server/server/workspace-git-service.d.ts +5 -1
  134. package/dist/server/server/workspace-git-service.d.ts.map +1 -1
  135. package/dist/server/server/workspace-git-service.js +122 -62
  136. package/dist/server/server/workspace-git-service.js.map +1 -1
  137. package/dist/server/shared/importable-providers.d.ts +1 -1
  138. package/dist/server/shared/importable-providers.d.ts.map +1 -1
  139. package/dist/server/shared/importable-providers.js +1 -1
  140. package/dist/server/shared/importable-providers.js.map +1 -1
  141. package/dist/server/shared/messages.d.ts +2187 -24
  142. package/dist/server/shared/messages.d.ts.map +1 -1
  143. package/dist/server/shared/messages.js +108 -0
  144. package/dist/server/shared/messages.js.map +1 -1
  145. package/dist/server/terminal/terminal-manager.d.ts +1 -0
  146. package/dist/server/terminal/terminal-manager.d.ts.map +1 -1
  147. package/dist/server/terminal/terminal-manager.js +8 -0
  148. package/dist/server/terminal/terminal-manager.js.map +1 -1
  149. package/dist/server/terminal/terminal-session-controller.d.ts +1 -0
  150. package/dist/server/terminal/terminal-session-controller.d.ts.map +1 -1
  151. package/dist/server/terminal/terminal-session-controller.js +26 -0
  152. package/dist/server/terminal/terminal-session-controller.js.map +1 -1
  153. package/dist/server/terminal/terminal.d.ts +1 -0
  154. package/dist/server/terminal/terminal.d.ts.map +1 -1
  155. package/dist/server/terminal/terminal.js +32 -10
  156. package/dist/server/terminal/terminal.js.map +1 -1
  157. package/dist/server/terminal/worker-terminal-manager.d.ts.map +1 -1
  158. package/dist/server/terminal/worker-terminal-manager.js +18 -0
  159. package/dist/server/terminal/worker-terminal-manager.js.map +1 -1
  160. package/dist/server/utils/branch-slug.d.ts +14 -0
  161. package/dist/server/utils/branch-slug.d.ts.map +1 -0
  162. package/dist/server/utils/branch-slug.js +49 -0
  163. package/dist/server/utils/branch-slug.js.map +1 -0
  164. package/dist/server/utils/directory-suggestions.js +2 -2
  165. package/dist/server/utils/directory-suggestions.js.map +1 -1
  166. package/dist/server/utils/path.d.ts +1 -0
  167. package/dist/server/utils/path.d.ts.map +1 -1
  168. package/dist/server/utils/path.js +31 -0
  169. package/dist/server/utils/path.js.map +1 -1
  170. package/dist/server/utils/run-git-command.d.ts.map +1 -1
  171. package/dist/server/utils/run-git-command.js +3 -1
  172. package/dist/server/utils/run-git-command.js.map +1 -1
  173. package/dist/server/utils/worktree.d.ts +1 -12
  174. package/dist/server/utils/worktree.d.ts.map +1 -1
  175. package/dist/server/utils/worktree.js +2 -52
  176. package/dist/server/utils/worktree.js.map +1 -1
  177. package/dist/src/server/persisted-config.js +1 -0
  178. package/dist/src/server/persisted-config.js.map +1 -1
  179. package/dist/src/shared/messages.js +108 -0
  180. package/dist/src/shared/messages.js.map +1 -1
  181. package/package.json +13 -11
  182. package/dist/server/server/agent/orchestrator-instructions.d.ts +0 -7
  183. package/dist/server/server/agent/orchestrator-instructions.d.ts.map +0 -1
  184. package/dist/server/server/agent/orchestrator-instructions.js +0 -51
  185. package/dist/server/server/agent/orchestrator-instructions.js.map +0 -1
  186. package/dist/server/server/agent/providers/pi-direct-agent.d.ts.map +0 -1
  187. package/dist/server/server/agent/providers/pi-direct-agent.js +0 -1151
  188. package/dist/server/server/agent/providers/pi-direct-agent.js.map +0 -1
  189. package/dist/server/server/agent/providers/pi-session-recovery-policy.d.ts +0 -22
  190. package/dist/server/server/agent/providers/pi-session-recovery-policy.d.ts.map +0 -1
  191. package/dist/server/server/agent/providers/pi-session-recovery-policy.js +0 -51
  192. package/dist/server/server/agent/providers/pi-session-recovery-policy.js.map +0 -1
@@ -0,0 +1,829 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
+ import { homedir, tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { runProviderTurn } from "../provider-runner.js";
6
+ import { renderPromptAttachmentAsText } from "../../prompt-attachments.js";
7
+ import { composeSystemPromptParts } from "../../system-prompt.js";
8
+ import { findExecutable } from "../../../../utils/executable.js";
9
+ import { formatDiagnosticStatus, formatProviderDiagnostic, formatProviderDiagnosticError, resolveBinaryVersion, toDiagnosticErrorMessage, } from "../diagnostic-utils.js";
10
+ import { streamPiHistory } from "./history-mapper.js";
11
+ import { PiCliRuntime } from "./cli-runtime.js";
12
+ import { listPiPersistedAgents } from "./session-descriptor.js";
13
+ import { mapToolDetail, parseToolArgs, parseToolResult, resolveToolCallName, } from "./tool-call-mapper.js";
14
+ const PI_PROVIDER = "pi";
15
+ const DEFAULT_PI_THINKING_LEVEL = "medium";
16
+ const PI_BINARY_COMMAND = process.env.PI_COMMAND ?? process.env.PI_ACP_PI_COMMAND ?? "pi";
17
+ const PI_CAPABILITIES = {
18
+ supportsStreaming: true,
19
+ supportsSessionPersistence: true,
20
+ supportsDynamicModes: true,
21
+ supportsMcpServers: false,
22
+ supportsReasoningStream: true,
23
+ supportsToolInvocations: true,
24
+ };
25
+ const PI_THINKING_OPTIONS = [
26
+ { id: "off", label: "Off", description: "No extra reasoning" },
27
+ { id: "minimal", label: "Minimal", description: "Light reasoning" },
28
+ { id: "low", label: "Low", description: "Faster reasoning" },
29
+ { id: "medium", label: "Medium", description: "Balanced reasoning", isDefault: true },
30
+ { id: "high", label: "High", description: "Deeper reasoning" },
31
+ { id: "xhigh", label: "XHigh", description: "Maximum reasoning" },
32
+ ];
33
+ function normalizePiModelLabel(label) {
34
+ return label.trim().replace(/[_\s]+/g, " ");
35
+ }
36
+ export function transformPiModels(models) {
37
+ return models.map((model) => {
38
+ if (!model.label.includes("/")) {
39
+ return model;
40
+ }
41
+ const segments = model.label.split("/").filter((segment) => segment.length > 0);
42
+ const rawLabel = segments.at(-1);
43
+ if (!rawLabel) {
44
+ return model;
45
+ }
46
+ return {
47
+ ...model,
48
+ label: normalizePiModelLabel(rawLabel),
49
+ description: model.description ?? model.label,
50
+ };
51
+ });
52
+ }
53
+ function isPiThinkingLevel(value) {
54
+ return (value === "off" ||
55
+ value === "minimal" ||
56
+ value === "low" ||
57
+ value === "medium" ||
58
+ value === "high" ||
59
+ value === "xhigh");
60
+ }
61
+ function normalizePiThinkingOption(value) {
62
+ if (!value) {
63
+ return null;
64
+ }
65
+ return isPiThinkingLevel(value) ? value : null;
66
+ }
67
+ function mapThinkingOption(option) {
68
+ const mappedOption = {
69
+ id: option.id,
70
+ label: option.label,
71
+ description: option.description,
72
+ };
73
+ if (option.isDefault) {
74
+ return {
75
+ ...mappedOption,
76
+ isDefault: true,
77
+ };
78
+ }
79
+ return mappedOption;
80
+ }
81
+ function toAgentUsage(stats) {
82
+ const inputTokens = stats.tokens?.input ?? 0;
83
+ const cachedInputTokens = stats.tokens?.cacheRead ?? 0;
84
+ const outputTokens = stats.tokens?.output ?? 0;
85
+ const totalCostUsd = stats.cost ?? 0;
86
+ const contextWindowMaxTokens = stats.contextUsage?.contextWindow ?? undefined;
87
+ const contextWindowUsedTokens = stats.contextUsage?.tokens ?? undefined;
88
+ if (inputTokens === 0 &&
89
+ cachedInputTokens === 0 &&
90
+ outputTokens === 0 &&
91
+ totalCostUsd === 0 &&
92
+ contextWindowMaxTokens === undefined &&
93
+ contextWindowUsedTokens === undefined) {
94
+ return undefined;
95
+ }
96
+ return {
97
+ inputTokens,
98
+ cachedInputTokens,
99
+ outputTokens,
100
+ totalCostUsd,
101
+ ...(typeof contextWindowMaxTokens === "number" ? { contextWindowMaxTokens } : {}),
102
+ ...(typeof contextWindowUsedTokens === "number" ? { contextWindowUsedTokens } : {}),
103
+ };
104
+ }
105
+ function convertPromptInput(prompt) {
106
+ if (typeof prompt === "string") {
107
+ return { text: prompt };
108
+ }
109
+ const textParts = [];
110
+ const images = [];
111
+ for (const block of prompt) {
112
+ if (block.type === "text") {
113
+ textParts.push(block.text);
114
+ continue;
115
+ }
116
+ if (block.type === "image") {
117
+ images.push({
118
+ type: "image",
119
+ data: block.data,
120
+ mimeType: block.mimeType,
121
+ });
122
+ continue;
123
+ }
124
+ textParts.push(renderPromptAttachmentAsText(block));
125
+ }
126
+ const payload = {
127
+ text: textParts.join("\n\n"),
128
+ };
129
+ if (images.length > 0) {
130
+ payload.images = images;
131
+ }
132
+ return payload;
133
+ }
134
+ function parseModelReference(modelId) {
135
+ if (!modelId) {
136
+ return null;
137
+ }
138
+ if (modelId.includes("/")) {
139
+ const [provider, ...rest] = modelId.split("/");
140
+ const id = rest.join("/");
141
+ if (provider && id) {
142
+ return { provider, id };
143
+ }
144
+ }
145
+ if (modelId.includes(":")) {
146
+ const [provider, ...rest] = modelId.split(":");
147
+ const id = rest.join(":");
148
+ if (provider && id) {
149
+ return { provider, id };
150
+ }
151
+ }
152
+ return { id: modelId };
153
+ }
154
+ function parsePersistenceMetadata(metadata) {
155
+ if (!metadata) {
156
+ return {};
157
+ }
158
+ return {
159
+ ...(typeof metadata.cwd === "string" ? { cwd: metadata.cwd } : {}),
160
+ ...(typeof metadata.model === "string" ? { model: metadata.model } : {}),
161
+ ...(typeof metadata.thinkingOptionId === "string"
162
+ ? { thinkingOptionId: metadata.thinkingOptionId }
163
+ : {}),
164
+ ...(typeof metadata.systemPrompt === "string" ? { systemPrompt: metadata.systemPrompt } : {}),
165
+ };
166
+ }
167
+ function buildResumeConfig(metadata, overrides) {
168
+ const overrideConfig = overrides ?? {};
169
+ const cwd = overrideConfig.cwd ?? metadata.cwd ?? process.cwd();
170
+ const model = overrideConfig.model ?? metadata.model;
171
+ const thinkingOptionId = overrideConfig.thinkingOptionId ?? metadata.thinkingOptionId;
172
+ return {
173
+ cwd,
174
+ model,
175
+ thinkingOptionId,
176
+ config: {
177
+ ...overrideConfig,
178
+ provider: PI_PROVIDER,
179
+ cwd,
180
+ model,
181
+ thinkingOptionId,
182
+ systemPrompt: overrideConfig.systemPrompt ?? metadata.systemPrompt,
183
+ },
184
+ };
185
+ }
186
+ function toPiMcpConfig(config) {
187
+ if (config.type === "stdio") {
188
+ return {
189
+ command: config.command,
190
+ ...(config.args ? { args: config.args } : {}),
191
+ ...(config.env ? { env: config.env } : {}),
192
+ };
193
+ }
194
+ return {
195
+ url: config.url,
196
+ ...(config.headers ? { headers: config.headers } : {}),
197
+ auth: false,
198
+ oauth: false,
199
+ };
200
+ }
201
+ function createPiMcpConfigFile(servers) {
202
+ const dir = mkdtempSync(join(tmpdir(), "paseo-pi-mcp-"));
203
+ const filePath = join(dir, "mcp.json");
204
+ const mcpServers = {};
205
+ for (const [name, serverConfig] of Object.entries(servers)) {
206
+ mcpServers[name] = toPiMcpConfig(serverConfig);
207
+ }
208
+ writeFileSync(filePath, `${JSON.stringify({ mcpServers }, null, 2)}\n`, "utf8");
209
+ return {
210
+ path: filePath,
211
+ cleanup: () => rmSync(dir, { recursive: true, force: true }),
212
+ };
213
+ }
214
+ function isPiMcpAdapterCommand(command) {
215
+ if (command.source !== "extension" || !/^mcp(?::\d+)?$/.test(command.name)) {
216
+ return false;
217
+ }
218
+ if (!command.sourceInfo) {
219
+ return true;
220
+ }
221
+ return JSON.stringify(command.sourceInfo).includes("pi-mcp-adapter");
222
+ }
223
+ function withPiMcpCapability(supportsMcpServers) {
224
+ return {
225
+ ...PI_CAPABILITIES,
226
+ supportsMcpServers,
227
+ };
228
+ }
229
+ function isPiRequestAbortError(error) {
230
+ if (error instanceof Error && error.name === "AbortError") {
231
+ return true;
232
+ }
233
+ return /\brequest was aborted\b|\babort(ed)?\b/i.test(toDiagnosticErrorMessage(error));
234
+ }
235
+ function resolveThinkingOptionId(cachedThinkingOptionId, sessionThinkingLevel) {
236
+ const currentThinking = cachedThinkingOptionId ?? sessionThinkingLevel;
237
+ return normalizePiThinkingOption(currentThinking);
238
+ }
239
+ function modelToId(model) {
240
+ return model?.provider && model.id ? `${model.provider}/${model.id}` : null;
241
+ }
242
+ function latestPiErrorMessage(messages) {
243
+ const latestAssistant = messages.findLast((message) => message.role === "assistant");
244
+ return latestAssistant && "errorMessage" in latestAssistant
245
+ ? (latestAssistant.errorMessage ?? null)
246
+ : null;
247
+ }
248
+ function mapPiModel(model) {
249
+ return {
250
+ provider: PI_PROVIDER,
251
+ id: `${model.provider}/${model.id}`,
252
+ label: `${model.provider}/${model.name ?? model.id}`,
253
+ description: `${model.provider}/${model.id}`,
254
+ metadata: {
255
+ provider: model.provider,
256
+ modelId: model.id,
257
+ },
258
+ thinkingOptions: model.reasoning ? PI_THINKING_OPTIONS.map(mapThinkingOption) : undefined,
259
+ defaultThinkingOptionId: model.reasoning ? DEFAULT_PI_THINKING_LEVEL : undefined,
260
+ };
261
+ }
262
+ function createRuntime(logger, runtimeSettings) {
263
+ return new PiCliRuntime({ logger, runtimeSettings });
264
+ }
265
+ export class PiRpcAgentSession {
266
+ constructor(options) {
267
+ this.provider = PI_PROVIDER;
268
+ this.subscribers = new Set();
269
+ this.activeToolCalls = new Map();
270
+ this.activeTurnId = null;
271
+ this.closed = false;
272
+ this.runtimeSession = options.runtimeSession;
273
+ this.config = options.config;
274
+ this.state = options.initialState;
275
+ this.capabilities = options.capabilities;
276
+ this.cleanup = options.cleanup;
277
+ this.lastKnownThinkingOptionId =
278
+ normalizePiThinkingOption(options.config.thinkingOptionId) ??
279
+ this.state.thinkingLevel ??
280
+ null;
281
+ this.runtimeSession.onEvent((event) => {
282
+ this.handleRuntimeEvent(event);
283
+ });
284
+ }
285
+ get id() {
286
+ return this.state.sessionId;
287
+ }
288
+ async run(prompt, options) {
289
+ return runProviderTurn({
290
+ prompt,
291
+ runOptions: options,
292
+ startTurn: (p, o) => this.startTurn(p, o),
293
+ subscribe: (callback) => this.subscribe(callback),
294
+ getSessionId: () => this.state.sessionId,
295
+ reduceFinalText: ({ current, item }) => item.type === "assistant_message" ? `${current}${item.text}` : current,
296
+ });
297
+ }
298
+ async startTurn(prompt, _options) {
299
+ if (this.activeTurnId) {
300
+ throw new Error("A Pi turn is already active");
301
+ }
302
+ const payload = convertPromptInput(prompt);
303
+ const turnId = randomUUID();
304
+ this.activeTurnId = turnId;
305
+ void this.runtimeSession.prompt(payload.text, payload.images).catch((error) => {
306
+ const failedTurnId = this.activeTurnId ?? turnId;
307
+ this.activeTurnId = null;
308
+ if (isPiRequestAbortError(error)) {
309
+ this.emit({
310
+ type: "turn_canceled",
311
+ provider: PI_PROVIDER,
312
+ turnId: failedTurnId,
313
+ reason: toDiagnosticErrorMessage(error),
314
+ });
315
+ return;
316
+ }
317
+ this.emit({
318
+ type: "turn_failed",
319
+ provider: PI_PROVIDER,
320
+ turnId: failedTurnId,
321
+ error: toDiagnosticErrorMessage(error),
322
+ });
323
+ });
324
+ return { turnId };
325
+ }
326
+ subscribe(callback) {
327
+ this.subscribers.add(callback);
328
+ return () => {
329
+ this.subscribers.delete(callback);
330
+ };
331
+ }
332
+ async *streamHistory() {
333
+ yield* streamPiHistory(PI_PROVIDER, await this.runtimeSession.getMessages());
334
+ }
335
+ async getRuntimeInfo() {
336
+ await this.refreshState();
337
+ return {
338
+ provider: PI_PROVIDER,
339
+ sessionId: this.state.sessionId,
340
+ model: modelToId(this.state.model),
341
+ thinkingOptionId: resolveThinkingOptionId(this.lastKnownThinkingOptionId, this.state.thinkingLevel),
342
+ modeId: null,
343
+ };
344
+ }
345
+ async getAvailableModes() {
346
+ return [];
347
+ }
348
+ async getCurrentMode() {
349
+ return null;
350
+ }
351
+ async setMode(modeId) {
352
+ void modeId;
353
+ throw new Error("Pi does not expose selectable modes");
354
+ }
355
+ getPendingPermissions() {
356
+ return [];
357
+ }
358
+ async respondToPermission(requestId, response) {
359
+ void requestId;
360
+ void response;
361
+ }
362
+ describePersistence() {
363
+ return {
364
+ provider: PI_PROVIDER,
365
+ sessionId: this.state.sessionId,
366
+ nativeHandle: this.state.sessionFile,
367
+ metadata: {
368
+ cwd: this.config.cwd,
369
+ ...(this.config.model ? { model: this.config.model } : {}),
370
+ ...(this.config.thinkingOptionId ? { thinkingOptionId: this.config.thinkingOptionId } : {}),
371
+ },
372
+ };
373
+ }
374
+ async interrupt() {
375
+ await this.runtimeSession.abort();
376
+ }
377
+ async close() {
378
+ if (this.closed) {
379
+ return;
380
+ }
381
+ this.closed = true;
382
+ try {
383
+ await this.runtimeSession.close();
384
+ }
385
+ finally {
386
+ this.cleanup?.();
387
+ }
388
+ }
389
+ async listCommands() {
390
+ const commands = await this.runtimeSession.getCommands();
391
+ return commands.map((command) => ({
392
+ name: command.name,
393
+ description: command.description ?? command.source,
394
+ argumentHint: "",
395
+ }));
396
+ }
397
+ async setModel(modelId) {
398
+ const parsedReference = parseModelReference(modelId);
399
+ if (!parsedReference) {
400
+ return;
401
+ }
402
+ if (!parsedReference.provider) {
403
+ throw new Error(`Pi model id must include a provider: ${modelId}`);
404
+ }
405
+ const model = await this.runtimeSession.setModel(parsedReference.provider, parsedReference.id);
406
+ this.state = {
407
+ ...this.state,
408
+ model,
409
+ };
410
+ this.config.model = `${model.provider}/${model.id}`;
411
+ }
412
+ async setThinkingOption(thinkingOptionId) {
413
+ const thinkingLevel = normalizePiThinkingOption(thinkingOptionId) ?? DEFAULT_PI_THINKING_LEVEL;
414
+ await this.runtimeSession.setThinkingLevel(thinkingLevel);
415
+ this.lastKnownThinkingOptionId = thinkingLevel;
416
+ this.config.thinkingOptionId = thinkingLevel;
417
+ this.state = {
418
+ ...this.state,
419
+ thinkingLevel,
420
+ };
421
+ }
422
+ emit(event) {
423
+ for (const subscriber of this.subscribers) {
424
+ subscriber(event);
425
+ }
426
+ }
427
+ currentTurnIdForEvent() {
428
+ return this.activeTurnId ?? undefined;
429
+ }
430
+ handleRuntimeEvent(event) {
431
+ if (event.type === "extension_ui_request") {
432
+ this.runtimeSession.cancelExtensionUiRequest(event.id);
433
+ return;
434
+ }
435
+ if (event.type === "process_exit") {
436
+ this.handleProcessExit(event.error);
437
+ return;
438
+ }
439
+ this.handleSessionEvent(event);
440
+ }
441
+ handleProcessExit(error) {
442
+ if (!this.activeTurnId) {
443
+ return;
444
+ }
445
+ const turnId = this.activeTurnId;
446
+ this.activeTurnId = null;
447
+ this.emit({
448
+ type: "turn_failed",
449
+ provider: PI_PROVIDER,
450
+ turnId,
451
+ error,
452
+ });
453
+ }
454
+ handleSessionEvent(event) {
455
+ const turnId = this.currentTurnIdForEvent();
456
+ switch (event.type) {
457
+ case "agent_start":
458
+ this.emit({
459
+ type: "thread_started",
460
+ provider: PI_PROVIDER,
461
+ sessionId: this.state.sessionId,
462
+ });
463
+ return;
464
+ case "turn_start":
465
+ this.emit({
466
+ type: "turn_started",
467
+ provider: PI_PROVIDER,
468
+ turnId,
469
+ });
470
+ return;
471
+ case "message_update":
472
+ this.handleMessageUpdate(event, turnId);
473
+ return;
474
+ case "tool_execution_start": {
475
+ const toolCall = parseToolArgs(event.toolName, event.args);
476
+ this.activeToolCalls.set(event.toolCallId, toolCall);
477
+ this.emitToolCallEvent(event.toolCallId, toolCall, "running", null, null);
478
+ return;
479
+ }
480
+ case "tool_execution_update": {
481
+ const toolCall = this.activeToolCalls.get(event.toolCallId);
482
+ if (!toolCall) {
483
+ return;
484
+ }
485
+ const partialResult = parseToolResult(event.partialResult);
486
+ this.emitToolCallEvent(event.toolCallId, toolCall, "running", partialResult, null);
487
+ return;
488
+ }
489
+ case "tool_execution_end": {
490
+ const toolCall = this.activeToolCalls.get(event.toolCallId) ?? parseToolArgs(event.toolName, null);
491
+ this.activeToolCalls.delete(event.toolCallId);
492
+ const result = parseToolResult(event.result);
493
+ const error = event.isError ? event.result : null;
494
+ const status = event.isError ? "failed" : "completed";
495
+ this.emitToolCallEvent(event.toolCallId, toolCall, status, result, error);
496
+ return;
497
+ }
498
+ case "compaction_start":
499
+ this.emit({
500
+ type: "timeline",
501
+ provider: PI_PROVIDER,
502
+ turnId,
503
+ item: {
504
+ type: "compaction",
505
+ status: "loading",
506
+ trigger: event.reason === "manual" ? "manual" : "auto",
507
+ },
508
+ });
509
+ return;
510
+ case "compaction_end":
511
+ this.emit({
512
+ type: "timeline",
513
+ provider: PI_PROVIDER,
514
+ turnId,
515
+ item: {
516
+ type: "compaction",
517
+ status: "completed",
518
+ },
519
+ });
520
+ return;
521
+ case "agent_end":
522
+ this.completeTurn(turnId, event.messages ?? []);
523
+ return;
524
+ default:
525
+ return;
526
+ }
527
+ }
528
+ handleMessageUpdate(event, turnId) {
529
+ if (event.message.role !== "assistant") {
530
+ return;
531
+ }
532
+ if (event.assistantMessageEvent.type === "text_delta") {
533
+ this.emit({
534
+ type: "timeline",
535
+ provider: PI_PROVIDER,
536
+ turnId,
537
+ item: {
538
+ type: "assistant_message",
539
+ text: event.assistantMessageEvent.delta ?? "",
540
+ },
541
+ });
542
+ return;
543
+ }
544
+ if (event.assistantMessageEvent.type === "thinking_delta") {
545
+ this.emit({
546
+ type: "timeline",
547
+ provider: PI_PROVIDER,
548
+ turnId,
549
+ item: {
550
+ type: "reasoning",
551
+ text: event.assistantMessageEvent.delta ?? "",
552
+ },
553
+ });
554
+ }
555
+ }
556
+ emitToolCallEvent(toolCallId, toolCall, status, result, error) {
557
+ const turnId = this.currentTurnIdForEvent();
558
+ const detail = mapToolDetail(toolCall, result);
559
+ const baseItem = {
560
+ type: "tool_call",
561
+ callId: toolCallId,
562
+ name: resolveToolCallName(toolCall, result),
563
+ detail,
564
+ };
565
+ const item = status === "failed" ? { ...baseItem, status, error } : { ...baseItem, status, error: null };
566
+ this.emit({
567
+ type: "timeline",
568
+ provider: PI_PROVIDER,
569
+ turnId,
570
+ item,
571
+ });
572
+ }
573
+ completeTurn(turnId, messages) {
574
+ this.activeTurnId = null;
575
+ const errorMessage = latestPiErrorMessage(messages);
576
+ if (typeof errorMessage === "string" && errorMessage.length > 0) {
577
+ this.emit({
578
+ type: "turn_failed",
579
+ provider: PI_PROVIDER,
580
+ turnId,
581
+ error: errorMessage,
582
+ });
583
+ return;
584
+ }
585
+ this.emit({
586
+ type: "turn_completed",
587
+ provider: PI_PROVIDER,
588
+ turnId,
589
+ });
590
+ void this.refreshAfterTurn(turnId);
591
+ }
592
+ async refreshState() {
593
+ this.state = await this.runtimeSession.getState();
594
+ }
595
+ async refreshAfterTurn(turnId) {
596
+ await this.refreshState().catch(() => undefined);
597
+ const usage = await this.runtimeSession
598
+ .getSessionStats()
599
+ .then(toAgentUsage)
600
+ .catch(() => undefined);
601
+ if (usage) {
602
+ this.emit({
603
+ type: "usage_updated",
604
+ provider: PI_PROVIDER,
605
+ turnId,
606
+ usage,
607
+ });
608
+ }
609
+ }
610
+ }
611
+ export class PiRpcAgentClient {
612
+ constructor(options) {
613
+ this.provider = PI_PROVIDER;
614
+ this.capabilities = PI_CAPABILITIES;
615
+ this.logger = options.logger;
616
+ this.runtimeSettings = options.runtimeSettings;
617
+ this.runtime = options.runtime ?? createRuntime(options.logger, options.runtimeSettings);
618
+ }
619
+ async createSession(config, launchContext) {
620
+ const mcpConfig = await this.prepareMcpConfig(config.cwd, config.mcpServers);
621
+ let runtimeSession;
622
+ try {
623
+ runtimeSession = await this.runtime.startSession({
624
+ cwd: config.cwd,
625
+ model: config.model,
626
+ thinkingOptionId: normalizePiThinkingOption(config.thinkingOptionId) ?? DEFAULT_PI_THINKING_LEVEL,
627
+ systemPrompt: composeSystemPromptParts(config.systemPrompt, config.daemonAppendSystemPrompt),
628
+ env: launchContext?.env,
629
+ mcpConfigPath: mcpConfig?.path,
630
+ });
631
+ }
632
+ catch (error) {
633
+ mcpConfig?.cleanup();
634
+ throw error;
635
+ }
636
+ try {
637
+ return new PiRpcAgentSession({
638
+ runtimeSession,
639
+ config,
640
+ initialState: await runtimeSession.getState(),
641
+ capabilities: withPiMcpCapability(mcpConfig !== null),
642
+ cleanup: mcpConfig?.cleanup,
643
+ });
644
+ }
645
+ catch (error) {
646
+ await runtimeSession.close().catch(() => undefined);
647
+ mcpConfig?.cleanup();
648
+ throw error;
649
+ }
650
+ }
651
+ async resumeSession(handle, overrides, _launchContext) {
652
+ const sessionFile = handle.nativeHandle;
653
+ if (!sessionFile) {
654
+ throw new Error("Pi resume requires a native session file handle");
655
+ }
656
+ const persistenceMetadata = parsePersistenceMetadata(handle.metadata);
657
+ const resumeConfig = buildResumeConfig(persistenceMetadata, overrides);
658
+ const mcpConfig = await this.prepareMcpConfig(resumeConfig.cwd, resumeConfig.config.mcpServers);
659
+ let runtimeSession;
660
+ try {
661
+ runtimeSession = await this.runtime.startSession({
662
+ cwd: resumeConfig.cwd,
663
+ session: sessionFile,
664
+ model: resumeConfig.model,
665
+ thinkingOptionId: normalizePiThinkingOption(resumeConfig.thinkingOptionId) ?? undefined,
666
+ systemPrompt: composeSystemPromptParts(resumeConfig.config.systemPrompt, resumeConfig.config.daemonAppendSystemPrompt),
667
+ mcpConfigPath: mcpConfig?.path,
668
+ });
669
+ }
670
+ catch (error) {
671
+ mcpConfig?.cleanup();
672
+ throw error;
673
+ }
674
+ try {
675
+ return new PiRpcAgentSession({
676
+ runtimeSession,
677
+ config: resumeConfig.config,
678
+ initialState: await runtimeSession.getState(),
679
+ capabilities: withPiMcpCapability(mcpConfig !== null),
680
+ cleanup: mcpConfig?.cleanup,
681
+ });
682
+ }
683
+ catch (error) {
684
+ await runtimeSession.close().catch(() => undefined);
685
+ mcpConfig?.cleanup();
686
+ throw error;
687
+ }
688
+ }
689
+ async listModels(options) {
690
+ const runtimeSession = await this.runtime.startSession({ cwd: options.cwd });
691
+ try {
692
+ return transformPiModels((await runtimeSession.getAvailableModels()).map(mapPiModel));
693
+ }
694
+ finally {
695
+ await runtimeSession.close();
696
+ }
697
+ }
698
+ async listModes(_options) {
699
+ return [];
700
+ }
701
+ async listPersistedAgents(options) {
702
+ return await listPiPersistedAgents({
703
+ ...options,
704
+ runtimeSettings: this.runtimeSettings,
705
+ });
706
+ }
707
+ async isAvailable() {
708
+ const binary = await this.resolvePiBinary();
709
+ if (!binary) {
710
+ return false;
711
+ }
712
+ const runtimeSession = await this.runtime.startSession({ cwd: homedir() }).catch(() => null);
713
+ if (!runtimeSession) {
714
+ return false;
715
+ }
716
+ try {
717
+ return (await runtimeSession.getAvailableModels()).length > 0;
718
+ }
719
+ catch {
720
+ return false;
721
+ }
722
+ finally {
723
+ await runtimeSession.close().catch(() => undefined);
724
+ }
725
+ }
726
+ async getDiagnostic() {
727
+ try {
728
+ const available = await this.isAvailable();
729
+ const binary = await this.resolvePiBinary();
730
+ const version = binary ? await resolveBinaryVersion(binary) : "unknown";
731
+ const authConfigPath = join(homedir(), ".pi", "agent", "auth.json");
732
+ let modelsValue = "Not checked";
733
+ let configuredProvidersValue = "none";
734
+ let mcpToolsValue = "Not checked";
735
+ let status = formatDiagnosticStatus(available);
736
+ if (binary) {
737
+ const runtimeSession = await this.runtime
738
+ .startSession({ cwd: homedir() })
739
+ .catch((error) => {
740
+ status = formatDiagnosticStatus(false, {
741
+ source: "startup",
742
+ cause: error,
743
+ });
744
+ return null;
745
+ });
746
+ if (runtimeSession) {
747
+ try {
748
+ const models = await runtimeSession.getAvailableModels();
749
+ modelsValue = String(models.length);
750
+ const configuredProviders = Array.from(new Set(models.map((model) => model.provider))).sort();
751
+ configuredProvidersValue =
752
+ configuredProviders.length > 0 ? configuredProviders.join(", ") : "none";
753
+ const commands = await runtimeSession.getCommands();
754
+ mcpToolsValue = commands.some(isPiMcpAdapterCommand)
755
+ ? "yes (pi-mcp-adapter loaded)"
756
+ : "no (install pi-mcp-adapter)";
757
+ }
758
+ catch (error) {
759
+ modelsValue = `Error - ${toDiagnosticErrorMessage(error)}`;
760
+ mcpToolsValue = `Error - ${toDiagnosticErrorMessage(error)}`;
761
+ status = formatDiagnosticStatus(available, {
762
+ source: "model fetch",
763
+ cause: error,
764
+ });
765
+ }
766
+ finally {
767
+ await runtimeSession.close().catch(() => undefined);
768
+ }
769
+ }
770
+ }
771
+ return {
772
+ diagnostic: formatProviderDiagnostic("Pi", [
773
+ { label: "Binary", value: binary ?? "not found" },
774
+ { label: "Version", value: version },
775
+ { label: "Configured providers", value: configuredProvidersValue },
776
+ {
777
+ label: "Auth config (~/.pi/agent/auth.json)",
778
+ value: existsSync(authConfigPath) ? "found" : "not found",
779
+ },
780
+ { label: "Models", value: modelsValue },
781
+ { label: "Paseo MCP tools", value: mcpToolsValue },
782
+ { label: "Status", value: status },
783
+ ]),
784
+ };
785
+ }
786
+ catch (error) {
787
+ this.logger.debug({ err: error }, "Pi diagnostic lookup failed");
788
+ return {
789
+ diagnostic: formatProviderDiagnosticError("Pi", error),
790
+ };
791
+ }
792
+ }
793
+ async prepareMcpConfig(cwd, servers) {
794
+ if (!servers || Object.keys(servers).length === 0) {
795
+ return null;
796
+ }
797
+ if (!(await this.detectMcpAdapter(cwd))) {
798
+ return null;
799
+ }
800
+ return createPiMcpConfigFile(servers);
801
+ }
802
+ async detectMcpAdapter(cwd) {
803
+ const runtimeSession = await this.runtime.startSession({ cwd }).catch((error) => {
804
+ this.logger.debug({ err: error, cwd }, "Pi MCP adapter probe failed to start");
805
+ return null;
806
+ });
807
+ if (!runtimeSession) {
808
+ return false;
809
+ }
810
+ try {
811
+ return (await runtimeSession.getCommands()).some(isPiMcpAdapterCommand);
812
+ }
813
+ catch (error) {
814
+ this.logger.debug({ err: error, cwd }, "Pi MCP adapter probe failed");
815
+ return false;
816
+ }
817
+ finally {
818
+ await runtimeSession.close().catch(() => undefined);
819
+ }
820
+ }
821
+ async resolvePiBinary() {
822
+ const command = this.runtimeSettings?.command;
823
+ if (command?.mode === "replace" && command.argv[0]) {
824
+ return await findExecutable(command.argv[0]);
825
+ }
826
+ return await findExecutable(PI_BINARY_COMMAND);
827
+ }
828
+ }
829
+ //# sourceMappingURL=agent.js.map