negotium 0.1.11 → 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.
- package/README.md +11 -2
- package/dist/canonical-mcp-bridge.js +2 -3
- package/dist/canonical-mcp-bridge.js.map +1 -1
- package/dist/{chunk-gz12qcf0.js → chunk-a9y2rwxf.js} +2 -2
- package/dist/{chunk-gz12qcf0.js.map → chunk-a9y2rwxf.js.map} +3 -3
- package/dist/{chunk-j0kjscb7.js → chunk-s2gez3wg.js} +20 -2
- package/dist/{chunk-j0kjscb7.js.map → chunk-s2gez3wg.js.map} +2 -2
- package/dist/cron.js +292 -256
- package/dist/cron.js.map +23 -22
- package/dist/hosted-agent.js +3012 -17
- package/dist/hosted-agent.js.map +30 -3
- package/dist/main.js +31323 -36
- package/dist/main.js.map +198 -3
- package/dist/prompts.js +12 -9
- package/dist/prompts.js.map +5 -5
- package/dist/registry.js +10 -6
- package/dist/registry.js.map +3 -3
- package/dist/rollout.js +1 -1
- package/dist/runtime/cron/store.ts +24 -1
- package/dist/runtime/src/application/submit-user-message.ts +3 -0
- package/dist/runtime/src/index.ts +7 -0
- package/dist/runtime/src/mcp/runtime-spec.ts +3 -0
- package/dist/runtime/src/mcp/session-comm/server.ts +1 -1
- package/dist/runtime/src/platform/config.ts +2 -2
- package/dist/runtime/src/platform/mcp-config.ts +13 -0
- package/dist/runtime/src/prompts/builders.ts +20 -6
- package/dist/runtime/src/query/active-rooms.ts +2 -0
- package/dist/runtime/src/runtime/delivery-ack.ts +112 -0
- package/dist/runtime/src/runtime/errors.ts +12 -12
- package/dist/runtime/src/runtime/turn-runner.ts +12 -0
- package/dist/runtime/src/storage/api-messages.ts +7 -5
- package/dist/runtime/src/storage/api-topics.ts +5 -2
- package/dist/runtime/src/storage/forum-db.ts +4 -1
- package/dist/runtime/src/storage/runtime-turn-requests.ts +1 -0
- package/dist/runtime/src/storage/session-asks.ts +13 -5
- package/dist/runtime/src/storage/storage-contract.ts +54 -0
- package/dist/runtime/src/storage/storage-host.ts +89 -36
- package/dist/runtime/src/storage/storage-public-host.ts +16 -0
- package/dist/runtime/src/storage/storage-public.ts +21 -5
- package/dist/runtime/src/storage/token-stats.ts +1 -1
- package/dist/runtime/src/types/api.ts +2 -0
- package/dist/runtime/src/types.ts +2 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-helpers.js +29 -18
- package/dist/runtime-helpers.js.map +8 -7
- package/dist/storage.js +260 -202
- package/dist/storage.js.map +11 -9
- package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +2 -0
- package/dist/types/packages/core/src/platform/mcp-config.d.ts +4 -0
- package/dist/types/packages/core/src/prompts/builders.d.ts +2 -0
- package/dist/types/packages/core/src/storage/api-messages.d.ts +6 -6
- package/dist/types/packages/core/src/storage/api-topics.d.ts +20 -2
- package/dist/types/packages/core/src/storage/forum-db.d.ts +2 -1
- package/dist/types/packages/core/src/storage/session-asks.d.ts +3 -2
- package/dist/types/packages/core/src/storage/storage-contract.d.ts +46 -0
- package/dist/types/packages/core/src/storage/storage-host.d.ts +12 -19
- package/dist/types/packages/core/src/storage/storage-public-host.d.ts +7 -0
- package/dist/types/packages/core/src/storage/storage-public.d.ts +4 -2
- package/dist/types/packages/core/src/types/api.d.ts +2 -0
- package/dist/types/packages/core/src/types.d.ts +2 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/types/packages/module-cron/src/store.d.ts +22 -2
- package/dist/vault.js +2 -2
- package/dist/vault.js.map +3 -3
- package/package.json +1 -1
- package/dist/chunk-01xcc856.js +0 -149
- package/dist/chunk-01xcc856.js.map +0 -10
- package/dist/chunk-1a6kv9vt.js +0 -118
- package/dist/chunk-1a6kv9vt.js.map +0 -10
- package/dist/chunk-1b62d730.js +0 -117
- package/dist/chunk-1b62d730.js.map +0 -10
- package/dist/chunk-1k7t7bnx.js +0 -97
- package/dist/chunk-1k7t7bnx.js.map +0 -10
- package/dist/chunk-28apmz4r.js +0 -431
- package/dist/chunk-28apmz4r.js.map +0 -11
- package/dist/chunk-2fvydfkx.js +0 -141
- package/dist/chunk-2fvydfkx.js.map +0 -10
- package/dist/chunk-41ygvg5k.js +0 -2387
- package/dist/chunk-41ygvg5k.js.map +0 -26
- package/dist/chunk-4q966ttx.js +0 -371
- package/dist/chunk-4q966ttx.js.map +0 -11
- package/dist/chunk-51rcsavw.js +0 -1712
- package/dist/chunk-51rcsavw.js.map +0 -18
- package/dist/chunk-59d0shyj.js +0 -103
- package/dist/chunk-59d0shyj.js.map +0 -10
- package/dist/chunk-5fzgvn79.js +0 -3536
- package/dist/chunk-5fzgvn79.js.map +0 -20
- package/dist/chunk-61px0717.js +0 -153
- package/dist/chunk-61px0717.js.map +0 -11
- package/dist/chunk-66y0hr8c.js +0 -2136
- package/dist/chunk-66y0hr8c.js.map +0 -29
- package/dist/chunk-69k45zg8.js +0 -250
- package/dist/chunk-69k45zg8.js.map +0 -11
- package/dist/chunk-6ah5farg.js +0 -130
- package/dist/chunk-6ah5farg.js.map +0 -10
- package/dist/chunk-6d4fmea5.js +0 -117
- package/dist/chunk-6d4fmea5.js.map +0 -12
- package/dist/chunk-8cahx7xc.js +0 -46
- package/dist/chunk-8cahx7xc.js.map +0 -10
- package/dist/chunk-8f20fk4n.js +0 -252
- package/dist/chunk-8f20fk4n.js.map +0 -10
- package/dist/chunk-91ckrvk8.js +0 -318
- package/dist/chunk-91ckrvk8.js.map +0 -10
- package/dist/chunk-93krf6ng.js +0 -3069
- package/dist/chunk-93krf6ng.js.map +0 -32
- package/dist/chunk-9qx1t77a.js +0 -214
- package/dist/chunk-9qx1t77a.js.map +0 -10
- package/dist/chunk-beqhdr9w.js +0 -589
- package/dist/chunk-beqhdr9w.js.map +0 -11
- package/dist/chunk-bftftsgq.js +0 -1637
- package/dist/chunk-bftftsgq.js.map +0 -15
- package/dist/chunk-c500xe9z.js +0 -33
- package/dist/chunk-c500xe9z.js.map +0 -10
- package/dist/chunk-cjsnkvq2.js +0 -23
- package/dist/chunk-cjsnkvq2.js.map +0 -10
- package/dist/chunk-cxa7yghg.js +0 -577
- package/dist/chunk-cxa7yghg.js.map +0 -14
- package/dist/chunk-edb07sjp.js +0 -567
- package/dist/chunk-edb07sjp.js.map +0 -14
- package/dist/chunk-f361dwba.js +0 -589
- package/dist/chunk-f361dwba.js.map +0 -11
- package/dist/chunk-f5xgprg1.js +0 -59
- package/dist/chunk-f5xgprg1.js.map +0 -10
- package/dist/chunk-ffefbd3r.js +0 -17
- package/dist/chunk-ffefbd3r.js.map +0 -10
- package/dist/chunk-fswhzdf5.js +0 -64
- package/dist/chunk-fswhzdf5.js.map +0 -10
- package/dist/chunk-g144wdrs.js +0 -2907
- package/dist/chunk-g144wdrs.js.map +0 -24
- package/dist/chunk-h980hb2n.js +0 -512
- package/dist/chunk-h980hb2n.js.map +0 -13
- package/dist/chunk-h9vbhhgr.js +0 -1337
- package/dist/chunk-h9vbhhgr.js.map +0 -16
- package/dist/chunk-hwy3n31w.js +0 -21
- package/dist/chunk-hwy3n31w.js.map +0 -9
- package/dist/chunk-jtrk0khr.js +0 -108
- package/dist/chunk-jtrk0khr.js.map +0 -10
- package/dist/chunk-jzz91jwh.js +0 -70
- package/dist/chunk-jzz91jwh.js.map +0 -10
- package/dist/chunk-m9e3tbr8.js +0 -708
- package/dist/chunk-m9e3tbr8.js.map +0 -14
- package/dist/chunk-mh5mexsf.js +0 -147
- package/dist/chunk-mh5mexsf.js.map +0 -11
- package/dist/chunk-npd8n03v.js +0 -2152
- package/dist/chunk-npd8n03v.js.map +0 -15
- package/dist/chunk-pg1azh6n.js +0 -2
- package/dist/chunk-pg1azh6n.js.map +0 -9
- package/dist/chunk-qwy57177.js +0 -237
- package/dist/chunk-qwy57177.js.map +0 -11
- package/dist/chunk-r31q21h5.js +0 -53
- package/dist/chunk-r31q21h5.js.map +0 -10
- package/dist/chunk-rbvctv1n.js +0 -366
- package/dist/chunk-rbvctv1n.js.map +0 -10
- package/dist/chunk-sa874j5c.js +0 -9
- package/dist/chunk-sa874j5c.js.map +0 -10
- package/dist/chunk-sctcs5zb.js +0 -281
- package/dist/chunk-sctcs5zb.js.map +0 -10
- package/dist/chunk-tsstrcfc.js +0 -122
- package/dist/chunk-tsstrcfc.js.map +0 -10
- package/dist/chunk-wk2qf31s.js +0 -58
- package/dist/chunk-wk2qf31s.js.map +0 -10
- package/dist/chunk-wx7ag4dd.js +0 -2936
- package/dist/chunk-wx7ag4dd.js.map +0 -20
- package/dist/chunk-znx1fpfd.js +0 -61
- package/dist/chunk-znx1fpfd.js.map +0 -10
package/dist/chunk-69k45zg8.js
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
startDefaultNode
|
|
4
|
-
} from "./chunk-bftftsgq.js";
|
|
5
|
-
import"./chunk-edb07sjp.js";
|
|
6
|
-
import {
|
|
7
|
-
executeVaultCommand,
|
|
8
|
-
isVaultCommandLine,
|
|
9
|
-
registerTopic
|
|
10
|
-
} from "./chunk-93krf6ng.js";
|
|
11
|
-
import"./chunk-fswhzdf5.js";
|
|
12
|
-
import"./chunk-cxa7yghg.js";
|
|
13
|
-
import"./chunk-59d0shyj.js";
|
|
14
|
-
import"./chunk-rbvctv1n.js";
|
|
15
|
-
import"./chunk-1k7t7bnx.js";
|
|
16
|
-
import {
|
|
17
|
-
answerPendingAskUserQuestion,
|
|
18
|
-
startAiTurn
|
|
19
|
-
} from "./chunk-g144wdrs.js";
|
|
20
|
-
import"./chunk-91ckrvk8.js";
|
|
21
|
-
import"./chunk-66y0hr8c.js";
|
|
22
|
-
import {
|
|
23
|
-
appendApiMessage,
|
|
24
|
-
runtimeBus
|
|
25
|
-
} from "./chunk-h9vbhhgr.js";
|
|
26
|
-
import {
|
|
27
|
-
getTopicByNameForUser
|
|
28
|
-
} from "./chunk-f361dwba.js";
|
|
29
|
-
import"./chunk-8cahx7xc.js";
|
|
30
|
-
import"./chunk-6d4fmea5.js";
|
|
31
|
-
import"./chunk-61px0717.js";
|
|
32
|
-
import"./chunk-tsstrcfc.js";
|
|
33
|
-
import"./chunk-6ah5farg.js";
|
|
34
|
-
import"./chunk-41ygvg5k.js";
|
|
35
|
-
import"./chunk-m9e3tbr8.js";
|
|
36
|
-
import"./chunk-mh5mexsf.js";
|
|
37
|
-
import {
|
|
38
|
-
isAgentKind
|
|
39
|
-
} from "./chunk-qwy57177.js";
|
|
40
|
-
import"./chunk-j0kjscb7.js";
|
|
41
|
-
import {
|
|
42
|
-
abortRoom
|
|
43
|
-
} from "./chunk-h980hb2n.js";
|
|
44
|
-
import"./chunk-ffefbd3r.js";
|
|
45
|
-
import"./chunk-pg1azh6n.js";
|
|
46
|
-
import"./chunk-1a6kv9vt.js";
|
|
47
|
-
import"./chunk-f5xgprg1.js";
|
|
48
|
-
import"./chunk-hwy3n31w.js";
|
|
49
|
-
|
|
50
|
-
// ../cli/src/commands/chat.ts
|
|
51
|
-
import { randomUUID } from "crypto";
|
|
52
|
-
import { createInterface } from "readline";
|
|
53
|
-
|
|
54
|
-
// ../cli/src/render.ts
|
|
55
|
-
var dim = (s) => `\x1B[2m${s}\x1B[0m`;
|
|
56
|
-
var bold = (s) => `\x1B[1m${s}\x1B[0m`;
|
|
57
|
-
var cyan = (s) => `\x1B[36m${s}\x1B[0m`;
|
|
58
|
-
var red = (s) => `\x1B[31m${s}\x1B[0m`;
|
|
59
|
-
function renderBusEvent(event, opts = {}) {
|
|
60
|
-
if (opts.topicId && event.topicId !== opts.topicId)
|
|
61
|
-
return;
|
|
62
|
-
switch (event.type) {
|
|
63
|
-
case "message": {
|
|
64
|
-
const msg = event.payload;
|
|
65
|
-
if (opts.selfUserId && msg.authorId === opts.selfUserId)
|
|
66
|
-
return;
|
|
67
|
-
if (msg.kind === "tool") {
|
|
68
|
-
console.log(dim(` ${firstLine(msg.text)}`));
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const author = msg.authorId === "ai" ? cyan(bold("ai")) : bold(msg.authorId);
|
|
72
|
-
console.log(`${author}${msg.agentType ? dim(` (${msg.agentType})`) : ""}: ${msg.text}`);
|
|
73
|
-
if (msg.kind === "ask_user_question" && msg.askUserQuestion) {
|
|
74
|
-
msg.askUserQuestion.choices.forEach((choice, index) => {
|
|
75
|
-
const description = choice.description ? dim(` \u2014 ${choice.description}`) : "";
|
|
76
|
-
console.log(` ${index + 1}) ${choice.label}${description}`);
|
|
77
|
-
});
|
|
78
|
-
console.log(dim(" choose by number or exact label"));
|
|
79
|
-
}
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
case "message-updated":
|
|
83
|
-
return;
|
|
84
|
-
case "ai-status": {
|
|
85
|
-
const status = event.payload;
|
|
86
|
-
const kind = String(status.kind ?? "");
|
|
87
|
-
if (kind === "ai-active" || kind === "typing")
|
|
88
|
-
return;
|
|
89
|
-
if (kind === "tool-call") {
|
|
90
|
-
console.log(dim(` \u2699 ${firstLine(String(status.label ?? status.tool ?? "tool"))}`));
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
if (kind === "error") {
|
|
94
|
-
console.log(red(` \u2716 ${firstLine(String(status.message ?? "error"))}`));
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (kind === "aborted") {
|
|
98
|
-
console.log(dim(" \u23F9 aborted"));
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
case "topic-created": {
|
|
104
|
-
const topic = event.payload;
|
|
105
|
-
console.log(dim(` + topic created: ${topic.title ?? topic.id}`));
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
case "topic-deleted":
|
|
109
|
-
console.log(dim(` - topic deleted: ${event.topicId}`));
|
|
110
|
-
return;
|
|
111
|
-
default:
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
function firstLine(s) {
|
|
116
|
-
const line = s.split(`
|
|
117
|
-
`, 1)[0] ?? "";
|
|
118
|
-
return line.length > 120 ? `${line.slice(0, 117)}...` : line;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// ../cli/src/commands/chat.ts
|
|
122
|
-
var DEFAULT_USER = "local";
|
|
123
|
-
var DEFAULT_TOPIC = "chat";
|
|
124
|
-
var VAULT_SET_COMMAND_PATTERN = /^\/vault(?:@\w+)?\s+set(?:\s|$)/i;
|
|
125
|
-
function scrubVaultSetCommandsFromHistory(history) {
|
|
126
|
-
for (let index = history.length - 1;index >= 0; index -= 1) {
|
|
127
|
-
if (VAULT_SET_COMMAND_PATTERN.test(history[index]?.trim() ?? "")) {
|
|
128
|
-
history.splice(index, 1);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
function ensureTopic(title, agent) {
|
|
133
|
-
const existing = getTopicByNameForUser(title, DEFAULT_USER);
|
|
134
|
-
if (existing)
|
|
135
|
-
return existing;
|
|
136
|
-
return registerTopic({
|
|
137
|
-
title,
|
|
138
|
-
userId: DEFAULT_USER,
|
|
139
|
-
kind: "agent",
|
|
140
|
-
...agent && isAgentKind(agent) ? { agent } : {}
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
async function chatCommand(args) {
|
|
144
|
-
const topicArg = args.find((a) => !a.startsWith("--"));
|
|
145
|
-
const agentArg = args.find((a) => a.startsWith("--agent="))?.slice("--agent=".length);
|
|
146
|
-
const node = await startDefaultNode();
|
|
147
|
-
let topic = ensureTopic(topicArg ?? DEFAULT_TOPIC, agentArg);
|
|
148
|
-
console.log(`negotium node on :${node.port} \u2014 topic "${topic.title}" (agent: ${topic.agent})`);
|
|
149
|
-
console.log(`commands: /vault, /switch <topic>, /abort, /quit
|
|
150
|
-
`);
|
|
151
|
-
const rl = createInterface({
|
|
152
|
-
input: process.stdin,
|
|
153
|
-
output: process.stdout,
|
|
154
|
-
prompt: "> "
|
|
155
|
-
});
|
|
156
|
-
let pendingAsk = null;
|
|
157
|
-
const unsubscribe = runtimeBus().subscribe((event) => {
|
|
158
|
-
renderBusEvent(event, { topicId: topic.id, selfUserId: DEFAULT_USER });
|
|
159
|
-
if (event.topicId !== topic.id)
|
|
160
|
-
return;
|
|
161
|
-
if (event.type === "message") {
|
|
162
|
-
const msg = event.payload;
|
|
163
|
-
if (msg.kind === "ask_user_question" && msg.askUserQuestion) {
|
|
164
|
-
pendingAsk = { messageId: msg.id, choices: msg.askUserQuestion.choices };
|
|
165
|
-
rl.prompt();
|
|
166
|
-
}
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (event.type === "message-updated" && pendingAsk) {
|
|
170
|
-
const payload = event.payload;
|
|
171
|
-
if (payload.messageId === pendingAsk.messageId && (payload.patch?.askUserQuestion?.expired || payload.patch?.askUserQuestion?.selectedLabel)) {
|
|
172
|
-
pendingAsk = null;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
rl.prompt();
|
|
177
|
-
rl.on("line", (line) => {
|
|
178
|
-
const text = line.trim();
|
|
179
|
-
if (VAULT_SET_COMMAND_PATTERN.test(text)) {
|
|
180
|
-
scrubVaultSetCommandsFromHistory(rl.history);
|
|
181
|
-
}
|
|
182
|
-
if (!text) {
|
|
183
|
-
rl.prompt();
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
if (text === "/quit" || text === "/exit") {
|
|
187
|
-
rl.close();
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
if (text === "/abort") {
|
|
191
|
-
const aborted = abortRoom(topic.id);
|
|
192
|
-
console.log(aborted ? "aborted." : "nothing running.");
|
|
193
|
-
rl.prompt();
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
if (text.startsWith("/switch ")) {
|
|
197
|
-
topic = ensureTopic(text.slice("/switch ".length).trim(), agentArg);
|
|
198
|
-
pendingAsk = null;
|
|
199
|
-
console.log(`\u2192 topic "${topic.title}" (agent: ${topic.agent})`);
|
|
200
|
-
rl.prompt();
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
if (isVaultCommandLine(text)) {
|
|
204
|
-
const result = executeVaultCommand(DEFAULT_USER, text);
|
|
205
|
-
if (result)
|
|
206
|
-
console.log(result);
|
|
207
|
-
rl.prompt();
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
if (pendingAsk) {
|
|
211
|
-
const choiceIndex = /^\d+$/.test(text) ? Number(text) - 1 : -1;
|
|
212
|
-
const choice = (choiceIndex >= 0 ? pendingAsk.choices[choiceIndex] : undefined) ?? pendingAsk.choices.find((item) => item.label === text);
|
|
213
|
-
if (!choice) {
|
|
214
|
-
console.log("invalid choice \u2014 enter one of the displayed numbers or labels.");
|
|
215
|
-
rl.prompt();
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
const answered = answerPendingAskUserQuestion(topic.id, pendingAsk.messageId, choice.label, DEFAULT_USER);
|
|
219
|
-
if (!answered.ok) {
|
|
220
|
-
console.log(`could not answer: ${answered.error}`);
|
|
221
|
-
} else {
|
|
222
|
-
pendingAsk = null;
|
|
223
|
-
}
|
|
224
|
-
rl.prompt();
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
appendApiMessage({
|
|
228
|
-
id: randomUUID(),
|
|
229
|
-
topicId: topic.id,
|
|
230
|
-
authorId: DEFAULT_USER,
|
|
231
|
-
text,
|
|
232
|
-
createdAt: new Date().toISOString()
|
|
233
|
-
});
|
|
234
|
-
startAiTurn({ topic, userId: DEFAULT_USER, prompt: text, allowAutoContinue: true });
|
|
235
|
-
rl.prompt();
|
|
236
|
-
});
|
|
237
|
-
await new Promise((resolve) => {
|
|
238
|
-
rl.on("close", async () => {
|
|
239
|
-
unsubscribe();
|
|
240
|
-
await node.stop();
|
|
241
|
-
resolve();
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
export {
|
|
246
|
-
scrubVaultSetCommandsFromHistory,
|
|
247
|
-
chatCommand
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
//# debugId=31CF6CADA058B1C964756E2164756E21
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../cli/src/commands/chat.ts", "../../cli/src/render.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * `negotium chat [topic]` — interactive terminal host.\n *\n * This command doubles as the reference implementation for anyone writing a\n * channel adapter: everything it does (ensure topic → persist user message →\n * startAiTurn → render bus events) is exactly what a Telegram/web/otium host\n * does with a different renderer.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { createInterface } from \"node:readline\";\nimport {\n type AgentKind,\n abortRoom,\n answerPendingAskUserQuestion,\n appendApiMessage,\n executeVaultCommand,\n getTopicByNameForUser,\n isAgentKind,\n isVaultCommandLine,\n type MessageDto,\n registerTopic,\n runtimeBus,\n startAiTurn,\n type TopicDto,\n} from \"@negotium/core\";\nimport { startDefaultNode } from \"@negotium/node\";\nimport { renderBusEvent } from \"@/render\";\n\nconst DEFAULT_USER = \"local\";\nconst DEFAULT_TOPIC = \"chat\";\nconst VAULT_SET_COMMAND_PATTERN = /^\\/vault(?:@\\w+)?\\s+set(?:\\s|$)/i;\n\n/**\n * Remove secret-bearing Vault writes from readline's in-memory history.\n *\n * Node records a line before emitting the `line` event, so this must run at\n * the beginning of the handler rather than after executing the command.\n */\nexport function scrubVaultSetCommandsFromHistory(history: string[]): void {\n for (let index = history.length - 1; index >= 0; index -= 1) {\n if (VAULT_SET_COMMAND_PATTERN.test(history[index]?.trim() ?? \"\")) {\n history.splice(index, 1);\n }\n }\n}\n\nfunction ensureTopic(title: string, agent?: string): TopicDto {\n const existing = getTopicByNameForUser(title, DEFAULT_USER);\n if (existing) return existing;\n return registerTopic({\n title,\n userId: DEFAULT_USER,\n kind: \"agent\",\n ...(agent && isAgentKind(agent) ? { agent: agent as AgentKind } : {}),\n });\n}\n\nexport async function chatCommand(args: string[]): Promise<void> {\n const topicArg = args.find((a) => !a.startsWith(\"--\"));\n const agentArg = args.find((a) => a.startsWith(\"--agent=\"))?.slice(\"--agent=\".length);\n\n const node = await startDefaultNode();\n let topic = ensureTopic(topicArg ?? DEFAULT_TOPIC, agentArg);\n\n console.log(`negotium node on :${node.port} — topic \"${topic.title}\" (agent: ${topic.agent})`);\n console.log(\"commands: /vault, /switch <topic>, /abort, /quit\\n\");\n\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: \"> \",\n }) as ReturnType<typeof createInterface> & { history: string[] };\n let pendingAsk: {\n messageId: string;\n choices: NonNullable<MessageDto[\"askUserQuestion\"]>[\"choices\"];\n } | null = null;\n const unsubscribe = runtimeBus().subscribe((event) => {\n renderBusEvent(event, { topicId: topic.id, selfUserId: DEFAULT_USER });\n if (event.topicId !== topic.id) return;\n if (event.type === \"message\") {\n const msg = event.payload as MessageDto;\n if (msg.kind === \"ask_user_question\" && msg.askUserQuestion) {\n pendingAsk = { messageId: msg.id, choices: msg.askUserQuestion.choices };\n rl.prompt();\n }\n return;\n }\n if (event.type === \"message-updated\" && pendingAsk) {\n const payload = event.payload as { messageId?: string; patch?: Partial<MessageDto> };\n if (\n payload.messageId === pendingAsk.messageId &&\n (payload.patch?.askUserQuestion?.expired || payload.patch?.askUserQuestion?.selectedLabel)\n ) {\n pendingAsk = null;\n }\n }\n });\n\n rl.prompt();\n\n rl.on(\"line\", (line) => {\n const text = line.trim();\n if (VAULT_SET_COMMAND_PATTERN.test(text)) {\n scrubVaultSetCommandsFromHistory(rl.history);\n }\n if (!text) {\n rl.prompt();\n return;\n }\n if (text === \"/quit\" || text === \"/exit\") {\n rl.close();\n return;\n }\n if (text === \"/abort\") {\n const aborted = abortRoom(topic.id);\n console.log(aborted ? \"aborted.\" : \"nothing running.\");\n rl.prompt();\n return;\n }\n if (text.startsWith(\"/switch \")) {\n topic = ensureTopic(text.slice(\"/switch \".length).trim(), agentArg);\n pendingAsk = null;\n console.log(`→ topic \"${topic.title}\" (agent: ${topic.agent})`);\n rl.prompt();\n return;\n }\n if (isVaultCommandLine(text)) {\n const result = executeVaultCommand(DEFAULT_USER, text);\n if (result) console.log(result);\n rl.prompt();\n return;\n }\n\n if (pendingAsk) {\n const choiceIndex = /^\\d+$/.test(text) ? Number(text) - 1 : -1;\n const choice =\n (choiceIndex >= 0 ? pendingAsk.choices[choiceIndex] : undefined) ??\n pendingAsk.choices.find((item) => item.label === text);\n if (!choice) {\n console.log(\"invalid choice — enter one of the displayed numbers or labels.\");\n rl.prompt();\n return;\n }\n const answered = answerPendingAskUserQuestion(\n topic.id,\n pendingAsk.messageId,\n choice.label,\n DEFAULT_USER,\n );\n if (!answered.ok) {\n console.log(`could not answer: ${answered.error}`);\n } else {\n pendingAsk = null;\n }\n rl.prompt();\n return;\n }\n\n appendApiMessage({\n id: randomUUID(),\n topicId: topic.id,\n authorId: DEFAULT_USER,\n text,\n createdAt: new Date().toISOString(),\n });\n startAiTurn({ topic, userId: DEFAULT_USER, prompt: text, allowAutoContinue: true });\n rl.prompt();\n });\n\n await new Promise<void>((resolve) => {\n rl.on(\"close\", async () => {\n unsubscribe();\n await node.stop();\n resolve();\n });\n });\n}\n",
|
|
6
|
-
"/**\n * Terminal rendering for RuntimeBus events — the CLI's half of the host\n * boundary. Deliberately dumb: everything the runtime wants a channel to show\n * arrives on the bus, so this file is the whole \"adapter\" a channel needs.\n */\n\nimport type { MessageDto, RuntimeBusEvent } from \"@negotium/core\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\n\nexport interface RenderOptions {\n /** Only render events for this topic id (chat mode). Undefined = all. */\n topicId?: string;\n /** Suppress echoing messages authored by this user (they typed them). */\n selfUserId?: string;\n}\n\nexport function renderBusEvent(event: RuntimeBusEvent, opts: RenderOptions = {}): void {\n if (opts.topicId && event.topicId !== opts.topicId) return;\n\n switch (event.type) {\n case \"message\": {\n const msg = event.payload as MessageDto;\n if (opts.selfUserId && msg.authorId === opts.selfUserId) return;\n if (msg.kind === \"tool\") {\n console.log(dim(` ${firstLine(msg.text)}`));\n return;\n }\n const author = msg.authorId === \"ai\" ? cyan(bold(\"ai\")) : bold(msg.authorId);\n console.log(`${author}${msg.agentType ? dim(` (${msg.agentType})`) : \"\"}: ${msg.text}`);\n if (msg.kind === \"ask_user_question\" && msg.askUserQuestion) {\n msg.askUserQuestion.choices.forEach((choice, index) => {\n const description = choice.description ? dim(` — ${choice.description}`) : \"\";\n console.log(` ${index + 1}) ${choice.label}${description}`);\n });\n console.log(dim(\" choose by number or exact label\"));\n }\n return;\n }\n case \"message-updated\":\n // Edit-in-place progress (tool status, subagent cards) — too chatty for\n // a line-oriented terminal; the final state arrives as ai-status/message.\n return;\n case \"ai-status\": {\n const status = event.payload as Record<string, unknown>;\n const kind = String(status.kind ?? \"\");\n if (kind === \"ai-active\" || kind === \"typing\") return;\n if (kind === \"tool-call\") {\n console.log(dim(` ⚙ ${firstLine(String(status.label ?? status.tool ?? \"tool\"))}`));\n return;\n }\n if (kind === \"error\") {\n console.log(red(` ✖ ${firstLine(String(status.message ?? \"error\"))}`));\n return;\n }\n if (kind === \"aborted\") {\n console.log(dim(\" ⏹ aborted\"));\n return;\n }\n return;\n }\n case \"topic-created\": {\n const topic = event.payload as { id: string; title?: string };\n console.log(dim(` + topic created: ${topic.title ?? topic.id}`));\n return;\n }\n case \"topic-deleted\":\n console.log(dim(` - topic deleted: ${event.topicId}`));\n return;\n default:\n return;\n }\n}\n\nfunction firstLine(s: string): string {\n const line = s.split(\"\\n\", 1)[0] ?? \"\";\n return line.length > 120 ? `${line.slice(0, 117)}...` : line;\n}\n"
|
|
7
|
-
],
|
|
8
|
-
"mappings": "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",
|
|
9
|
-
"debugId": "31CF6CADA058B1C964756E2164756E21",
|
|
10
|
-
"names": []
|
|
11
|
-
}
|
package/dist/chunk-6ah5farg.js
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import"./chunk-pg1azh6n.js";
|
|
3
|
-
import {
|
|
4
|
-
registerStorageSchemaInitializer,
|
|
5
|
-
storageDatabase
|
|
6
|
-
} from "./chunk-1a6kv9vt.js";
|
|
7
|
-
import"./chunk-f5xgprg1.js";
|
|
8
|
-
import"./chunk-hwy3n31w.js";
|
|
9
|
-
|
|
10
|
-
// ../../packages/core/src/storage/api-topic-config.ts
|
|
11
|
-
function tableColumns(table) {
|
|
12
|
-
const rows = storageDatabase.query(`PRAGMA table_info(${table})`).all();
|
|
13
|
-
return new Set(rows.map((row) => row.name));
|
|
14
|
-
}
|
|
15
|
-
function createCanonicalConfigTable(name = "api_topic_config") {
|
|
16
|
-
storageDatabase.exec(`
|
|
17
|
-
CREATE TABLE IF NOT EXISTS ${name} (
|
|
18
|
-
topic_id TEXT PRIMARY KEY REFERENCES api_topics(id) ON DELETE CASCADE,
|
|
19
|
-
model TEXT,
|
|
20
|
-
effort TEXT CHECK (effort IS NULL OR effort IN ('low','medium','high','xhigh','max')),
|
|
21
|
-
mcp TEXT,
|
|
22
|
-
agent_locked INTEGER NOT NULL DEFAULT 0 CHECK (agent_locked IN (0,1)),
|
|
23
|
-
model_locked INTEGER NOT NULL DEFAULT 0 CHECK (model_locked IN (0,1)),
|
|
24
|
-
effort_locked INTEGER NOT NULL DEFAULT 0 CHECK (effort_locked IN (0,1))
|
|
25
|
-
)
|
|
26
|
-
`);
|
|
27
|
-
}
|
|
28
|
-
function initializeApiTopicConfigSchema() {
|
|
29
|
-
const existingConfigColumns = tableColumns("api_topic_config");
|
|
30
|
-
if (existingConfigColumns.size === 0) {
|
|
31
|
-
createCanonicalConfigTable();
|
|
32
|
-
} else if (existingConfigColumns.has("agent") || existingConfigColumns.has("agent_pinned") || existingConfigColumns.has("runtime_locked") || existingConfigColumns.has("model_pinned") || existingConfigColumns.has("effort_pinned") || existingConfigColumns.has("last_shown_agent")) {
|
|
33
|
-
const topicColumns = tableColumns("api_topics");
|
|
34
|
-
const agentColumn = topicColumns.has("agent") ? "agent" : topicColumns.has("runtime_agent") ? "runtime_agent" : null;
|
|
35
|
-
if (agentColumn && existingConfigColumns.has("agent")) {
|
|
36
|
-
storageDatabase.exec(`UPDATE api_topics
|
|
37
|
-
SET ${agentColumn} = (
|
|
38
|
-
SELECT c.agent FROM api_topic_config c WHERE c.topic_id = api_topics.id
|
|
39
|
-
)
|
|
40
|
-
WHERE ${agentColumn} IS NULL
|
|
41
|
-
AND EXISTS (
|
|
42
|
-
SELECT 1 FROM api_topic_config c
|
|
43
|
-
WHERE c.topic_id = api_topics.id AND c.agent IS NOT NULL
|
|
44
|
-
)`);
|
|
45
|
-
}
|
|
46
|
-
const previousForeignKeys = storageDatabase.query("PRAGMA foreign_keys").get()?.foreign_keys;
|
|
47
|
-
storageDatabase.exec("PRAGMA foreign_keys = OFF");
|
|
48
|
-
try {
|
|
49
|
-
const agentLockSource = existingConfigColumns.has("runtime_locked") ? "runtime_locked" : existingConfigColumns.has("agent_pinned") ? "agent_pinned" : "0";
|
|
50
|
-
const modelLockSource = existingConfigColumns.has("model_locked") ? "model_locked" : existingConfigColumns.has("model_pinned") ? "model_pinned" : "0";
|
|
51
|
-
const effortLockSource = existingConfigColumns.has("effort_locked") ? "effort_locked" : existingConfigColumns.has("effort_pinned") ? "effort_pinned" : "0";
|
|
52
|
-
storageDatabase.transaction(() => {
|
|
53
|
-
createCanonicalConfigTable("api_topic_config_next");
|
|
54
|
-
storageDatabase.exec(`
|
|
55
|
-
INSERT INTO api_topic_config_next
|
|
56
|
-
(topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
|
|
57
|
-
SELECT
|
|
58
|
-
topic_id,
|
|
59
|
-
model,
|
|
60
|
-
effort,
|
|
61
|
-
mcp,
|
|
62
|
-
COALESCE(${agentLockSource}, 0),
|
|
63
|
-
COALESCE(${modelLockSource}, 0),
|
|
64
|
-
COALESCE(${effortLockSource}, 0)
|
|
65
|
-
FROM api_topic_config
|
|
66
|
-
WHERE EXISTS (SELECT 1 FROM api_topics t WHERE t.id = api_topic_config.topic_id)
|
|
67
|
-
`);
|
|
68
|
-
storageDatabase.exec("DROP TABLE api_topic_config");
|
|
69
|
-
storageDatabase.exec("ALTER TABLE api_topic_config_next RENAME TO api_topic_config");
|
|
70
|
-
})();
|
|
71
|
-
} finally {
|
|
72
|
-
storageDatabase.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? "ON" : "OFF"}`);
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
75
|
-
createCanonicalConfigTable();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
registerStorageSchemaInitializer(initializeApiTopicConfigSchema, 40);
|
|
79
|
-
function rowToConfig(r) {
|
|
80
|
-
const cfg = {};
|
|
81
|
-
if (r.model)
|
|
82
|
-
cfg.model = r.model;
|
|
83
|
-
if (r.effort)
|
|
84
|
-
cfg.effort = r.effort;
|
|
85
|
-
if (r.mcp) {
|
|
86
|
-
try {
|
|
87
|
-
const parsed = JSON.parse(r.mcp);
|
|
88
|
-
if (Array.isArray(parsed))
|
|
89
|
-
cfg.mcp = parsed;
|
|
90
|
-
} catch {}
|
|
91
|
-
}
|
|
92
|
-
if (r.agent_locked)
|
|
93
|
-
cfg.agentLocked = true;
|
|
94
|
-
if (r.model_locked)
|
|
95
|
-
cfg.modelLocked = true;
|
|
96
|
-
if (r.effort_locked)
|
|
97
|
-
cfg.effortLocked = true;
|
|
98
|
-
return cfg;
|
|
99
|
-
}
|
|
100
|
-
function getApiTopicConfig(topicId) {
|
|
101
|
-
const row = storageDatabase.query("SELECT topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked FROM api_topic_config WHERE topic_id = ?").get(topicId);
|
|
102
|
-
if (!row)
|
|
103
|
-
return;
|
|
104
|
-
const config = rowToConfig(row);
|
|
105
|
-
return Object.keys(config).length > 0 ? config : undefined;
|
|
106
|
-
}
|
|
107
|
-
function setApiTopicConfig(topicId, config) {
|
|
108
|
-
storageDatabase.query(`INSERT INTO api_topic_config
|
|
109
|
-
(topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
|
|
110
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
111
|
-
ON CONFLICT(topic_id) DO UPDATE SET
|
|
112
|
-
model = excluded.model,
|
|
113
|
-
effort = excluded.effort,
|
|
114
|
-
mcp = excluded.mcp,
|
|
115
|
-
agent_locked = excluded.agent_locked,
|
|
116
|
-
model_locked = excluded.model_locked,
|
|
117
|
-
effort_locked = excluded.effort_locked`).run(topicId, config.model ?? null, config.effort ?? null, config.mcp ? JSON.stringify(config.mcp) : null, config.agentLocked ? 1 : 0, config.modelLocked ? 1 : 0, config.effortLocked ? 1 : 0);
|
|
118
|
-
}
|
|
119
|
-
function deleteApiTopicConfig(topicId) {
|
|
120
|
-
storageDatabase.query("DELETE FROM api_topic_config WHERE topic_id = ?").run(topicId);
|
|
121
|
-
}
|
|
122
|
-
export {
|
|
123
|
-
setApiTopicConfig,
|
|
124
|
-
getApiTopicConfig,
|
|
125
|
-
deleteApiTopicConfig
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
export { getApiTopicConfig, setApiTopicConfig, deleteApiTopicConfig };
|
|
129
|
-
|
|
130
|
-
//# debugId=9D9A4F4E725454F064756E2164756E21
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../packages/core/src/storage/api-topic-config.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"// Persistent per-topic model/effort/MCP overrides and user locks.\n// SQLite. Mirrors api-topics.ts. This replaces the previous in-memory Map in\n// routes/topic-config.ts, which lost every override on server restart — a\n// regression now that topic config is the canonical path for model/effort\n// switching (the MCP-based direction), not just a transient convenience.\nimport { db } from \"#storage/forum-db\";\nimport { registerStorageSchemaInitializer } from \"#storage/storage-host\";\nimport type { EffortLevel } from \"#types\";\n\nfunction tableColumns(table: string): Set<string> {\n const rows = db.query(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;\n return new Set(rows.map((row) => row.name));\n}\n\nfunction createCanonicalConfigTable(name = \"api_topic_config\"): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS ${name} (\n topic_id TEXT PRIMARY KEY REFERENCES api_topics(id) ON DELETE CASCADE,\n model TEXT,\n effort TEXT CHECK (effort IS NULL OR effort IN ('low','medium','high','xhigh','max')),\n mcp TEXT,\n agent_locked INTEGER NOT NULL DEFAULT 0 CHECK (agent_locked IN (0,1)),\n model_locked INTEGER NOT NULL DEFAULT 0 CHECK (model_locked IN (0,1)),\n effort_locked INTEGER NOT NULL DEFAULT 0 CHECK (effort_locked IN (0,1))\n )\n `);\n}\n\nfunction initializeApiTopicConfigSchema(): void {\n const existingConfigColumns = tableColumns(\"api_topic_config\");\n if (existingConfigColumns.size === 0) {\n createCanonicalConfigTable();\n } else if (\n existingConfigColumns.has(\"agent\") ||\n existingConfigColumns.has(\"agent_pinned\") ||\n existingConfigColumns.has(\"runtime_locked\") ||\n existingConfigColumns.has(\"model_pinned\") ||\n existingConfigColumns.has(\"effort_pinned\") ||\n existingConfigColumns.has(\"last_shown_agent\")\n ) {\n // Complete the old agent-override migration before dropping the column. The\n // selected agent itself belongs to api_topics; only its user lock belongs here.\n const topicColumns = tableColumns(\"api_topics\");\n const agentColumn = topicColumns.has(\"agent\")\n ? \"agent\"\n : topicColumns.has(\"runtime_agent\")\n ? \"runtime_agent\"\n : null;\n if (agentColumn && existingConfigColumns.has(\"agent\")) {\n db.exec(\n `UPDATE api_topics\n SET ${agentColumn} = (\n SELECT c.agent FROM api_topic_config c WHERE c.topic_id = api_topics.id\n )\n WHERE ${agentColumn} IS NULL\n AND EXISTS (\n SELECT 1 FROM api_topic_config c\n WHERE c.topic_id = api_topics.id AND c.agent IS NOT NULL\n )`,\n );\n }\n\n const previousForeignKeys = db\n .query<{ foreign_keys: number }, []>(\"PRAGMA foreign_keys\")\n .get()?.foreign_keys;\n db.exec(\"PRAGMA foreign_keys = OFF\");\n try {\n const agentLockSource = existingConfigColumns.has(\"runtime_locked\")\n ? \"runtime_locked\"\n : existingConfigColumns.has(\"agent_pinned\")\n ? \"agent_pinned\"\n : \"0\";\n const modelLockSource = existingConfigColumns.has(\"model_locked\")\n ? \"model_locked\"\n : existingConfigColumns.has(\"model_pinned\")\n ? \"model_pinned\"\n : \"0\";\n const effortLockSource = existingConfigColumns.has(\"effort_locked\")\n ? \"effort_locked\"\n : existingConfigColumns.has(\"effort_pinned\")\n ? \"effort_pinned\"\n : \"0\";\n db.transaction(() => {\n createCanonicalConfigTable(\"api_topic_config_next\");\n db.exec(`\n INSERT INTO api_topic_config_next\n (topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)\n SELECT\n topic_id,\n model,\n effort,\n mcp,\n COALESCE(${agentLockSource}, 0),\n COALESCE(${modelLockSource}, 0),\n COALESCE(${effortLockSource}, 0)\n FROM api_topic_config\n WHERE EXISTS (SELECT 1 FROM api_topics t WHERE t.id = api_topic_config.topic_id)\n `);\n db.exec(\"DROP TABLE api_topic_config\");\n db.exec(\"ALTER TABLE api_topic_config_next RENAME TO api_topic_config\");\n })();\n } finally {\n db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? \"ON\" : \"OFF\"}`);\n }\n } else {\n createCanonicalConfigTable();\n }\n}\n\nregisterStorageSchemaInitializer(initializeApiTopicConfigSchema, 40);\n\nexport interface TopicConfig {\n model?: string;\n effort?: EffortLevel;\n mcp?: string[]; // enabled optional MCP server names\n // Per-field user locks: when true, AI self-config cannot override the field.\n agentLocked?: boolean;\n modelLocked?: boolean;\n effortLocked?: boolean;\n}\n\ninterface ConfigRow {\n topic_id: string;\n model: string | null;\n effort: string | null;\n mcp: string | null;\n agent_locked: number;\n model_locked: number;\n effort_locked: number;\n}\n\nfunction rowToConfig(r: ConfigRow): TopicConfig {\n const cfg: TopicConfig = {};\n if (r.model) cfg.model = r.model;\n if (r.effort) cfg.effort = r.effort as EffortLevel;\n if (r.mcp) {\n try {\n const parsed = JSON.parse(r.mcp);\n if (Array.isArray(parsed)) cfg.mcp = parsed as string[];\n } catch {\n // corrupt JSON — treat as no mcp override\n }\n }\n if (r.agent_locked) cfg.agentLocked = true;\n if (r.model_locked) cfg.modelLocked = true;\n if (r.effort_locked) cfg.effortLocked = true;\n return cfg;\n}\n\n/**\n * Per-topic override set via `PATCH /config` (and, going forward, the MCP\n * self-config tools). Returns `undefined` when the topic has no stored row,\n * so callers can distinguish \"no override\" from \"override with empty fields\".\n */\nexport function getApiTopicConfig(topicId: string): TopicConfig | undefined {\n const row = db\n .query(\n \"SELECT topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked FROM api_topic_config WHERE topic_id = ?\",\n )\n .get(topicId) as ConfigRow | null;\n if (!row) return undefined;\n const config = rowToConfig(row);\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\n/**\n * Upsert the full override for a topic. Fields set to `undefined` are cleared\n * (stored as SQL NULL), matching the previous Map semantics where the route\n * built a complete `updated` object before persisting.\n */\nexport function setApiTopicConfig(topicId: string, config: TopicConfig): void {\n db.query(\n `INSERT INTO api_topic_config\n (topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(topic_id) DO UPDATE SET\n model = excluded.model,\n effort = excluded.effort,\n mcp = excluded.mcp,\n agent_locked = excluded.agent_locked,\n model_locked = excluded.model_locked,\n effort_locked = excluded.effort_locked`,\n ).run(\n topicId,\n config.model ?? null,\n config.effort ?? null,\n config.mcp ? JSON.stringify(config.mcp) : null,\n config.agentLocked ? 1 : 0,\n config.modelLocked ? 1 : 0,\n config.effortLocked ? 1 : 0,\n );\n}\n\n/** Remove a topic's override row entirely (e.g. on topic hard-delete). */\nexport function deleteApiTopicConfig(topicId: string): void {\n db.query(\"DELETE FROM api_topic_config WHERE topic_id = ?\").run(topicId);\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "9D9A4F4E725454F064756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
package/dist/chunk-6d4fmea5.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
readConversation
|
|
4
|
-
} from "./chunk-61px0717.js";
|
|
5
|
-
import {
|
|
6
|
-
claudeRegistry,
|
|
7
|
-
writeCodexRollout
|
|
8
|
-
} from "./chunk-m9e3tbr8.js";
|
|
9
|
-
import"./chunk-mh5mexsf.js";
|
|
10
|
-
import {
|
|
11
|
-
CODEX_EFFORT_VALUES
|
|
12
|
-
} from "./chunk-qwy57177.js";
|
|
13
|
-
import {
|
|
14
|
-
logger
|
|
15
|
-
} from "./chunk-ffefbd3r.js";
|
|
16
|
-
import"./chunk-1a6kv9vt.js";
|
|
17
|
-
import"./chunk-f5xgprg1.js";
|
|
18
|
-
import"./chunk-hwy3n31w.js";
|
|
19
|
-
|
|
20
|
-
// ../../packages/core/src/agents/codex-registry.ts
|
|
21
|
-
import { unlinkSync } from "fs";
|
|
22
|
-
import { homedir } from "os";
|
|
23
|
-
import { join } from "path";
|
|
24
|
-
var VALID_EFFORTS = new Set(CODEX_EFFORT_VALUES);
|
|
25
|
-
var codexRegistry = {
|
|
26
|
-
kind: "codex",
|
|
27
|
-
defaultModel: "gpt-5.6-luna",
|
|
28
|
-
expandModelAlias(s) {
|
|
29
|
-
return s;
|
|
30
|
-
},
|
|
31
|
-
validateModel(s) {
|
|
32
|
-
return typeof s === "string" && s.length > 0;
|
|
33
|
-
},
|
|
34
|
-
validEfforts: CODEX_EFFORT_VALUES,
|
|
35
|
-
validateEffort(s) {
|
|
36
|
-
return VALID_EFFORTS.has(s);
|
|
37
|
-
},
|
|
38
|
-
footerLabel(model, effort) {
|
|
39
|
-
return `${model} \xB7 ${effort ?? "(off)"}`;
|
|
40
|
-
},
|
|
41
|
-
writeRollout(opts) {
|
|
42
|
-
const { threadId, rolloutPath } = writeCodexRollout({
|
|
43
|
-
cwd: opts.cwd,
|
|
44
|
-
entries: opts.entries,
|
|
45
|
-
model: opts.model ?? codexRegistry.defaultModel,
|
|
46
|
-
...opts.effort ? { effort: opts.effort } : {},
|
|
47
|
-
...opts.reuseSessionId ? { threadId: opts.reuseSessionId } : {}
|
|
48
|
-
});
|
|
49
|
-
return { sessionId: threadId, rolloutPath };
|
|
50
|
-
},
|
|
51
|
-
async forkSession({ cwd, userId, topicName, model, effort }) {
|
|
52
|
-
const entries = readConversation(userId, topicName);
|
|
53
|
-
const { threadId, rolloutPath } = writeCodexRollout({
|
|
54
|
-
cwd,
|
|
55
|
-
entries,
|
|
56
|
-
model: model ?? codexRegistry.defaultModel,
|
|
57
|
-
...effort ? { effort } : {}
|
|
58
|
-
});
|
|
59
|
-
return { forkId: threadId, rolloutPath };
|
|
60
|
-
},
|
|
61
|
-
async cleanupRollouts({ sessionIds }) {
|
|
62
|
-
if (sessionIds.length === 0)
|
|
63
|
-
return;
|
|
64
|
-
const sessionsDir = join(process.env.CODEX_HOME || join(homedir(), ".codex"), "sessions");
|
|
65
|
-
const failures = [];
|
|
66
|
-
for (const tid of sessionIds) {
|
|
67
|
-
try {
|
|
68
|
-
const glob = new Bun.Glob(`**/rollout-*-${tid}.jsonl`);
|
|
69
|
-
for await (const rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {
|
|
70
|
-
const path = join(sessionsDir, rel);
|
|
71
|
-
try {
|
|
72
|
-
unlinkSync(path);
|
|
73
|
-
} catch (e) {
|
|
74
|
-
if (e?.code !== "ENOENT") {
|
|
75
|
-
logger.warn({ err: e, path }, "codex cleanupRollouts: unlink failed");
|
|
76
|
-
failures.push(e);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
} catch (e) {
|
|
81
|
-
logger.warn({ err: e, threadId: tid }, "codex cleanupRollouts: scan failed");
|
|
82
|
-
failures.push(e);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (failures.length > 0) {
|
|
86
|
-
throw new AggregateError(failures, "codex cleanupRollouts failed");
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// ../../packages/core/src/agents/maestro-registry.ts
|
|
92
|
-
import {
|
|
93
|
-
setConversationReader,
|
|
94
|
-
maestroRegistry as upstreamMaestroRegistry
|
|
95
|
-
} from "maestro-agent-sdk";
|
|
96
|
-
setConversationReader(readConversation);
|
|
97
|
-
var maestroRegistry = {
|
|
98
|
-
...upstreamMaestroRegistry,
|
|
99
|
-
defaultModel: "deepseek-pro"
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// ../../packages/core/src/agents/registry.ts
|
|
103
|
-
var REGISTRIES = {
|
|
104
|
-
claude: claudeRegistry,
|
|
105
|
-
codex: codexRegistry,
|
|
106
|
-
maestro: maestroRegistry
|
|
107
|
-
};
|
|
108
|
-
function getRegistry(agent) {
|
|
109
|
-
return REGISTRIES[agent];
|
|
110
|
-
}
|
|
111
|
-
export {
|
|
112
|
-
getRegistry
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
export { getRegistry };
|
|
116
|
-
|
|
117
|
-
//# debugId=40E6B322C20232BB64756E2164756E21
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../packages/core/src/agents/codex-registry.ts", "../../../packages/core/src/agents/maestro-registry.ts", "../../../packages/core/src/agents/registry.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import { unlinkSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { AgentRegistry } from \"#agents/contracts\";\nimport { writeCodexRollout } from \"#agents/rollout/codex\";\nimport { logger } from \"#platform/logger\";\nimport { readConversation } from \"#storage/conversations\";\nimport { CODEX_EFFORT_VALUES, type EffortLevel } from \"#types\";\n\nconst VALID_EFFORTS = new Set<EffortLevel>(CODEX_EFFORT_VALUES);\n\n// Codex CLI's own empirical default is gpt-5.6-sol (`codex exec` 2026-07-10 →\n// \"model: gpt-5.6-sol\"), but we deliberately default to gpt-5.6-luna — the\n// cheapest/fastest GPT-5.6 tier — for a general always-on assistant where most\n// queries are light. Heavier work escalates to terra/sol via set_model. This\n// value is passed explicitly to the SDK (see event-processor resolveDefaultModel),\n// so the footer and the actual model stay in sync.\nexport const codexRegistry: AgentRegistry = {\n kind: \"codex\",\n defaultModel: \"gpt-5.6-luna\",\n // defaultEffort intentionally omitted — Codex SDK treats absence as\n // \"reasoning off\". Setting \"high\"/etc. would silently flip on reasoning.\n\n expandModelAlias(s) {\n return s;\n },\n\n validateModel(s) {\n // Codex doesn't publish a closed model list and OpenAI ships new IDs\n // (gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, o3, ...) frequently. Best-effort: accept any\n // non-empty string. Bad IDs surface at SDK call time with a clear error.\n return typeof s === \"string\" && s.length > 0;\n },\n\n validEfforts: CODEX_EFFORT_VALUES,\n validateEffort(s) {\n // GPT-5.6 accepts low/medium/high/xhigh/max; 'minimal'\n // was removed because the Codex API rejects it when default tools\n // (image_gen, web_search) are active.\n return VALID_EFFORTS.has(s);\n },\n\n footerLabel(model, effort) {\n // Codex omits effort to mean \"reasoning off\". Show `(off)` explicitly so\n // the user can distinguish from claude (which always has a default).\n return `${model} · ${effort ?? \"(off)\"}`;\n },\n\n writeRollout(opts) {\n // Codex SDK exposes the resume key as `threadId`; AgentRegistry unifies\n // the name to `sessionId` so callers don't branch on agent.\n // `reuseSessionId` (if any) is forwarded as `threadId` so claude→codex→claude\n // round-trips also keep one continuous codex thread instead of orphaning a\n // fresh uuidv7 on every switch.\n const { threadId, rolloutPath } = writeCodexRollout({\n cwd: opts.cwd,\n entries: opts.entries,\n model: opts.model ?? codexRegistry.defaultModel,\n ...(opts.effort ? { effort: opts.effort } : {}),\n ...(opts.reuseSessionId ? { threadId: opts.reuseSessionId } : {}),\n });\n return { sessionId: threadId, rolloutPath };\n },\n\n // Codex SDK has no fork API. We synthesize a rollout from the\n // provider-agnostic conversation log (same path as `set_agent` cross-agent\n // bridging). Caveats: extractChatPairs folds tool_use/tool_result into\n // assistant text as `[Tool: ...]` annotations, so structural tool history\n // is lost.\n async forkSession({ cwd, userId, topicName, model, effort }) {\n const entries = readConversation(userId, topicName);\n const { threadId, rolloutPath } = writeCodexRollout({\n cwd,\n entries,\n model: model ?? codexRegistry.defaultModel,\n ...(effort ? { effort } : {}),\n });\n return { forkId: threadId, rolloutPath };\n },\n\n // Codex stores rollouts at `~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-<ts>-<threadId>.jsonl`.\n // The date prefix is unknown at cleanup time (it's the *original* write\n // timestamp, not \"now\"), so we glob across the whole sessions tree by\n // threadId suffix. With at most a few thousand files in active use this\n // is well under a millisecond on a warm filesystem.\n async cleanupRollouts({ sessionIds }) {\n if (sessionIds.length === 0) return;\n const sessionsDir = join(process.env.CODEX_HOME || join(homedir(), \".codex\"), \"sessions\");\n const failures: unknown[] = [];\n // One Glob per threadId so a single corrupt entry can't poison the rest.\n // Bun.Glob's `scan` yields paths relative to its base dir.\n for (const tid of sessionIds) {\n try {\n const glob = new Bun.Glob(`**/rollout-*-${tid}.jsonl`);\n for await (const rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {\n const path = join(sessionsDir, rel);\n try {\n unlinkSync(path);\n } catch (e) {\n if ((e as NodeJS.ErrnoException)?.code !== \"ENOENT\") {\n logger.warn({ err: e, path }, \"codex cleanupRollouts: unlink failed\");\n failures.push(e);\n }\n }\n }\n } catch (e) {\n logger.warn({ err: e, threadId: tid }, \"codex cleanupRollouts: scan failed\");\n failures.push(e);\n }\n }\n if (failures.length > 0) {\n throw new AggregateError(failures, \"codex cleanupRollouts failed\");\n }\n },\n};\n",
|
|
6
|
-
"/**\n * Maestro agent registry — local re-export of `maestro-agent-sdk` with\n * a project-specific default-model override.\n *\n * Mirrors the pattern of claude-registry.ts / codex-registry.ts so that\n * agents/registry.ts can resolve all three AgentRegistry instances from\n * sibling `@/agents/*` paths, keeping the import topology consistent.\n *\n * maestro-agent-sdk v0.1.39 is DeepSeek-only — the Anthropic and Codex\n * providers were removed. The SDK's own default is `deepseek-pro`, which\n * matches this override. The override is kept explicit so the intent is\n * clear if the upstream default ever changes; users can still switch to\n * `deepseek-flash` per-topic via `/model deepseek-flash`.\n */\nimport \"#platform/maestro-bootstrap-env\";\nimport {\n setConversationReader,\n maestroRegistry as upstreamMaestroRegistry,\n} from \"maestro-agent-sdk\";\nimport type { AgentRegistry } from \"#agents/contracts\";\nimport { readConversation } from \"#storage/conversations\";\n\n// The SDK intentionally defaults its conversation reader to `() => []` so it\n// can stay storage-agnostic. Wire Negotium's unified log into it once at module\n// load; otherwise Maestro forkSession() creates a valid but empty rollout.\nsetConversationReader(readConversation as Parameters<typeof setConversationReader>[0]);\n\nexport const maestroRegistry: AgentRegistry = {\n ...(upstreamMaestroRegistry as AgentRegistry),\n defaultModel: \"deepseek-pro\",\n};\n",
|
|
7
|
-
"import { claudeRegistry } from \"#agents/claude-registry\";\nimport { codexRegistry } from \"#agents/codex-registry\";\nimport type { AgentRegistry } from \"#agents/contracts\";\nimport { maestroRegistry } from \"#agents/maestro-registry\";\nimport type { AgentKind } from \"#types\";\n\nexport type {\n AgentRegistry,\n CleanupRolloutsOptions,\n ForkRegistryOptions,\n ForkRegistryResult,\n WriteRolloutOptions,\n WriteRolloutResult,\n} from \"#agents/contracts\";\n\nconst REGISTRIES: Record<AgentKind, AgentRegistry> = {\n claude: claudeRegistry,\n codex: codexRegistry,\n maestro: maestroRegistry,\n};\n\nexport function getRegistry(agent: AgentKind): AgentRegistry {\n return REGISTRIES[agent];\n}\n"
|
|
8
|
-
],
|
|
9
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AAOA,IAAM,gBAAgB,IAAI,IAAiB,mBAAmB;AAQvD,IAAM,gBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,cAAc;AAAA,EAId,gBAAgB,CAAC,GAAG;AAAA,IAClB,OAAO;AAAA;AAAA,EAGT,aAAa,CAAC,GAAG;AAAA,IAIf,OAAO,OAAO,MAAM,YAAY,EAAE,SAAS;AAAA;AAAA,EAG7C,cAAc;AAAA,EACd,cAAc,CAAC,GAAG;AAAA,IAIhB,OAAO,cAAc,IAAI,CAAC;AAAA;AAAA,EAG5B,WAAW,CAAC,OAAO,QAAQ;AAAA,IAGzB,OAAO,GAAG,cAAU,UAAU;AAAA;AAAA,EAGhC,YAAY,CAAC,MAAM;AAAA,IAMjB,QAAQ,UAAU,gBAAgB,kBAAkB;AAAA,MAClD,KAAK,KAAK;AAAA,MACV,SAAS,KAAK;AAAA,MACd,OAAO,KAAK,SAAS,cAAc;AAAA,SAC/B,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,SACzC,KAAK,iBAAiB,EAAE,UAAU,KAAK,eAAe,IAAI,CAAC;AAAA,IACjE,CAAC;AAAA,IACD,OAAO,EAAE,WAAW,UAAU,YAAY;AAAA;AAAA,OAQtC,YAAW,GAAG,KAAK,QAAQ,WAAW,OAAO,UAAU;AAAA,IAC3D,MAAM,UAAU,iBAAiB,QAAQ,SAAS;AAAA,IAClD,QAAQ,UAAU,gBAAgB,kBAAkB;AAAA,MAClD;AAAA,MACA;AAAA,MACA,OAAO,SAAS,cAAc;AAAA,SAC1B,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC7B,CAAC;AAAA,IACD,OAAO,EAAE,QAAQ,UAAU,YAAY;AAAA;AAAA,OAQnC,gBAAe,GAAG,cAAc;AAAA,IACpC,IAAI,WAAW,WAAW;AAAA,MAAG;AAAA,IAC7B,MAAM,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,QAAQ,GAAG,QAAQ,GAAG,UAAU;AAAA,IACxF,MAAM,WAAsB,CAAC;AAAA,IAG7B,WAAW,OAAO,YAAY;AAAA,MAC5B,IAAI;AAAA,QACF,MAAM,OAAO,IAAI,IAAI,KAAK,gBAAgB,WAAW;AAAA,QACrD,iBAAiB,OAAO,KAAK,KAAK,EAAE,KAAK,aAAa,WAAW,KAAK,CAAC,GAAG;AAAA,UACxE,MAAM,OAAO,KAAK,aAAa,GAAG;AAAA,UAClC,IAAI;AAAA,YACF,WAAW,IAAI;AAAA,YACf,OAAO,GAAG;AAAA,YACV,IAAK,GAA6B,SAAS,UAAU;AAAA,cACnD,OAAO,KAAK,EAAE,KAAK,GAAG,KAAK,GAAG,sCAAsC;AAAA,cACpE,SAAS,KAAK,CAAC;AAAA,YACjB;AAAA;AAAA,QAEJ;AAAA,QACA,OAAO,GAAG;AAAA,QACV,OAAO,KAAK,EAAE,KAAK,GAAG,UAAU,IAAI,GAAG,oCAAoC;AAAA,QAC3E,SAAS,KAAK,CAAC;AAAA;AAAA,IAEnB;AAAA,IACA,IAAI,SAAS,SAAS,GAAG;AAAA,MACvB,MAAM,IAAI,eAAe,UAAU,8BAA8B;AAAA,IACnE;AAAA;AAEJ;;;ACnGA;AAAA;AAAA,qBAEE;AAAA;AAQF,sBAAsB,gBAA+D;AAE9E,IAAM,kBAAiC;AAAA,KACxC;AAAA,EACJ,cAAc;AAChB;;;ACfA,IAAM,aAA+C;AAAA,EACnD,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAEO,SAAS,WAAW,CAAC,OAAiC;AAAA,EAC3D,OAAO,WAAW;AAAA;",
|
|
10
|
-
"debugId": "40E6B322C20232BB64756E2164756E21",
|
|
11
|
-
"names": []
|
|
12
|
-
}
|
package/dist/chunk-8cahx7xc.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import {
|
|
3
|
-
getRegistry
|
|
4
|
-
} from "./chunk-6d4fmea5.js";
|
|
5
|
-
import"./chunk-61px0717.js";
|
|
6
|
-
import"./chunk-m9e3tbr8.js";
|
|
7
|
-
import"./chunk-mh5mexsf.js";
|
|
8
|
-
import"./chunk-qwy57177.js";
|
|
9
|
-
import {
|
|
10
|
-
logger
|
|
11
|
-
} from "./chunk-ffefbd3r.js";
|
|
12
|
-
import"./chunk-1a6kv9vt.js";
|
|
13
|
-
import"./chunk-f5xgprg1.js";
|
|
14
|
-
import"./chunk-hwy3n31w.js";
|
|
15
|
-
|
|
16
|
-
// ../../packages/core/src/agents/fork.ts
|
|
17
|
-
import { existsSync, unlinkSync } from "fs";
|
|
18
|
-
async function forkAgentSession(opts) {
|
|
19
|
-
const { forkId, rolloutPath } = await getRegistry(opts.agent).forkSession({
|
|
20
|
-
parentSessionId: opts.parentSessionId,
|
|
21
|
-
cwd: opts.cwd,
|
|
22
|
-
userId: opts.userId,
|
|
23
|
-
topicName: opts.topicName,
|
|
24
|
-
...opts.title ? { title: opts.title } : {},
|
|
25
|
-
...opts.model ? { model: opts.model } : {},
|
|
26
|
-
...opts.effort ? { effort: opts.effort } : {}
|
|
27
|
-
});
|
|
28
|
-
return { agent: opts.agent, forkId, rolloutPath };
|
|
29
|
-
}
|
|
30
|
-
function cleanupAgentFork(handle) {
|
|
31
|
-
try {
|
|
32
|
-
if (existsSync(handle.rolloutPath)) {
|
|
33
|
-
unlinkSync(handle.rolloutPath);
|
|
34
|
-
}
|
|
35
|
-
} catch (err) {
|
|
36
|
-
logger.warn({ err, agent: handle.agent, forkId: handle.forkId, rolloutPath: handle.rolloutPath }, "cleanupAgentFork: failed to remove rollout");
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
export {
|
|
40
|
-
forkAgentSession,
|
|
41
|
-
cleanupAgentFork
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export { forkAgentSession, cleanupAgentFork };
|
|
45
|
-
|
|
46
|
-
//# debugId=391C8BC9C9E5158464756E2164756E21
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../packages/core/src/agents/fork.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import { existsSync, unlinkSync } from \"node:fs\";\nimport { getRegistry } from \"#agents/registry\";\nimport { logger } from \"#platform/logger\";\nimport type { AgentKind, EffortLevel } from \"#types\";\n\n/**\n * Agent-aware fork primitives.\n *\n * Strategy lives in each agent's registry (`*-registry.ts:forkSession`).\n * Claude uses the SDK's native `forkSession` (byte-equivalent rollout copy);\n * Codex synthesizes a rollout from the provider-agnostic conversation log\n * because the SDK has no fork API. Both surfaces converge on `ForkHandle`.\n */\n\nexport interface ForkAgentSessionOptions {\n agent: AgentKind;\n /** Parent session/thread id to clone from. */\n parentSessionId: string;\n /** Workspace directory the resumed fork will report. Claude also writes\n * the rollout file under this directory. */\n cwd: string;\n /** Used to locate the conversation log for codex synthesis. */\n userId: number | string;\n /** Used to locate the conversation log for codex synthesis. */\n topicName: string;\n /** Optional title forwarded to Claude SDK forkSession; ignored by Codex. */\n title?: string;\n /** Effective model/effort the fork will use when it resumes. */\n model?: string;\n effort?: EffortLevel;\n}\n\nexport interface ForkHandle {\n agent: AgentKind;\n forkId: string;\n /** Absolute path of the rollout file to remove on cleanup. */\n rolloutPath: string;\n}\n\nexport async function forkAgentSession(opts: ForkAgentSessionOptions): Promise<ForkHandle> {\n const { forkId, rolloutPath } = await getRegistry(opts.agent).forkSession({\n parentSessionId: opts.parentSessionId,\n cwd: opts.cwd,\n userId: opts.userId,\n topicName: opts.topicName,\n ...(opts.title ? { title: opts.title } : {}),\n ...(opts.model ? { model: opts.model } : {}),\n ...(opts.effort ? { effort: opts.effort } : {}),\n });\n return { agent: opts.agent, forkId, rolloutPath };\n}\n\n/** Best-effort cleanup of a fork's rollout file. Errors are logged, never thrown. */\nexport function cleanupAgentFork(handle: ForkHandle): void {\n try {\n if (existsSync(handle.rolloutPath)) {\n unlinkSync(handle.rolloutPath);\n }\n } catch (err) {\n logger.warn(\n { err, agent: handle.agent, forkId: handle.forkId, rolloutPath: handle.rolloutPath },\n \"cleanupAgentFork: failed to remove rollout\",\n );\n }\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;AAAA;AAuCA,eAAsB,gBAAgB,CAAC,MAAoD;AAAA,EACzF,QAAQ,QAAQ,gBAAgB,MAAM,YAAY,KAAK,KAAK,EAAE,YAAY;AAAA,IACxE,iBAAiB,KAAK;AAAA,IACtB,KAAK,KAAK;AAAA,IACV,QAAQ,KAAK;AAAA,IACb,WAAW,KAAK;AAAA,OACZ,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,OACtC,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,OACtC,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,EAC/C,CAAC;AAAA,EACD,OAAO,EAAE,OAAO,KAAK,OAAO,QAAQ,YAAY;AAAA;AAI3C,SAAS,gBAAgB,CAAC,QAA0B;AAAA,EACzD,IAAI;AAAA,IACF,IAAI,WAAW,OAAO,WAAW,GAAG;AAAA,MAClC,WAAW,OAAO,WAAW;AAAA,IAC/B;AAAA,IACA,OAAO,KAAK;AAAA,IACZ,OAAO,KACL,EAAE,KAAK,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,aAAa,OAAO,YAAY,GACnF,4CACF;AAAA;AAAA;",
|
|
8
|
-
"debugId": "391C8BC9C9E5158464756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|