@averyyy/pi-coding-agent 0.84.2-piclient.1 → 0.84.3-piclient.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +8 -4
- package/dist/bundle/chunks/anthropic-messages-JWX2WP65.js +45 -0
- package/dist/bundle/chunks/anthropic.js +75 -0
- package/dist/bundle/chunks/azure-openai-responses-B2RCCN5N.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +74 -0
- package/dist/bundle/chunks/chunk-4L3WN2XY.js +2 -0
- package/dist/bundle/chunks/chunk-6CYCI3EJ.js +12 -0
- package/dist/bundle/chunks/chunk-6R7UI4IY.js +2 -0
- package/dist/bundle/chunks/chunk-AXIIZGTV.js +2 -0
- package/dist/bundle/chunks/chunk-DRQDKNXA.js +2 -0
- package/dist/bundle/chunks/chunk-GMWCTUPB.js +2 -0
- package/dist/bundle/chunks/chunk-GPPBJGBU.js +50 -0
- package/dist/bundle/chunks/chunk-JUUC5AZY.js +2 -0
- package/dist/bundle/chunks/chunk-L2ZPNLYD.js +2 -0
- package/dist/bundle/chunks/chunk-LRBSW3NQ.js +11 -0
- package/dist/bundle/chunks/chunk-MNAIPA3J.js +2 -0
- package/dist/bundle/chunks/chunk-NUHFSC37.js +25 -0
- package/dist/bundle/chunks/chunk-PGXDEOVV.js +2 -0
- package/dist/bundle/chunks/chunk-PJACZCIR.js +2 -0
- package/dist/bundle/chunks/chunk-PRRNXB7S.js +2 -0
- package/dist/bundle/chunks/chunk-QI42RBZ4.js +1632 -0
- package/dist/bundle/chunks/chunk-TEPMHNKQ.js +2 -0
- package/dist/bundle/chunks/chunk-TRDNDS6A.js +4 -0
- package/dist/bundle/chunks/chunk-UAQELI3K.js +2 -0
- package/dist/bundle/chunks/chunk-XDUWOHPL.js +6 -0
- package/dist/bundle/chunks/chunk-XNGRGP62.js +2 -0
- package/dist/bundle/chunks/dist-RDWOYWHR.js +13 -0
- package/dist/bundle/chunks/github-copilot.js +2 -0
- package/dist/bundle/chunks/google-generative-ai-XDKMGBCJ.js +2 -0
- package/dist/bundle/chunks/google-vertex-D5FGEO3Y.js +2 -0
- package/dist/bundle/chunks/image-resize-worker.js +2 -0
- package/dist/bundle/chunks/kimi-coding.js +2 -0
- package/dist/bundle/chunks/lib-HGQMNYVT.js +9 -0
- package/dist/bundle/chunks/mistral-conversations-YK73UAOZ.js +5 -0
- package/dist/bundle/chunks/multipart-parser-SQ6GDJL7.js +3 -0
- package/dist/bundle/chunks/openai-codex-responses-MJHX7NXI.js +8 -0
- package/dist/bundle/chunks/openai-codex.js +75 -0
- package/dist/bundle/chunks/openai-completions-JD4WAC3R.js +7 -0
- package/dist/bundle/chunks/openai-responses-CP4VKB27.js +2 -0
- package/dist/bundle/chunks/openrouter-images-N4XVVFSD.js +2 -0
- package/dist/bundle/chunks/openrouter.js +75 -0
- package/dist/bundle/chunks/pi-messages-TPFH44NP.js +8 -0
- package/dist/bundle/chunks/radius.js +75 -0
- package/dist/bundle/chunks/src-UK77SYZE.js +4 -0
- package/dist/bundle/chunks/xai.js +2 -0
- package/dist/bundle/cli.js +3 -0
- package/dist/bundle/client.js +2 -0
- package/dist/bundle/index.js +2 -0
- package/dist/bundle/rpc-entry.js +3 -0
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +29 -9
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/config.d.ts +4 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +22 -14
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +15 -8
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +48 -39
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +6 -7
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +3 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +115 -48
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +38 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +20 -19
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +26 -5
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-config.d.ts +5 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +3 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +14 -8
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +22 -14
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-client-cli-adapter.d.ts +11 -0
- package/dist/core/pi-client-cli-adapter.d.ts.map +1 -0
- package/dist/core/pi-client-cli-adapter.js +91 -0
- package/dist/core/pi-client-cli-adapter.js.map +1 -0
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/pi-server-client.d.ts +0 -1
- package/dist/core/pi-server-client.d.ts.map +1 -1
- package/dist/core/pi-server-client.js +148 -65
- package/dist/core/pi-server-client.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +10 -3
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +4 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +32 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +9 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +52 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +11 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +13 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +30 -14
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +20 -4
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts +4 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +18 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +16 -0
- package/dist/core/tools/powershell.d.ts.map +1 -0
- package/dist/core/tools/powershell.js +39 -0
- package/dist/core/tools/powershell.js.map +1 -0
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/extensions/llama/client.d.ts +6 -0
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +7 -0
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts +3 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +29 -4
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -15
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +2 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +9 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +56 -12
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +7 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +118 -56
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +74 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +13 -12
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +196 -226
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts +16 -0
- package/dist/modes/interactive/session-share.d.ts.map +1 -0
- package/dist/modes/interactive/session-share.js +188 -0
- package/dist/modes/interactive/session-share.js.map +1 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +4 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/package-manager-cli.d.ts +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +186 -2
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +8 -3
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +21 -7
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +60 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +2 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +15 -0
- package/docs/custom-provider.md +5 -2
- package/docs/environment-variables.md +8 -8
- package/docs/extensions.md +17 -7
- package/docs/json.md +7 -2
- package/docs/keybindings.md +8 -8
- package/docs/llama-cpp.md +2 -0
- package/docs/models.md +8 -2
- package/docs/packages.md +2 -2
- package/docs/rpc.md +9 -3
- package/docs/sdk.md +7 -2
- package/docs/settings.md +11 -3
- package/docs/skills.md +4 -3
- package/docs/terminal-setup.md +11 -9
- package/docs/usage.md +6 -2
- package/docs/windows.md +24 -2
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/examples/extensions/subagent/index.ts +6 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/package.json +12 -14
|
@@ -36,6 +36,14 @@ const sessionHasTemporaryTree = new Set();
|
|
|
36
36
|
const RESPONSE_BODY_EXCERPT_CHARS = 500;
|
|
37
37
|
const TRANSIENT_PI_SERVER_RETRY_DELAYS_MS = [250, 750, 1500];
|
|
38
38
|
const TRANSIENT_PI_SERVER_STATUS_CODES = new Set([502, 503, 504, 530]);
|
|
39
|
+
const PI_SERVER_RUN_RECOVERY_POLL_MS = 250;
|
|
40
|
+
const DEFAULT_PI_SERVER_RUN_RECOVERY_TIMEOUT_MS = 10 * 60 * 1000;
|
|
41
|
+
class PiServerRunRecoveryTimeoutError extends Error {
|
|
42
|
+
constructor() {
|
|
43
|
+
super("pi-server run recovery timed out; the server may still be processing the request");
|
|
44
|
+
this.name = "PiServerRunRecoveryTimeoutError";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
39
47
|
export function hashStaticContext(ctx) {
|
|
40
48
|
return hashPiServerStaticContext(ctx);
|
|
41
49
|
}
|
|
@@ -74,6 +82,63 @@ export function resetAllSessionTracking() {
|
|
|
74
82
|
sessionTreeLeafIds.clear();
|
|
75
83
|
sessionHasTemporaryTree.clear();
|
|
76
84
|
}
|
|
85
|
+
class PiServerResponseError extends Error {
|
|
86
|
+
code;
|
|
87
|
+
details;
|
|
88
|
+
constructor(message, code, details) {
|
|
89
|
+
super(message);
|
|
90
|
+
this.name = "PiServerResponseError";
|
|
91
|
+
this.code = code;
|
|
92
|
+
this.details = details;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
class ServerSentEventParser {
|
|
96
|
+
buffer = "";
|
|
97
|
+
event = "message";
|
|
98
|
+
dataLines = [];
|
|
99
|
+
feed(text) {
|
|
100
|
+
this.buffer += text;
|
|
101
|
+
const lines = this.buffer.split("\n");
|
|
102
|
+
this.buffer = lines.pop() ?? "";
|
|
103
|
+
return lines.flatMap((line) => this.consumeLine(line));
|
|
104
|
+
}
|
|
105
|
+
finish() {
|
|
106
|
+
const events = [];
|
|
107
|
+
if (this.buffer.length > 0) {
|
|
108
|
+
events.push(...this.consumeLine(this.buffer));
|
|
109
|
+
this.buffer = "";
|
|
110
|
+
}
|
|
111
|
+
const final = this.flush();
|
|
112
|
+
if (final)
|
|
113
|
+
events.push(final);
|
|
114
|
+
return events;
|
|
115
|
+
}
|
|
116
|
+
consumeLine(rawLine) {
|
|
117
|
+
const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
|
|
118
|
+
if (line === "") {
|
|
119
|
+
const event = this.flush();
|
|
120
|
+
return event ? [event] : [];
|
|
121
|
+
}
|
|
122
|
+
if (line.startsWith(":"))
|
|
123
|
+
return [];
|
|
124
|
+
if (line.startsWith("event:")) {
|
|
125
|
+
this.event = getServerSentEventFieldValue(line, "event");
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
if (line.startsWith("data:")) {
|
|
129
|
+
this.dataLines.push(getServerSentEventFieldValue(line, "data"));
|
|
130
|
+
}
|
|
131
|
+
return [];
|
|
132
|
+
}
|
|
133
|
+
flush() {
|
|
134
|
+
if (this.dataLines.length === 0)
|
|
135
|
+
return undefined;
|
|
136
|
+
const event = { event: this.event, data: this.dataLines.join("\n") };
|
|
137
|
+
this.event = "message";
|
|
138
|
+
this.dataLines = [];
|
|
139
|
+
return event;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
77
142
|
function isObject(value) {
|
|
78
143
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
79
144
|
}
|
|
@@ -91,34 +156,46 @@ function getBodyExcerpt(text) {
|
|
|
91
156
|
const excerpt = trimmed.slice(0, RESPONSE_BODY_EXCERPT_CHARS);
|
|
92
157
|
return excerpt.length < trimmed.length ? `${excerpt}...` : excerpt;
|
|
93
158
|
}
|
|
94
|
-
function
|
|
159
|
+
function getJsonErrorResponse(text) {
|
|
95
160
|
if (!text)
|
|
96
161
|
return undefined;
|
|
97
162
|
try {
|
|
98
163
|
const parsed = JSON.parse(text);
|
|
99
|
-
if (!isObject(parsed))
|
|
164
|
+
if (!isObject(parsed) || typeof parsed.error !== "string" || parsed.error.length === 0)
|
|
100
165
|
return undefined;
|
|
101
|
-
const
|
|
102
|
-
return
|
|
166
|
+
const code = parsed.code;
|
|
167
|
+
return {
|
|
168
|
+
error: parsed.error,
|
|
169
|
+
code: typeof code === "string" ? code : undefined,
|
|
170
|
+
details: isObject(parsed.details) ? parsed.details : undefined,
|
|
171
|
+
};
|
|
103
172
|
}
|
|
104
173
|
catch {
|
|
105
174
|
return undefined;
|
|
106
175
|
}
|
|
107
176
|
}
|
|
177
|
+
function getJsonErrorText(text) {
|
|
178
|
+
return getJsonErrorResponse(text)?.error;
|
|
179
|
+
}
|
|
108
180
|
function formatResponseDetails(response, bodyText) {
|
|
109
181
|
const body = getJsonErrorText(bodyText) ?? getBodyExcerpt(bodyText);
|
|
110
182
|
return `${getResponseStatus(response)}; content-type: ${getResponseContentType(response)}; body excerpt: ${body}`;
|
|
111
183
|
}
|
|
112
184
|
async function readPiServerFailure(response) {
|
|
113
185
|
const bodyText = await response.text();
|
|
186
|
+
const errorResponse = getJsonErrorResponse(bodyText);
|
|
114
187
|
return {
|
|
115
188
|
details: formatResponseDetails(response, bodyText),
|
|
116
|
-
|
|
189
|
+
code: errorResponse?.code,
|
|
117
190
|
};
|
|
118
191
|
}
|
|
119
192
|
async function readPiServerJson(response, errorPrefix) {
|
|
120
193
|
const bodyText = await response.text();
|
|
121
194
|
if (!response.ok) {
|
|
195
|
+
const errorResponse = getJsonErrorResponse(bodyText);
|
|
196
|
+
if (errorResponse) {
|
|
197
|
+
throw new PiServerResponseError(`${errorPrefix} (${formatResponseDetails(response, bodyText)})`, errorResponse.code, errorResponse.details);
|
|
198
|
+
}
|
|
122
199
|
throw new Error(`${errorPrefix} (${formatResponseDetails(response, bodyText)})`);
|
|
123
200
|
}
|
|
124
201
|
try {
|
|
@@ -134,33 +211,8 @@ function getServerSentEventFieldValue(line, field) {
|
|
|
134
211
|
return value.startsWith(" ") ? value.slice(1) : value;
|
|
135
212
|
}
|
|
136
213
|
function parseServerSentEvents(bodyText) {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
let dataLines = [];
|
|
140
|
-
const flush = () => {
|
|
141
|
-
if (dataLines.length === 0)
|
|
142
|
-
return;
|
|
143
|
-
events.push({ event, data: dataLines.join("\n") });
|
|
144
|
-
event = "message";
|
|
145
|
-
dataLines = [];
|
|
146
|
-
};
|
|
147
|
-
for (const line of bodyText.split(/\r?\n/)) {
|
|
148
|
-
if (line === "") {
|
|
149
|
-
flush();
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
if (line.startsWith(":"))
|
|
153
|
-
continue;
|
|
154
|
-
if (line.startsWith("event:")) {
|
|
155
|
-
event = getServerSentEventFieldValue(line, "event");
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
158
|
-
if (line.startsWith("data:")) {
|
|
159
|
-
dataLines.push(getServerSentEventFieldValue(line, "data"));
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
flush();
|
|
163
|
-
return events;
|
|
214
|
+
const parser = new ServerSentEventParser();
|
|
215
|
+
return [...parser.feed(bodyText), ...parser.finish()];
|
|
164
216
|
}
|
|
165
217
|
function parseServerSentEventData(event, errorPrefix) {
|
|
166
218
|
try {
|
|
@@ -233,6 +285,10 @@ async function postPiServerJsonWithTransientRetry(request, endpoint, body, error
|
|
|
233
285
|
await waitForPiServerRetry(attempt, request.options.signal);
|
|
234
286
|
continue;
|
|
235
287
|
}
|
|
288
|
+
const errorResponse = getJsonErrorResponse(bodyText);
|
|
289
|
+
if (errorResponse) {
|
|
290
|
+
throw new PiServerResponseError(`${errorPrefix} (${formatResponseDetails(response, bodyText)})`, errorResponse.code, errorResponse.details);
|
|
291
|
+
}
|
|
236
292
|
throw new Error(`${errorPrefix} (${formatResponseDetails(response, bodyText)})`);
|
|
237
293
|
}
|
|
238
294
|
try {
|
|
@@ -337,6 +393,17 @@ async function fetchPiServerRun(sessionId, runId, request) {
|
|
|
337
393
|
}
|
|
338
394
|
return readPiServerJson(response, "Session run recovery failed");
|
|
339
395
|
}
|
|
396
|
+
async function waitForPiServerRunCompletion(sessionId, runId, request, options) {
|
|
397
|
+
const deadline = Date.now() + DEFAULT_PI_SERVER_RUN_RECOVERY_TIMEOUT_MS;
|
|
398
|
+
for (;;) {
|
|
399
|
+
const run = await fetchPiServerRun(sessionId, runId, request);
|
|
400
|
+
if (!run || run.status !== "running")
|
|
401
|
+
return run;
|
|
402
|
+
if (Date.now() >= deadline)
|
|
403
|
+
throw new PiServerRunRecoveryTimeoutError();
|
|
404
|
+
await sleep(PI_SERVER_RUN_RECOVERY_POLL_MS, undefined, { signal: options?.signal });
|
|
405
|
+
}
|
|
406
|
+
}
|
|
340
407
|
function getKnownServerPrefixIds(sessionId, entries) {
|
|
341
408
|
const entryCount = sessionTreeEntryCounts.get(sessionId);
|
|
342
409
|
const treeHash = sessionTreeHashes.get(sessionId);
|
|
@@ -351,14 +418,25 @@ function getKnownServerPrefixIds(sessionId, entries) {
|
|
|
351
418
|
sessionSyncedEntryIds.set(sessionId, ids);
|
|
352
419
|
return ids;
|
|
353
420
|
}
|
|
421
|
+
function isRecoverableTreeDivergenceCode(code) {
|
|
422
|
+
return code === "PARENT_ENTRY_NOT_FOUND" || code === "LEAF_ID_NOT_FOUND" || code === "ENTRY_ALREADY_EXISTS";
|
|
423
|
+
}
|
|
424
|
+
function isRecoverableMissingServerStateCode(code) {
|
|
425
|
+
return code === "SESSION_NOT_FOUND" || code === "SESSION_NO_STATIC_CONTEXT" || isRecoverableTreeDivergenceCode(code);
|
|
426
|
+
}
|
|
354
427
|
function isRecoverableTreeDivergenceError(error) {
|
|
355
|
-
|
|
356
|
-
|
|
428
|
+
if (error instanceof PiServerResponseError) {
|
|
429
|
+
return isRecoverableTreeDivergenceCode(error.code);
|
|
430
|
+
}
|
|
431
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
432
|
+
return isRecoverableTreeDivergenceCode(error.code);
|
|
433
|
+
}
|
|
434
|
+
return false;
|
|
357
435
|
}
|
|
358
|
-
function isRecoverableMissingServerState(response,
|
|
436
|
+
function isRecoverableMissingServerState(response, errorCode) {
|
|
359
437
|
if (response.status !== 400 && response.status !== 404)
|
|
360
438
|
return false;
|
|
361
|
-
return
|
|
439
|
+
return isRecoverableMissingServerStateCode(errorCode);
|
|
362
440
|
}
|
|
363
441
|
async function syncFullPiServerTree(sessionId, context, tree, request) {
|
|
364
442
|
await postTreeJson(request, "/api/session/tree/sync", {
|
|
@@ -473,13 +551,13 @@ export async function compactPiServer(model, context, options) {
|
|
|
473
551
|
let response = await request.postJson("/api/session/compact", makeBody());
|
|
474
552
|
if (!response.ok) {
|
|
475
553
|
let failure = await readPiServerFailure(response);
|
|
476
|
-
if (!options?.signal?.aborted && isRecoverableMissingServerState(response, failure.
|
|
554
|
+
if (!options?.signal?.aborted && isRecoverableMissingServerState(response, failure.code)) {
|
|
477
555
|
resetSessionTracking(sessionId);
|
|
478
556
|
await ensureSessionInit(sessionId, context, request);
|
|
479
557
|
await syncPiServerTreeWithRequest(sessionId, context, tree, request, options?.onHistoryReconciled);
|
|
480
558
|
response = await request.postJson("/api/session/compact", makeBody());
|
|
481
559
|
if (response.ok) {
|
|
482
|
-
failure = { details: "",
|
|
560
|
+
failure = { details: "", code: undefined };
|
|
483
561
|
}
|
|
484
562
|
else {
|
|
485
563
|
failure = await readPiServerFailure(response);
|
|
@@ -510,11 +588,6 @@ export async function compactPiServer(model, context, options) {
|
|
|
510
588
|
messages: result.messages ?? [],
|
|
511
589
|
};
|
|
512
590
|
}
|
|
513
|
-
export async function dropLastPiServerAssistantError(sessionId) {
|
|
514
|
-
const request = createPiServerRequest();
|
|
515
|
-
const response = await request.postJson("/api/session/drop-last-assistant-error", { sessionId });
|
|
516
|
-
await readPiServerJson(response, "Dropping server assistant error failed");
|
|
517
|
-
}
|
|
518
591
|
export async function streamPiServer(model, context, options) {
|
|
519
592
|
const sessionId = options?.sessionId ?? randomUUID();
|
|
520
593
|
const runId = randomUUID();
|
|
@@ -556,12 +629,12 @@ export async function streamPiServer(model, context, options) {
|
|
|
556
629
|
let response = await request.postJson("/api/stream", makeBody());
|
|
557
630
|
if (!response.ok) {
|
|
558
631
|
let failure = await readPiServerFailure(response);
|
|
559
|
-
if (!options?.signal?.aborted && isRecoverableMissingServerState(response, failure.
|
|
632
|
+
if (!options?.signal?.aborted && isRecoverableMissingServerState(response, failure.code)) {
|
|
560
633
|
resetSessionTracking(sessionId);
|
|
561
634
|
await ensureSessionInit(sessionId, context, request);
|
|
562
635
|
response = await request.postJson("/api/stream", makeBody());
|
|
563
636
|
if (response.ok) {
|
|
564
|
-
failure = { details: "",
|
|
637
|
+
failure = { details: "", code: undefined };
|
|
565
638
|
}
|
|
566
639
|
else {
|
|
567
640
|
failure = await readPiServerFailure(response);
|
|
@@ -574,7 +647,19 @@ export async function streamPiServer(model, context, options) {
|
|
|
574
647
|
await ensurePiServerEventStream(response);
|
|
575
648
|
const reader = response.body.getReader();
|
|
576
649
|
const decoder = new TextDecoder();
|
|
577
|
-
|
|
650
|
+
const parser = new ServerSentEventParser();
|
|
651
|
+
let terminalReceived = false;
|
|
652
|
+
const consumeEvents = (events) => {
|
|
653
|
+
for (const serverEvent of events) {
|
|
654
|
+
const proxyEvent = parseServerSentEventData(serverEvent, "pi-server stream");
|
|
655
|
+
const event = processProxyEvent(proxyEvent, partial);
|
|
656
|
+
if (!event)
|
|
657
|
+
continue;
|
|
658
|
+
if (event.type === "done" || event.type === "error")
|
|
659
|
+
terminalReceived = true;
|
|
660
|
+
stream.push(event);
|
|
661
|
+
}
|
|
662
|
+
};
|
|
578
663
|
while (true) {
|
|
579
664
|
const { done, value } = await reader.read();
|
|
580
665
|
if (done)
|
|
@@ -582,35 +667,26 @@ export async function streamPiServer(model, context, options) {
|
|
|
582
667
|
if (options?.signal?.aborted) {
|
|
583
668
|
throw new Error("Request aborted by user");
|
|
584
669
|
}
|
|
585
|
-
|
|
586
|
-
const lines = buffer.split("\n");
|
|
587
|
-
buffer = lines.pop() || "";
|
|
588
|
-
for (const line of lines) {
|
|
589
|
-
if (line.startsWith("data: ")) {
|
|
590
|
-
const data = line.slice(6).trim();
|
|
591
|
-
if (!data)
|
|
592
|
-
continue;
|
|
593
|
-
const proxyEvent = JSON.parse(data);
|
|
594
|
-
const event = processProxyEvent(proxyEvent, partial);
|
|
595
|
-
if (event) {
|
|
596
|
-
stream.push(event);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
670
|
+
consumeEvents(parser.feed(decoder.decode(value, { stream: true })));
|
|
600
671
|
}
|
|
672
|
+
consumeEvents(parser.feed(decoder.decode()));
|
|
673
|
+
consumeEvents(parser.finish());
|
|
601
674
|
if (options?.signal?.aborted) {
|
|
602
675
|
throw new Error("Request aborted by user");
|
|
603
676
|
}
|
|
677
|
+
if (!terminalReceived) {
|
|
678
|
+
throw new Error("pi-server stream ended before a terminal response event");
|
|
679
|
+
}
|
|
604
680
|
if (isEphemeralSession) {
|
|
605
681
|
resetSessionTracking(sessionId);
|
|
606
682
|
}
|
|
607
683
|
stream.end();
|
|
608
684
|
}
|
|
609
685
|
catch (error) {
|
|
610
|
-
|
|
686
|
+
let errorMessage = error instanceof Error ? error.message : String(error);
|
|
611
687
|
if (!options?.signal?.aborted && phase === "provider_stream") {
|
|
612
688
|
try {
|
|
613
|
-
const recoveredRun = await
|
|
689
|
+
const recoveredRun = await waitForPiServerRunCompletion(sessionId, runId, createPiServerRequest(options?.signal), options);
|
|
614
690
|
if (recoveredRun?.status === "completed" && recoveredRun.message) {
|
|
615
691
|
switch (recoveredRun.message.stopReason) {
|
|
616
692
|
case "stop":
|
|
@@ -633,9 +709,13 @@ export async function streamPiServer(model, context, options) {
|
|
|
633
709
|
stream.end();
|
|
634
710
|
return;
|
|
635
711
|
}
|
|
712
|
+
if (recoveredRun?.status === "failed" && recoveredRun.errorMessage) {
|
|
713
|
+
errorMessage = recoveredRun.errorMessage;
|
|
714
|
+
}
|
|
636
715
|
}
|
|
637
|
-
catch {
|
|
638
|
-
|
|
716
|
+
catch (recoveryError) {
|
|
717
|
+
phase = "history_reconcile";
|
|
718
|
+
errorMessage = recoveryError instanceof Error ? recoveryError.message : String(recoveryError);
|
|
639
719
|
}
|
|
640
720
|
}
|
|
641
721
|
const reason = options?.signal?.aborted ? "aborted" : "error";
|
|
@@ -724,12 +804,15 @@ function processProxyEvent(proxyEvent, partial) {
|
|
|
724
804
|
case "toolcall_end": {
|
|
725
805
|
const content = partial.content[proxyEvent.contentIndex];
|
|
726
806
|
if (content?.type === "toolCall") {
|
|
807
|
+
Object.assign(content, proxyEvent.toolCall);
|
|
727
808
|
delete content.partialJson;
|
|
728
809
|
return { type: "toolcall_end", contentIndex: proxyEvent.contentIndex, toolCall: content, partial };
|
|
729
810
|
}
|
|
730
811
|
return undefined;
|
|
731
812
|
}
|
|
732
813
|
case "done":
|
|
814
|
+
if (proxyEvent.message)
|
|
815
|
+
return { type: "done", reason: proxyEvent.reason, message: proxyEvent.message };
|
|
733
816
|
partial.stopReason = proxyEvent.reason;
|
|
734
817
|
partial.usage = proxyEvent.usage;
|
|
735
818
|
partial.deferred = proxyEvent.deferred;
|