negotium 0.1.12 → 0.1.13

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.
Files changed (137) hide show
  1. package/dist/canonical-mcp-bridge.js +2 -3
  2. package/dist/canonical-mcp-bridge.js.map +1 -1
  3. package/dist/chunk-a9y2rwxf.js.map +1 -1
  4. package/dist/{chunk-j0kjscb7.js → chunk-s2gez3wg.js} +20 -2
  5. package/dist/{chunk-j0kjscb7.js.map → chunk-s2gez3wg.js.map} +2 -2
  6. package/dist/cron.js +49 -25
  7. package/dist/cron.js.map +15 -14
  8. package/dist/hosted-agent.js +3012 -17
  9. package/dist/hosted-agent.js.map +30 -3
  10. package/dist/main.js +31323 -36
  11. package/dist/main.js.map +198 -3
  12. package/dist/prompts.js +11 -8
  13. package/dist/prompts.js.map +4 -4
  14. package/dist/runtime/src/application/submit-user-message.ts +3 -0
  15. package/dist/runtime/src/index.ts +7 -0
  16. package/dist/runtime/src/mcp/runtime-spec.ts +3 -0
  17. package/dist/runtime/src/mcp/session-comm/server.ts +1 -1
  18. package/dist/runtime/src/platform/mcp-config.ts +13 -0
  19. package/dist/runtime/src/prompts/builders.ts +20 -6
  20. package/dist/runtime/src/query/active-rooms.ts +2 -0
  21. package/dist/runtime/src/runtime/delivery-ack.ts +112 -0
  22. package/dist/runtime/src/runtime/errors.ts +12 -12
  23. package/dist/runtime/src/runtime/turn-runner.ts +12 -0
  24. package/dist/runtime/src/storage/runtime-turn-requests.ts +1 -0
  25. package/dist/runtime/src/types/api.ts +2 -0
  26. package/dist/runtime/src/types.ts +2 -0
  27. package/dist/runtime/src/version.ts +1 -1
  28. package/dist/runtime-helpers.js.map +1 -1
  29. package/dist/storage.js.map +1 -1
  30. package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +2 -0
  31. package/dist/types/packages/core/src/platform/mcp-config.d.ts +4 -0
  32. package/dist/types/packages/core/src/prompts/builders.d.ts +2 -0
  33. package/dist/types/packages/core/src/types/api.d.ts +2 -0
  34. package/dist/types/packages/core/src/types.d.ts +2 -0
  35. package/dist/types/packages/core/src/version.d.ts +1 -1
  36. package/dist/vault.js.map +1 -1
  37. package/package.json +1 -1
  38. package/dist/chunk-00q25k7p.js +0 -2387
  39. package/dist/chunk-00q25k7p.js.map +0 -26
  40. package/dist/chunk-03kv7mvj.js +0 -2152
  41. package/dist/chunk-03kv7mvj.js.map +0 -15
  42. package/dist/chunk-05pm51dh.js +0 -589
  43. package/dist/chunk-05pm51dh.js.map +0 -11
  44. package/dist/chunk-0eh16bk1.js +0 -2936
  45. package/dist/chunk-0eh16bk1.js.map +0 -20
  46. package/dist/chunk-0yfqyv88.js +0 -108
  47. package/dist/chunk-0yfqyv88.js.map +0 -10
  48. package/dist/chunk-1k7t7bnx.js +0 -97
  49. package/dist/chunk-1k7t7bnx.js.map +0 -10
  50. package/dist/chunk-3gkfr9vb.js +0 -431
  51. package/dist/chunk-3gkfr9vb.js.map +0 -11
  52. package/dist/chunk-5akd1gbj.js +0 -281
  53. package/dist/chunk-5akd1gbj.js.map +0 -10
  54. package/dist/chunk-7k19pcg8.js +0 -577
  55. package/dist/chunk-7k19pcg8.js.map +0 -14
  56. package/dist/chunk-81tbfbmt.js +0 -10
  57. package/dist/chunk-81tbfbmt.js.map +0 -10
  58. package/dist/chunk-82qhv1mq.js +0 -512
  59. package/dist/chunk-82qhv1mq.js.map +0 -13
  60. package/dist/chunk-8dy7e2a9.js +0 -103
  61. package/dist/chunk-8dy7e2a9.js.map +0 -10
  62. package/dist/chunk-8f2sqmrj.js +0 -1712
  63. package/dist/chunk-8f2sqmrj.js.map +0 -18
  64. package/dist/chunk-9hjeemfz.js +0 -372
  65. package/dist/chunk-9hjeemfz.js.map +0 -10
  66. package/dist/chunk-a4aa2ccv.js +0 -141
  67. package/dist/chunk-a4aa2ccv.js.map +0 -10
  68. package/dist/chunk-bsg215q3.js +0 -3536
  69. package/dist/chunk-bsg215q3.js.map +0 -20
  70. package/dist/chunk-bxnfsc7w.js +0 -58
  71. package/dist/chunk-bxnfsc7w.js.map +0 -10
  72. package/dist/chunk-c500xe9z.js +0 -33
  73. package/dist/chunk-c500xe9z.js.map +0 -10
  74. package/dist/chunk-cngrf7ab.js +0 -149
  75. package/dist/chunk-cngrf7ab.js.map +0 -10
  76. package/dist/chunk-d7tprf06.js +0 -53
  77. package/dist/chunk-d7tprf06.js.map +0 -10
  78. package/dist/chunk-ddnrmkrv.js +0 -61
  79. package/dist/chunk-ddnrmkrv.js.map +0 -10
  80. package/dist/chunk-edb07sjp.js +0 -567
  81. package/dist/chunk-edb07sjp.js.map +0 -14
  82. package/dist/chunk-ejcm6zx8.js +0 -591
  83. package/dist/chunk-ejcm6zx8.js.map +0 -11
  84. package/dist/chunk-ezs352qs.js +0 -237
  85. package/dist/chunk-ezs352qs.js.map +0 -11
  86. package/dist/chunk-f5xgprg1.js +0 -59
  87. package/dist/chunk-f5xgprg1.js.map +0 -10
  88. package/dist/chunk-fbtb3v0s.js +0 -1339
  89. package/dist/chunk-fbtb3v0s.js.map +0 -16
  90. package/dist/chunk-ffefbd3r.js +0 -17
  91. package/dist/chunk-ffefbd3r.js.map +0 -10
  92. package/dist/chunk-gaknyw04.js +0 -708
  93. package/dist/chunk-gaknyw04.js.map +0 -14
  94. package/dist/chunk-gxmny6tq.js +0 -1637
  95. package/dist/chunk-gxmny6tq.js.map +0 -15
  96. package/dist/chunk-h7bj5zwb.js +0 -3069
  97. package/dist/chunk-h7bj5zwb.js.map +0 -32
  98. package/dist/chunk-hp4g7wx7.js +0 -46
  99. package/dist/chunk-hp4g7wx7.js.map +0 -10
  100. package/dist/chunk-hwy3n31w.js +0 -21
  101. package/dist/chunk-hwy3n31w.js.map +0 -9
  102. package/dist/chunk-jzz91jwh.js +0 -70
  103. package/dist/chunk-jzz91jwh.js.map +0 -10
  104. package/dist/chunk-k778y16p.js +0 -153
  105. package/dist/chunk-k778y16p.js.map +0 -11
  106. package/dist/chunk-mh5mexsf.js +0 -147
  107. package/dist/chunk-mh5mexsf.js.map +0 -11
  108. package/dist/chunk-mnwaext5.js +0 -318
  109. package/dist/chunk-mnwaext5.js.map +0 -10
  110. package/dist/chunk-nkgs40ch.js +0 -23
  111. package/dist/chunk-nkgs40ch.js.map +0 -10
  112. package/dist/chunk-pz57vwsm.js +0 -250
  113. package/dist/chunk-pz57vwsm.js.map +0 -11
  114. package/dist/chunk-r6kdp7gn.js +0 -252
  115. package/dist/chunk-r6kdp7gn.js.map +0 -10
  116. package/dist/chunk-rkvrkcgx.js +0 -117
  117. package/dist/chunk-rkvrkcgx.js.map +0 -10
  118. package/dist/chunk-s74rdyqe.js +0 -117
  119. package/dist/chunk-s74rdyqe.js.map +0 -12
  120. package/dist/chunk-sa874j5c.js +0 -9
  121. package/dist/chunk-sa874j5c.js.map +0 -10
  122. package/dist/chunk-sffqdkvq.js +0 -122
  123. package/dist/chunk-sffqdkvq.js.map +0 -10
  124. package/dist/chunk-tcs9qjps.js +0 -64
  125. package/dist/chunk-tcs9qjps.js.map +0 -10
  126. package/dist/chunk-wx83ep8e.js +0 -131
  127. package/dist/chunk-wx83ep8e.js.map +0 -10
  128. package/dist/chunk-xag86ng3.js +0 -122
  129. package/dist/chunk-xag86ng3.js.map +0 -10
  130. package/dist/chunk-xfdkep71.js +0 -371
  131. package/dist/chunk-xfdkep71.js.map +0 -11
  132. package/dist/chunk-xhm1rfpt.js +0 -2907
  133. package/dist/chunk-xhm1rfpt.js.map +0 -24
  134. package/dist/chunk-xpcps28p.js +0 -2138
  135. package/dist/chunk-xpcps28p.js.map +0 -29
  136. package/dist/chunk-yb4rbev9.js +0 -214
  137. package/dist/chunk-yb4rbev9.js.map +0 -10
@@ -1,589 +0,0 @@
1
- // @bun
2
- import {
3
- NODE_CONTROL_BASE_PATH,
4
- NODE_CONTROL_PROTOCOL_VERSION,
5
- startDefaultNode
6
- } from "./chunk-gxmny6tq.js";
7
- import"./chunk-edb07sjp.js";
8
- import {
9
- deleteVaultEntry,
10
- executeVaultCommand,
11
- listBackgroundSessionsForUser,
12
- listVaultEntries,
13
- saveVaultEntry,
14
- submitUserMessage,
15
- switchTopicEffort,
16
- switchTopicModel,
17
- topicService
18
- } from "./chunk-h7bj5zwb.js";
19
- import"./chunk-tcs9qjps.js";
20
- import"./chunk-7k19pcg8.js";
21
- import"./chunk-8dy7e2a9.js";
22
- import"./chunk-9hjeemfz.js";
23
- import"./chunk-1k7t7bnx.js";
24
- import"./chunk-xhm1rfpt.js";
25
- import {
26
- getVisibleTopics
27
- } from "./chunk-mnwaext5.js";
28
- import"./chunk-xpcps28p.js";
29
- import {
30
- ensurePersonalGeneral,
31
- getAllMessagesForTopic,
32
- getApiMessage,
33
- listApiMessages,
34
- listRecentRuntimeEventsForTopic,
35
- runtimeBus
36
- } from "./chunk-fbtb3v0s.js";
37
- import"./chunk-ejcm6zx8.js";
38
- import"./chunk-hp4g7wx7.js";
39
- import"./chunk-s74rdyqe.js";
40
- import"./chunk-k778y16p.js";
41
- import"./chunk-xag86ng3.js";
42
- import"./chunk-wx83ep8e.js";
43
- import"./chunk-00q25k7p.js";
44
- import"./chunk-gaknyw04.js";
45
- import"./chunk-mh5mexsf.js";
46
- import"./chunk-ezs352qs.js";
47
- import"./chunk-j0kjscb7.js";
48
- import {
49
- listRunningTopicQueries
50
- } from "./chunk-82qhv1mq.js";
51
- import"./chunk-ffefbd3r.js";
52
- import {
53
- db
54
- } from "./chunk-81tbfbmt.js";
55
- import"./chunk-sffqdkvq.js";
56
- import"./chunk-f5xgprg1.js";
57
- import"./chunk-hwy3n31w.js";
58
-
59
- // ../../adapters/terminal/src/history-store.ts
60
- var MAX_STORED_HISTORY = 500;
61
- db.exec(`
62
- CREATE TABLE IF NOT EXISTS terminal_input_history (
63
- seq INTEGER PRIMARY KEY AUTOINCREMENT,
64
- user_id TEXT NOT NULL,
65
- text TEXT NOT NULL,
66
- created_at INTEGER NOT NULL
67
- )
68
- `);
69
- db.exec("CREATE INDEX IF NOT EXISTS idx_terminal_input_history_user_seq ON terminal_input_history(user_id, seq)");
70
- function loadTerminalInputHistory(userId, limit = 200) {
71
- const safeLimit = Math.max(1, Math.min(limit, MAX_STORED_HISTORY));
72
- return db.query(`SELECT text FROM (
73
- SELECT seq, text
74
- FROM terminal_input_history
75
- WHERE user_id = ?
76
- ORDER BY seq DESC
77
- LIMIT ?
78
- ) ORDER BY seq ASC`).all(userId, safeLimit).map((row) => row.text);
79
- }
80
- function appendTerminalInputHistory(userId, value) {
81
- const text = value.trim();
82
- if (!text)
83
- return;
84
- db.transaction(() => {
85
- const latest = db.query("SELECT text FROM terminal_input_history WHERE user_id = ? ORDER BY seq DESC LIMIT 1").get(userId);
86
- if (latest?.text === text)
87
- return;
88
- db.query("INSERT INTO terminal_input_history (user_id, text, created_at) VALUES (?, ?, ?)").run(userId, text, Date.now());
89
- db.query(`DELETE FROM terminal_input_history
90
- WHERE user_id = ? AND seq NOT IN (
91
- SELECT seq FROM terminal_input_history
92
- WHERE user_id = ? ORDER BY seq DESC LIMIT ?
93
- )`).run(userId, userId, MAX_STORED_HISTORY);
94
- }).immediate();
95
- }
96
-
97
- // ../../adapters/terminal/src/client.ts
98
- var MESSAGE_HISTORY_PAGE_SIZE = 50;
99
- var INITIAL_MESSAGE_HISTORY_PAGE_COUNT = 3;
100
- var INITIAL_MESSAGE_HISTORY_LIMIT = MESSAGE_HISTORY_PAGE_SIZE * INITIAL_MESSAGE_HISTORY_PAGE_COUNT;
101
-
102
- class EmbeddedNegotiumClient {
103
- #userId;
104
- #port;
105
- #startNode;
106
- #node = null;
107
- #unsubscribe = null;
108
- #started = false;
109
- constructor(options) {
110
- this.#userId = options.userId;
111
- this.#port = options.port ?? 0;
112
- this.#startNode = options.startNode !== false;
113
- }
114
- async start(onEvent) {
115
- if (this.#started)
116
- return;
117
- this.#started = true;
118
- this.#unsubscribe = runtimeBus().subscribe(onEvent);
119
- try {
120
- if (this.#startNode)
121
- this.#node = await startDefaultNode({ port: this.#port });
122
- ensurePersonalGeneral(this.#userId);
123
- } catch (error) {
124
- this.#unsubscribe?.();
125
- this.#unsubscribe = null;
126
- this.#started = false;
127
- throw error;
128
- }
129
- }
130
- async stop() {
131
- this.#unsubscribe?.();
132
- this.#unsubscribe = null;
133
- this.#started = false;
134
- const node = this.#node;
135
- this.#node = null;
136
- if (node)
137
- await node.stop();
138
- }
139
- listTopics() {
140
- const runningTopics = listRunningTopicQueries();
141
- return getVisibleTopics().filter((topic) => topic.participants.some((participant) => participant.userId === this.#userId)).map((topic) => {
142
- const runningQueryId = runningTopics.get(topic.id);
143
- return { ...topic, running: Boolean(runningQueryId), runningQueryId };
144
- });
145
- }
146
- listBackgroundSessions() {
147
- return listBackgroundSessionsForUser(this.#userId);
148
- }
149
- listMessages(topicId) {
150
- const rows = getAllMessagesForTopic(topicId);
151
- return rows.map((row) => typeof row.id === "string" ? getApiMessage(topicId, row.id) : null).filter((message) => message !== null);
152
- }
153
- listMessagePage(topicId, cursor, limit = MESSAGE_HISTORY_PAGE_SIZE) {
154
- const result = listApiMessages(topicId, { cursor, limit });
155
- return { messages: result.page, cursor: result.cursor, hasMore: result.hasMore };
156
- }
157
- listRecentEvents(topicId) {
158
- return listRecentRuntimeEventsForTopic(topicId).map((event) => ({
159
- type: event.type,
160
- topicId: event.topicId,
161
- payload: event.payload,
162
- seq: event.seq,
163
- createdAt: event.createdAt
164
- }));
165
- }
166
- createTopic(title, agent) {
167
- return topicService.create({
168
- title,
169
- userId: this.#userId,
170
- kind: "agent",
171
- ...agent ? { agent } : {}
172
- });
173
- }
174
- async deriveTopic(topic, copyHistory, name) {
175
- const derived = await topicService.derive({
176
- sourceTopicId: topic.id,
177
- userId: this.#userId,
178
- copyHistory,
179
- ...name ? { name } : {}
180
- });
181
- if (!derived)
182
- throw new Error(`Failed to ${copyHistory ? "fork" : "spawn"} "${topic.title}"`);
183
- return derived;
184
- }
185
- async resetTopic(topic) {
186
- const result = await topicService.reset({
187
- topicId: topic.id,
188
- userId: this.#userId,
189
- reason: "terminal-session-reset"
190
- });
191
- if (result.isError)
192
- throw new Error(result.text);
193
- return result.text;
194
- }
195
- async compactTopic(topic) {
196
- const result = await topicService.compact({
197
- topicId: topic.id,
198
- userId: this.#userId,
199
- reason: "terminal-session-compact"
200
- });
201
- if (result.isError)
202
- throw new Error(result.text);
203
- return result.text;
204
- }
205
- setModel(topic, model) {
206
- const result = switchTopicModel({ topicId: topic.id, userId: this.#userId, model });
207
- if (!result.ok)
208
- throw new Error(result.error);
209
- return result.text;
210
- }
211
- setEffort(topic, effort) {
212
- const result = switchTopicEffort({ topicId: topic.id, userId: this.#userId, effort });
213
- if (!result.ok)
214
- throw new Error(result.error);
215
- return result.text;
216
- }
217
- async deleteTopic(topic) {
218
- await topicService.delete({ topicId: topic.id, userId: this.#userId });
219
- }
220
- sendMessage(topic, text) {
221
- return submitUserMessage({
222
- topic,
223
- userId: this.#userId,
224
- text,
225
- sourceAdapter: "terminal",
226
- visualTools: false
227
- }).message;
228
- }
229
- answerQuestion(topicId, messageId, label) {
230
- const result = topicService.answerQuestion(topicId, messageId, label, this.#userId);
231
- return result.ok ? { ok: true } : { ok: false, error: result.error };
232
- }
233
- abort(topicId) {
234
- return topicService.abortTurn(topicId, this.#userId);
235
- }
236
- runVaultCommand(commandLine) {
237
- return executeVaultCommand(this.#userId, commandLine);
238
- }
239
- listVaultEntries() {
240
- return listVaultEntries(this.#userId);
241
- }
242
- saveVaultEntry(key, value, description) {
243
- return saveVaultEntry(this.#userId, key, value, description);
244
- }
245
- deleteVaultEntry(key) {
246
- return deleteVaultEntry(this.#userId, key);
247
- }
248
- listInputHistory() {
249
- return loadTerminalInputHistory(this.#userId);
250
- }
251
- appendInputHistory(text) {
252
- appendTerminalInputHistory(this.#userId, text);
253
- }
254
- }
255
- function missingControlRoute(error) {
256
- const message = error instanceof Error ? error.message : String(error);
257
- return /not found|http 404/i.test(message);
258
- }
259
- function parseLegacyVaultList(output) {
260
- if (!output || /vault is empty/i.test(output))
261
- return [];
262
- return output.split(`
263
- `).slice(1).flatMap((line) => {
264
- const match = line.match(/^- ([A-Z][A-Z0-9_]*)(?:: (.*))?$/);
265
- return match?.[1] ? [{ key: match[1], description: match[2] ?? "" }] : [];
266
- });
267
- }
268
- function isSecureControlTransport(baseUrl) {
269
- const url = new URL(baseUrl);
270
- if (url.protocol === "https:")
271
- return true;
272
- if (url.protocol !== "http:")
273
- return false;
274
- const hostname = url.hostname.toLowerCase();
275
- if (hostname === "localhost" || hostname === "::1" || hostname === "[::1]")
276
- return true;
277
- const octets = hostname.split(".");
278
- return octets.length === 4 && octets[0] === "127" && octets.every((octet) => /^\d{1,3}$/.test(octet) && Number(octet) <= 255);
279
- }
280
-
281
- class RemoteNegotiumClient {
282
- #userId;
283
- #baseUrl;
284
- #token;
285
- #onEvent = null;
286
- #eventAbort = null;
287
- #eventTask = null;
288
- #started = false;
289
- constructor(options) {
290
- this.#userId = options.userId;
291
- this.#baseUrl = options.baseUrl.replace(/\/+$/, "");
292
- if (!isSecureControlTransport(this.#baseUrl)) {
293
- throw new Error("Remote node control requires HTTPS or loopback HTTP");
294
- }
295
- this.#token = options.token;
296
- }
297
- async start(onEvent) {
298
- if (this.#started)
299
- return;
300
- const session = await this.#request(`/session?user=${encodeURIComponent(this.#userId)}`);
301
- if (session.protocolVersion !== NODE_CONTROL_PROTOCOL_VERSION) {
302
- throw new Error(`Node protocol ${String(session.protocolVersion)} is incompatible with terminal protocol ${NODE_CONTROL_PROTOCOL_VERSION}`);
303
- }
304
- const cursor = Number(session.cursor ?? 0);
305
- this.#onEvent = onEvent;
306
- this.#eventAbort = new AbortController;
307
- try {
308
- const first = await this.#openEventStream(cursor, this.#eventAbort.signal);
309
- this.#started = true;
310
- this.#eventTask = this.#runEventLoop(first, cursor, this.#eventAbort.signal);
311
- } catch (error) {
312
- this.#eventAbort = null;
313
- this.#onEvent = null;
314
- throw error;
315
- }
316
- }
317
- async stop() {
318
- this.#started = false;
319
- this.#eventAbort?.abort();
320
- this.#eventAbort = null;
321
- await this.#eventTask?.catch(() => {});
322
- this.#eventTask = null;
323
- this.#onEvent = null;
324
- }
325
- async listTopics() {
326
- const result = await this.#request(`/topics?user=${encodeURIComponent(this.#userId)}`);
327
- return result.topics ?? [];
328
- }
329
- async listBackgroundSessions() {
330
- const result = await this.#request(`/background-sessions?user=${encodeURIComponent(this.#userId)}`);
331
- return result.sessions ?? [];
332
- }
333
- async listMessages(topicId) {
334
- const result = await this.#request(`/topics/${encodeURIComponent(topicId)}/messages?user=${encodeURIComponent(this.#userId)}`);
335
- return result.messages ?? [];
336
- }
337
- async listMessagePage(topicId, cursor, limit = MESSAGE_HISTORY_PAGE_SIZE) {
338
- const query = new URLSearchParams({ user: this.#userId, limit: String(limit) });
339
- if (cursor)
340
- query.set("cursor", cursor);
341
- const result = await this.#request(`/topics/${encodeURIComponent(topicId)}/messages?${query.toString()}`);
342
- return {
343
- messages: result.messages ?? [],
344
- cursor: typeof result.cursor === "string" ? result.cursor : undefined,
345
- hasMore: result.hasMore === true
346
- };
347
- }
348
- async listRecentEvents(topicId) {
349
- const result = await this.#request(`/topics/${encodeURIComponent(topicId)}/recent-events?user=${encodeURIComponent(this.#userId)}`);
350
- return result.events ?? [];
351
- }
352
- async createTopic(title, agent) {
353
- const result = await this.#request("/topics", {
354
- method: "POST",
355
- body: JSON.stringify({ userId: this.#userId, title, agent })
356
- });
357
- return result.topic;
358
- }
359
- async deriveTopic(topic, copyHistory, name) {
360
- const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/derive`, {
361
- method: "POST",
362
- body: JSON.stringify({ userId: this.#userId, copyHistory, ...name ? { name } : {} })
363
- });
364
- return result.topic;
365
- }
366
- async resetTopic(topic) {
367
- const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/session/reset`, {
368
- method: "POST",
369
- body: JSON.stringify({ userId: this.#userId })
370
- });
371
- return String(result.result ?? `Session reset for "${topic.title}".`);
372
- }
373
- async compactTopic(topic) {
374
- const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/session/compact`, {
375
- method: "POST",
376
- body: JSON.stringify({ userId: this.#userId })
377
- }, 180000);
378
- return String(result.result ?? `Compacted context for "${topic.title}".`);
379
- }
380
- async setModel(topic, model) {
381
- const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/model`, {
382
- method: "POST",
383
- body: JSON.stringify({ userId: this.#userId, model })
384
- });
385
- return String(result.result ?? `Model set to '${model}'.`);
386
- }
387
- async setEffort(topic, effort) {
388
- const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/effort`, {
389
- method: "POST",
390
- body: JSON.stringify({ userId: this.#userId, effort })
391
- });
392
- return String(result.result ?? `Effort set to '${effort}'.`);
393
- }
394
- async deleteTopic(topic) {
395
- await this.#request(`/topics/${encodeURIComponent(topic.id)}?user=${encodeURIComponent(this.#userId)}`, { method: "DELETE" });
396
- }
397
- async sendMessage(topic, text) {
398
- const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/messages`, {
399
- method: "POST",
400
- body: JSON.stringify({ userId: this.#userId, text })
401
- });
402
- return result.message;
403
- }
404
- async answerQuestion(topicId, messageId, label) {
405
- try {
406
- const result = await this.#request(`/questions/${encodeURIComponent(messageId)}/answer`, {
407
- method: "POST",
408
- body: JSON.stringify({ topicId, userId: this.#userId, label })
409
- });
410
- return result.ok ? { ok: true } : { ok: false, error: result.error };
411
- } catch (error) {
412
- return { ok: false, error: error instanceof Error ? error.message : String(error) };
413
- }
414
- }
415
- async abort(topicId) {
416
- const result = await this.#request(`/topics/${encodeURIComponent(topicId)}/abort`, {
417
- method: "POST",
418
- body: JSON.stringify({ userId: this.#userId })
419
- });
420
- return result.aborted === true;
421
- }
422
- async runVaultCommand(commandLine) {
423
- const result = await this.#request("/vault/command", {
424
- method: "POST",
425
- body: JSON.stringify({ userId: this.#userId, commandLine })
426
- });
427
- return typeof result.result === "string" ? result.result : null;
428
- }
429
- async listVaultEntries() {
430
- try {
431
- const result = await this.#request(`/vault?user=${encodeURIComponent(this.#userId)}`);
432
- return result.entries ?? [];
433
- } catch (error) {
434
- if (!missingControlRoute(error))
435
- throw error;
436
- return parseLegacyVaultList(await this.runVaultCommand("/vault list"));
437
- }
438
- }
439
- async saveVaultEntry(key, value, description) {
440
- try {
441
- const result = await this.#request("/vault", {
442
- method: "POST",
443
- body: JSON.stringify({ userId: this.#userId, key, value, description })
444
- });
445
- return result.result;
446
- } catch (error) {
447
- if (!missingControlRoute(error))
448
- throw error;
449
- if (/\s\|\s/.test(value)) {
450
- throw new Error("Restart the Negotium node before saving a secret containing ' | '.");
451
- }
452
- const output = await this.runVaultCommand(`/vault set ${key} ${value} | ${description}`);
453
- if (!output)
454
- throw new Error("Vault save failed.");
455
- return { key, updated: output.startsWith("Updated") };
456
- }
457
- }
458
- async deleteVaultEntry(key) {
459
- try {
460
- const result = await this.#request(`/vault?user=${encodeURIComponent(this.#userId)}&key=${encodeURIComponent(key)}`, { method: "DELETE" });
461
- return result.deleted === true;
462
- } catch (error) {
463
- if (!missingControlRoute(error))
464
- throw error;
465
- const output = await this.runVaultCommand(`/vault del ${key}`);
466
- return output?.startsWith("Deleted") === true;
467
- }
468
- }
469
- listInputHistory() {
470
- return loadTerminalInputHistory(this.#userId);
471
- }
472
- appendInputHistory(text) {
473
- appendTerminalInputHistory(this.#userId, text);
474
- }
475
- async#request(path, init = {}, timeoutMs = 15000) {
476
- const controller = new AbortController;
477
- const timer = setTimeout(() => controller.abort(), timeoutMs);
478
- try {
479
- const response = await fetch(`${this.#baseUrl}${NODE_CONTROL_BASE_PATH}${path}`, {
480
- ...init,
481
- signal: controller.signal,
482
- headers: {
483
- authorization: `Bearer ${this.#token}`,
484
- ...init.body ? { "content-type": "application/json" } : {},
485
- ...init.headers
486
- }
487
- });
488
- const result = await response.json().catch(() => ({}));
489
- if (!response.ok || result.ok === false) {
490
- throw new Error(result.error || `Node request failed with HTTP ${response.status}`);
491
- }
492
- return result;
493
- } finally {
494
- clearTimeout(timer);
495
- }
496
- }
497
- async#openEventStream(after, signal) {
498
- const response = await fetch(`${this.#baseUrl}${NODE_CONTROL_BASE_PATH}/events?user=${encodeURIComponent(this.#userId)}&after=${after}`, {
499
- signal,
500
- headers: {
501
- accept: "text/event-stream",
502
- authorization: `Bearer ${this.#token}`
503
- }
504
- });
505
- if (!response.ok || !response.body) {
506
- const result = await response.json().catch(() => ({}));
507
- throw new Error(result.error || `Event stream failed with HTTP ${response.status}`);
508
- }
509
- return response;
510
- }
511
- async#runEventLoop(first, initialCursor, signal) {
512
- let response = first;
513
- let cursor = initialCursor;
514
- while (!signal.aborted) {
515
- try {
516
- cursor = await this.#consumeEventStream(response, cursor, signal);
517
- } catch {
518
- if (signal.aborted)
519
- break;
520
- }
521
- if (signal.aborted)
522
- break;
523
- await new Promise((resolvePromise) => setTimeout(resolvePromise, 250));
524
- try {
525
- response = await this.#openEventStream(cursor, signal);
526
- } catch {
527
- if (signal.aborted)
528
- break;
529
- await new Promise((resolvePromise) => setTimeout(resolvePromise, 750));
530
- }
531
- }
532
- }
533
- async#consumeEventStream(response, initialCursor, signal) {
534
- const reader = response.body?.getReader();
535
- if (!reader)
536
- return initialCursor;
537
- const decoder = new TextDecoder;
538
- let cursor = initialCursor;
539
- let buffer = "";
540
- while (!signal.aborted) {
541
- const { done, value } = await reader.read();
542
- if (done)
543
- break;
544
- buffer += decoder.decode(value, { stream: true }).replaceAll(`\r
545
- `, `
546
- `);
547
- let boundary = buffer.indexOf(`
548
-
549
- `);
550
- while (boundary >= 0) {
551
- const block = buffer.slice(0, boundary);
552
- buffer = buffer.slice(boundary + 2);
553
- const fields = new Map;
554
- for (const line of block.split(`
555
- `)) {
556
- if (!line || line.startsWith(":"))
557
- continue;
558
- const separator = line.indexOf(":");
559
- if (separator < 0)
560
- continue;
561
- fields.set(line.slice(0, separator), line.slice(separator + 1).trimStart());
562
- }
563
- const id = Number.parseInt(fields.get("id") ?? "", 10);
564
- if (Number.isFinite(id))
565
- cursor = Math.max(cursor, id);
566
- if (fields.get("event") === "runtime" && fields.has("data")) {
567
- try {
568
- this.#onEvent?.(JSON.parse(fields.get("data") ?? "null"));
569
- } catch {}
570
- }
571
- boundary = buffer.indexOf(`
572
-
573
- `);
574
- }
575
- }
576
- return cursor;
577
- }
578
- }
579
- export {
580
- RemoteNegotiumClient,
581
- MESSAGE_HISTORY_PAGE_SIZE,
582
- INITIAL_MESSAGE_HISTORY_PAGE_COUNT,
583
- INITIAL_MESSAGE_HISTORY_LIMIT,
584
- EmbeddedNegotiumClient
585
- };
586
-
587
- export { MESSAGE_HISTORY_PAGE_SIZE, INITIAL_MESSAGE_HISTORY_LIMIT, EmbeddedNegotiumClient, RemoteNegotiumClient };
588
-
589
- //# debugId=098757144B7A04D564756E2164756E21
@@ -1,11 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../adapters/terminal/src/history-store.ts", "../../../adapters/terminal/src/client.ts"],
4
- "sourcesContent": [
5
- "import { db } from \"@negotium/core\";\n\nconst MAX_STORED_HISTORY = 500;\n\ninterface HistoryRow {\n text: string;\n}\n\ndb.exec(`\n CREATE TABLE IF NOT EXISTS terminal_input_history (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n user_id TEXT NOT NULL,\n text TEXT NOT NULL,\n created_at INTEGER NOT NULL\n )\n`);\ndb.exec(\n \"CREATE INDEX IF NOT EXISTS idx_terminal_input_history_user_seq ON terminal_input_history(user_id, seq)\",\n);\n\nexport function loadTerminalInputHistory(userId: string, limit = 200): string[] {\n const safeLimit = Math.max(1, Math.min(limit, MAX_STORED_HISTORY));\n return db\n .query<HistoryRow, [string, number]>(\n `SELECT text FROM (\n SELECT seq, text\n FROM terminal_input_history\n WHERE user_id = ?\n ORDER BY seq DESC\n LIMIT ?\n ) ORDER BY seq ASC`,\n )\n .all(userId, safeLimit)\n .map((row) => row.text);\n}\n\nexport function appendTerminalInputHistory(userId: string, value: string): void {\n const text = value.trim();\n if (!text) return;\n db.transaction(() => {\n const latest = db\n .query<HistoryRow, [string]>(\n \"SELECT text FROM terminal_input_history WHERE user_id = ? ORDER BY seq DESC LIMIT 1\",\n )\n .get(userId);\n if (latest?.text === text) return;\n db.query(\"INSERT INTO terminal_input_history (user_id, text, created_at) VALUES (?, ?, ?)\").run(\n userId,\n text,\n Date.now(),\n );\n db.query(\n `DELETE FROM terminal_input_history\n WHERE user_id = ? AND seq NOT IN (\n SELECT seq FROM terminal_input_history\n WHERE user_id = ? ORDER BY seq DESC LIMIT ?\n )`,\n ).run(userId, userId, MAX_STORED_HISTORY);\n }).immediate();\n}\n",
6
- "import {\n type AgentKind,\n type BackgroundSessionDto,\n deleteVaultEntry,\n type EffortLevel,\n ensurePersonalGeneral,\n executeVaultCommand,\n getAllMessagesForTopic,\n getApiMessage,\n getVisibleTopics,\n listApiMessages,\n listBackgroundSessionsForUser,\n listRecentRuntimeEventsForTopic,\n listRunningTopicQueries,\n listVaultEntries,\n type MessageDto,\n type RuntimeBusEvent,\n runtimeBus,\n type SaveVaultEntryResult,\n saveVaultEntry,\n submitUserMessage,\n switchTopicEffort,\n switchTopicModel,\n type TopicDto,\n topicService,\n type VaultEntry,\n} from \"@negotium/core\";\nimport {\n NODE_CONTROL_BASE_PATH,\n NODE_CONTROL_PROTOCOL_VERSION,\n type NodeDaemonConnection,\n type NodeHandle,\n startDefaultNode,\n} from \"@negotium/node\";\nimport { appendTerminalInputHistory, loadTerminalInputHistory } from \"@/history-store\";\n\nexport type ClientResult<T> = T | Promise<T>;\n\nexport const MESSAGE_HISTORY_PAGE_SIZE = 50;\nexport const INITIAL_MESSAGE_HISTORY_PAGE_COUNT = 3;\nexport const INITIAL_MESSAGE_HISTORY_LIMIT =\n MESSAGE_HISTORY_PAGE_SIZE * INITIAL_MESSAGE_HISTORY_PAGE_COUNT;\n\nexport interface MessageHistoryPage {\n messages: MessageDto[];\n cursor?: string;\n hasMore: boolean;\n}\n\nexport interface NegotiumClient {\n start(onEvent: (event: RuntimeBusEvent) => void): Promise<void>;\n stop(): Promise<void>;\n listTopics(): ClientResult<TopicDto[]>;\n listBackgroundSessions?(): ClientResult<BackgroundSessionDto[]>;\n listMessages(topicId: string): ClientResult<MessageDto[]>;\n listMessagePage?(\n topicId: string,\n cursor?: string,\n limit?: number,\n ): ClientResult<MessageHistoryPage>;\n createTopic(title: string, agent?: AgentKind): ClientResult<TopicDto>;\n deriveTopic(topic: TopicDto, copyHistory: boolean, name?: string): Promise<TopicDto>;\n resetTopic(topic: TopicDto): Promise<string>;\n compactTopic(topic: TopicDto): Promise<string>;\n setModel(topic: TopicDto, model: string): ClientResult<string>;\n setEffort(topic: TopicDto, effort: EffortLevel): ClientResult<string>;\n deleteTopic(topic: TopicDto): Promise<void>;\n sendMessage(topic: TopicDto, text: string): ClientResult<MessageDto>;\n answerQuestion(\n topicId: string,\n messageId: string,\n label: string,\n ): ClientResult<{ ok: boolean; error?: string }>;\n abort(topicId: string): ClientResult<boolean>;\n runVaultCommand?(commandLine: string): ClientResult<string | null>;\n listVaultEntries?(): ClientResult<VaultEntry[]>;\n saveVaultEntry?(\n key: string,\n value: string,\n description: string,\n ): ClientResult<SaveVaultEntryResult>;\n deleteVaultEntry?(key: string): ClientResult<boolean>;\n listInputHistory?(): string[];\n appendInputHistory?(text: string): void;\n listRecentEvents?(topicId: string): ClientResult<RuntimeBusEvent[]>;\n}\n\nexport interface EmbeddedClientOptions {\n userId: string;\n port?: number;\n /** Start and own a node. False attaches to an already-running in-process node. */\n startNode?: boolean;\n}\n\n/**\n * Explicit in-process recovery/development host. The default CLI path uses\n * RemoteNegotiumClient so the UI does not own the node or active turns.\n */\nexport class EmbeddedNegotiumClient implements NegotiumClient {\n readonly #userId: string;\n readonly #port: number;\n readonly #startNode: boolean;\n #node: NodeHandle | null = null;\n #unsubscribe: (() => void) | null = null;\n #started = false;\n\n constructor(options: EmbeddedClientOptions) {\n this.#userId = options.userId;\n this.#port = options.port ?? 0;\n this.#startNode = options.startNode !== false;\n }\n\n async start(onEvent: (event: RuntimeBusEvent) => void): Promise<void> {\n if (this.#started) return;\n this.#started = true;\n this.#unsubscribe = runtimeBus().subscribe(onEvent);\n try {\n if (this.#startNode) this.#node = await startDefaultNode({ port: this.#port });\n ensurePersonalGeneral(this.#userId);\n } catch (error) {\n this.#unsubscribe?.();\n this.#unsubscribe = null;\n this.#started = false;\n throw error;\n }\n }\n\n async stop(): Promise<void> {\n this.#unsubscribe?.();\n this.#unsubscribe = null;\n this.#started = false;\n const node = this.#node;\n this.#node = null;\n if (node) await node.stop();\n }\n\n listTopics(): TopicDto[] {\n const runningTopics = listRunningTopicQueries();\n return getVisibleTopics()\n .filter((topic) =>\n topic.participants.some((participant) => participant.userId === this.#userId),\n )\n .map((topic) => {\n const runningQueryId = runningTopics.get(topic.id);\n return { ...topic, running: Boolean(runningQueryId), runningQueryId };\n });\n }\n\n listBackgroundSessions(): BackgroundSessionDto[] {\n return listBackgroundSessionsForUser(this.#userId);\n }\n\n listMessages(topicId: string): MessageDto[] {\n const rows = getAllMessagesForTopic(topicId) as Array<{ id?: unknown }>;\n return rows\n .map((row) => (typeof row.id === \"string\" ? getApiMessage(topicId, row.id) : null))\n .filter((message): message is MessageDto => message !== null);\n }\n\n listMessagePage(\n topicId: string,\n cursor?: string,\n limit = MESSAGE_HISTORY_PAGE_SIZE,\n ): MessageHistoryPage {\n const result = listApiMessages(topicId, { cursor, limit });\n return { messages: result.page, cursor: result.cursor, hasMore: result.hasMore };\n }\n\n listRecentEvents(topicId: string): RuntimeBusEvent[] {\n return listRecentRuntimeEventsForTopic(topicId).map((event) => ({\n type: event.type,\n topicId: event.topicId,\n payload: event.payload,\n seq: event.seq,\n createdAt: event.createdAt,\n }));\n }\n\n createTopic(title: string, agent?: AgentKind): TopicDto {\n return topicService.create({\n title,\n userId: this.#userId,\n kind: \"agent\",\n ...(agent ? { agent } : {}),\n });\n }\n\n async deriveTopic(topic: TopicDto, copyHistory: boolean, name?: string): Promise<TopicDto> {\n const derived = await topicService.derive({\n sourceTopicId: topic.id,\n userId: this.#userId,\n copyHistory,\n ...(name ? { name } : {}),\n });\n if (!derived) throw new Error(`Failed to ${copyHistory ? \"fork\" : \"spawn\"} \"${topic.title}\"`);\n return derived;\n }\n\n async resetTopic(topic: TopicDto): Promise<string> {\n const result = await topicService.reset({\n topicId: topic.id,\n userId: this.#userId,\n reason: \"terminal-session-reset\",\n });\n if (result.isError) throw new Error(result.text);\n return result.text;\n }\n\n async compactTopic(topic: TopicDto): Promise<string> {\n const result = await topicService.compact({\n topicId: topic.id,\n userId: this.#userId,\n reason: \"terminal-session-compact\",\n });\n if (result.isError) throw new Error(result.text);\n return result.text;\n }\n\n setModel(topic: TopicDto, model: string): string {\n const result = switchTopicModel({ topicId: topic.id, userId: this.#userId, model });\n if (!result.ok) throw new Error(result.error);\n return result.text;\n }\n\n setEffort(topic: TopicDto, effort: EffortLevel): string {\n const result = switchTopicEffort({ topicId: topic.id, userId: this.#userId, effort });\n if (!result.ok) throw new Error(result.error);\n return result.text;\n }\n\n async deleteTopic(topic: TopicDto): Promise<void> {\n await topicService.delete({ topicId: topic.id, userId: this.#userId });\n }\n\n sendMessage(topic: TopicDto, text: string): MessageDto {\n return submitUserMessage({\n topic,\n userId: this.#userId,\n text,\n sourceAdapter: \"terminal\",\n visualTools: false,\n }).message;\n }\n\n answerQuestion(\n topicId: string,\n messageId: string,\n label: string,\n ): { ok: boolean; error?: string } {\n const result = topicService.answerQuestion(topicId, messageId, label, this.#userId);\n return result.ok ? { ok: true } : { ok: false, error: result.error };\n }\n\n abort(topicId: string): boolean {\n return topicService.abortTurn(topicId, this.#userId);\n }\n\n runVaultCommand(commandLine: string): string | null {\n return executeVaultCommand(this.#userId, commandLine);\n }\n\n listVaultEntries(): VaultEntry[] {\n return listVaultEntries(this.#userId);\n }\n\n saveVaultEntry(key: string, value: string, description: string): SaveVaultEntryResult {\n return saveVaultEntry(this.#userId, key, value, description);\n }\n\n deleteVaultEntry(key: string): boolean {\n return deleteVaultEntry(this.#userId, key);\n }\n\n listInputHistory(): string[] {\n return loadTerminalInputHistory(this.#userId);\n }\n\n appendInputHistory(text: string): void {\n appendTerminalInputHistory(this.#userId, text);\n }\n}\n\nexport interface RemoteClientOptions extends NodeDaemonConnection {\n userId: string;\n}\n\ninterface ApiEnvelope {\n ok?: boolean;\n error?: string;\n [key: string]: unknown;\n}\n\nfunction missingControlRoute(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n return /not found|http 404/i.test(message);\n}\n\nfunction parseLegacyVaultList(output: string | null): VaultEntry[] {\n if (!output || /vault is empty/i.test(output)) return [];\n return output\n .split(\"\\n\")\n .slice(1)\n .flatMap((line) => {\n const match = line.match(/^- ([A-Z][A-Z0-9_]*)(?:: (.*))?$/);\n return match?.[1] ? [{ key: match[1], description: match[2] ?? \"\" }] : [];\n });\n}\n\nfunction isSecureControlTransport(baseUrl: string): boolean {\n const url = new URL(baseUrl);\n if (url.protocol === \"https:\") return true;\n if (url.protocol !== \"http:\") return false;\n const hostname = url.hostname.toLowerCase();\n if (hostname === \"localhost\" || hostname === \"::1\" || hostname === \"[::1]\") return true;\n const octets = hostname.split(\".\");\n return (\n octets.length === 4 &&\n octets[0] === \"127\" &&\n octets.every((octet) => /^\\d{1,3}$/.test(octet) && Number(octet) <= 255)\n );\n}\n\n/** REST/SSE client. Stopping it only disconnects the UI; it never stops the node. */\nexport class RemoteNegotiumClient implements NegotiumClient {\n readonly #userId: string;\n readonly #baseUrl: string;\n readonly #token: string;\n #onEvent: ((event: RuntimeBusEvent) => void) | null = null;\n #eventAbort: AbortController | null = null;\n #eventTask: Promise<void> | null = null;\n #started = false;\n\n constructor(options: RemoteClientOptions) {\n this.#userId = options.userId;\n this.#baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n if (!isSecureControlTransport(this.#baseUrl)) {\n throw new Error(\"Remote node control requires HTTPS or loopback HTTP\");\n }\n this.#token = options.token;\n }\n\n async start(onEvent: (event: RuntimeBusEvent) => void): Promise<void> {\n if (this.#started) return;\n const session = await this.#request(`/session?user=${encodeURIComponent(this.#userId)}`);\n if (session.protocolVersion !== NODE_CONTROL_PROTOCOL_VERSION) {\n throw new Error(\n `Node protocol ${String(session.protocolVersion)} is incompatible with terminal protocol ${NODE_CONTROL_PROTOCOL_VERSION}`,\n );\n }\n const cursor = Number(session.cursor ?? 0);\n this.#onEvent = onEvent;\n this.#eventAbort = new AbortController();\n try {\n const first = await this.#openEventStream(cursor, this.#eventAbort.signal);\n this.#started = true;\n this.#eventTask = this.#runEventLoop(first, cursor, this.#eventAbort.signal);\n } catch (error) {\n this.#eventAbort = null;\n this.#onEvent = null;\n throw error;\n }\n }\n\n async stop(): Promise<void> {\n this.#started = false;\n this.#eventAbort?.abort();\n this.#eventAbort = null;\n await this.#eventTask?.catch(() => {});\n this.#eventTask = null;\n this.#onEvent = null;\n }\n\n async listTopics(): Promise<TopicDto[]> {\n const result = await this.#request(`/topics?user=${encodeURIComponent(this.#userId)}`);\n return (result.topics ?? []) as TopicDto[];\n }\n\n async listBackgroundSessions(): Promise<BackgroundSessionDto[]> {\n const result = await this.#request(\n `/background-sessions?user=${encodeURIComponent(this.#userId)}`,\n );\n return (result.sessions ?? []) as BackgroundSessionDto[];\n }\n\n async listMessages(topicId: string): Promise<MessageDto[]> {\n const result = await this.#request(\n `/topics/${encodeURIComponent(topicId)}/messages?user=${encodeURIComponent(this.#userId)}`,\n );\n return (result.messages ?? []) as MessageDto[];\n }\n\n async listMessagePage(\n topicId: string,\n cursor?: string,\n limit = MESSAGE_HISTORY_PAGE_SIZE,\n ): Promise<MessageHistoryPage> {\n const query = new URLSearchParams({ user: this.#userId, limit: String(limit) });\n if (cursor) query.set(\"cursor\", cursor);\n const result = await this.#request(\n `/topics/${encodeURIComponent(topicId)}/messages?${query.toString()}`,\n );\n return {\n messages: (result.messages ?? []) as MessageDto[],\n cursor: typeof result.cursor === \"string\" ? result.cursor : undefined,\n hasMore: result.hasMore === true,\n };\n }\n\n async listRecentEvents(topicId: string): Promise<RuntimeBusEvent[]> {\n const result = await this.#request(\n `/topics/${encodeURIComponent(topicId)}/recent-events?user=${encodeURIComponent(this.#userId)}`,\n );\n return (result.events ?? []) as RuntimeBusEvent[];\n }\n\n async createTopic(title: string, agent?: AgentKind): Promise<TopicDto> {\n const result = await this.#request(\"/topics\", {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId, title, agent }),\n });\n return result.topic as TopicDto;\n }\n\n async deriveTopic(topic: TopicDto, copyHistory: boolean, name?: string): Promise<TopicDto> {\n const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/derive`, {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId, copyHistory, ...(name ? { name } : {}) }),\n });\n return result.topic as TopicDto;\n }\n\n async resetTopic(topic: TopicDto): Promise<string> {\n const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/session/reset`, {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId }),\n });\n return String(result.result ?? `Session reset for \"${topic.title}\".`);\n }\n\n async compactTopic(topic: TopicDto): Promise<string> {\n const result = await this.#request(\n `/topics/${encodeURIComponent(topic.id)}/session/compact`,\n {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId }),\n },\n 180_000,\n );\n return String(result.result ?? `Compacted context for \"${topic.title}\".`);\n }\n\n async setModel(topic: TopicDto, model: string): Promise<string> {\n const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/model`, {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId, model }),\n });\n return String(result.result ?? `Model set to '${model}'.`);\n }\n\n async setEffort(topic: TopicDto, effort: EffortLevel): Promise<string> {\n const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/effort`, {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId, effort }),\n });\n return String(result.result ?? `Effort set to '${effort}'.`);\n }\n\n async deleteTopic(topic: TopicDto): Promise<void> {\n await this.#request(\n `/topics/${encodeURIComponent(topic.id)}?user=${encodeURIComponent(this.#userId)}`,\n { method: \"DELETE\" },\n );\n }\n\n async sendMessage(topic: TopicDto, text: string): Promise<MessageDto> {\n const result = await this.#request(`/topics/${encodeURIComponent(topic.id)}/messages`, {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId, text }),\n });\n return result.message as MessageDto;\n }\n\n async answerQuestion(\n topicId: string,\n messageId: string,\n label: string,\n ): Promise<{ ok: boolean; error?: string }> {\n try {\n const result = await this.#request(`/questions/${encodeURIComponent(messageId)}/answer`, {\n method: \"POST\",\n body: JSON.stringify({ topicId, userId: this.#userId, label }),\n });\n return result.ok ? { ok: true } : { ok: false, error: result.error };\n } catch (error) {\n return { ok: false, error: error instanceof Error ? error.message : String(error) };\n }\n }\n\n async abort(topicId: string): Promise<boolean> {\n const result = await this.#request(`/topics/${encodeURIComponent(topicId)}/abort`, {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId }),\n });\n return result.aborted === true;\n }\n\n async runVaultCommand(commandLine: string): Promise<string | null> {\n const result = await this.#request(\"/vault/command\", {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId, commandLine }),\n });\n return typeof result.result === \"string\" ? result.result : null;\n }\n\n async listVaultEntries(): Promise<VaultEntry[]> {\n try {\n const result = await this.#request(`/vault?user=${encodeURIComponent(this.#userId)}`);\n return (result.entries ?? []) as VaultEntry[];\n } catch (error) {\n if (!missingControlRoute(error)) throw error;\n return parseLegacyVaultList(await this.runVaultCommand(\"/vault list\"));\n }\n }\n\n async saveVaultEntry(\n key: string,\n value: string,\n description: string,\n ): Promise<SaveVaultEntryResult> {\n try {\n const result = await this.#request(\"/vault\", {\n method: \"POST\",\n body: JSON.stringify({ userId: this.#userId, key, value, description }),\n });\n return result.result as SaveVaultEntryResult;\n } catch (error) {\n if (!missingControlRoute(error)) throw error;\n if (/\\s\\|\\s/.test(value)) {\n throw new Error(\"Restart the Negotium node before saving a secret containing ' | '.\");\n }\n const output = await this.runVaultCommand(\n // Always include the legacy value/description delimiter. Without it,\n // a multi-word value with an empty description is parsed by old nodes\n // as a one-word secret plus a description, silently corrupting it.\n `/vault set ${key} ${value} | ${description}`,\n );\n if (!output) throw new Error(\"Vault save failed.\");\n return { key, updated: output.startsWith(\"Updated\") };\n }\n }\n\n async deleteVaultEntry(key: string): Promise<boolean> {\n try {\n const result = await this.#request(\n `/vault?user=${encodeURIComponent(this.#userId)}&key=${encodeURIComponent(key)}`,\n { method: \"DELETE\" },\n );\n return result.deleted === true;\n } catch (error) {\n if (!missingControlRoute(error)) throw error;\n const output = await this.runVaultCommand(`/vault del ${key}`);\n return output?.startsWith(\"Deleted\") === true;\n }\n }\n\n listInputHistory(): string[] {\n return loadTerminalInputHistory(this.#userId);\n }\n\n appendInputHistory(text: string): void {\n appendTerminalInputHistory(this.#userId, text);\n }\n\n async #request(path: string, init: RequestInit = {}, timeoutMs = 15_000): Promise<ApiEnvelope> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetch(`${this.#baseUrl}${NODE_CONTROL_BASE_PATH}${path}`, {\n ...init,\n signal: controller.signal,\n headers: {\n authorization: `Bearer ${this.#token}`,\n ...(init.body ? { \"content-type\": \"application/json\" } : {}),\n ...init.headers,\n },\n });\n const result = (await response.json().catch(() => ({}))) as ApiEnvelope;\n if (!response.ok || result.ok === false) {\n throw new Error(result.error || `Node request failed with HTTP ${response.status}`);\n }\n return result;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async #openEventStream(after: number, signal: AbortSignal): Promise<Response> {\n const response = await fetch(\n `${this.#baseUrl}${NODE_CONTROL_BASE_PATH}/events?user=${encodeURIComponent(this.#userId)}&after=${after}`,\n {\n signal,\n headers: {\n accept: \"text/event-stream\",\n authorization: `Bearer ${this.#token}`,\n },\n },\n );\n if (!response.ok || !response.body) {\n const result = (await response.json().catch(() => ({}))) as ApiEnvelope;\n throw new Error(result.error || `Event stream failed with HTTP ${response.status}`);\n }\n return response;\n }\n\n async #runEventLoop(first: Response, initialCursor: number, signal: AbortSignal): Promise<void> {\n let response = first;\n let cursor = initialCursor;\n while (!signal.aborted) {\n try {\n cursor = await this.#consumeEventStream(response, cursor, signal);\n } catch {\n if (signal.aborted) break;\n }\n if (signal.aborted) break;\n await new Promise((resolvePromise) => setTimeout(resolvePromise, 250));\n try {\n response = await this.#openEventStream(cursor, signal);\n } catch {\n if (signal.aborted) break;\n await new Promise((resolvePromise) => setTimeout(resolvePromise, 750));\n }\n }\n }\n\n async #consumeEventStream(\n response: Response,\n initialCursor: number,\n signal: AbortSignal,\n ): Promise<number> {\n const reader = response.body?.getReader();\n if (!reader) return initialCursor;\n const decoder = new TextDecoder();\n let cursor = initialCursor;\n let buffer = \"\";\n while (!signal.aborted) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true }).replaceAll(\"\\r\\n\", \"\\n\");\n let boundary = buffer.indexOf(\"\\n\\n\");\n while (boundary >= 0) {\n const block = buffer.slice(0, boundary);\n buffer = buffer.slice(boundary + 2);\n const fields = new Map<string, string>();\n for (const line of block.split(\"\\n\")) {\n if (!line || line.startsWith(\":\")) continue;\n const separator = line.indexOf(\":\");\n if (separator < 0) continue;\n fields.set(line.slice(0, separator), line.slice(separator + 1).trimStart());\n }\n const id = Number.parseInt(fields.get(\"id\") ?? \"\", 10);\n if (Number.isFinite(id)) cursor = Math.max(cursor, id);\n if (fields.get(\"event\") === \"runtime\" && fields.has(\"data\")) {\n try {\n this.#onEvent?.(JSON.parse(fields.get(\"data\") ?? \"null\") as RuntimeBusEvent);\n } catch {\n // Ignore one malformed event without dropping the durable stream.\n }\n }\n boundary = buffer.indexOf(\"\\n\\n\");\n }\n }\n return cursor;\n }\n}\n"
7
- ],
8
- "mappings": "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",
9
- "debugId": "098757144B7A04D564756E2164756E21",
10
- "names": []
11
- }