@openchambery/web 1.19.7-beta.24 → 1.19.7-beta.26
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/assets/{AgentAvatar-DI2zs2WH.js → AgentAvatar-CX0a1rKE.js} +1 -1
- package/dist/assets/AssistantView-BYHD7Fcy.js +2 -0
- package/dist/assets/{DiagramView-DZhC-gPw.js → DiagramView-BUucK4Mn.js} +1 -1
- package/dist/assets/{FadeInOnReveal-BWJcUp5P.js → FadeInOnReveal-CK4asqVR.js} +1 -1
- package/dist/assets/{Icon-4My8YZwt.js → Icon-BYM02QyU.js} +1 -1
- package/dist/assets/{MarkdownLoadingSkeleton-Vezjvk9B.js → MarkdownLoadingSkeleton-DWs4Jg7b.js} +1 -1
- package/dist/assets/{MarkdownRenderer-Dd7nPtW4.js → MarkdownRenderer-uiTtRexW.js} +2 -2
- package/dist/assets/{MarkdownRendererImpl-CuGusb9c.js → MarkdownRendererImpl-DszSA6px.js} +1 -1
- package/dist/assets/MarkstreamRendererImpl-CsNwy1T5.css +1 -0
- package/dist/assets/MarkstreamRendererImpl-DkjZ7QYA.js +1 -0
- package/dist/assets/{MobileDetailNavigation-DXLN8AfE.js → MobileDetailNavigation-BElZdvTL.js} +1 -1
- package/dist/assets/MobileShareBridge-DiXOck30.js +4 -0
- package/dist/assets/{MobileSurface-DZys0gQW.js → MobileSurface-BCIZyDOc.js} +1 -1
- package/dist/assets/{MultiRunWindow-DNSCvp1n.js → MultiRunWindow-XXWgGd6d.js} +1 -1
- package/dist/assets/{OnboardingScreen-BNEtPmvw.js → OnboardingScreen-C3-wzeSX.js} +1 -1
- package/dist/assets/{OverlayScrollbar-BZB21Yp_.js → OverlayScrollbar-KUpvYHdv.js} +1 -1
- package/dist/assets/{SettingsView-CW0sP1G5.js → SettingsView-CdYIJh0f.js} +5 -5
- package/dist/assets/{SettingsWindow-BbY8rAaP.js → SettingsWindow-CLr0dXVg.js} +1 -1
- package/dist/assets/{TerminalView-Blou_qZo.js → TerminalView-BdtasXsi.js} +1 -1
- package/dist/assets/{ToolOutputDialog-D69bhD7_.js → ToolOutputDialog-D22RYqMI.js} +1 -1
- package/dist/assets/{appThemeRegistry-DTf7Ymvj.js → appThemeRegistry-D1wTvHoc.js} +1 -1
- package/dist/assets/{button-Or0daT9o.js → button-C0cth9tl.js} +1 -1
- package/dist/assets/{clipboard-BXxLshVq.js → clipboard-DJ4nQEuY.js} +1 -1
- package/dist/assets/{collapsible-C-kzSGkq.js → collapsible-DFT9cE80.js} +1 -1
- package/dist/assets/{context-menu-Dpjla5p4.js → context-menu-CAp74NfV.js} +1 -1
- package/dist/assets/desktopHosts-CWxex1c3.js +1 -0
- package/dist/assets/{desktopRelayRestore-BaKjk1kQ.js → desktopRelayRestore-9EbBYQ9s.js} +1 -1
- package/dist/assets/{diagram-D0mT3mo1.js → diagram-BryzMuta.js} +1 -1
- package/dist/assets/{dialog-BkhHBTd4.js → dialog-CgbV5ljg.js} +1 -1
- package/dist/assets/{fileQueries-DFY6Kiy1.js → fileQueries-BY-9OWzp.js} +1 -1
- package/dist/assets/{fileReferenceActions-Di_DoDex.js → fileReferenceActions-BJJtX_S5.js} +1 -1
- package/dist/assets/{gitApi-s3lJ_NUC.js → gitApi-RhwRTt2X.js} +1 -1
- package/dist/assets/{input-BUsGnzwe.js → input-DFLpqjGR.js} +1 -1
- package/dist/assets/{insertionBoundaries-BXIh3qwN.js → insertionBoundaries-D-UUqego.js} +1 -1
- package/dist/assets/{main-CbWB2MxW.js → main-BRB8Kly8.js} +2 -2
- package/dist/assets/{main-6h4AIMd7.js → main-BaSeqhTm.js} +11 -11
- package/dist/assets/{markdownTheme-CVS01wHf.js → markdownTheme-CzZm3riB.js} +1 -1
- package/dist/assets/{miniChat-DuYRiHjj.js → miniChat-CDZ48aEf.js} +2 -2
- package/dist/assets/{mobile-DKja4fFV.js → mobile-B2Hpp_5U.js} +2 -2
- package/dist/assets/{multirun-CWbdKSsT.js → multirun-CfvHH_3s.js} +1 -1
- package/dist/assets/{outsideFileGrants-BB4GPvCq.js → outsideFileGrants-DnplRxr-.js} +1 -1
- package/dist/assets/persistence-DdUac14I.js +3 -0
- package/dist/assets/platform-B4KKLnZ5.js +2 -0
- package/dist/assets/{projectMeta-BjeUc8MG.js → projectMeta-vCCip4-G.js} +1 -1
- package/dist/assets/{renderElectronMiniChatApp-Cv1F39fu.js → renderElectronMiniChatApp-D9RarEOS.js} +2 -2
- package/dist/assets/{renderMobileApp-C4zDY0CW.js → renderMobileApp-DOiQLCcY.js} +7 -7
- package/dist/assets/{runtimeConfig-D0G_wzhg.js → runtimeConfig-CkWKMmAR.js} +1 -1
- package/dist/assets/{runtimeEndpointReset-Cx37ZLh4.js → runtimeEndpointReset-aW8qogl0.js} +1 -1
- package/dist/assets/{sessionChangeSummary-CX2MJIkc.js → sessionChangeSummary-DOq8EN_H.js} +1 -1
- package/dist/assets/{sessionLookup-B56D_zE1.js → sessionLookup-BNO4Ta46.js} +1 -1
- package/dist/assets/{sortable-tabs-strip-C5gGnikj.js → sortable-tabs-strip-C8_9kHqu.js} +1 -1
- package/dist/assets/src-DasvfkEg.css +2 -0
- package/dist/assets/{terminalApi-CIIs9vFx.js → terminalApi-947l7Ra3.js} +1 -1
- package/dist/assets/{textarea-CIO34TZz.js → textarea-Cgo_nWUU.js} +1 -1
- package/dist/assets/{tooltip-BSrJYYYc.js → tooltip-BifLJ8o0.js} +1 -1
- package/dist/assets/{url-CE_gAfNa.js → url-Pk6tQ1EZ.js} +1 -1
- package/dist/assets/{useAppFontEffects-i1QzgXKU.js → useAppFontEffects-BqBeuVr8.js} +6 -6
- package/dist/assets/{useAssistantUIStore-BHacrxe_.js → useAssistantUIStore-me6s63b2.js} +1 -1
- package/dist/assets/{useDesktopWindowControlsLayout-BqT0VDLV.js → useDesktopWindowControlsLayout-CnX7JJa1.js} +1 -1
- package/dist/assets/{useEffectiveDirectory-CUSBKiSi.js → useEffectiveDirectory-F2fNcQ22.js} +1 -1
- package/dist/assets/{useFontPreferences-BxOHKuVw.js → useFontPreferences-BCOBlaAd.js} +1 -1
- package/dist/assets/useMobileNavigationStore-CBfSvE2P.js +413 -0
- package/dist/assets/{useSessionAutoCleanup-mitMfzXN.js → useSessionAutoCleanup-BVJKWCtK.js} +1 -1
- package/dist/assets/useUIStore-CuaA8-Hp.js +1 -0
- package/dist/assets/{useWorkerHighlightedLines-BZHDVxzL.js → useWorkerHighlightedLines-WYqpkPyP.js} +1 -1
- package/dist/assets/{utils-B0mQXN9L.js → utils-BiK3tBGM.js} +1 -1
- package/dist/index.html +9 -9
- package/dist/mini-chat.html +9 -9
- package/dist/mobile.html +9 -9
- package/package.json +1 -1
- package/server/lib/assistants/contact-tools.test.js +6 -6
- package/server/lib/assistants/harness.test.js +3 -3
- package/server/lib/assistants/service.test.js +1 -1
- package/server/lib/event-stream/DOCUMENTATION.md +12 -1
- package/server/lib/event-stream/directory-ws-bridge.js +11 -2
- package/server/lib/event-stream/global-ws-bridge.js +19 -3
- package/server/lib/event-stream/protocol.js +11 -1
- package/server/lib/event-stream/reasoning-projection.js +425 -0
- package/server/lib/event-stream/reasoning-projection.test.js +300 -0
- package/server/lib/event-stream/runtime.js +10 -0
- package/server/lib/event-stream/runtime.test.js +53 -0
- package/server/lib/opencode/DOCUMENTATION.md +2 -1
- package/server/lib/opencode/proxy.js +103 -9
- package/server/lib/opencode/proxy.test.js +177 -1
- package/server/lib/relay/reasoning-projection.e2e.test.ts +529 -0
- package/server/lib/session-turn-pages/DOCUMENTATION.md +2 -1
- package/server/lib/session-turn-pages/routes.js +22 -3
- package/server/lib/session-turn-pages/routes.test.js +43 -0
- package/server/lib/transcript-cache/DOCUMENTATION.md +2 -2
- package/server/lib/transcript-cache/routes.js +9 -2
- package/server/lib/transcript-cache/routes.test.js +32 -0
- package/dist/assets/AssistantView-DDIVh1W4.js +0 -2
- package/dist/assets/MarkstreamRendererImpl-Ca7RATbs.css +0 -1
- package/dist/assets/MarkstreamRendererImpl-DANegq9r.js +0 -1
- package/dist/assets/MobileShareBridge-BVHXNDqj.js +0 -4
- package/dist/assets/desktopHosts-BzSE0sK7.js +0 -1
- package/dist/assets/persistence-CSZp1CNB.js +0 -3
- package/dist/assets/platform-CenlWqxu.js +0 -2
- package/dist/assets/src-Cs2WiOMc.css +0 -2
- package/dist/assets/useMobileNavigationStore-C-EBQ7Zt.js +0 -412
- package/dist/assets/useUIStore-CqqO11ZI.js +0 -1
|
@@ -1,12 +1,69 @@
|
|
|
1
|
-
import
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import request from 'supertest';
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
4
|
|
|
3
5
|
import {
|
|
4
6
|
createDirectoryQueryCanonicalizer,
|
|
5
7
|
isInteractiveSessionRequest,
|
|
6
8
|
normalizeForwardedDirectoryHeaders,
|
|
9
|
+
registerOpenCodeProxy,
|
|
7
10
|
resolveSessionTurnAdmissionRequest,
|
|
8
11
|
} from './proxy.js';
|
|
9
12
|
|
|
13
|
+
const originalFetch = globalThis.fetch;
|
|
14
|
+
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
globalThis.fetch = originalFetch;
|
|
17
|
+
vi.restoreAllMocks();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const readyRuntime = () => ({
|
|
21
|
+
isOpenCodeReady: true,
|
|
22
|
+
openCodeNotReadySince: 0,
|
|
23
|
+
isRestartingOpenCode: false,
|
|
24
|
+
openCodePort: 4096,
|
|
25
|
+
openCodeBaseUrl: 'http://127.0.0.1:4096',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const mountProxy = () => {
|
|
29
|
+
const app = express();
|
|
30
|
+
// Fresh app each time — registerOpenCodeProxy guards on app setting.
|
|
31
|
+
registerOpenCodeProxy(app, {
|
|
32
|
+
fs: { promises: { realpath: async (v) => v } },
|
|
33
|
+
os: {},
|
|
34
|
+
path: {},
|
|
35
|
+
OPEN_CODE_READY_GRACE_MS: 1000,
|
|
36
|
+
LONG_REQUEST_TIMEOUT_MS: 60_000,
|
|
37
|
+
SSE_UPSTREAM_CONNECT_TIMEOUT_MS: 5_000,
|
|
38
|
+
SSE_UPSTREAM_STALL_TIMEOUT_MS: 5_000,
|
|
39
|
+
getRuntime: readyRuntime,
|
|
40
|
+
getOpenCodeAuthHeaders: () => ({}),
|
|
41
|
+
buildOpenCodeUrl: (path) => `http://127.0.0.1:4096${path}`,
|
|
42
|
+
ensureOpenCodeApiPrefix: () => {},
|
|
43
|
+
});
|
|
44
|
+
return app;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const sseBody = (blocks) => {
|
|
48
|
+
const encoder = new TextEncoder();
|
|
49
|
+
const text = blocks.join('');
|
|
50
|
+
let sent = false;
|
|
51
|
+
return {
|
|
52
|
+
getReader() {
|
|
53
|
+
return {
|
|
54
|
+
async read() {
|
|
55
|
+
if (sent) return { done: true, value: undefined };
|
|
56
|
+
sent = true;
|
|
57
|
+
return { done: false, value: encoder.encode(text) };
|
|
58
|
+
},
|
|
59
|
+
async cancel() {},
|
|
60
|
+
releaseLock() {},
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
async cancel() {},
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
10
67
|
describe('createDirectoryQueryCanonicalizer', () => {
|
|
11
68
|
it('canonicalizes directory query params and preserves other params', async () => {
|
|
12
69
|
const canonicalize = createDirectoryQueryCanonicalizer({
|
|
@@ -124,3 +181,122 @@ describe('resolveSessionTurnAdmissionRequest', () => {
|
|
|
124
181
|
expect(resolveSessionTurnAdmissionRequest({ method: 'POST', url: '/api/session/ses_1/message' })).toBeNull();
|
|
125
182
|
});
|
|
126
183
|
});
|
|
184
|
+
|
|
185
|
+
describe('registerOpenCodeProxy reasoning projection routes', () => {
|
|
186
|
+
it('strips includeReasoning from SSE upstream and drops reasoning events when false', async () => {
|
|
187
|
+
const upstreamUrls = [];
|
|
188
|
+
globalThis.fetch = vi.fn(async (url) => {
|
|
189
|
+
upstreamUrls.push(String(url));
|
|
190
|
+
return {
|
|
191
|
+
ok: true,
|
|
192
|
+
status: 200,
|
|
193
|
+
headers: new Headers({ 'content-type': 'text/event-stream' }),
|
|
194
|
+
body: sseBody([
|
|
195
|
+
'id: 1\ndata: {"type":"message.part.updated","properties":{"part":{"id":"t","messageID":"m","type":"text","text":"hi"}}}\n\n',
|
|
196
|
+
'id: 2\ndata: {"type":"session.next.reasoning.delta.1","properties":{"delta":"secret"}}\n\n',
|
|
197
|
+
'id: 3\ndata: {"type":"message.part.delta","properties":{"messageID":"m","partID":"t","field":"text","delta":"!"}}\n\n',
|
|
198
|
+
]),
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const app = mountProxy();
|
|
203
|
+
const res = await request(app)
|
|
204
|
+
.get('/api/event?directory=%2Ftmp&includeReasoning=false')
|
|
205
|
+
.buffer(true)
|
|
206
|
+
.parse((response, callback) => {
|
|
207
|
+
const chunks = [];
|
|
208
|
+
response.on('data', (c) => chunks.push(Buffer.from(c)));
|
|
209
|
+
response.on('end', () => callback(null, Buffer.concat(chunks).toString('utf8')));
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
expect(res.status).toBe(200);
|
|
213
|
+
expect(upstreamUrls).toHaveLength(1);
|
|
214
|
+
expect(upstreamUrls[0]).not.toContain('includeReasoning');
|
|
215
|
+
expect(upstreamUrls[0]).toContain('directory=');
|
|
216
|
+
expect(res.body).toContain('"type":"message.part.updated"');
|
|
217
|
+
expect(res.body).toContain('"type":"message.part.delta"');
|
|
218
|
+
expect(res.body).not.toContain('reasoning');
|
|
219
|
+
expect(res.body).not.toContain('secret');
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('byte-passthrough SSE when includeReasoning is omitted', async () => {
|
|
223
|
+
const raw =
|
|
224
|
+
'id: 1\ndata: {"type":"session.next.reasoning.delta","properties":{"delta":"keep"}}\n\n';
|
|
225
|
+
globalThis.fetch = vi.fn(async () => ({
|
|
226
|
+
ok: true,
|
|
227
|
+
status: 200,
|
|
228
|
+
headers: new Headers({ 'content-type': 'text/event-stream' }),
|
|
229
|
+
body: sseBody([raw]),
|
|
230
|
+
}));
|
|
231
|
+
|
|
232
|
+
const app = mountProxy();
|
|
233
|
+
const res = await request(app)
|
|
234
|
+
.get('/api/global/event')
|
|
235
|
+
.buffer(true)
|
|
236
|
+
.parse((response, callback) => {
|
|
237
|
+
const chunks = [];
|
|
238
|
+
response.on('data', (c) => chunks.push(Buffer.from(c)));
|
|
239
|
+
response.on('end', () => callback(null, Buffer.concat(chunks).toString('utf8')));
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
expect(res.status).toBe(200);
|
|
243
|
+
expect(res.body).toContain('session.next.reasoning.delta');
|
|
244
|
+
expect(res.body).toContain('keep');
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('filters session.messages list JSON and strips includeReasoning upstream', async () => {
|
|
248
|
+
const upstreamUrls = [];
|
|
249
|
+
globalThis.fetch = vi.fn(async (url) => {
|
|
250
|
+
upstreamUrls.push(String(url));
|
|
251
|
+
return {
|
|
252
|
+
ok: true,
|
|
253
|
+
status: 200,
|
|
254
|
+
headers: new Headers({ 'content-type': 'application/json' }),
|
|
255
|
+
async text() {
|
|
256
|
+
return JSON.stringify([
|
|
257
|
+
{
|
|
258
|
+
info: { id: 'msg_1', tokens: { reasoning: 12 } },
|
|
259
|
+
parts: [
|
|
260
|
+
{ id: 'r', type: 'reasoning', text: 'hidden' },
|
|
261
|
+
{ id: 't', type: 'text', text: 'visible' },
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
]);
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const app = mountProxy();
|
|
270
|
+
const res = await request(app)
|
|
271
|
+
.get('/api/session/ses_1/message?limit=30&includeReasoning=false&directory=%2Frepo');
|
|
272
|
+
|
|
273
|
+
expect(res.status).toBe(200);
|
|
274
|
+
expect(upstreamUrls[0]).not.toContain('includeReasoning');
|
|
275
|
+
expect(upstreamUrls[0]).toContain('/session/ses_1/message');
|
|
276
|
+
expect(res.body[0].parts).toEqual([{ id: 't', type: 'text', text: 'visible' }]);
|
|
277
|
+
expect(res.body[0].info.tokens.reasoning).toBe(12);
|
|
278
|
+
expect(JSON.stringify(res.body)).not.toContain('hidden');
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it('keeps reasoning parts on session.messages list when includeReasoning is omitted', async () => {
|
|
282
|
+
globalThis.fetch = vi.fn(async () => ({
|
|
283
|
+
ok: true,
|
|
284
|
+
status: 200,
|
|
285
|
+
headers: new Headers({ 'content-type': 'application/json' }),
|
|
286
|
+
async text() {
|
|
287
|
+
return JSON.stringify([
|
|
288
|
+
{
|
|
289
|
+
info: { id: 'msg_1' },
|
|
290
|
+
parts: [{ id: 'r', type: 'reasoning', text: 'keep-me' }],
|
|
291
|
+
},
|
|
292
|
+
]);
|
|
293
|
+
},
|
|
294
|
+
}));
|
|
295
|
+
|
|
296
|
+
const app = mountProxy();
|
|
297
|
+
const res = await request(app).get('/api/session/ses_1/message');
|
|
298
|
+
expect(res.status).toBe(200);
|
|
299
|
+
expect(res.body[0].parts[0].type).toBe('reasoning');
|
|
300
|
+
expect(res.body[0].parts[0].text).toBe('keep-me');
|
|
301
|
+
});
|
|
302
|
+
});
|