@getpaseo/server 0.1.97 → 0.1.99
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/dist/server/server/agent/agent-manager.d.ts +11 -3
- package/dist/server/server/agent/agent-manager.js +96 -24
- package/dist/server/server/agent/agent-prompt.d.ts +1 -1
- package/dist/server/server/agent/agent-prompt.js +3 -10
- package/dist/server/server/agent/agent-sdk-types.d.ts +20 -9
- package/dist/server/server/agent/create-agent/create.d.ts +2 -0
- package/dist/server/server/agent/create-agent/create.js +8 -7
- package/dist/server/server/agent/lifecycle-command.d.ts +15 -1
- package/dist/server/server/agent/lifecycle-command.js +9 -2
- package/dist/server/server/agent/mcp-server.js +254 -115
- package/dist/server/server/agent/provider-notices.d.ts +3 -0
- package/dist/server/server/agent/provider-notices.js +5 -0
- package/dist/server/server/agent/provider-registry.d.ts +8 -3
- package/dist/server/server/agent/provider-registry.js +58 -25
- package/dist/server/server/agent/provider-snapshot-manager.d.ts +3 -0
- package/dist/server/server/agent/provider-snapshot-manager.js +37 -16
- package/dist/server/server/agent/providers/acp-agent.d.ts +5 -3
- package/dist/server/server/agent/providers/acp-agent.js +32 -19
- package/dist/server/server/agent/providers/claude/agent.d.ts +2 -2
- package/dist/server/server/agent/providers/claude/agent.js +261 -167
- package/dist/server/server/agent/providers/claude/models.js +7 -3
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +6 -4
- package/dist/server/server/agent/providers/codex-app-server-agent.js +48 -25
- package/dist/server/server/agent/providers/copilot-acp-agent.js +4 -31
- package/dist/server/server/agent/providers/diagnostic-utils.d.ts +9 -0
- package/dist/server/server/agent/providers/diagnostic-utils.js +188 -0
- package/dist/server/server/agent/providers/generic-acp-agent.d.ts +0 -1
- package/dist/server/server/agent/providers/generic-acp-agent.js +2 -108
- package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +2 -3
- package/dist/server/server/agent/providers/mock-load-test-agent.js +5 -5
- package/dist/server/server/agent/providers/mock-slow-provider.d.ts +2 -3
- package/dist/server/server/agent/providers/mock-slow-provider.js +3 -6
- package/dist/server/server/agent/providers/opencode/server-manager.d.ts +29 -2
- package/dist/server/server/agent/providers/opencode/server-manager.js +83 -17
- package/dist/server/server/agent/providers/opencode-agent.d.ts +6 -3
- package/dist/server/server/agent/providers/opencode-agent.js +61 -107
- package/dist/server/server/agent/providers/pi/agent.d.ts +2 -3
- package/dist/server/server/agent/providers/pi/agent.js +11 -63
- package/dist/server/server/agent/providers/pi/cli-runtime.js +2 -2
- package/dist/server/server/agent/providers/pi/runtime.d.ts +1 -1
- package/dist/server/server/agent/providers/pi/test-utils/fake-pi.d.ts +1 -1
- package/dist/server/server/agent/providers/pi/test-utils/fake-pi.js +1 -1
- package/dist/server/server/bootstrap.d.ts +2 -0
- package/dist/server/server/bootstrap.js +32 -2
- package/dist/server/server/managed-processes/managed-processes.d.ts +76 -0
- package/dist/server/server/managed-processes/managed-processes.js +326 -0
- package/dist/server/server/resolve-worktree-creation-intent.d.ts +3 -0
- package/dist/server/server/resolve-worktree-creation-intent.js +3 -3
- package/dist/server/server/session/agent-config/agent-config-session.d.ts +50 -0
- package/dist/server/server/session/agent-config/agent-config-session.js +98 -0
- package/dist/server/server/session/chat/chat-schedule-loop-session.d.ts +120 -0
- package/dist/server/server/session/chat/chat-schedule-loop-session.js +489 -0
- package/dist/server/server/session/checkout/checkout-session.d.ts +142 -0
- package/dist/server/server/session/checkout/checkout-session.js +925 -0
- package/dist/server/server/session/daemon/daemon-session.d.ts +50 -0
- package/dist/server/server/session/daemon/daemon-session.js +98 -0
- package/dist/server/server/session/files/workspace-files-session.d.ts +43 -0
- package/dist/server/server/session/files/workspace-files-session.js +218 -0
- package/dist/server/server/session/project-config/project-config-session.d.ts +34 -0
- package/dist/server/server/session/project-config/project-config-session.js +125 -0
- package/dist/server/server/session/provider/provider-catalog-session.d.ts +74 -0
- package/dist/server/server/session/provider/provider-catalog-session.js +339 -0
- package/dist/server/server/session/voice/voice-session.d.ts +166 -0
- package/dist/server/server/session/voice/voice-session.js +893 -0
- package/dist/server/server/{voice → session/voice}/voice-turn-controller.d.ts +2 -2
- package/dist/server/server/{voice → session/voice}/voice-turn-controller.js +2 -2
- package/dist/server/server/session.d.ts +23 -207
- package/dist/server/server/session.js +2319 -5102
- package/dist/server/server/speech/providers/openai/runtime.js +3 -4
- package/dist/server/server/websocket-server.d.ts +1 -0
- package/dist/server/server/websocket-server.js +11 -0
- package/dist/server/server/workspace-archive-service.js +2 -3
- package/dist/server/server/workspace-directory.js +5 -5
- package/dist/server/server/workspace-reconciliation-service.js +2 -2
- package/dist/server/server/worktree-core.d.ts +1 -0
- package/dist/server/server/worktree-core.js +5 -1
- package/dist/server/services/quota-fetcher/manifest.d.ts +4 -0
- package/dist/server/services/quota-fetcher/manifest.js +47 -0
- package/dist/server/services/quota-fetcher/provider.d.ts +17 -0
- package/dist/server/services/quota-fetcher/provider.js +2 -0
- package/dist/server/services/quota-fetcher/providers/claude.d.ts +26 -0
- package/dist/server/services/quota-fetcher/providers/claude.js +217 -0
- package/dist/server/services/quota-fetcher/providers/codex.d.ts +23 -0
- package/dist/server/services/quota-fetcher/providers/codex.js +211 -0
- package/dist/server/services/quota-fetcher/providers/copilot.d.ts +17 -0
- package/dist/server/services/quota-fetcher/providers/copilot.js +75 -0
- package/dist/server/services/quota-fetcher/providers/cursor.d.ts +17 -0
- package/dist/server/services/quota-fetcher/providers/cursor.js +123 -0
- package/dist/server/services/quota-fetcher/providers/grok.d.ts +18 -0
- package/dist/server/services/quota-fetcher/providers/grok.js +89 -0
- package/dist/server/services/quota-fetcher/providers/kimi.d.ts +20 -0
- package/dist/server/services/quota-fetcher/providers/kimi.js +89 -0
- package/dist/server/services/quota-fetcher/providers/zai.d.ts +17 -0
- package/dist/server/services/quota-fetcher/providers/zai.js +58 -0
- package/dist/server/services/quota-fetcher/service.d.ts +28 -0
- package/dist/server/services/quota-fetcher/service.js +58 -0
- package/dist/server/services/quota-fetcher/usage.d.ts +22 -0
- package/dist/server/services/quota-fetcher/usage.js +49 -0
- package/dist/server/utils/checkout-git.d.ts +6 -0
- package/dist/server/utils/directory-suggestions.js +98 -2
- package/package.json +5 -5
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ChildProcess } from "node:child_process";
|
|
2
2
|
import type { Logger } from "pino";
|
|
3
|
+
import { type SpawnProcessOptions } from "../../../../utils/spawn.js";
|
|
4
|
+
import { type ProcessTerminator } from "../../../../utils/tree-kill.js";
|
|
5
|
+
import type { ManagedProcessRegistry } from "../../../managed-processes/managed-processes.js";
|
|
3
6
|
import { type ProviderRuntimeSettings } from "../../provider-launch-config.js";
|
|
4
7
|
export interface OpenCodeServerAcquisition {
|
|
5
8
|
server: {
|
|
@@ -24,6 +27,22 @@ export interface OpenCodeServerGeneration {
|
|
|
24
27
|
url: string;
|
|
25
28
|
refCount: number;
|
|
26
29
|
retired: boolean;
|
|
30
|
+
managedProcessId?: string;
|
|
31
|
+
}
|
|
32
|
+
export type OpenCodePortAllocator = () => Promise<number>;
|
|
33
|
+
export type OpenCodeCommandPrefixResolver = () => Promise<{
|
|
34
|
+
command: string;
|
|
35
|
+
args: string[];
|
|
36
|
+
}>;
|
|
37
|
+
export type OpenCodeServerProcessSpawner = (command: string, args: string[], options: SpawnProcessOptions) => ChildProcess;
|
|
38
|
+
export interface OpenCodeServerManagerOptions {
|
|
39
|
+
logger: Logger;
|
|
40
|
+
runtimeSettings?: ProviderRuntimeSettings;
|
|
41
|
+
managedProcesses?: ManagedProcessRegistry;
|
|
42
|
+
terminateProcess?: ProcessTerminator;
|
|
43
|
+
portAllocator?: OpenCodePortAllocator;
|
|
44
|
+
resolveCommandPrefix?: OpenCodeCommandPrefixResolver;
|
|
45
|
+
spawnServerProcess?: OpenCodeServerProcessSpawner;
|
|
27
46
|
}
|
|
28
47
|
export declare class OpenCodeServerManager implements OpenCodeServerManagerLike {
|
|
29
48
|
private static instance;
|
|
@@ -35,8 +54,13 @@ export declare class OpenCodeServerManager implements OpenCodeServerManagerLike
|
|
|
35
54
|
private readonly logger;
|
|
36
55
|
private readonly runtimeSettings?;
|
|
37
56
|
private readonly runtimeSettingsKey;
|
|
38
|
-
private
|
|
39
|
-
|
|
57
|
+
private readonly managedProcesses?;
|
|
58
|
+
private readonly terminateProcess;
|
|
59
|
+
private readonly portAllocator;
|
|
60
|
+
private readonly resolveCommandPrefix;
|
|
61
|
+
private readonly spawnServerProcess;
|
|
62
|
+
constructor(options: OpenCodeServerManagerOptions);
|
|
63
|
+
static getInstance(logger: Logger, runtimeSettings?: ProviderRuntimeSettings, options?: Omit<OpenCodeServerManagerOptions, "logger" | "runtimeSettings">): OpenCodeServerManager;
|
|
40
64
|
private static registerExitHandler;
|
|
41
65
|
ensureRunning(): Promise<{
|
|
42
66
|
port: number;
|
|
@@ -55,5 +79,8 @@ export declare class OpenCodeServerManager implements OpenCodeServerManagerLike
|
|
|
55
79
|
shutdown(): Promise<void>;
|
|
56
80
|
private cleanupRetiredServers;
|
|
57
81
|
private killServer;
|
|
82
|
+
private recordManagedServerProcess;
|
|
83
|
+
private removeManagedProcessRecordWhenResolved;
|
|
84
|
+
private removeManagedProcessId;
|
|
58
85
|
}
|
|
59
86
|
//# sourceMappingURL=server-manager.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import net from "node:net";
|
|
2
|
+
import os from "node:os";
|
|
2
3
|
import { findExecutable } from "../../../../executable-resolution/executable-resolution.js";
|
|
3
4
|
import { spawnProcess } from "../../../../utils/spawn.js";
|
|
4
5
|
import { terminateWithTreeKill } from "../../../../utils/tree-kill.js";
|
|
@@ -6,19 +7,30 @@ import { createProviderEnvSpec, resolveProviderCommandPrefix, } from "../../prov
|
|
|
6
7
|
const OPENCODE_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT_MS = 5000;
|
|
7
8
|
const OPENCODE_SERVER_FORCE_SHUTDOWN_TIMEOUT_MS = 1000;
|
|
8
9
|
export class OpenCodeServerManager {
|
|
9
|
-
constructor(
|
|
10
|
+
constructor(options) {
|
|
10
11
|
this.currentServer = null;
|
|
11
12
|
this.retiredServers = new Set();
|
|
12
13
|
this.startPromise = null;
|
|
13
14
|
this.forcedRefreshPromise = null;
|
|
14
|
-
this.logger = logger;
|
|
15
|
-
this.runtimeSettings = runtimeSettings;
|
|
16
|
-
this.runtimeSettingsKey = JSON.stringify(runtimeSettings ?? {});
|
|
15
|
+
this.logger = options.logger;
|
|
16
|
+
this.runtimeSettings = options.runtimeSettings;
|
|
17
|
+
this.runtimeSettingsKey = JSON.stringify(this.runtimeSettings ?? {});
|
|
18
|
+
this.managedProcesses = options.managedProcesses;
|
|
19
|
+
this.terminateProcess = options.terminateProcess ?? terminateWithTreeKill;
|
|
20
|
+
this.portAllocator = options.portAllocator ?? findAvailablePort;
|
|
21
|
+
this.resolveCommandPrefix =
|
|
22
|
+
options.resolveCommandPrefix ??
|
|
23
|
+
(() => resolveProviderCommandPrefix(this.runtimeSettings?.command, resolveOpenCodeBinary));
|
|
24
|
+
this.spawnServerProcess = options.spawnServerProcess ?? spawnProcess;
|
|
17
25
|
}
|
|
18
|
-
static getInstance(logger, runtimeSettings) {
|
|
26
|
+
static getInstance(logger, runtimeSettings, options = {}) {
|
|
19
27
|
const nextSettingsKey = JSON.stringify(runtimeSettings ?? {});
|
|
20
28
|
if (!OpenCodeServerManager.instance) {
|
|
21
|
-
OpenCodeServerManager.instance = new OpenCodeServerManager(
|
|
29
|
+
OpenCodeServerManager.instance = new OpenCodeServerManager({
|
|
30
|
+
logger,
|
|
31
|
+
runtimeSettings,
|
|
32
|
+
...options,
|
|
33
|
+
});
|
|
22
34
|
OpenCodeServerManager.registerExitHandler();
|
|
23
35
|
}
|
|
24
36
|
else if (OpenCodeServerManager.instance.runtimeSettingsKey !== nextSettingsKey) {
|
|
@@ -128,11 +140,14 @@ export class OpenCodeServerManager {
|
|
|
128
140
|
return server;
|
|
129
141
|
}
|
|
130
142
|
async startServer(launchEnv) {
|
|
131
|
-
const port = await
|
|
143
|
+
const port = await this.portAllocator();
|
|
132
144
|
const url = `http://127.0.0.1:${port}`;
|
|
133
|
-
const launchPrefix = await
|
|
145
|
+
const launchPrefix = await this.resolveCommandPrefix();
|
|
146
|
+
const serverArgs = [...launchPrefix.args, "serve", "--port", String(port)];
|
|
147
|
+
const serverCwd = os.homedir();
|
|
134
148
|
return new Promise((resolve, reject) => {
|
|
135
|
-
const serverProcess =
|
|
149
|
+
const serverProcess = this.spawnServerProcess(launchPrefix.command, serverArgs, {
|
|
150
|
+
cwd: serverCwd,
|
|
136
151
|
detached: process.platform !== "win32",
|
|
137
152
|
stdio: ["ignore", "pipe", "pipe"],
|
|
138
153
|
...createProviderEnvSpec({
|
|
@@ -140,6 +155,12 @@ export class OpenCodeServerManager {
|
|
|
140
155
|
overlays: [launchEnv],
|
|
141
156
|
}),
|
|
142
157
|
});
|
|
158
|
+
const managedProcessRecord = this.recordManagedServerProcess({
|
|
159
|
+
process: serverProcess,
|
|
160
|
+
command: launchPrefix.command,
|
|
161
|
+
args: serverArgs,
|
|
162
|
+
port,
|
|
163
|
+
});
|
|
143
164
|
let started = false;
|
|
144
165
|
let stderrBuffer = "";
|
|
145
166
|
let stdoutBuffer = "";
|
|
@@ -174,13 +195,17 @@ export class OpenCodeServerManager {
|
|
|
174
195
|
if (output.includes("listening on") && !started) {
|
|
175
196
|
started = true;
|
|
176
197
|
clearTimeout(timeout);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
198
|
+
void (async () => {
|
|
199
|
+
const record = await managedProcessRecord;
|
|
200
|
+
resolve({
|
|
201
|
+
process: serverProcess,
|
|
202
|
+
port,
|
|
203
|
+
url,
|
|
204
|
+
refCount: 0,
|
|
205
|
+
retired: false,
|
|
206
|
+
...(record ? { managedProcessId: record.id } : {}),
|
|
207
|
+
});
|
|
208
|
+
})();
|
|
184
209
|
}
|
|
185
210
|
});
|
|
186
211
|
serverProcess.stderr?.on("data", (data) => {
|
|
@@ -190,10 +215,12 @@ export class OpenCodeServerManager {
|
|
|
190
215
|
});
|
|
191
216
|
serverProcess.on("error", (error) => {
|
|
192
217
|
clearTimeout(timeout);
|
|
218
|
+
this.removeManagedProcessRecordWhenResolved(managedProcessRecord);
|
|
193
219
|
const headline = error instanceof Error ? error.message : String(error);
|
|
194
220
|
reject(new Error(buildStartupErrorMessage(headline)));
|
|
195
221
|
});
|
|
196
222
|
serverProcess.on("exit", (code) => {
|
|
223
|
+
this.removeManagedProcessRecordWhenResolved(managedProcessRecord);
|
|
197
224
|
if (!started) {
|
|
198
225
|
clearTimeout(timeout);
|
|
199
226
|
reject(new Error(buildStartupErrorMessage(`OpenCode server exited with code ${code}`)));
|
|
@@ -231,7 +258,7 @@ export class OpenCodeServerManager {
|
|
|
231
258
|
(server.process.signalCode !== null && server.process.signalCode !== undefined)) {
|
|
232
259
|
return;
|
|
233
260
|
}
|
|
234
|
-
const result = await
|
|
261
|
+
const result = await this.terminateProcess(server.process, {
|
|
235
262
|
gracefulTimeoutMs: OPENCODE_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT_MS,
|
|
236
263
|
forceTimeoutMs: OPENCODE_SERVER_FORCE_SHUTDOWN_TIMEOUT_MS,
|
|
237
264
|
onForceSignal: () => {
|
|
@@ -241,6 +268,45 @@ export class OpenCodeServerManager {
|
|
|
241
268
|
if (result === "kill-timeout") {
|
|
242
269
|
this.logger.warn({ timeoutMs: OPENCODE_SERVER_FORCE_SHUTDOWN_TIMEOUT_MS }, "OpenCode server did not report exit after SIGKILL");
|
|
243
270
|
}
|
|
271
|
+
if (server.managedProcessId) {
|
|
272
|
+
await this.removeManagedProcessId(server.managedProcessId);
|
|
273
|
+
server.managedProcessId = undefined;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
async recordManagedServerProcess(options) {
|
|
277
|
+
const pid = options.process.pid;
|
|
278
|
+
if (!this.managedProcesses || typeof pid !== "number" || pid <= 0) {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
return await this.managedProcesses.record({
|
|
283
|
+
owner: { provider: "opencode", kind: "helper-server" },
|
|
284
|
+
pid,
|
|
285
|
+
command: options.command,
|
|
286
|
+
args: options.args,
|
|
287
|
+
metadata: { port: options.port },
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
this.logger.warn({ err: error, pid, port: options.port }, "Failed to record OpenCode helper process");
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
removeManagedProcessRecordWhenResolved(record) {
|
|
296
|
+
void record.then((resolved) => {
|
|
297
|
+
if (resolved) {
|
|
298
|
+
return this.removeManagedProcessId(resolved.id);
|
|
299
|
+
}
|
|
300
|
+
return undefined;
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
async removeManagedProcessId(id) {
|
|
304
|
+
try {
|
|
305
|
+
await this.managedProcesses?.remove(id);
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
this.logger.warn({ err: error, id }, "Failed to remove OpenCode helper process record");
|
|
309
|
+
}
|
|
244
310
|
}
|
|
245
311
|
}
|
|
246
312
|
OpenCodeServerManager.instance = null;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type AssistantMessage as OpenCodeAssistantMessage, type Event as OpenCodeEvent, type FilePartInput as OpenCodeFilePartInput, type Message as OpenCodeMessage, type OpencodeClient, type Part as OpenCodePart, type TextPartInput as OpenCodeTextPartInput } from "@opencode-ai/sdk/v2/client";
|
|
2
2
|
import type { Logger } from "pino";
|
|
3
|
-
import { type AgentCapabilityFlags, type AgentClient, type AgentCreateSessionOptions, type AgentFeature, type AgentLaunchContext, type AgentMode, type AgentModelDefinition, type AgentPermissionRequest, type AgentPermissionResponse, type AgentPersistenceHandle, type AgentPromptInput, type AgentRunOptions, type AgentRunResult, type AgentRuntimeInfo, type AgentSession, type AgentSessionConfig, type AgentSlashCommand, type AgentStreamEvent, type AgentTimelineItem, type AgentUsage, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type ResolveAgentCreateConfigInput, type ResolveAgentCreateConfigResult, type
|
|
3
|
+
import { type AgentCapabilityFlags, type AgentClient, type AgentCreateSessionOptions, type AgentFeature, type AgentLaunchContext, type AgentMode, type AgentModelDefinition, type AgentPermissionRequest, type AgentPermissionResponse, type AgentPersistenceHandle, type AgentPromptInput, type AgentRunOptions, type AgentRunResult, type AgentRuntimeInfo, type AgentSession, type AgentSessionConfig, type AgentSlashCommand, type AgentStreamEvent, type AgentTimelineItem, type AgentUsage, type FetchCatalogOptions, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type ResolveAgentCreateConfigInput, type ResolveAgentCreateConfigResult, type ProviderCatalog, type ToolCallTimelineItem } from "../agent-sdk-types.js";
|
|
4
4
|
import { isDefaultAgentCreateConfigUnattended } from "../create-agent-mode.js";
|
|
5
5
|
import { type ProviderRuntimeSettings } from "../provider-launch-config.js";
|
|
6
6
|
import { type OpenCodeRuntime } from "./opencode/runtime.js";
|
|
7
|
+
import type { ManagedProcessRegistry } from "../../managed-processes/managed-processes.js";
|
|
7
8
|
declare function resolveOpenCodeCreateConfig(input: ResolveAgentCreateConfigInput): ResolveAgentCreateConfigResult;
|
|
8
9
|
declare function isOpenCodeCreateConfigUnattended(input: Parameters<typeof isDefaultAgentCreateConfigUnattended>[0]): boolean;
|
|
9
10
|
type OpenCodeAgentConfig = AgentSessionConfig & {
|
|
@@ -103,6 +104,7 @@ export declare const __openCodeInternals: {
|
|
|
103
104
|
};
|
|
104
105
|
interface OpenCodeAgentClientDeps {
|
|
105
106
|
runtime?: OpenCodeRuntime;
|
|
107
|
+
managedProcesses?: ManagedProcessRegistry;
|
|
106
108
|
}
|
|
107
109
|
export declare class OpenCodeAgentClient implements AgentClient {
|
|
108
110
|
readonly provider: "opencode";
|
|
@@ -116,8 +118,7 @@ export declare class OpenCodeAgentClient implements AgentClient {
|
|
|
116
118
|
constructor(logger: Logger, runtimeSettings?: ProviderRuntimeSettings, deps?: OpenCodeAgentClientDeps);
|
|
117
119
|
createSession(config: AgentSessionConfig, launchContext?: AgentLaunchContext, options?: AgentCreateSessionOptions): Promise<AgentSession>;
|
|
118
120
|
resumeSession(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>, launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
119
|
-
|
|
120
|
-
listModes(options: ListModesOptions): Promise<AgentMode[]>;
|
|
121
|
+
fetchCatalog(options: FetchCatalogOptions): Promise<ProviderCatalog>;
|
|
121
122
|
listCommands(config: AgentSessionConfig): Promise<AgentSlashCommand[]>;
|
|
122
123
|
listFeatures(config: AgentSessionConfig): Promise<AgentFeature[]>;
|
|
123
124
|
listImportableSessions(options?: ListImportableSessionsOptions): Promise<ImportableProviderSession[]>;
|
|
@@ -127,6 +128,8 @@ export declare class OpenCodeAgentClient implements AgentClient {
|
|
|
127
128
|
getDiagnostic(): Promise<{
|
|
128
129
|
diagnostic: string;
|
|
129
130
|
}>;
|
|
131
|
+
private fetchModelsFromClient;
|
|
132
|
+
private fetchModesFromClient;
|
|
130
133
|
private assertConfig;
|
|
131
134
|
private populateModelContextWindowCache;
|
|
132
135
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { homedir } from "node:os";
|
|
2
1
|
import { createPathEquivalenceMatcher } from "../../../utils/path.js";
|
|
3
2
|
import pLimit from "p-limit";
|
|
4
3
|
import { z } from "zod";
|
|
@@ -11,7 +10,7 @@ import { execCommand } from "../../../utils/spawn.js";
|
|
|
11
10
|
import { buildToolCallDisplayModel } from "@getpaseo/protocol/tool-call-display";
|
|
12
11
|
import { mapOpencodeToolCall } from "./opencode/tool-call-mapper.js";
|
|
13
12
|
import { OpenCodeServerManager } from "./opencode/server-manager.js";
|
|
14
|
-
import {
|
|
13
|
+
import { formatProviderDiagnostic, formatProviderDiagnosticError, buildBinaryDiagnosticRows, buildCommandResolutionDiagnosticRows, toDiagnosticErrorMessage, } from "./diagnostic-utils.js";
|
|
15
14
|
import { runProviderTurn } from "./provider-runner.js";
|
|
16
15
|
import { renderPromptAttachmentAsText } from "../prompt-attachments.js";
|
|
17
16
|
import { composeSystemPromptParts } from "../system-prompt.js";
|
|
@@ -398,14 +397,14 @@ function mapOpenCodeAgentToMode(agent) {
|
|
|
398
397
|
};
|
|
399
398
|
}
|
|
400
399
|
function mergeOpenCodeModes(discoveredModes) {
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
400
|
+
const filtered = discoveredModes.filter((mode) => mode.id !== OPENCODE_LEGACY_FULL_ACCESS_MODE_ID);
|
|
401
|
+
// When discovery returns results, trust them exactly — don't inject hardcoded
|
|
402
|
+
// defaults that the user may have intentionally disabled in their OpenCode config.
|
|
403
|
+
// Fall back to DEFAULT_MODES only when discovery produced nothing.
|
|
404
|
+
if (filtered.length > 0) {
|
|
405
|
+
return sortOpenCodeModes(filtered);
|
|
407
406
|
}
|
|
408
|
-
return sortOpenCodeModes(
|
|
407
|
+
return sortOpenCodeModes([...DEFAULT_MODES]);
|
|
409
408
|
}
|
|
410
409
|
function sortOpenCodeModes(modes) {
|
|
411
410
|
const order = new Map(DEFAULT_MODES.map((mode, index) => [mode.id, index]));
|
|
@@ -880,7 +879,9 @@ export class OpenCodeAgentClient {
|
|
|
880
879
|
this.runtimeSettings = runtimeSettings;
|
|
881
880
|
this.runtime =
|
|
882
881
|
deps.runtime ??
|
|
883
|
-
new ProductionOpenCodeRuntime(OpenCodeServerManager.getInstance(this.logger, runtimeSettings
|
|
882
|
+
new ProductionOpenCodeRuntime(OpenCodeServerManager.getInstance(this.logger, runtimeSettings, {
|
|
883
|
+
managedProcesses: deps.managedProcesses,
|
|
884
|
+
}));
|
|
884
885
|
}
|
|
885
886
|
async createSession(config, launchContext, options) {
|
|
886
887
|
const openCodeConfig = this.assertConfig(config);
|
|
@@ -938,70 +939,17 @@ export class OpenCodeAgentClient {
|
|
|
938
939
|
throw error;
|
|
939
940
|
}
|
|
940
941
|
}
|
|
941
|
-
async
|
|
942
|
-
const acquisition = await this.runtime.acquireServer({ force: options.force });
|
|
943
|
-
const { url } = acquisition.server;
|
|
944
|
-
const client = this.runtime.createClient({
|
|
945
|
-
baseUrl: url,
|
|
946
|
-
directory: options.cwd,
|
|
947
|
-
});
|
|
948
|
-
try {
|
|
949
|
-
// Background model discovery can be legitimately slow while OpenCode refreshes
|
|
950
|
-
// provider state, so allow longer than turn execution paths.
|
|
951
|
-
const response = await openCodeMetadataLimit(() => withTimeout(client.provider.list({ directory: options.cwd }), OPENCODE_PROVIDER_LIST_TIMEOUT_MS, `OpenCode provider.list timed out after ${OPENCODE_PROVIDER_LIST_TIMEOUT_MS / 1000}s - server may not be authenticated or connected to any providers`));
|
|
952
|
-
if (response.error) {
|
|
953
|
-
throw new Error(`Failed to fetch OpenCode providers: ${JSON.stringify(response.error)}`);
|
|
954
|
-
}
|
|
955
|
-
const providers = response.data;
|
|
956
|
-
if (!providers) {
|
|
957
|
-
return [];
|
|
958
|
-
}
|
|
959
|
-
const connectedProviderIds = new Set(providers.connected);
|
|
960
|
-
// Providers with source "api" are managed by the OpenCode console/subscription (e.g. Pi
|
|
961
|
-
// coding agent). They do not appear in `connected` (which only lists env/config providers)
|
|
962
|
-
// but are fully usable — OpenCode authenticates them internally via the console session.
|
|
963
|
-
const isAccessible = (provider) => connectedProviderIds.has(provider.id) || provider.source === "api";
|
|
964
|
-
// Fail fast if no providers are accessible at all
|
|
965
|
-
if (!providers.all.some(isAccessible)) {
|
|
966
|
-
throw new Error("OpenCode has no connected providers. Please authenticate with at least one provider " +
|
|
967
|
-
"(e.g., openai, anthropic), set appropriate environment variables (e.g., OPENAI_API_KEY), " +
|
|
968
|
-
"or log in to OpenCode Go via the console.");
|
|
969
|
-
}
|
|
970
|
-
const models = [];
|
|
971
|
-
this.modelContextWindows.clear();
|
|
972
|
-
for (const provider of providers.all) {
|
|
973
|
-
if (!isAccessible(provider)) {
|
|
974
|
-
continue;
|
|
975
|
-
}
|
|
976
|
-
for (const [modelId, model] of Object.entries(provider.models)) {
|
|
977
|
-
const definition = buildOpenCodeModelDefinition(provider, modelId, model);
|
|
978
|
-
const contextWindowMaxTokens = extractOpenCodeModelContextWindow(model);
|
|
979
|
-
if (contextWindowMaxTokens !== undefined) {
|
|
980
|
-
this.modelContextWindows.set(buildOpenCodeModelLookupKey(provider.id, modelId), contextWindowMaxTokens);
|
|
981
|
-
}
|
|
982
|
-
models.push(definition);
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
return models;
|
|
986
|
-
}
|
|
987
|
-
finally {
|
|
988
|
-
acquisition.release();
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
async listModes(options) {
|
|
942
|
+
async fetchCatalog(options) {
|
|
992
943
|
const acquisition = await this.runtime.acquireServer({ force: options.force });
|
|
993
944
|
const { url } = acquisition.server;
|
|
994
945
|
const directory = options.cwd;
|
|
995
946
|
const client = this.runtime.createClient({ baseUrl: url, directory });
|
|
996
947
|
try {
|
|
997
|
-
const
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
.filter(isSelectableOpenCodeAgent)
|
|
1003
|
-
.map(mapOpenCodeAgentToMode);
|
|
1004
|
-
return mergeOpenCodeModes(discovered);
|
|
948
|
+
const [models, modes] = await Promise.all([
|
|
949
|
+
this.fetchModelsFromClient(client, directory),
|
|
950
|
+
this.fetchModesFromClient(client, directory),
|
|
951
|
+
]);
|
|
952
|
+
return { models, modes };
|
|
1005
953
|
}
|
|
1006
954
|
finally {
|
|
1007
955
|
acquisition.release();
|
|
@@ -1092,17 +1040,6 @@ export class OpenCodeAgentClient {
|
|
|
1092
1040
|
defaultBinary: "opencode",
|
|
1093
1041
|
});
|
|
1094
1042
|
const availability = await checkProviderLaunchAvailable(launch);
|
|
1095
|
-
const available = availability.available;
|
|
1096
|
-
let serverStatus = "Not running";
|
|
1097
|
-
let modelsValue = "Not checked";
|
|
1098
|
-
let status = formatDiagnosticStatus(available);
|
|
1099
|
-
try {
|
|
1100
|
-
const { url } = await this.runtime.ensureServerRunning();
|
|
1101
|
-
serverStatus = `Running (${url})`;
|
|
1102
|
-
}
|
|
1103
|
-
catch (error) {
|
|
1104
|
-
serverStatus = `Unavailable (${toDiagnosticErrorMessage(error)})`;
|
|
1105
|
-
}
|
|
1106
1043
|
let authValue = "Not checked";
|
|
1107
1044
|
const authCommand = availability.available
|
|
1108
1045
|
? (availability.resolvedPath ?? launch.command)
|
|
@@ -1120,37 +1057,13 @@ export class OpenCodeAgentClient {
|
|
|
1120
1057
|
authValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1121
1058
|
}
|
|
1122
1059
|
}
|
|
1123
|
-
if (available) {
|
|
1124
|
-
try {
|
|
1125
|
-
const models = await this.listModels({ cwd: homedir(), force: false });
|
|
1126
|
-
modelsValue = String(models.length);
|
|
1127
|
-
}
|
|
1128
|
-
catch (error) {
|
|
1129
|
-
modelsValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1130
|
-
status = formatDiagnosticStatus(available, {
|
|
1131
|
-
source: "model fetch",
|
|
1132
|
-
cause: error,
|
|
1133
|
-
});
|
|
1134
|
-
}
|
|
1135
|
-
if (!modelsValue.startsWith("Error -")) {
|
|
1136
|
-
try {
|
|
1137
|
-
await this.listModes({ cwd: homedir(), force: false });
|
|
1138
|
-
}
|
|
1139
|
-
catch (error) {
|
|
1140
|
-
status = formatDiagnosticStatus(available, {
|
|
1141
|
-
source: "mode fetch",
|
|
1142
|
-
cause: error,
|
|
1143
|
-
});
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
1060
|
return {
|
|
1148
1061
|
diagnostic: formatProviderDiagnostic("OpenCode", [
|
|
1062
|
+
...(await buildCommandResolutionDiagnosticRows(launch, {
|
|
1063
|
+
knownBinaryNames: ["opencode"],
|
|
1064
|
+
})),
|
|
1149
1065
|
...(await buildBinaryDiagnosticRows(launch, availability)),
|
|
1150
|
-
{ label: "Server", value: serverStatus },
|
|
1151
1066
|
{ label: "Auth", value: authValue },
|
|
1152
|
-
{ label: "Models", value: modelsValue },
|
|
1153
|
-
{ label: "Status", value: status },
|
|
1154
1067
|
]),
|
|
1155
1068
|
};
|
|
1156
1069
|
}
|
|
@@ -1160,6 +1073,47 @@ export class OpenCodeAgentClient {
|
|
|
1160
1073
|
};
|
|
1161
1074
|
}
|
|
1162
1075
|
}
|
|
1076
|
+
async fetchModelsFromClient(client, directory) {
|
|
1077
|
+
const response = await openCodeMetadataLimit(() => withTimeout(client.provider.list({ directory }), OPENCODE_PROVIDER_LIST_TIMEOUT_MS, `OpenCode provider.list timed out after ${OPENCODE_PROVIDER_LIST_TIMEOUT_MS / 1000}s - server may not be authenticated or connected to any providers`));
|
|
1078
|
+
if (response.error) {
|
|
1079
|
+
throw new Error(`Failed to fetch OpenCode providers: ${JSON.stringify(response.error)}`);
|
|
1080
|
+
}
|
|
1081
|
+
const providers = response.data;
|
|
1082
|
+
if (!providers) {
|
|
1083
|
+
return [];
|
|
1084
|
+
}
|
|
1085
|
+
const connectedProviderIds = new Set(providers.connected);
|
|
1086
|
+
const isAccessible = (provider) => connectedProviderIds.has(provider.id) || provider.source === "api";
|
|
1087
|
+
if (!providers.all.some(isAccessible)) {
|
|
1088
|
+
throw new Error("OpenCode has no connected providers. Please authenticate with at least one provider " +
|
|
1089
|
+
"(e.g., openai, anthropic), set appropriate environment variables (e.g., OPENAI_API_KEY), " +
|
|
1090
|
+
"or log in to OpenCode Go via the console.");
|
|
1091
|
+
}
|
|
1092
|
+
const models = [];
|
|
1093
|
+
this.modelContextWindows.clear();
|
|
1094
|
+
for (const provider of providers.all) {
|
|
1095
|
+
if (!isAccessible(provider)) {
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1098
|
+
for (const [modelId, model] of Object.entries(provider.models)) {
|
|
1099
|
+
const definition = buildOpenCodeModelDefinition(provider, modelId, model);
|
|
1100
|
+
const contextWindowMaxTokens = extractOpenCodeModelContextWindow(model);
|
|
1101
|
+
if (contextWindowMaxTokens !== undefined) {
|
|
1102
|
+
this.modelContextWindows.set(buildOpenCodeModelLookupKey(provider.id, modelId), contextWindowMaxTokens);
|
|
1103
|
+
}
|
|
1104
|
+
models.push(definition);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return models;
|
|
1108
|
+
}
|
|
1109
|
+
async fetchModesFromClient(client, directory) {
|
|
1110
|
+
const response = await openCodeMetadataLimit(() => withTimeout(client.app.agents({ directory }), 10000, "OpenCode app.agents timed out after 10s"));
|
|
1111
|
+
if (response.error || !response.data) {
|
|
1112
|
+
return DEFAULT_MODES;
|
|
1113
|
+
}
|
|
1114
|
+
const discovered = response.data.filter(isSelectableOpenCodeAgent).map(mapOpenCodeAgentToMode);
|
|
1115
|
+
return mergeOpenCodeModes(discovered);
|
|
1116
|
+
}
|
|
1163
1117
|
assertConfig(config) {
|
|
1164
1118
|
if (config.provider !== "opencode") {
|
|
1165
1119
|
throw new Error(`OpenCodeAgentClient received config for provider '${config.provider}'`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Logger } from "pino";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { type AgentCapabilityFlags, type AgentClient, type AgentLaunchContext, type AgentMode, type AgentModelDefinition, type AgentPermissionRequest, type AgentPermissionResponse, type AgentPersistenceHandle, type AgentPromptInput, type AgentRunOptions, type AgentRunResult, type AgentRuntimeInfo, type AgentSession, type AgentSessionConfig, type AgentSlashCommand, type AgentStreamEvent, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type
|
|
3
|
+
import { type AgentCapabilityFlags, type AgentClient, type AgentLaunchContext, type AgentMode, type AgentModelDefinition, type AgentPermissionRequest, type AgentPermissionResponse, type AgentPersistenceHandle, type AgentPromptInput, type AgentRunOptions, type AgentRunResult, type AgentRuntimeInfo, type AgentSession, type AgentSessionConfig, type AgentSlashCommand, type AgentStreamEvent, type FetchCatalogOptions, type ImportableProviderSession, type ImportProviderSessionContext, type ImportProviderSessionInput, type ListImportableSessionsOptions, type ProviderCatalog } from "../../agent-sdk-types.js";
|
|
4
4
|
import { type ProviderRuntimeSettings } from "../../provider-launch-config.js";
|
|
5
5
|
import type { PiRuntime, PiRuntimeSession } from "./runtime.js";
|
|
6
6
|
import type { PiSessionState } from "./rpc-types.js";
|
|
@@ -112,8 +112,7 @@ export declare class PiRpcAgentClient implements AgentClient {
|
|
|
112
112
|
constructor(options: PiRpcAgentClientOptions);
|
|
113
113
|
createSession(config: AgentSessionConfig, launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
114
114
|
resumeSession(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>, _launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
115
|
-
|
|
116
|
-
listModes(_options: ListModesOptions): Promise<AgentMode[]>;
|
|
115
|
+
fetchCatalog(options: FetchCatalogOptions): Promise<ProviderCatalog>;
|
|
117
116
|
listImportableSessions(options?: ListImportableSessionsOptions): Promise<ImportableProviderSession[]>;
|
|
118
117
|
importSession(input: ImportProviderSessionInput, context: ImportProviderSessionContext): Promise<import("../../agent-sdk-types.js").ImportedProviderSession>;
|
|
119
118
|
isAvailable(): Promise<boolean>;
|
|
@@ -8,7 +8,7 @@ import { runProviderTurn } from "../provider-runner.js";
|
|
|
8
8
|
import { checkProviderLaunchAvailable, resolveProviderLaunch, } from "../../provider-launch-config.js";
|
|
9
9
|
import { renderPromptAttachmentAsText } from "../../prompt-attachments.js";
|
|
10
10
|
import { composeSystemPromptParts } from "../../system-prompt.js";
|
|
11
|
-
import { buildBinaryDiagnosticRows,
|
|
11
|
+
import { buildBinaryDiagnosticRows, buildCommandResolutionDiagnosticRows, formatProviderDiagnostic, formatProviderDiagnosticError, toDiagnosticErrorMessage, } from "../diagnostic-utils.js";
|
|
12
12
|
import { getUserMessageText, streamPiHistory, } from "./history-mapper.js";
|
|
13
13
|
import { PiCliRuntime } from "./cli-runtime.js";
|
|
14
14
|
import { revertPiConversation } from "./rewind.js";
|
|
@@ -17,6 +17,7 @@ import { mapToolDetail, parseToolArgs, parseToolResult, resolveToolCallName, } f
|
|
|
17
17
|
const PI_PROVIDER = "pi";
|
|
18
18
|
const DEFAULT_PI_THINKING_LEVEL = "medium";
|
|
19
19
|
const PI_BINARY_COMMAND = process.env.PI_COMMAND ?? process.env.PI_ACP_PI_COMMAND ?? "pi";
|
|
20
|
+
const PI_CATALOG_REQUEST_TIMEOUT_MS = 120000;
|
|
20
21
|
const PASEO_PI_TREE_EXTENSION_COMMAND = "paseo_tree";
|
|
21
22
|
const PASEO_PI_CAPTURE_EXTENSION_COMMAND = "paseo_capture_entries";
|
|
22
23
|
const PASEO_PI_ENTRY_CAPTURE_MARKER = "PASEO_ENTRY_CAPTURE";
|
|
@@ -1537,18 +1538,16 @@ export class PiRpcAgentClient {
|
|
|
1537
1538
|
throw error;
|
|
1538
1539
|
}
|
|
1539
1540
|
}
|
|
1540
|
-
async
|
|
1541
|
+
async fetchCatalog(options) {
|
|
1541
1542
|
const runtimeSession = await this.runtime.startSession({ cwd: options.cwd });
|
|
1542
1543
|
try {
|
|
1543
|
-
|
|
1544
|
+
const models = transformPiModels((await runtimeSession.getAvailableModels(PI_CATALOG_REQUEST_TIMEOUT_MS)).map(mapPiModel));
|
|
1545
|
+
return { models, modes: [] };
|
|
1544
1546
|
}
|
|
1545
1547
|
finally {
|
|
1546
1548
|
await runtimeSession.close();
|
|
1547
1549
|
}
|
|
1548
1550
|
}
|
|
1549
|
-
async listModes(_options) {
|
|
1550
|
-
return [];
|
|
1551
|
-
}
|
|
1552
1551
|
async listImportableSessions(options) {
|
|
1553
1552
|
return await listPiImportableSessions({
|
|
1554
1553
|
...options,
|
|
@@ -1567,81 +1566,30 @@ export class PiRpcAgentClient {
|
|
|
1567
1566
|
});
|
|
1568
1567
|
}
|
|
1569
1568
|
async isAvailable() {
|
|
1570
|
-
const launch = await this.resolvePiLaunch();
|
|
1571
|
-
const availability = await checkProviderLaunchAvailable(launch);
|
|
1572
|
-
if (!availability.available) {
|
|
1573
|
-
return false;
|
|
1574
|
-
}
|
|
1575
|
-
const runtimeSession = await this.runtime.startSession({ cwd: homedir() }).catch(() => null);
|
|
1576
|
-
if (!runtimeSession) {
|
|
1577
|
-
return false;
|
|
1578
|
-
}
|
|
1579
1569
|
try {
|
|
1580
|
-
|
|
1570
|
+
const launch = await this.resolvePiLaunch();
|
|
1571
|
+
const availability = await checkProviderLaunchAvailable(launch);
|
|
1572
|
+
return availability.available;
|
|
1581
1573
|
}
|
|
1582
1574
|
catch {
|
|
1583
1575
|
return false;
|
|
1584
1576
|
}
|
|
1585
|
-
finally {
|
|
1586
|
-
await runtimeSession.close().catch(() => undefined);
|
|
1587
|
-
}
|
|
1588
1577
|
}
|
|
1589
1578
|
async getDiagnostic() {
|
|
1590
1579
|
try {
|
|
1591
1580
|
const launch = await this.resolvePiLaunch();
|
|
1592
1581
|
const availability = await checkProviderLaunchAvailable(launch);
|
|
1593
|
-
const available = availability.available;
|
|
1594
1582
|
const authConfigPath = join(homedir(), ".pi", "agent", "auth.json");
|
|
1595
|
-
let modelsValue = "Not checked";
|
|
1596
|
-
let configuredProvidersValue = "none";
|
|
1597
|
-
let mcpToolsValue = "Not checked";
|
|
1598
|
-
let status = formatDiagnosticStatus(available);
|
|
1599
|
-
if (availability.available) {
|
|
1600
|
-
const runtimeSession = await this.runtime
|
|
1601
|
-
.startSession({ cwd: homedir() })
|
|
1602
|
-
.catch((error) => {
|
|
1603
|
-
status = formatDiagnosticStatus(false, {
|
|
1604
|
-
source: "startup",
|
|
1605
|
-
cause: error,
|
|
1606
|
-
});
|
|
1607
|
-
return null;
|
|
1608
|
-
});
|
|
1609
|
-
if (runtimeSession) {
|
|
1610
|
-
try {
|
|
1611
|
-
const models = await runtimeSession.getAvailableModels();
|
|
1612
|
-
modelsValue = String(models.length);
|
|
1613
|
-
const configuredProviders = Array.from(new Set(models.map((model) => model.provider))).sort();
|
|
1614
|
-
configuredProvidersValue =
|
|
1615
|
-
configuredProviders.length > 0 ? configuredProviders.join(", ") : "none";
|
|
1616
|
-
const commands = await runtimeSession.getCommands();
|
|
1617
|
-
mcpToolsValue = commands.some(isPiMcpAdapterCommand)
|
|
1618
|
-
? "yes (pi-mcp-adapter loaded)"
|
|
1619
|
-
: "no (install pi-mcp-adapter)";
|
|
1620
|
-
}
|
|
1621
|
-
catch (error) {
|
|
1622
|
-
modelsValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1623
|
-
mcpToolsValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1624
|
-
status = formatDiagnosticStatus(available, {
|
|
1625
|
-
source: "model fetch",
|
|
1626
|
-
cause: error,
|
|
1627
|
-
});
|
|
1628
|
-
}
|
|
1629
|
-
finally {
|
|
1630
|
-
await runtimeSession.close().catch(() => undefined);
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
1583
|
return {
|
|
1635
1584
|
diagnostic: formatProviderDiagnostic("Pi", [
|
|
1585
|
+
...(await buildCommandResolutionDiagnosticRows(launch, {
|
|
1586
|
+
knownBinaryNames: [launch.command],
|
|
1587
|
+
})),
|
|
1636
1588
|
...(await buildBinaryDiagnosticRows(launch, availability)),
|
|
1637
|
-
{ label: "Configured providers", value: configuredProvidersValue },
|
|
1638
1589
|
{
|
|
1639
1590
|
label: "Auth config (~/.pi/agent/auth.json)",
|
|
1640
1591
|
value: existsSync(authConfigPath) ? "found" : "not found",
|
|
1641
1592
|
},
|
|
1642
|
-
{ label: "Models", value: modelsValue },
|
|
1643
|
-
{ label: "Paseo MCP tools", value: mcpToolsValue },
|
|
1644
|
-
{ label: "Status", value: status },
|
|
1645
1593
|
]),
|
|
1646
1594
|
};
|
|
1647
1595
|
}
|
|
@@ -95,8 +95,8 @@ class PiCliRuntimeSession {
|
|
|
95
95
|
const data = (await this.request({ type: "get_messages" }));
|
|
96
96
|
return data.messages ?? [];
|
|
97
97
|
}
|
|
98
|
-
async getAvailableModels() {
|
|
99
|
-
const data = (await this.request({ type: "get_available_models" }));
|
|
98
|
+
async getAvailableModels(timeoutMs) {
|
|
99
|
+
const data = (await this.request({ type: "get_available_models" }, timeoutMs));
|
|
100
100
|
return data.models ?? [];
|
|
101
101
|
}
|
|
102
102
|
async setModel(provider, modelId) {
|
|
@@ -33,7 +33,7 @@ export interface PiRuntimeSession {
|
|
|
33
33
|
abort(): Promise<void>;
|
|
34
34
|
getState(): Promise<PiSessionState>;
|
|
35
35
|
getMessages(): Promise<PiAgentMessage[]>;
|
|
36
|
-
getAvailableModels(): Promise<PiModel[]>;
|
|
36
|
+
getAvailableModels(timeoutMs?: number): Promise<PiModel[]>;
|
|
37
37
|
setModel(provider: string, modelId: string): Promise<PiModel>;
|
|
38
38
|
setThinkingLevel(level: string): Promise<void>;
|
|
39
39
|
getSessionStats(): Promise<PiSessionStats>;
|