@getpaseo/server 0.1.98 → 0.1.100
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 +49 -22
- package/dist/server/server/agent/provider-snapshot-manager.js +26 -14
- package/dist/server/server/agent/providers/acp-agent.d.ts +23 -3
- package/dist/server/server/agent/providers/acp-agent.js +139 -9
- package/dist/server/server/agent/providers/claude/agent.d.ts +2 -2
- package/dist/server/server/agent/providers/claude/agent.js +41 -77
- 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.d.ts +2 -1
- package/dist/server/server/agent/providers/copilot-acp-agent.js +11 -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/server-manager.d.ts +14 -11
- package/dist/server/server/agent/providers/opencode/server-manager.js +149 -91
- package/dist/server/server/agent/providers/opencode/test-server-manager.d.ts +6 -5
- package/dist/server/server/agent/providers/opencode/test-server-manager.js +13 -3
- package/dist/server/server/agent/providers/opencode/test-utils/{test-opencode-runtime.d.ts → test-opencode-harness.d.ts} +11 -11
- package/dist/server/server/agent/providers/opencode/test-utils/{test-opencode-runtime.js → test-opencode-harness.js} +23 -10
- package/dist/server/server/agent/providers/opencode-agent.d.ts +13 -6
- package/dist/server/server/agent/providers/opencode-agent.js +74 -137
- package/dist/server/server/agent/providers/pi/agent.d.ts +4 -4
- package/dist/server/server/agent/providers/pi/agent.js +13 -76
- package/dist/server/server/agent/providers/pi/cli-runtime.d.ts +3 -0
- package/dist/server/server/agent/providers/pi/cli-runtime.js +8 -5
- package/dist/server/server/agent/providers/pi/rpc-types.d.ts +2 -1
- 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
- package/dist/server/server/agent/providers/opencode/runtime.d.ts +0 -28
- package/dist/server/server/agent/providers/opencode/runtime.js +0 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createOpencodeClient, } from "@opencode-ai/sdk/v2/client";
|
|
2
2
|
import { createPathEquivalenceMatcher } from "../../../utils/path.js";
|
|
3
3
|
import pLimit from "p-limit";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -10,12 +10,11 @@ import { withTimeout } from "../../../utils/promise-timeout.js";
|
|
|
10
10
|
import { execCommand } from "../../../utils/spawn.js";
|
|
11
11
|
import { buildToolCallDisplayModel } from "@getpaseo/protocol/tool-call-display";
|
|
12
12
|
import { mapOpencodeToolCall } from "./opencode/tool-call-mapper.js";
|
|
13
|
-
import { OpenCodeServerManager } from "./opencode/server-manager.js";
|
|
14
|
-
import {
|
|
13
|
+
import { OpenCodeServerManager, } from "./opencode/server-manager.js";
|
|
14
|
+
import { formatProviderDiagnostic, formatProviderDiagnosticError, buildBinaryDiagnosticRows, buildCommandResolutionDiagnosticRows, toDiagnosticErrorMessage, } from "./diagnostic-utils.js";
|
|
15
15
|
import { runProviderTurn } from "./provider-runner.js";
|
|
16
16
|
import { renderPromptAttachmentAsText } from "../prompt-attachments.js";
|
|
17
17
|
import { composeSystemPromptParts } from "../system-prompt.js";
|
|
18
|
-
import { createSdkOpenCodeClient, } from "./opencode/runtime.js";
|
|
19
18
|
import { normalizeProviderReplayTimestamp } from "../provider-history-timestamps.js";
|
|
20
19
|
import { revertOpenCodeConversationAndFiles } from "./opencode/rewind.js";
|
|
21
20
|
const OPENCODE_CAPABILITIES = {
|
|
@@ -852,22 +851,8 @@ export const __openCodeInternals = {
|
|
|
852
851
|
return OpenCodeAgentSession;
|
|
853
852
|
},
|
|
854
853
|
};
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
this.serverManager = serverManager;
|
|
858
|
-
}
|
|
859
|
-
async acquireServer(options) {
|
|
860
|
-
return this.serverManager.acquire(options);
|
|
861
|
-
}
|
|
862
|
-
async ensureServerRunning() {
|
|
863
|
-
return this.serverManager.ensureRunning();
|
|
864
|
-
}
|
|
865
|
-
createClient(options) {
|
|
866
|
-
return createSdkOpenCodeClient(options);
|
|
867
|
-
}
|
|
868
|
-
async shutdown() {
|
|
869
|
-
await this.serverManager.shutdown();
|
|
870
|
-
}
|
|
854
|
+
function createSdkOpenCodeClient(options) {
|
|
855
|
+
return createOpencodeClient(options);
|
|
871
856
|
}
|
|
872
857
|
export class OpenCodeAgentClient {
|
|
873
858
|
constructor(logger, runtimeSettings, deps = {}) {
|
|
@@ -878,20 +863,20 @@ export class OpenCodeAgentClient {
|
|
|
878
863
|
this.modelContextWindows = new Map();
|
|
879
864
|
this.logger = logger.child({ module: "agent", provider: "opencode" });
|
|
880
865
|
this.runtimeSettings = runtimeSettings;
|
|
881
|
-
this.
|
|
882
|
-
deps.
|
|
883
|
-
|
|
866
|
+
this.serverManager =
|
|
867
|
+
deps.serverManager ??
|
|
868
|
+
OpenCodeServerManager.getInstance(this.logger, runtimeSettings, {
|
|
884
869
|
managedProcesses: deps.managedProcesses,
|
|
885
|
-
})
|
|
870
|
+
});
|
|
871
|
+
this.createOpenCodeClient = deps.createClient ?? createSdkOpenCodeClient;
|
|
886
872
|
}
|
|
887
873
|
async createSession(config, launchContext, options) {
|
|
888
874
|
const openCodeConfig = this.assertConfig(config);
|
|
889
|
-
const acquisition =
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
});
|
|
875
|
+
const acquisition = launchContext?.env
|
|
876
|
+
? await this.serverManager.acquireDedicated(launchContext.env)
|
|
877
|
+
: await this.serverManager.acquireCurrent();
|
|
893
878
|
const { url } = acquisition.server;
|
|
894
|
-
const client = this.
|
|
879
|
+
const client = this.createOpenCodeClient({
|
|
895
880
|
baseUrl: url,
|
|
896
881
|
directory: openCodeConfig.cwd,
|
|
897
882
|
});
|
|
@@ -925,9 +910,9 @@ export class OpenCodeAgentClient {
|
|
|
925
910
|
cwd,
|
|
926
911
|
};
|
|
927
912
|
const openCodeConfig = this.assertConfig(config);
|
|
928
|
-
const acquisition = await this.
|
|
913
|
+
const acquisition = await this.serverManager.acquireCurrent();
|
|
929
914
|
const { url } = acquisition.server;
|
|
930
|
-
const client = this.
|
|
915
|
+
const client = this.createOpenCodeClient({
|
|
931
916
|
baseUrl: url,
|
|
932
917
|
directory: openCodeConfig.cwd,
|
|
933
918
|
});
|
|
@@ -940,70 +925,19 @@ export class OpenCodeAgentClient {
|
|
|
940
925
|
throw error;
|
|
941
926
|
}
|
|
942
927
|
}
|
|
943
|
-
async
|
|
944
|
-
const acquisition =
|
|
945
|
-
|
|
946
|
-
|
|
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) {
|
|
994
|
-
const acquisition = await this.runtime.acquireServer({ force: options.force });
|
|
928
|
+
async fetchCatalog(options) {
|
|
929
|
+
const acquisition = options.force
|
|
930
|
+
? await this.serverManager.acquireNew()
|
|
931
|
+
: await this.serverManager.acquireCurrent();
|
|
995
932
|
const { url } = acquisition.server;
|
|
996
933
|
const directory = options.cwd;
|
|
997
|
-
const client = this.
|
|
934
|
+
const client = this.createOpenCodeClient({ baseUrl: url, directory });
|
|
998
935
|
try {
|
|
999
|
-
const
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
.filter(isSelectableOpenCodeAgent)
|
|
1005
|
-
.map(mapOpenCodeAgentToMode);
|
|
1006
|
-
return mergeOpenCodeModes(discovered);
|
|
936
|
+
const [models, modes] = await Promise.all([
|
|
937
|
+
this.fetchModelsFromClient(client, directory),
|
|
938
|
+
this.fetchModesFromClient(client, directory),
|
|
939
|
+
]);
|
|
940
|
+
return { models, modes };
|
|
1007
941
|
}
|
|
1008
942
|
finally {
|
|
1009
943
|
acquisition.release();
|
|
@@ -1011,9 +945,9 @@ export class OpenCodeAgentClient {
|
|
|
1011
945
|
}
|
|
1012
946
|
async listCommands(config) {
|
|
1013
947
|
const openCodeConfig = this.assertConfig(config);
|
|
1014
|
-
const acquisition = await this.
|
|
948
|
+
const acquisition = await this.serverManager.acquireCurrent();
|
|
1015
949
|
const { url } = acquisition.server;
|
|
1016
|
-
const client = this.
|
|
950
|
+
const client = this.createOpenCodeClient({
|
|
1017
951
|
baseUrl: url,
|
|
1018
952
|
directory: openCodeConfig.cwd,
|
|
1019
953
|
});
|
|
@@ -1028,9 +962,9 @@ export class OpenCodeAgentClient {
|
|
|
1028
962
|
return [buildOpenCodeAutoAcceptFeature(this.assertConfig(config))];
|
|
1029
963
|
}
|
|
1030
964
|
async listImportableSessions(options) {
|
|
1031
|
-
const acquisition = await this.
|
|
965
|
+
const acquisition = await this.serverManager.acquireCurrent();
|
|
1032
966
|
const { url } = acquisition.server;
|
|
1033
|
-
const client = this.
|
|
967
|
+
const client = this.createOpenCodeClient({
|
|
1034
968
|
baseUrl: url,
|
|
1035
969
|
directory: options?.cwd ?? "",
|
|
1036
970
|
});
|
|
@@ -1042,9 +976,9 @@ export class OpenCodeAgentClient {
|
|
|
1042
976
|
}
|
|
1043
977
|
}
|
|
1044
978
|
async importSession(input, context) {
|
|
1045
|
-
const acquisition = await this.
|
|
979
|
+
const acquisition = await this.serverManager.acquireCurrent();
|
|
1046
980
|
const { url } = acquisition.server;
|
|
1047
|
-
const client = this.
|
|
981
|
+
const client = this.createOpenCodeClient({
|
|
1048
982
|
baseUrl: url,
|
|
1049
983
|
directory: input.cwd,
|
|
1050
984
|
});
|
|
@@ -1085,7 +1019,7 @@ export class OpenCodeAgentClient {
|
|
|
1085
1019
|
return availability.available;
|
|
1086
1020
|
}
|
|
1087
1021
|
async shutdown() {
|
|
1088
|
-
await this.
|
|
1022
|
+
await this.serverManager.shutdown();
|
|
1089
1023
|
}
|
|
1090
1024
|
async getDiagnostic() {
|
|
1091
1025
|
try {
|
|
@@ -1094,17 +1028,6 @@ export class OpenCodeAgentClient {
|
|
|
1094
1028
|
defaultBinary: "opencode",
|
|
1095
1029
|
});
|
|
1096
1030
|
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
1031
|
let authValue = "Not checked";
|
|
1109
1032
|
const authCommand = availability.available
|
|
1110
1033
|
? (availability.resolvedPath ?? launch.command)
|
|
@@ -1122,40 +1045,13 @@ export class OpenCodeAgentClient {
|
|
|
1122
1045
|
authValue = `Error - ${toDiagnosticErrorMessage(error)}`;
|
|
1123
1046
|
}
|
|
1124
1047
|
}
|
|
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
1048
|
return {
|
|
1150
1049
|
diagnostic: formatProviderDiagnostic("OpenCode", [
|
|
1151
1050
|
...(await buildCommandResolutionDiagnosticRows(launch, {
|
|
1152
1051
|
knownBinaryNames: ["opencode"],
|
|
1153
1052
|
})),
|
|
1154
1053
|
...(await buildBinaryDiagnosticRows(launch, availability)),
|
|
1155
|
-
{ label: "Server", value: serverStatus },
|
|
1156
1054
|
{ label: "Auth", value: authValue },
|
|
1157
|
-
{ label: "Models", value: modelsValue },
|
|
1158
|
-
{ label: "Status", value: status },
|
|
1159
1055
|
]),
|
|
1160
1056
|
};
|
|
1161
1057
|
}
|
|
@@ -1165,6 +1061,47 @@ export class OpenCodeAgentClient {
|
|
|
1165
1061
|
};
|
|
1166
1062
|
}
|
|
1167
1063
|
}
|
|
1064
|
+
async fetchModelsFromClient(client, directory) {
|
|
1065
|
+
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`));
|
|
1066
|
+
if (response.error) {
|
|
1067
|
+
throw new Error(`Failed to fetch OpenCode providers: ${JSON.stringify(response.error)}`);
|
|
1068
|
+
}
|
|
1069
|
+
const providers = response.data;
|
|
1070
|
+
if (!providers) {
|
|
1071
|
+
return [];
|
|
1072
|
+
}
|
|
1073
|
+
const connectedProviderIds = new Set(providers.connected);
|
|
1074
|
+
const isAccessible = (provider) => connectedProviderIds.has(provider.id) || provider.source === "api";
|
|
1075
|
+
if (!providers.all.some(isAccessible)) {
|
|
1076
|
+
throw new Error("OpenCode has no connected providers. Please authenticate with at least one provider " +
|
|
1077
|
+
"(e.g., openai, anthropic), set appropriate environment variables (e.g., OPENAI_API_KEY), " +
|
|
1078
|
+
"or log in to OpenCode Go via the console.");
|
|
1079
|
+
}
|
|
1080
|
+
const models = [];
|
|
1081
|
+
this.modelContextWindows.clear();
|
|
1082
|
+
for (const provider of providers.all) {
|
|
1083
|
+
if (!isAccessible(provider)) {
|
|
1084
|
+
continue;
|
|
1085
|
+
}
|
|
1086
|
+
for (const [modelId, model] of Object.entries(provider.models)) {
|
|
1087
|
+
const definition = buildOpenCodeModelDefinition(provider, modelId, model);
|
|
1088
|
+
const contextWindowMaxTokens = extractOpenCodeModelContextWindow(model);
|
|
1089
|
+
if (contextWindowMaxTokens !== undefined) {
|
|
1090
|
+
this.modelContextWindows.set(buildOpenCodeModelLookupKey(provider.id, modelId), contextWindowMaxTokens);
|
|
1091
|
+
}
|
|
1092
|
+
models.push(definition);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
return models;
|
|
1096
|
+
}
|
|
1097
|
+
async fetchModesFromClient(client, directory) {
|
|
1098
|
+
const response = await openCodeMetadataLimit(() => withTimeout(client.app.agents({ directory }), 10000, "OpenCode app.agents timed out after 10s"));
|
|
1099
|
+
if (response.error || !response.data) {
|
|
1100
|
+
return DEFAULT_MODES;
|
|
1101
|
+
}
|
|
1102
|
+
const discovered = response.data.filter(isSelectableOpenCodeAgent).map(mapOpenCodeAgentToMode);
|
|
1103
|
+
return mergeOpenCodeModes(discovered);
|
|
1104
|
+
}
|
|
1168
1105
|
assertConfig(config) {
|
|
1169
1106
|
if (config.provider !== "opencode") {
|
|
1170
1107
|
throw new Error(`OpenCodeAgentClient received config for provider '${config.provider}'`);
|
|
@@ -1,9 +1,9 @@
|
|
|
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
|
-
import type { PiSessionState } from "./rpc-types.js";
|
|
6
|
+
import type { PiCommandsRpcType, PiSessionState } from "./rpc-types.js";
|
|
7
7
|
export declare const PiProviderParamsSchema: z.ZodObject<{
|
|
8
8
|
sessionDir: z.ZodOptional<z.ZodString>;
|
|
9
9
|
}, z.core.$strict>;
|
|
@@ -11,6 +11,7 @@ interface PiRpcAgentClientOptions {
|
|
|
11
11
|
logger: Logger;
|
|
12
12
|
runtimeSettings?: ProviderRuntimeSettings;
|
|
13
13
|
providerParams?: unknown;
|
|
14
|
+
commandsRpcType?: PiCommandsRpcType;
|
|
14
15
|
runtime?: PiRuntime;
|
|
15
16
|
}
|
|
16
17
|
interface StartTurnResult {
|
|
@@ -112,8 +113,7 @@ export declare class PiRpcAgentClient implements AgentClient {
|
|
|
112
113
|
constructor(options: PiRpcAgentClientOptions);
|
|
113
114
|
createSession(config: AgentSessionConfig, launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
114
115
|
resumeSession(handle: AgentPersistenceHandle, overrides?: Partial<AgentSessionConfig>, _launchContext?: AgentLaunchContext): Promise<AgentSession>;
|
|
115
|
-
|
|
116
|
-
listModes(_options: ListModesOptions): Promise<AgentMode[]>;
|
|
116
|
+
fetchCatalog(options: FetchCatalogOptions): Promise<ProviderCatalog>;
|
|
117
117
|
listImportableSessions(options?: ListImportableSessionsOptions): Promise<ImportableProviderSession[]>;
|
|
118
118
|
importSession(input: ImportProviderSessionInput, context: ImportProviderSessionContext): Promise<import("../../agent-sdk-types.js").ImportedProviderSession>;
|
|
119
119
|
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";
|
|
@@ -685,8 +685,8 @@ function mapPiModel(model) {
|
|
|
685
685
|
defaultThinkingOptionId: model.reasoning ? DEFAULT_PI_THINKING_LEVEL : undefined,
|
|
686
686
|
};
|
|
687
687
|
}
|
|
688
|
-
function createRuntime(logger, runtimeSettings) {
|
|
689
|
-
return new PiCliRuntime({ logger, runtimeSettings });
|
|
688
|
+
function createRuntime(logger, runtimeSettings, commandsRpcType) {
|
|
689
|
+
return new PiCliRuntime({ logger, runtimeSettings, commandsRpcType });
|
|
690
690
|
}
|
|
691
691
|
export class PiRpcAgentSession {
|
|
692
692
|
constructor(options) {
|
|
@@ -1458,7 +1458,9 @@ export class PiRpcAgentClient {
|
|
|
1458
1458
|
this.logger = options.logger;
|
|
1459
1459
|
this.runtimeSettings = options.runtimeSettings;
|
|
1460
1460
|
this.providerParams = PiProviderParamsSchema.parse(options.providerParams ?? {});
|
|
1461
|
-
this.runtime =
|
|
1461
|
+
this.runtime =
|
|
1462
|
+
options.runtime ??
|
|
1463
|
+
createRuntime(options.logger, options.runtimeSettings, options.commandsRpcType);
|
|
1462
1464
|
}
|
|
1463
1465
|
async createSession(config, launchContext) {
|
|
1464
1466
|
const mcpConfig = await this.prepareMcpConfig(config.cwd, config.mcpServers);
|
|
@@ -1538,18 +1540,16 @@ export class PiRpcAgentClient {
|
|
|
1538
1540
|
throw error;
|
|
1539
1541
|
}
|
|
1540
1542
|
}
|
|
1541
|
-
async
|
|
1543
|
+
async fetchCatalog(options) {
|
|
1542
1544
|
const runtimeSession = await this.runtime.startSession({ cwd: options.cwd });
|
|
1543
1545
|
try {
|
|
1544
|
-
|
|
1546
|
+
const models = transformPiModels((await runtimeSession.getAvailableModels(PI_CATALOG_REQUEST_TIMEOUT_MS)).map(mapPiModel));
|
|
1547
|
+
return { models, modes: [] };
|
|
1545
1548
|
}
|
|
1546
1549
|
finally {
|
|
1547
1550
|
await runtimeSession.close();
|
|
1548
1551
|
}
|
|
1549
1552
|
}
|
|
1550
|
-
async listModes(_options) {
|
|
1551
|
-
return [];
|
|
1552
|
-
}
|
|
1553
1553
|
async listImportableSessions(options) {
|
|
1554
1554
|
return await listPiImportableSessions({
|
|
1555
1555
|
...options,
|
|
@@ -1569,28 +1569,9 @@ export class PiRpcAgentClient {
|
|
|
1569
1569
|
}
|
|
1570
1570
|
async isAvailable() {
|
|
1571
1571
|
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");
|
|
1572
|
+
const launch = await this.resolvePiLaunch();
|
|
1573
|
+
const availability = await checkProviderLaunchAvailable(launch);
|
|
1574
|
+
return availability.available;
|
|
1594
1575
|
}
|
|
1595
1576
|
catch {
|
|
1596
1577
|
return false;
|
|
@@ -1600,61 +1581,17 @@ export class PiRpcAgentClient {
|
|
|
1600
1581
|
try {
|
|
1601
1582
|
const launch = await this.resolvePiLaunch();
|
|
1602
1583
|
const availability = await checkProviderLaunchAvailable(launch);
|
|
1603
|
-
const available = availability.available;
|
|
1604
1584
|
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
1585
|
return {
|
|
1645
1586
|
diagnostic: formatProviderDiagnostic("Pi", [
|
|
1646
1587
|
...(await buildCommandResolutionDiagnosticRows(launch, {
|
|
1647
1588
|
knownBinaryNames: [launch.command],
|
|
1648
1589
|
})),
|
|
1649
1590
|
...(await buildBinaryDiagnosticRows(launch, availability)),
|
|
1650
|
-
{ label: "Configured providers", value: configuredProvidersValue },
|
|
1651
1591
|
{
|
|
1652
1592
|
label: "Auth config (~/.pi/agent/auth.json)",
|
|
1653
1593
|
value: existsSync(authConfigPath) ? "found" : "not found",
|
|
1654
1594
|
},
|
|
1655
|
-
{ label: "Models", value: modelsValue },
|
|
1656
|
-
{ label: "Paseo MCP tools", value: mcpToolsValue },
|
|
1657
|
-
{ label: "Status", value: status },
|
|
1658
1595
|
]),
|
|
1659
1596
|
};
|
|
1660
1597
|
}
|
|
@@ -2,15 +2,18 @@ import { type ChildProcessWithoutNullStreams } from "node:child_process";
|
|
|
2
2
|
import type { Logger } from "pino";
|
|
3
3
|
import type { ProviderRuntimeSettings } from "../../provider-launch-config.js";
|
|
4
4
|
import { type PiRuntime, type PiRuntimeLaunch, type PiRuntimeSession, type PiStartSessionInput } from "./runtime.js";
|
|
5
|
+
import type { PiCommandsRpcType } from "./rpc-types.js";
|
|
5
6
|
export interface PiCliRuntimeOptions {
|
|
6
7
|
logger: Logger;
|
|
7
8
|
runtimeSettings?: ProviderRuntimeSettings;
|
|
8
9
|
command?: [string, ...string[]];
|
|
10
|
+
commandsRpcType?: PiCommandsRpcType;
|
|
9
11
|
spawnProcess?: (launch: PiRuntimeLaunch) => ChildProcessWithoutNullStreams;
|
|
10
12
|
}
|
|
11
13
|
export declare class PiCliRuntime implements PiRuntime {
|
|
12
14
|
private readonly options;
|
|
13
15
|
private readonly command;
|
|
16
|
+
private readonly commandsRpcType;
|
|
14
17
|
private readonly spawnProcess;
|
|
15
18
|
constructor(options: PiCliRuntimeOptions);
|
|
16
19
|
startSession(input: PiStartSessionInput): Promise<PiRuntimeSession>;
|
|
@@ -5,6 +5,7 @@ const DEFAULT_PI_COMMAND = [
|
|
|
5
5
|
process.env.PI_COMMAND ?? process.env.PI_ACP_PI_COMMAND ?? "pi",
|
|
6
6
|
];
|
|
7
7
|
const DEFAULT_TIMEOUT_MS = 30000;
|
|
8
|
+
const DEFAULT_COMMANDS_RPC_TYPE = "get_commands";
|
|
8
9
|
const STDERR_BUFFER_LIMIT = 8192;
|
|
9
10
|
const GRACEFUL_SHUTDOWN_TIMEOUT_MS = 2000;
|
|
10
11
|
const FORCE_SHUTDOWN_TIMEOUT_MS = 1000;
|
|
@@ -17,6 +18,7 @@ export class PiCliRuntime {
|
|
|
17
18
|
constructor(options) {
|
|
18
19
|
this.options = options;
|
|
19
20
|
this.command = options.command ?? DEFAULT_PI_COMMAND;
|
|
21
|
+
this.commandsRpcType = options.commandsRpcType ?? DEFAULT_COMMANDS_RPC_TYPE;
|
|
20
22
|
this.spawnProcess =
|
|
21
23
|
options.spawnProcess ??
|
|
22
24
|
((launch) => {
|
|
@@ -36,13 +38,14 @@ export class PiCliRuntime {
|
|
|
36
38
|
runtimeSettings: this.options.runtimeSettings,
|
|
37
39
|
session: input,
|
|
38
40
|
});
|
|
39
|
-
return new PiCliRuntimeSession(launch, this.spawnProcess(launch), this.options.logger);
|
|
41
|
+
return new PiCliRuntimeSession(launch, this.spawnProcess(launch), this.options.logger, this.commandsRpcType);
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
class PiCliRuntimeSession {
|
|
43
|
-
constructor(_launch, child, logger) {
|
|
45
|
+
constructor(_launch, child, logger, commandsRpcType) {
|
|
44
46
|
this.child = child;
|
|
45
47
|
this.logger = logger;
|
|
48
|
+
this.commandsRpcType = commandsRpcType;
|
|
46
49
|
this.pending = new Map();
|
|
47
50
|
this.subscribers = new Set();
|
|
48
51
|
this.stderrBuffer = "";
|
|
@@ -95,8 +98,8 @@ class PiCliRuntimeSession {
|
|
|
95
98
|
const data = (await this.request({ type: "get_messages" }));
|
|
96
99
|
return data.messages ?? [];
|
|
97
100
|
}
|
|
98
|
-
async getAvailableModels() {
|
|
99
|
-
const data = (await this.request({ type: "get_available_models" }));
|
|
101
|
+
async getAvailableModels(timeoutMs) {
|
|
102
|
+
const data = (await this.request({ type: "get_available_models" }, timeoutMs));
|
|
100
103
|
return data.models ?? [];
|
|
101
104
|
}
|
|
102
105
|
async setModel(provider, modelId) {
|
|
@@ -109,7 +112,7 @@ class PiCliRuntimeSession {
|
|
|
109
112
|
return (await this.request({ type: "get_session_stats" }));
|
|
110
113
|
}
|
|
111
114
|
async getCommands() {
|
|
112
|
-
const data = (await this.request({ type:
|
|
115
|
+
const data = (await this.request({ type: this.commandsRpcType }));
|
|
113
116
|
return data.commands ?? [];
|
|
114
117
|
}
|
|
115
118
|
respondToExtensionUiRequest(id, response) {
|
|
@@ -94,6 +94,7 @@ export interface PiRpcSlashCommand {
|
|
|
94
94
|
source: "extension" | "prompt" | "skill";
|
|
95
95
|
sourceInfo?: Record<string, unknown>;
|
|
96
96
|
}
|
|
97
|
+
export type PiCommandsRpcType = "get_commands" | "get_available_commands";
|
|
97
98
|
export type PiRpcCommand = {
|
|
98
99
|
id?: string;
|
|
99
100
|
type: "prompt";
|
|
@@ -133,7 +134,7 @@ export type PiRpcCommand = {
|
|
|
133
134
|
type: "get_session_stats";
|
|
134
135
|
} | {
|
|
135
136
|
id?: string;
|
|
136
|
-
type:
|
|
137
|
+
type: PiCommandsRpcType;
|
|
137
138
|
};
|
|
138
139
|
export interface PiRpcResponse {
|
|
139
140
|
id?: string;
|
|
@@ -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>;
|