@getpaseo/server 0.1.98 → 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.js +2 -2
- package/dist/server/server/agent/agent-sdk-types.d.ts +11 -6
- package/dist/server/server/agent/provider-registry.d.ts +6 -3
- package/dist/server/server/agent/provider-registry.js +48 -22
- package/dist/server/server/agent/provider-snapshot-manager.js +26 -14
- 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 +5 -25
- package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +3 -2
- package/dist/server/server/agent/providers/codex-app-server-agent.js +6 -25
- package/dist/server/server/agent/providers/copilot-acp-agent.js +1 -31
- 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 +2 -5
- package/dist/server/server/agent/providers/opencode-agent.d.ts +4 -3
- package/dist/server/server/agent/providers/opencode-agent.js +48 -99
- package/dist/server/server/agent/providers/pi/agent.d.ts +2 -3
- package/dist/server/server/agent/providers/pi/agent.js +8 -73
- 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/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 +13 -208
- package/dist/server/server/session.js +2132 -5105
- package/dist/server/utils/checkout-git.d.ts +6 -0
- package/package.json +5 -5
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import { homedir } from "node:os";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { checkProviderLaunchAvailable, resolveProviderLaunch } from "../provider-launch-config.js";
|
|
4
|
-
import { ACPAgentClient, DEFAULT_ACP_CAPABILITIES
|
|
5
|
-
import {
|
|
6
|
-
const ACP_DIAGNOSTIC_INITIALIZE_TIMEOUT_MS = 8000;
|
|
7
|
-
const ACP_DIAGNOSTIC_SESSION_TIMEOUT_MS = 8000;
|
|
3
|
+
import { ACPAgentClient, DEFAULT_ACP_CAPABILITIES } from "./acp-agent.js";
|
|
4
|
+
import { formatProviderDiagnostic, formatProviderDiagnosticError, buildBinaryDiagnosticRows, } from "./diagnostic-utils.js";
|
|
8
5
|
export const GenericACPProviderParamsSchema = z
|
|
9
6
|
.object({
|
|
10
7
|
supportsMcpServers: z.boolean().optional(),
|
|
@@ -43,17 +40,7 @@ export class GenericACPAgentClient extends ACPAgentClient {
|
|
|
43
40
|
try {
|
|
44
41
|
const launch = await this.resolveConfiguredLaunch();
|
|
45
42
|
const availability = await checkProviderLaunchAvailable(launch);
|
|
46
|
-
const available = availability.available;
|
|
47
43
|
const versionProbe = buildVersionProbeCommand(this.command);
|
|
48
|
-
const probeResult = available
|
|
49
|
-
? await this.runDiagnosticACPProbe()
|
|
50
|
-
: {
|
|
51
|
-
status: formatDiagnosticStatus(false),
|
|
52
|
-
initialize: "Not checked",
|
|
53
|
-
session: "Not checked",
|
|
54
|
-
models: "Not checked",
|
|
55
|
-
modes: "Not checked",
|
|
56
|
-
};
|
|
57
44
|
return {
|
|
58
45
|
diagnostic: formatProviderDiagnostic(providerName, [
|
|
59
46
|
{ label: "Provider ID", value: this.providerId ?? "unknown" },
|
|
@@ -70,11 +57,6 @@ export class GenericACPAgentClient extends ACPAgentClient {
|
|
|
70
57
|
label: "Version command",
|
|
71
58
|
value: formatCommand(versionProbe.command, versionProbe.args),
|
|
72
59
|
},
|
|
73
|
-
{ label: "ACP initialize", value: probeResult.initialize },
|
|
74
|
-
{ label: "ACP session/new", value: probeResult.session },
|
|
75
|
-
{ label: "Models", value: probeResult.models },
|
|
76
|
-
{ label: "Modes", value: probeResult.modes },
|
|
77
|
-
{ label: "Status", value: probeResult.status },
|
|
78
60
|
]),
|
|
79
61
|
};
|
|
80
62
|
}
|
|
@@ -90,50 +72,6 @@ export class GenericACPAgentClient extends ACPAgentClient {
|
|
|
90
72
|
defaultBinary: this.command[0],
|
|
91
73
|
});
|
|
92
74
|
}
|
|
93
|
-
async runDiagnosticACPProbe() {
|
|
94
|
-
let initializeValue = "Not checked";
|
|
95
|
-
let sessionValue = "Not checked";
|
|
96
|
-
try {
|
|
97
|
-
const probe = await this.spawnProcess({
|
|
98
|
-
NO_BROWSER: "true",
|
|
99
|
-
NO_OPEN_BROWSER: "1",
|
|
100
|
-
GEMINI_CLI_NO_BROWSER: "true",
|
|
101
|
-
CI: "1",
|
|
102
|
-
}, {
|
|
103
|
-
initializeTimeoutMs: ACP_DIAGNOSTIC_INITIALIZE_TIMEOUT_MS,
|
|
104
|
-
});
|
|
105
|
-
try {
|
|
106
|
-
initializeValue = formatInitializeResult(probe.initialize);
|
|
107
|
-
const response = await withTimeout(probe.connection.newSession({
|
|
108
|
-
cwd: homedir(),
|
|
109
|
-
mcpServers: [],
|
|
110
|
-
}), ACP_DIAGNOSTIC_SESSION_TIMEOUT_MS, "ACP session/new");
|
|
111
|
-
sessionValue = response.sessionId ? `ok (${response.sessionId})` : "ok";
|
|
112
|
-
const transformed = this.transformSessionResponse(response);
|
|
113
|
-
return {
|
|
114
|
-
status: formatDiagnosticStatus(true),
|
|
115
|
-
initialize: initializeValue,
|
|
116
|
-
session: sessionValue,
|
|
117
|
-
...summarizeSessionState(this.provider, transformed),
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
finally {
|
|
121
|
-
await this.closeProbe(probe);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
catch (error) {
|
|
125
|
-
return {
|
|
126
|
-
status: formatDiagnosticStatus(true, {
|
|
127
|
-
source: "ACP probe",
|
|
128
|
-
cause: error,
|
|
129
|
-
}),
|
|
130
|
-
initialize: formatProbeError(initializeValue, error),
|
|
131
|
-
session: initializeValue === "Not checked" ? "Not checked" : formatProbeError(sessionValue, error),
|
|
132
|
-
models: "Not checked",
|
|
133
|
-
modes: "Not checked",
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
75
|
}
|
|
138
76
|
function buildGenericACPCapabilities(options) {
|
|
139
77
|
const params = parseGenericACPProviderParams(options.providerParams);
|
|
@@ -200,48 +138,4 @@ function takePackageSpecPrefix(args) {
|
|
|
200
138
|
}
|
|
201
139
|
return prefix;
|
|
202
140
|
}
|
|
203
|
-
function formatInitializeResult(initialize) {
|
|
204
|
-
const agentInfo = isAgentInfo(initialize.agentInfo)
|
|
205
|
-
? `${initialize.agentInfo.name}${initialize.agentInfo.version ? ` ${initialize.agentInfo.version}` : ""}`
|
|
206
|
-
: "ok";
|
|
207
|
-
return `ok (protocol ${initialize.protocolVersion}, ${agentInfo})`;
|
|
208
|
-
}
|
|
209
|
-
function isAgentInfo(value) {
|
|
210
|
-
return (typeof value === "object" &&
|
|
211
|
-
value !== null &&
|
|
212
|
-
"name" in value &&
|
|
213
|
-
typeof Reflect.get(value, "name") === "string");
|
|
214
|
-
}
|
|
215
|
-
function summarizeSessionState(provider, response) {
|
|
216
|
-
const models = deriveModelDefinitionsFromACP(provider, response.models, response.configOptions);
|
|
217
|
-
const { modes } = deriveModesFromACP([], response.modes, response.configOptions);
|
|
218
|
-
return {
|
|
219
|
-
models: `${models.length}`,
|
|
220
|
-
modes: modes.length > 0 ? modes.map((mode) => mode.label || mode.id).join(", ") : "none reported",
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
function formatProbeError(currentValue, error) {
|
|
224
|
-
if (currentValue !== "Not checked") {
|
|
225
|
-
return currentValue;
|
|
226
|
-
}
|
|
227
|
-
return `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
228
|
-
}
|
|
229
|
-
async function withTimeout(promise, timeoutMs, label) {
|
|
230
|
-
let timeout = null;
|
|
231
|
-
try {
|
|
232
|
-
return await Promise.race([
|
|
233
|
-
promise,
|
|
234
|
-
new Promise((_, reject) => {
|
|
235
|
-
timeout = setTimeout(() => {
|
|
236
|
-
reject(new Error(`${label} timed out after ${timeoutMs}ms`));
|
|
237
|
-
}, timeoutMs);
|
|
238
|
-
}),
|
|
239
|
-
]);
|
|
240
|
-
}
|
|
241
|
-
finally {
|
|
242
|
-
if (timeout) {
|
|
243
|
-
clearTimeout(timeout);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
141
|
//# sourceMappingURL=generic-acp-agent.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Logger } from "pino";
|
|
2
|
-
import type { AgentCapabilityFlags, AgentClient, AgentFeature, AgentLaunchContext, AgentMode,
|
|
2
|
+
import type { AgentCapabilityFlags, AgentClient, AgentFeature, AgentLaunchContext, AgentMode, AgentPersistenceHandle, AgentPermissionRequest, AgentPermissionResponse, AgentPermissionResult, AgentPromptInput, AgentProvider, AgentRunOptions, AgentRunResult, AgentRuntimeInfo, AgentSession, AgentSessionConfig, AgentStreamEvent, FetchCatalogOptions, ImportableProviderSession, ImportProviderSessionContext, ImportProviderSessionInput, ProviderCatalog } from "../agent-sdk-types.js";
|
|
3
3
|
export declare const MOCK_LOAD_TEST_PROVIDER_ID = "mock";
|
|
4
4
|
export declare const MOCK_LOAD_TEST_DEFAULT_MODEL_ID = "five-minute-stream";
|
|
5
5
|
export declare class MockLoadTestAgentClient implements AgentClient {
|
|
@@ -9,8 +9,7 @@ export declare class MockLoadTestAgentClient implements AgentClient {
|
|
|
9
9
|
constructor(logger?: Logger | undefined);
|
|
10
10
|
createSession(config: AgentSessionConfig, _launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
11
11
|
resumeSession(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>, _launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
12
|
-
|
|
13
|
-
listModes(_options: ListModesOptions): Promise<AgentMode[]>;
|
|
12
|
+
fetchCatalog(_options: FetchCatalogOptions): Promise<ProviderCatalog>;
|
|
14
13
|
listImportableSessions(): Promise<ImportableProviderSession[]>;
|
|
15
14
|
importSession(input: ImportProviderSessionInput, context: ImportProviderSessionContext): Promise<import("../agent-sdk-types.js").ImportedProviderSession>;
|
|
16
15
|
isAvailable(): Promise<boolean>;
|
|
@@ -379,11 +379,11 @@ export class MockLoadTestAgentClient {
|
|
|
379
379
|
logger: this.logger,
|
|
380
380
|
});
|
|
381
381
|
}
|
|
382
|
-
async
|
|
383
|
-
return
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
382
|
+
async fetchCatalog(_options) {
|
|
383
|
+
return {
|
|
384
|
+
models: MODELS,
|
|
385
|
+
modes: getAgentProviderDefinition(MOCK_LOAD_TEST_PROVIDER_ID).modes,
|
|
386
|
+
};
|
|
387
387
|
}
|
|
388
388
|
async listImportableSessions() {
|
|
389
389
|
return [];
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type { AgentCapabilityFlags, AgentClient, AgentLaunchContext,
|
|
1
|
+
import type { AgentCapabilityFlags, AgentClient, AgentLaunchContext, AgentPersistenceHandle, AgentProvider, AgentSession, AgentSessionConfig, FetchCatalogOptions, ProviderCatalog } from "../agent-sdk-types.js";
|
|
2
2
|
export declare const MOCK_SLOW_PROVIDER_ID = "mock-slow";
|
|
3
3
|
export declare class MockSlowProviderClient implements AgentClient {
|
|
4
4
|
readonly provider: AgentProvider;
|
|
5
5
|
readonly capabilities: AgentCapabilityFlags;
|
|
6
6
|
isAvailable(): Promise<boolean>;
|
|
7
|
-
|
|
8
|
-
listModes(_options: ListModesOptions): Promise<AgentMode[]>;
|
|
7
|
+
fetchCatalog(_options: FetchCatalogOptions): Promise<ProviderCatalog>;
|
|
9
8
|
getDiagnostic(): Promise<{
|
|
10
9
|
diagnostic: string;
|
|
11
10
|
}>;
|
|
@@ -21,15 +21,12 @@ export class MockSlowProviderClient {
|
|
|
21
21
|
async isAvailable() {
|
|
22
22
|
return process.env.PASEO_ENABLE_MOCK_SLOW === "true";
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
return neverResolves();
|
|
26
|
-
}
|
|
27
|
-
listModes(_options) {
|
|
24
|
+
async fetchCatalog(_options) {
|
|
28
25
|
return neverResolves();
|
|
29
26
|
}
|
|
30
27
|
async getDiagnostic() {
|
|
31
28
|
return {
|
|
32
|
-
diagnostic: "Mock slow provider: dev-only.
|
|
29
|
+
diagnostic: "Mock slow provider: dev-only. fetchCatalog() never resolves so the snapshot manager will time out.",
|
|
33
30
|
};
|
|
34
31
|
}
|
|
35
32
|
createSession(_config, _launchContext) {
|
|
@@ -1,6 +1,6 @@
|
|
|
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";
|
|
@@ -118,8 +118,7 @@ export declare class OpenCodeAgentClient implements AgentClient {
|
|
|
118
118
|
constructor(logger: Logger, runtimeSettings?: ProviderRuntimeSettings, deps?: OpenCodeAgentClientDeps);
|
|
119
119
|
createSession(config: AgentSessionConfig, launchContext?: AgentLaunchContext, options?: AgentCreateSessionOptions): Promise<AgentSession>;
|
|
120
120
|
resumeSession(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>, launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
121
|
-
|
|
122
|
-
listModes(options: ListModesOptions): Promise<AgentMode[]>;
|
|
121
|
+
fetchCatalog(options: FetchCatalogOptions): Promise<ProviderCatalog>;
|
|
123
122
|
listCommands(config: AgentSessionConfig): Promise<AgentSlashCommand[]>;
|
|
124
123
|
listFeatures(config: AgentSessionConfig): Promise<AgentFeature[]>;
|
|
125
124
|
listImportableSessions(options?: ListImportableSessionsOptions): Promise<ImportableProviderSession[]>;
|
|
@@ -129,6 +128,8 @@ export declare class OpenCodeAgentClient implements AgentClient {
|
|
|
129
128
|
getDiagnostic(): Promise<{
|
|
130
129
|
diagnostic: string;
|
|
131
130
|
}>;
|
|
131
|
+
private fetchModelsFromClient;
|
|
132
|
+
private fetchModesFromClient;
|
|
132
133
|
private assertConfig;
|
|
133
134
|
private populateModelContextWindowCache;
|
|
134
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";
|
|
@@ -940,70 +939,17 @@ export class OpenCodeAgentClient {
|
|
|
940
939
|
throw error;
|
|
941
940
|
}
|
|
942
941
|
}
|
|
943
|
-
async
|
|
944
|
-
const acquisition = await this.runtime.acquireServer({ force: options.force });
|
|
945
|
-
const { url } = acquisition.server;
|
|
946
|
-
const client = this.runtime.createClient({
|
|
947
|
-
baseUrl: url,
|
|
948
|
-
directory: options.cwd,
|
|
949
|
-
});
|
|
950
|
-
try {
|
|
951
|
-
// Background model discovery can be legitimately slow while OpenCode refreshes
|
|
952
|
-
// provider state, so allow longer than turn execution paths.
|
|
953
|
-
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`));
|
|
954
|
-
if (response.error) {
|
|
955
|
-
throw new Error(`Failed to fetch OpenCode providers: ${JSON.stringify(response.error)}`);
|
|
956
|
-
}
|
|
957
|
-
const providers = response.data;
|
|
958
|
-
if (!providers) {
|
|
959
|
-
return [];
|
|
960
|
-
}
|
|
961
|
-
const connectedProviderIds = new Set(providers.connected);
|
|
962
|
-
// Providers with source "api" are managed by the OpenCode console/subscription (e.g. Pi
|
|
963
|
-
// coding agent). They do not appear in `connected` (which only lists env/config providers)
|
|
964
|
-
// but are fully usable — OpenCode authenticates them internally via the console session.
|
|
965
|
-
const isAccessible = (provider) => connectedProviderIds.has(provider.id) || provider.source === "api";
|
|
966
|
-
// Fail fast if no providers are accessible at all
|
|
967
|
-
if (!providers.all.some(isAccessible)) {
|
|
968
|
-
throw new Error("OpenCode has no connected providers. Please authenticate with at least one provider " +
|
|
969
|
-
"(e.g., openai, anthropic), set appropriate environment variables (e.g., OPENAI_API_KEY), " +
|
|
970
|
-
"or log in to OpenCode Go via the console.");
|
|
971
|
-
}
|
|
972
|
-
const models = [];
|
|
973
|
-
this.modelContextWindows.clear();
|
|
974
|
-
for (const provider of providers.all) {
|
|
975
|
-
if (!isAccessible(provider)) {
|
|
976
|
-
continue;
|
|
977
|
-
}
|
|
978
|
-
for (const [modelId, model] of Object.entries(provider.models)) {
|
|
979
|
-
const definition = buildOpenCodeModelDefinition(provider, modelId, model);
|
|
980
|
-
const contextWindowMaxTokens = extractOpenCodeModelContextWindow(model);
|
|
981
|
-
if (contextWindowMaxTokens !== undefined) {
|
|
982
|
-
this.modelContextWindows.set(buildOpenCodeModelLookupKey(provider.id, modelId), contextWindowMaxTokens);
|
|
983
|
-
}
|
|
984
|
-
models.push(definition);
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
return models;
|
|
988
|
-
}
|
|
989
|
-
finally {
|
|
990
|
-
acquisition.release();
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
async listModes(options) {
|
|
942
|
+
async fetchCatalog(options) {
|
|
994
943
|
const acquisition = await this.runtime.acquireServer({ force: options.force });
|
|
995
944
|
const { url } = acquisition.server;
|
|
996
945
|
const directory = options.cwd;
|
|
997
946
|
const client = this.runtime.createClient({ baseUrl: url, directory });
|
|
998
947
|
try {
|
|
999
|
-
const
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
.filter(isSelectableOpenCodeAgent)
|
|
1005
|
-
.map(mapOpenCodeAgentToMode);
|
|
1006
|
-
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 };
|
|
1007
953
|
}
|
|
1008
954
|
finally {
|
|
1009
955
|
acquisition.release();
|
|
@@ -1094,17 +1040,6 @@ export class OpenCodeAgentClient {
|
|
|
1094
1040
|
defaultBinary: "opencode",
|
|
1095
1041
|
});
|
|
1096
1042
|
const availability = await checkProviderLaunchAvailable(launch);
|
|
1097
|
-
const available = availability.available;
|
|
1098
|
-
let serverStatus = "Not running";
|
|
1099
|
-
let modelsValue = "Not checked";
|
|
1100
|
-
let status = formatDiagnosticStatus(available);
|
|
1101
|
-
try {
|
|
1102
|
-
const { url } = await this.runtime.ensureServerRunning();
|
|
1103
|
-
serverStatus = `Running (${url})`;
|
|
1104
|
-
}
|
|
1105
|
-
catch (error) {
|
|
1106
|
-
serverStatus = `Unavailable (${toDiagnosticErrorMessage(error)})`;
|
|
1107
|
-
}
|
|
1108
1043
|
let authValue = "Not checked";
|
|
1109
1044
|
const authCommand = availability.available
|
|
1110
1045
|
? (availability.resolvedPath ?? launch.command)
|
|
@@ -1122,40 +1057,13 @@ export class OpenCodeAgentClient {
|
|
|
1122
1057
|
authValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1123
1058
|
}
|
|
1124
1059
|
}
|
|
1125
|
-
if (available) {
|
|
1126
|
-
try {
|
|
1127
|
-
const models = await this.listModels({ cwd: homedir(), force: false });
|
|
1128
|
-
modelsValue = String(models.length);
|
|
1129
|
-
}
|
|
1130
|
-
catch (error) {
|
|
1131
|
-
modelsValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1132
|
-
status = formatDiagnosticStatus(available, {
|
|
1133
|
-
source: "model fetch",
|
|
1134
|
-
cause: error,
|
|
1135
|
-
});
|
|
1136
|
-
}
|
|
1137
|
-
if (!modelsValue.startsWith("Error -")) {
|
|
1138
|
-
try {
|
|
1139
|
-
await this.listModes({ cwd: homedir(), force: false });
|
|
1140
|
-
}
|
|
1141
|
-
catch (error) {
|
|
1142
|
-
status = formatDiagnosticStatus(available, {
|
|
1143
|
-
source: "mode fetch",
|
|
1144
|
-
cause: error,
|
|
1145
|
-
});
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
1060
|
return {
|
|
1150
1061
|
diagnostic: formatProviderDiagnostic("OpenCode", [
|
|
1151
1062
|
...(await buildCommandResolutionDiagnosticRows(launch, {
|
|
1152
1063
|
knownBinaryNames: ["opencode"],
|
|
1153
1064
|
})),
|
|
1154
1065
|
...(await buildBinaryDiagnosticRows(launch, availability)),
|
|
1155
|
-
{ label: "Server", value: serverStatus },
|
|
1156
1066
|
{ label: "Auth", value: authValue },
|
|
1157
|
-
{ label: "Models", value: modelsValue },
|
|
1158
|
-
{ label: "Status", value: status },
|
|
1159
1067
|
]),
|
|
1160
1068
|
};
|
|
1161
1069
|
}
|
|
@@ -1165,6 +1073,47 @@ export class OpenCodeAgentClient {
|
|
|
1165
1073
|
};
|
|
1166
1074
|
}
|
|
1167
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
|
+
}
|
|
1168
1117
|
assertConfig(config) {
|
|
1169
1118
|
if (config.provider !== "opencode") {
|
|
1170
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>;
|
|
@@ -3,13 +3,12 @@ import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { homedir, tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
import { withTimeout } from "../../../../utils/promise-timeout.js";
|
|
7
6
|
import { importSessionFromPersistence } from "../../provider-session-import.js";
|
|
8
7
|
import { runProviderTurn } from "../provider-runner.js";
|
|
9
8
|
import { checkProviderLaunchAvailable, resolveProviderLaunch, } from "../../provider-launch-config.js";
|
|
10
9
|
import { renderPromptAttachmentAsText } from "../../prompt-attachments.js";
|
|
11
10
|
import { composeSystemPromptParts } from "../../system-prompt.js";
|
|
12
|
-
import { buildBinaryDiagnosticRows, buildCommandResolutionDiagnosticRows,
|
|
11
|
+
import { buildBinaryDiagnosticRows, buildCommandResolutionDiagnosticRows, formatProviderDiagnostic, formatProviderDiagnosticError, toDiagnosticErrorMessage, } from "../diagnostic-utils.js";
|
|
13
12
|
import { getUserMessageText, streamPiHistory, } from "./history-mapper.js";
|
|
14
13
|
import { PiCliRuntime } from "./cli-runtime.js";
|
|
15
14
|
import { revertPiConversation } from "./rewind.js";
|
|
@@ -18,6 +17,7 @@ import { mapToolDetail, parseToolArgs, parseToolResult, resolveToolCallName, } f
|
|
|
18
17
|
const PI_PROVIDER = "pi";
|
|
19
18
|
const DEFAULT_PI_THINKING_LEVEL = "medium";
|
|
20
19
|
const PI_BINARY_COMMAND = process.env.PI_COMMAND ?? process.env.PI_ACP_PI_COMMAND ?? "pi";
|
|
20
|
+
const PI_CATALOG_REQUEST_TIMEOUT_MS = 120000;
|
|
21
21
|
const PASEO_PI_TREE_EXTENSION_COMMAND = "paseo_tree";
|
|
22
22
|
const PASEO_PI_CAPTURE_EXTENSION_COMMAND = "paseo_capture_entries";
|
|
23
23
|
const PASEO_PI_ENTRY_CAPTURE_MARKER = "PASEO_ENTRY_CAPTURE";
|
|
@@ -1538,18 +1538,16 @@ export class PiRpcAgentClient {
|
|
|
1538
1538
|
throw error;
|
|
1539
1539
|
}
|
|
1540
1540
|
}
|
|
1541
|
-
async
|
|
1541
|
+
async fetchCatalog(options) {
|
|
1542
1542
|
const runtimeSession = await this.runtime.startSession({ cwd: options.cwd });
|
|
1543
1543
|
try {
|
|
1544
|
-
|
|
1544
|
+
const models = transformPiModels((await runtimeSession.getAvailableModels(PI_CATALOG_REQUEST_TIMEOUT_MS)).map(mapPiModel));
|
|
1545
|
+
return { models, modes: [] };
|
|
1545
1546
|
}
|
|
1546
1547
|
finally {
|
|
1547
1548
|
await runtimeSession.close();
|
|
1548
1549
|
}
|
|
1549
1550
|
}
|
|
1550
|
-
async listModes(_options) {
|
|
1551
|
-
return [];
|
|
1552
|
-
}
|
|
1553
1551
|
async listImportableSessions(options) {
|
|
1554
1552
|
return await listPiImportableSessions({
|
|
1555
1553
|
...options,
|
|
@@ -1569,28 +1567,9 @@ export class PiRpcAgentClient {
|
|
|
1569
1567
|
}
|
|
1570
1568
|
async isAvailable() {
|
|
1571
1569
|
try {
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
if (!availability.available) {
|
|
1576
|
-
return false;
|
|
1577
|
-
}
|
|
1578
|
-
const runtimeSession = await this.runtime
|
|
1579
|
-
.startSession({ cwd: homedir() })
|
|
1580
|
-
.catch(() => null);
|
|
1581
|
-
if (!runtimeSession) {
|
|
1582
|
-
return false;
|
|
1583
|
-
}
|
|
1584
|
-
try {
|
|
1585
|
-
return (await runtimeSession.getAvailableModels()).length > 0;
|
|
1586
|
-
}
|
|
1587
|
-
catch {
|
|
1588
|
-
return false;
|
|
1589
|
-
}
|
|
1590
|
-
finally {
|
|
1591
|
-
await runtimeSession.close().catch(() => undefined);
|
|
1592
|
-
}
|
|
1593
|
-
})(), 2000, "Pi availability check timed out");
|
|
1570
|
+
const launch = await this.resolvePiLaunch();
|
|
1571
|
+
const availability = await checkProviderLaunchAvailable(launch);
|
|
1572
|
+
return availability.available;
|
|
1594
1573
|
}
|
|
1595
1574
|
catch {
|
|
1596
1575
|
return false;
|
|
@@ -1600,61 +1579,17 @@ export class PiRpcAgentClient {
|
|
|
1600
1579
|
try {
|
|
1601
1580
|
const launch = await this.resolvePiLaunch();
|
|
1602
1581
|
const availability = await checkProviderLaunchAvailable(launch);
|
|
1603
|
-
const available = availability.available;
|
|
1604
1582
|
const authConfigPath = join(homedir(), ".pi", "agent", "auth.json");
|
|
1605
|
-
let modelsValue = "Not checked";
|
|
1606
|
-
let configuredProvidersValue = "none";
|
|
1607
|
-
let mcpToolsValue = "Not checked";
|
|
1608
|
-
let status = formatDiagnosticStatus(available);
|
|
1609
|
-
if (availability.available) {
|
|
1610
|
-
const runtimeSession = await this.runtime
|
|
1611
|
-
.startSession({ cwd: homedir() })
|
|
1612
|
-
.catch((error) => {
|
|
1613
|
-
status = formatDiagnosticStatus(false, {
|
|
1614
|
-
source: "startup",
|
|
1615
|
-
cause: error,
|
|
1616
|
-
});
|
|
1617
|
-
return null;
|
|
1618
|
-
});
|
|
1619
|
-
if (runtimeSession) {
|
|
1620
|
-
try {
|
|
1621
|
-
const models = await runtimeSession.getAvailableModels();
|
|
1622
|
-
modelsValue = String(models.length);
|
|
1623
|
-
const configuredProviders = Array.from(new Set(models.map((model) => model.provider))).sort();
|
|
1624
|
-
configuredProvidersValue =
|
|
1625
|
-
configuredProviders.length > 0 ? configuredProviders.join(", ") : "none";
|
|
1626
|
-
const commands = await runtimeSession.getCommands();
|
|
1627
|
-
mcpToolsValue = commands.some(isPiMcpAdapterCommand)
|
|
1628
|
-
? "yes (pi-mcp-adapter loaded)"
|
|
1629
|
-
: "no (install pi-mcp-adapter)";
|
|
1630
|
-
}
|
|
1631
|
-
catch (error) {
|
|
1632
|
-
modelsValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1633
|
-
mcpToolsValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1634
|
-
status = formatDiagnosticStatus(available, {
|
|
1635
|
-
source: "model fetch",
|
|
1636
|
-
cause: error,
|
|
1637
|
-
});
|
|
1638
|
-
}
|
|
1639
|
-
finally {
|
|
1640
|
-
await runtimeSession.close().catch(() => undefined);
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
1583
|
return {
|
|
1645
1584
|
diagnostic: formatProviderDiagnostic("Pi", [
|
|
1646
1585
|
...(await buildCommandResolutionDiagnosticRows(launch, {
|
|
1647
1586
|
knownBinaryNames: [launch.command],
|
|
1648
1587
|
})),
|
|
1649
1588
|
...(await buildBinaryDiagnosticRows(launch, availability)),
|
|
1650
|
-
{ label: "Configured providers", value: configuredProvidersValue },
|
|
1651
1589
|
{
|
|
1652
1590
|
label: "Auth config (~/.pi/agent/auth.json)",
|
|
1653
1591
|
value: existsSync(authConfigPath) ? "found" : "not found",
|
|
1654
1592
|
},
|
|
1655
|
-
{ label: "Models", value: modelsValue },
|
|
1656
|
-
{ label: "Paseo MCP tools", value: mcpToolsValue },
|
|
1657
|
-
{ label: "Status", value: status },
|
|
1658
1593
|
]),
|
|
1659
1594
|
};
|
|
1660
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>;
|
|
@@ -61,7 +61,7 @@ export declare class FakePiSession implements PiRuntimeSession {
|
|
|
61
61
|
abort(): Promise<void>;
|
|
62
62
|
getState(): Promise<PiSessionState>;
|
|
63
63
|
getMessages(): Promise<PiAgentMessage[]>;
|
|
64
|
-
getAvailableModels(): Promise<PiModel[]>;
|
|
64
|
+
getAvailableModels(_timeoutMs?: number): Promise<PiModel[]>;
|
|
65
65
|
setModel(provider: string, modelId: string): Promise<PiModel>;
|
|
66
66
|
setThinkingLevel(level: string): Promise<void>;
|
|
67
67
|
getSessionStats(): Promise<PiSessionStats>;
|