@openchambery/web 1.19.7-beta.13 → 1.19.7-beta.14
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-Dp_hbVcD.js → AgentAvatar-BsU82CEP.js} +1 -1
- package/dist/assets/AssistantView-CKNR7FFf.js +2 -0
- package/dist/assets/{DiagramView-iX3nhWaN.js → DiagramView-Db1VvSIR.js} +1 -1
- package/dist/assets/{MarkdownRendererImpl-tDry9J76.js → MarkdownRendererImpl-NBG7O4aX.js} +1 -1
- package/dist/assets/{MarkstreamRendererImpl-BDVGi72n.js → MarkstreamRendererImpl-Bs829ng-.js} +1 -1
- package/dist/assets/MobileDetailNavigation-CooM1BN7.js +1 -0
- package/dist/assets/{MobileShareBridge-BQ79cuPX.js → MobileShareBridge-CcG4lLaD.js} +3 -3
- package/dist/assets/MobileSurface-c_7RkYa2.js +2 -0
- package/dist/assets/{MultiRunWindow-CzMbzYD3.js → MultiRunWindow-Ds8nyikm.js} +1 -1
- package/dist/assets/{OnboardingScreen-CuvjeXSo.js → OnboardingScreen-BNEtPmvw.js} +1 -1
- package/dist/assets/SettingsView-Dac1dDOs.js +25 -0
- package/dist/assets/{SettingsWindow-DqwoBYvU.js → SettingsWindow-CHnMwzd6.js} +1 -1
- package/dist/assets/{TerminalView-4pFqXfvj.js → TerminalView-DfGueSOI.js} +1 -1
- package/dist/assets/{ToolOutputDialog-GmD4kIoH.js → ToolOutputDialog-BrR9iqiW.js} +1 -1
- package/dist/assets/{appThemeRegistry-BlEYFhXM.js → appThemeRegistry-BEG7NRFm.js} +2 -2
- package/dist/assets/{clipboard-Bu0lpyX1.js → clipboard-BXxLshVq.js} +1 -1
- package/dist/assets/context-menu-Dpjla5p4.js +1 -0
- package/dist/assets/{dialog-D21YndEx.js → dialog-BkhHBTd4.js} +1 -1
- package/dist/assets/dropdown-menu.styles-Bzo6L3FH.js +1 -0
- package/dist/assets/{es-C8Sqjsia.js → es-BHqnSjoZ.js} +1 -1
- package/dist/assets/{fr-p-Zwm_j2.js → fr-BfrlJY9i.js} +1 -1
- package/dist/assets/{gitApi-CciB055B.js → gitApi-Br5EdS29.js} +3 -3
- package/dist/assets/insertionBoundaries-ncyYkgWy.js +4 -0
- package/dist/assets/{ja-B6REu1qP.js → ja-DP-7qt-x.js} +1 -1
- package/dist/assets/{ko-CJBNH9IZ.js → ko-E2B5vGQP.js} +1 -1
- package/dist/assets/main-DX_9iX64.js +169 -0
- package/dist/assets/{main-DYFky6Uj.js → main-Dl-XWJxN.js} +2 -2
- package/dist/assets/miniChat-Cho-Pywx.js +2 -0
- package/dist/assets/mobile-1_JD1EGE.js +2 -0
- package/dist/assets/multirun-ByFn3xhO.js +4 -0
- package/dist/assets/{pl-B2cBI_7K.js → pl-r8X5gRM5.js} +1 -1
- package/dist/assets/projectMeta-BHw8kRhQ.js +3 -0
- package/dist/assets/{pt-BR-CrCc9hmt.js → pt-BR-DcpdXCf5.js} +1 -1
- package/dist/assets/renderElectronMiniChatApp-CvIxnUQY.js +2 -0
- package/dist/assets/renderMobileApp-DscicBzZ.js +28 -0
- package/dist/assets/{runtimeConfig-DNsnUkyp.js → runtimeConfig-Dkt3p8CZ.js} +1 -1
- package/dist/assets/runtimeEndpointReset-hBFsO83_.js +147 -0
- package/dist/assets/sessionChangeSummary-CX2MJIkc.js +1 -0
- package/dist/assets/sessionLookup-jCEot_fX.js +1 -0
- package/dist/assets/{sortable-tabs-strip-Biow4Fqu.js → sortable-tabs-strip-C5gGnikj.js} +1 -1
- package/dist/assets/src-KcdsQIuP.css +2 -0
- package/dist/assets/{store-CL3WP48T.js → store-BDFdnk6l.js} +2 -2
- package/dist/assets/textarea-CIO34TZz.js +1 -0
- package/dist/assets/{uk-C8YKAz0x.js → uk-Di0vl9V-.js} +1 -1
- package/dist/assets/{ChatContainer-C04WuLo8.js → useAppFontEffects-kJR0NlNH.js} +44 -39
- package/dist/assets/useDesktopWindowControlsLayout-BmbOASBQ.js +1 -0
- package/dist/assets/useEffectiveDirectory-DOToiRZd.js +1 -0
- package/dist/assets/useMobileNavigationStore-CEmn-d1X.js +412 -0
- package/dist/assets/useSessionAutoCleanup-DcmXMo-p.js +1 -0
- package/dist/assets/{useWorkerHighlightedLines-BaNK-wuY.js → useWorkerHighlightedLines-r5Ww4sY7.js} +1 -1
- package/dist/assets/{zh-CN-CCYwUnmB.js → zh-CN-coFCfeQE.js} +1 -1
- package/dist/assets/{zh-TW-D8Y6py08.js → zh-TW-oDRZ1-yb.js} +1 -1
- package/dist/index.html +3 -3
- package/dist/mini-chat.html +3 -3
- package/dist/mobile.html +3 -3
- package/package.json +2 -1
- package/server/index.js +2 -0
- package/server/lib/assistant-delivery-parts.js +3 -1
- package/server/lib/assistant-delivery-parts.test.js +11 -0
- package/server/lib/assistants/DOCUMENTATION.md +76 -3
- package/server/lib/assistants/assign.js +225 -0
- package/server/lib/assistants/assign.test.js +118 -0
- package/server/lib/assistants/bubbles.js +45 -0
- package/server/lib/assistants/bubbles.test.js +36 -0
- package/server/lib/assistants/cards.js +148 -0
- package/server/lib/assistants/cards.test.js +116 -0
- package/server/lib/assistants/contact-store.js +284 -0
- package/server/lib/assistants/contact-store.test.js +131 -0
- package/server/lib/assistants/contact-tools.js +761 -0
- package/server/lib/assistants/contact-tools.test.js +328 -0
- package/server/lib/assistants/contracts.js +20 -1
- package/server/lib/assistants/harness.js +551 -0
- package/server/lib/assistants/harness.test.js +607 -0
- package/server/lib/assistants/routes.js +44 -4
- package/server/lib/assistants/service.js +930 -17
- package/server/lib/assistants/service.test.js +1163 -45
- package/server/lib/llm/DOCUMENTATION.md +84 -0
- package/server/lib/llm/catalog.js +100 -0
- package/server/lib/llm/catalog.test.js +78 -0
- package/server/lib/llm/completions.js +151 -0
- package/server/lib/llm/completions.test.js +127 -0
- package/server/lib/llm/generate.js +570 -0
- package/server/lib/llm/generate.test.js +459 -0
- package/server/lib/llm/routes.js +47 -0
- package/server/lib/llm/temp-directory.js +37 -0
- package/server/lib/notifications/runtime.js +52 -0
- package/server/lib/notifications/runtime.test.js +39 -0
- package/server/lib/opencode/feature-routes-runtime.js +30 -0
- package/server/lib/opencode/feature-routes-runtime.test.js +20 -0
- package/server/lib/session-goal/DOCUMENTATION.md +8 -1
- package/server/lib/session-goal/runtime.js +20 -0
- package/server/lib/session-index/DOCUMENTATION.md +3 -1
- package/server/lib/session-index/service.js +10 -4
- package/server/lib/session-index/service.test.js +37 -0
- package/server/lib/session-title/runtime.js +1 -0
- package/server/lib/session-title/runtime.test.js +11 -0
- package/dist/assets/AssistantView-CQHey6je.js +0 -1
- package/dist/assets/ContextPanel-BJEFzgz7.js +0 -285
- package/dist/assets/MobileDetailNavigation-Dcl7Upvc.js +0 -1
- package/dist/assets/MobileSurface-CpAbBAQ5.js +0 -2
- package/dist/assets/SettingsView-DRiEDi23.js +0 -25
- package/dist/assets/insertionBoundaries-DcS10A9Q.js +0 -4
- package/dist/assets/main-Coj1Z4LN.js +0 -29
- package/dist/assets/miniChat-DK-d_3-7.js +0 -2
- package/dist/assets/mobile-8QzXy5wz.js +0 -2
- package/dist/assets/multirun-BFHWrDOR.js +0 -4
- package/dist/assets/projectMeta-CEGa4Czs.js +0 -3
- package/dist/assets/radio-Bw11T40N.js +0 -1
- package/dist/assets/renderElectronMiniChatApp-_fchgm-8.js +0 -2
- package/dist/assets/renderMobileApp-B1j1BUXB.js +0 -28
- package/dist/assets/runtimeEndpointReset-C-Sm4wpj.js +0 -4
- package/dist/assets/shikiHighlight-GaNLBDUk.js +0 -1
- package/dist/assets/src-BGao3JmJ.css +0 -2
- package/dist/assets/useAppFontEffects-D0UWTJui.js +0 -7
- package/dist/assets/useDesktopWindowControlsLayout-_5M7NHJ8.js +0 -1
- package/dist/assets/useEffectiveDirectory-DqOLKISv.js +0 -1
- package/dist/assets/useMobileNavigationStore-DxH1DjU-.js +0 -412
- package/dist/assets/useSessionAutoCleanup-Dpp0-zw2.js +0 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { describe, expect, it } from 'vitest';
|
|
6
|
+
import { createSessionCardPart } from './cards.js';
|
|
7
|
+
import {
|
|
8
|
+
CONTACT_LLM_FETCH_LIMIT,
|
|
9
|
+
CONTACT_LLM_FILE_CHAR_WEIGHT,
|
|
10
|
+
CONTACT_LLM_MAX_CHARS,
|
|
11
|
+
CONTACT_LLM_MAX_TURNS,
|
|
12
|
+
contactHistoryForLlm,
|
|
13
|
+
deleteContactMessages,
|
|
14
|
+
ensureContactSchema,
|
|
15
|
+
insertContactMessage,
|
|
16
|
+
listContactMessages,
|
|
17
|
+
nextContactOrdinal,
|
|
18
|
+
trimContactHistoryForLlm,
|
|
19
|
+
} from './contact-store.js';
|
|
20
|
+
|
|
21
|
+
const require = createRequire(import.meta.url);
|
|
22
|
+
|
|
23
|
+
const openDb = () => {
|
|
24
|
+
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'contact-store-'));
|
|
25
|
+
const Database = require('better-sqlite3');
|
|
26
|
+
const db = new Database(path.join(directory, 'contact.sqlite'));
|
|
27
|
+
ensureContactSchema(db);
|
|
28
|
+
return db;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const insert = (db, assistantID, { role, text = '', parts, status = 'complete', fromAssistantID = null, fromAssistantName = null }) => {
|
|
32
|
+
const messageID = crypto.randomUUID();
|
|
33
|
+
insertContactMessage(db, {
|
|
34
|
+
messageID,
|
|
35
|
+
assistantID,
|
|
36
|
+
role,
|
|
37
|
+
turnID: messageID,
|
|
38
|
+
bubbleIndex: 0,
|
|
39
|
+
createdAt: Date.now(),
|
|
40
|
+
ordinal: nextContactOrdinal(db, assistantID),
|
|
41
|
+
status,
|
|
42
|
+
parts: parts || (text ? [{ type: 'text', text }] : [{ type: 'text', text: '' }]),
|
|
43
|
+
fromAssistantID,
|
|
44
|
+
fromAssistantName,
|
|
45
|
+
});
|
|
46
|
+
return messageID;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
describe('contact LLM history trim', () => {
|
|
50
|
+
it('documents the budget constants in one place', () => {
|
|
51
|
+
expect(CONTACT_LLM_MAX_TURNS).toBe(8);
|
|
52
|
+
expect(CONTACT_LLM_MAX_CHARS).toBe(6_000);
|
|
53
|
+
expect(CONTACT_LLM_FETCH_LIMIT).toBe(40);
|
|
54
|
+
expect(CONTACT_LLM_FILE_CHAR_WEIGHT).toBe(80);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('keeps the newest user+assistant turns and leaves older SQLite rows for the UI', () => {
|
|
58
|
+
const db = openDb();
|
|
59
|
+
const assistantID = 'asst_trim';
|
|
60
|
+
for (let index = 0; index < 12; index += 1) {
|
|
61
|
+
insert(db, assistantID, { role: 'user', text: `user-${index}` });
|
|
62
|
+
insert(db, assistantID, { role: 'assistant', text: `assistant-${index}` });
|
|
63
|
+
}
|
|
64
|
+
const history = contactHistoryForLlm(db, assistantID);
|
|
65
|
+
expect(history).toHaveLength(CONTACT_LLM_MAX_TURNS * 2);
|
|
66
|
+
expect(history[0]).toEqual({ role: 'user', content: 'user-4' });
|
|
67
|
+
expect(history.at(-1)).toEqual({ role: 'assistant', content: 'assistant-11' });
|
|
68
|
+
const page = listContactMessages(db, assistantID, { limit: 100 });
|
|
69
|
+
expect(page.messages).toHaveLength(24);
|
|
70
|
+
expect(page.messages[0].text).toBe('user-0');
|
|
71
|
+
db.close();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('drops peer, error, and pure-card rows from the LLM window', () => {
|
|
75
|
+
const db = openDb();
|
|
76
|
+
const assistantID = 'asst_filter';
|
|
77
|
+
insert(db, assistantID, { role: 'user', text: 'keep-user' });
|
|
78
|
+
insert(db, assistantID, { role: 'assistant', text: 'keep-assistant' });
|
|
79
|
+
insert(db, assistantID, { role: 'peer', text: 'secret-from-peer', fromAssistantID: 'other', fromAssistantName: 'PeerQA' });
|
|
80
|
+
insert(db, assistantID, { role: 'assistant', text: 'failed', status: 'error' });
|
|
81
|
+
insert(db, assistantID, {
|
|
82
|
+
role: 'assistant',
|
|
83
|
+
parts: [createSessionCardPart({ sessionID: 'ses_1', directory: '/repo', title: 'Work', status: 'busy' })],
|
|
84
|
+
});
|
|
85
|
+
expect(contactHistoryForLlm(db, assistantID)).toEqual([
|
|
86
|
+
{ role: 'user', content: 'keep-user' },
|
|
87
|
+
{ role: 'assistant', content: 'keep-assistant' },
|
|
88
|
+
]);
|
|
89
|
+
expect(listContactMessages(db, assistantID, { limit: 50 }).messages).toHaveLength(5);
|
|
90
|
+
db.close();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('stops before an older turn that would exceed the char budget', () => {
|
|
94
|
+
const huge = 'x'.repeat(CONTACT_LLM_MAX_CHARS - 10);
|
|
95
|
+
const messages = [
|
|
96
|
+
{ role: 'user', status: 'complete', text: huge, parts: [{ type: 'text', text: huge }] },
|
|
97
|
+
{ role: 'assistant', status: 'complete', text: 'old-reply', parts: [{ type: 'text', text: 'old-reply' }] },
|
|
98
|
+
{ role: 'user', status: 'complete', text: 'recent', parts: [{ type: 'text', text: 'recent' }] },
|
|
99
|
+
{ role: 'assistant', status: 'complete', text: 'fresh', parts: [{ type: 'text', text: 'fresh' }] },
|
|
100
|
+
];
|
|
101
|
+
expect(trimContactHistoryForLlm(messages)).toEqual([
|
|
102
|
+
{ role: 'user', content: 'recent' },
|
|
103
|
+
{ role: 'assistant', content: 'fresh' },
|
|
104
|
+
]);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('always keeps the newest turn even when it exceeds the char budget', () => {
|
|
108
|
+
const huge = 'y'.repeat(CONTACT_LLM_MAX_CHARS + 200);
|
|
109
|
+
const messages = [
|
|
110
|
+
{ role: 'user', status: 'complete', text: 'older', parts: [{ type: 'text', text: 'older' }] },
|
|
111
|
+
{ role: 'assistant', status: 'complete', text: 'older-reply', parts: [{ type: 'text', text: 'older-reply' }] },
|
|
112
|
+
{ role: 'user', status: 'complete', text: huge, parts: [{ type: 'text', text: huge }] },
|
|
113
|
+
{ role: 'assistant', status: 'complete', text: 'now', parts: [{ type: 'text', text: 'now' }] },
|
|
114
|
+
];
|
|
115
|
+
expect(trimContactHistoryForLlm(messages)).toEqual([
|
|
116
|
+
{ role: 'user', content: huge },
|
|
117
|
+
{ role: 'assistant', content: 'now' },
|
|
118
|
+
]);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('clears LLM history after deleteContactMessages', () => {
|
|
122
|
+
const db = openDb();
|
|
123
|
+
const assistantID = 'asst_reset';
|
|
124
|
+
insert(db, assistantID, { role: 'user', text: 'before' });
|
|
125
|
+
insert(db, assistantID, { role: 'assistant', text: 'reply' });
|
|
126
|
+
deleteContactMessages(db, assistantID);
|
|
127
|
+
expect(contactHistoryForLlm(db, assistantID)).toEqual([]);
|
|
128
|
+
expect(listContactMessages(db, assistantID, { limit: 50 }).messages).toEqual([]);
|
|
129
|
+
db.close();
|
|
130
|
+
});
|
|
131
|
+
});
|