@pasko70/pibo 3.5.0 → 3.5.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/dist/agent-runtime/routed-session.js +80 -19
- package/dist/agent-runtimes/codex-native/turn.js +27 -3
- package/dist/apps/chat/data/chat-data-mappers.js +8 -1
- package/dist/apps/chat/data/read-state-service.js +24 -3
- package/dist/apps/chat/message-command-dispatcher.js +16 -1
- package/dist/apps/chat/web-app.js +40 -19
- package/dist/apps/chat-ui/assets/{dist-D79vyxSX.js → dist-B-auLrzD.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-DFZ8cwh0.js → dist-BA_dsINH.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-D6TjFhAm.js → dist-eJZar_0-.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BG0n7zLd.js → dist-wNNR2Bci.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-cOjokPrK.js → dist-zcmEsIEp.js} +1 -1
- package/dist/apps/chat-ui/assets/{index-RMHUTJ62.js → index-DEkbN5Vo.js} +43 -43
- package/dist/apps/chat-ui/assets/index-DZK6Tzil.css +1 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/{index-xacbCyTx.js → index-DZgW1fCB.js} +11 -11
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/cli-session/localSessionSource.js +3 -2
- package/dist/core/output-render-sequence.js +63 -6
- package/dist/core/session-router.js +99 -11
- package/dist/data/async-chat-storage.js +7 -2
- package/dist/data/bounded-worker-client.js +1 -1
- package/dist/data/chat-read-projections.js +4 -4
- package/dist/data/chat-storage-worker.js +24 -3
- package/dist/data/ingest-service.js +73 -4
- package/dist/data/message-command-store.js +153 -11
- package/dist/data/schema.js +24 -3
- package/dist/data/storage-maintenance.js +344 -0
- package/dist/data/storage-verification-worker.js +25 -0
- package/dist/debug/index.js +155 -1
- package/dist/debug/message-queue.js +108 -0
- package/dist/debug/output-collision-repair.js +140 -0
- package/dist/debug/output-integrity.js +38 -2
- package/dist/debug/output-repair.js +1 -0
- package/dist/debug/storage-backup.js +12 -4
- package/dist/debug/storage-maintenance.js +78 -0
- package/dist/gateway/cli.js +71 -7
- package/dist/gateway/server.js +1 -0
- package/dist/reliability/store.js +119 -23
- package/dist/session-ui/terminalRows.js +7 -8
- package/dist/sessions/pibo-data-store.js +18 -14
- package/dist/shared/trace-event-projection.js +13 -3
- package/dist/web/channel.js +114 -12
- package/dist/web/http.js +105 -44
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/apps/chat-ui/assets/index-hEkrlRk-.css +0 -1
package/dist/web/http.js
CHANGED
|
@@ -78,74 +78,136 @@ export async function nodeRequestToWebRequest(request, baseURL, signal) {
|
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
export async function sendWebResponse(response, webResponse, options = {}) {
|
|
81
|
+
assertResponseCanStart(response);
|
|
81
82
|
const headers = responseHeaders(webResponse);
|
|
82
83
|
const compressEncoding = preferredResponseEncoding(response.req?.headers["accept-encoding"], webResponse);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
let reader = webResponse.body?.getReader();
|
|
85
|
+
let wroteHeaders = false;
|
|
86
|
+
let clientClosed = false;
|
|
87
|
+
const cancelReader = () => {
|
|
88
|
+
if (reader)
|
|
89
|
+
void reader.cancel().catch(() => undefined);
|
|
90
|
+
};
|
|
91
|
+
const close = () => {
|
|
92
|
+
clientClosed = true;
|
|
93
|
+
cancelReader();
|
|
94
|
+
};
|
|
95
|
+
const abort = () => {
|
|
96
|
+
cancelReader();
|
|
97
|
+
try {
|
|
98
|
+
if (!response.destroyed && !response.writableEnded)
|
|
99
|
+
response.end();
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
tryDestroyResponse(response);
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
response.socket?.end();
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
tryDestroyResponse(response);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
if (reader) {
|
|
112
|
+
response.once("close", close);
|
|
113
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
114
|
+
if (options.signal?.aborted)
|
|
115
|
+
abort();
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
if (compressEncoding && reader) {
|
|
119
|
+
const body = await readResponseBody(reader);
|
|
120
|
+
if (clientClosed || options.signal?.aborted || response.destroyed || response.writableEnded || response.writableFinished)
|
|
121
|
+
return;
|
|
122
|
+
assertResponseCanStart(response);
|
|
123
|
+
if (body.length >= MIN_COMPRESS_RESPONSE_BYTES && body.length <= MAX_SYNC_GZIP_RESPONSE_BYTES) {
|
|
124
|
+
const compressionStartedAt = performance.now();
|
|
125
|
+
const compressed = gzipSync(body, { level: 1 });
|
|
126
|
+
appendServerTimingHeader(headers, `response_compress;dur=${(performance.now() - compressionStartedAt).toFixed(1)}`);
|
|
127
|
+
headers["content-encoding"] = compressEncoding;
|
|
128
|
+
headers["content-length"] = String(compressed.length);
|
|
129
|
+
headers.vary = appendVary(headers.vary, "accept-encoding");
|
|
130
|
+
response.writeHead(webResponse.status, headers);
|
|
131
|
+
wroteHeaders = true;
|
|
132
|
+
response.end(compressed);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (body.length > MAX_SYNC_GZIP_RESPONSE_BYTES) {
|
|
136
|
+
headers["x-pibo-compression-skipped"] = "sync-gzip-size-limit";
|
|
137
|
+
}
|
|
92
138
|
response.writeHead(webResponse.status, headers);
|
|
93
|
-
|
|
139
|
+
wroteHeaders = true;
|
|
140
|
+
response.end(body);
|
|
94
141
|
return;
|
|
95
142
|
}
|
|
96
|
-
if (body.length > MAX_SYNC_GZIP_RESPONSE_BYTES) {
|
|
97
|
-
headers["x-pibo-compression-skipped"] = "sync-gzip-size-limit";
|
|
98
|
-
}
|
|
99
143
|
response.writeHead(webResponse.status, headers);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
response.writeHead(webResponse.status, headers);
|
|
104
|
-
if (!webResponse.body) {
|
|
105
|
-
response.end();
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const reader = webResponse.body.getReader();
|
|
109
|
-
const cancel = () => {
|
|
110
|
-
void reader.cancel().catch(() => undefined);
|
|
111
|
-
};
|
|
112
|
-
const abort = () => {
|
|
113
|
-
const socket = response.socket;
|
|
114
|
-
void reader.cancel().catch(() => undefined);
|
|
115
|
-
if (!response.writableEnded)
|
|
144
|
+
wroteHeaders = true;
|
|
145
|
+
if (!reader) {
|
|
116
146
|
response.end();
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
response.once("close", cancel);
|
|
120
|
-
options.signal?.addEventListener("abort", abort, { once: true });
|
|
121
|
-
if (options.signal?.aborted)
|
|
122
|
-
abort();
|
|
123
|
-
try {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
124
149
|
while (true) {
|
|
125
150
|
const { done, value } = await reader.read();
|
|
126
151
|
if (done)
|
|
127
152
|
break;
|
|
128
153
|
const bytes = Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
129
154
|
for (let offset = 0; offset < bytes.length; offset += 64 * 1024) {
|
|
130
|
-
if (response.destroyed || response.writableEnded)
|
|
155
|
+
if (response.destroyed || response.writableEnded || response.writableFinished) {
|
|
156
|
+
cancelReader();
|
|
131
157
|
return;
|
|
158
|
+
}
|
|
132
159
|
if (!response.write(bytes.subarray(offset, offset + 64 * 1024))) {
|
|
133
160
|
const drained = await waitForResponseDrain(response, (webResponse.headers.get("content-type") ?? "").startsWith("text/event-stream") ? 5000 : undefined, options.signal);
|
|
134
161
|
if (!drained) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
response.destroy();
|
|
162
|
+
cancelReader();
|
|
163
|
+
tryDestroyResponse(response);
|
|
138
164
|
return;
|
|
139
165
|
}
|
|
140
166
|
}
|
|
141
167
|
}
|
|
142
168
|
}
|
|
143
|
-
if (!response.writableEnded)
|
|
169
|
+
if (!response.destroyed && !response.writableEnded && !response.writableFinished)
|
|
144
170
|
response.end();
|
|
145
171
|
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
cancelReader();
|
|
174
|
+
if (clientClosed || response.destroyed || response.writableEnded || response.writableFinished)
|
|
175
|
+
return;
|
|
176
|
+
if (wroteHeaders || response.headersSent)
|
|
177
|
+
tryDestroyResponse(response, error);
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
146
180
|
finally {
|
|
147
|
-
response.off("close",
|
|
181
|
+
response.off("close", close);
|
|
148
182
|
options.signal?.removeEventListener("abort", abort);
|
|
183
|
+
if (reader) {
|
|
184
|
+
try {
|
|
185
|
+
reader.releaseLock();
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Cancellation/read settlement owns the lock until the pending read resolves.
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function assertResponseCanStart(response) {
|
|
194
|
+
if (response.destroyed)
|
|
195
|
+
throw new Error("HTTP response is destroyed");
|
|
196
|
+
if (response.writableEnded)
|
|
197
|
+
throw new Error("HTTP response has ended");
|
|
198
|
+
if (response.writableFinished)
|
|
199
|
+
throw new Error("HTTP response has finished");
|
|
200
|
+
if (response.headersSent)
|
|
201
|
+
throw new Error("HTTP response headers were already sent");
|
|
202
|
+
}
|
|
203
|
+
function tryDestroyResponse(response, error) {
|
|
204
|
+
if (response.destroyed)
|
|
205
|
+
return;
|
|
206
|
+
try {
|
|
207
|
+
response.destroy(error instanceof Error ? error : undefined);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// The request boundary is best-effort once the response implementation itself fails.
|
|
149
211
|
}
|
|
150
212
|
}
|
|
151
213
|
function appendServerTimingHeader(headers, value) {
|
|
@@ -198,9 +260,8 @@ function responseCanBeCompressed(webResponse) {
|
|
|
198
260
|
const contentType = webResponse.headers.get("content-type") ?? "";
|
|
199
261
|
return /^application\/json\b/.test(contentType);
|
|
200
262
|
}
|
|
201
|
-
async function readResponseBody(
|
|
263
|
+
async function readResponseBody(reader) {
|
|
202
264
|
const chunks = [];
|
|
203
|
-
const reader = webResponse.body.getReader();
|
|
204
265
|
while (true) {
|
|
205
266
|
const { done, value } = await reader.read();
|
|
206
267
|
if (done)
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pasko70/pibo",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@pasko70/pibo",
|
|
9
|
-
"version": "3.5.
|
|
9
|
+
"version": "3.5.1",
|
|
10
10
|
"workspaces": [
|
|
11
11
|
"packages/workflows"
|
|
12
12
|
],
|