negotium 0.6.13 → 0.6.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-helpers.js +2 -2
- package/dist/agent-helpers.js.map +2 -2
- package/dist/{chunk-sr48tc2c.js → chunk-q81bf70c.js} +2 -2
- package/dist/{chunk-sr48tc2c.js.map → chunk-q81bf70c.js.map} +2 -2
- package/dist/hosted-agent.js +2 -2
- package/dist/hosted-agent.js.map +2 -2
- package/dist/main.js +201 -8
- package/dist/main.js.map +6 -6
- package/dist/mcp-factories.js +2 -2
- package/dist/mcp-factories.js.map +2 -2
- package/dist/registry.js +1 -1
- package/dist/runtime/src/node-host.ts +8 -1
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -3708,7 +3708,7 @@ var exports_version = {};
|
|
|
3708
3708
|
__export(exports_version, {
|
|
3709
3709
|
NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
|
|
3710
3710
|
});
|
|
3711
|
-
var NEGOTIUM_VERSION = "0.6.
|
|
3711
|
+
var NEGOTIUM_VERSION = "0.6.15";
|
|
3712
3712
|
|
|
3713
3713
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
3714
3714
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -24195,6 +24195,7 @@ __export(exports_node_host, {
|
|
|
24195
24195
|
writeDecisionGraphSvg: () => writeDecisionGraphSvg,
|
|
24196
24196
|
upsertTopic: () => upsertTopic,
|
|
24197
24197
|
updateTopicSettings: () => updateTopicSettings,
|
|
24198
|
+
updateApiMessageText: () => updateApiMessageText,
|
|
24198
24199
|
topicService: () => topicService,
|
|
24199
24200
|
switchTopicModel: () => switchTopicModel,
|
|
24200
24201
|
switchTopicEffort: () => switchTopicEffort,
|
|
@@ -24215,6 +24216,8 @@ __export(exports_node_host, {
|
|
|
24215
24216
|
setFileHooks: () => setFileHooks,
|
|
24216
24217
|
setCuaRsMcpPort: () => setCuaRsMcpPort,
|
|
24217
24218
|
setBashrsCompletionSink: () => setBashrsCompletionSink,
|
|
24219
|
+
setApiTopicConfig: () => setApiTopicConfig,
|
|
24220
|
+
setApiMessageReactions: () => setApiMessageReactions,
|
|
24218
24221
|
saveVaultEntry: () => saveVaultEntry,
|
|
24219
24222
|
runtimeBus: () => runtimeBus,
|
|
24220
24223
|
runShutdown: () => runShutdown,
|
|
@@ -24245,6 +24248,7 @@ __export(exports_node_host, {
|
|
|
24245
24248
|
getPortableTopicVisual: () => getPortableTopicVisual,
|
|
24246
24249
|
getLastMessagePreviews: () => getLastMessagePreviews,
|
|
24247
24250
|
getGlobalAiName: () => getGlobalAiName,
|
|
24251
|
+
getApiTopicConfig: () => getApiTopicConfig,
|
|
24248
24252
|
getApiMessage: () => getApiMessage,
|
|
24249
24253
|
flushBashrsCompletions: () => flushBashrsCompletions,
|
|
24250
24254
|
executeVaultCommand: () => executeVaultCommand,
|
|
@@ -24300,6 +24304,7 @@ var init_node_host = __esm(async () => {
|
|
|
24300
24304
|
await init_turn_runner();
|
|
24301
24305
|
await init_visual_store();
|
|
24302
24306
|
await init_api_messages();
|
|
24307
|
+
await init_api_topic_config();
|
|
24303
24308
|
await init_api_topics();
|
|
24304
24309
|
await init_app_settings();
|
|
24305
24310
|
await init_decisions();
|
|
@@ -32804,6 +32809,8 @@ function createNodeControlHandler(options) {
|
|
|
32804
32809
|
"canonical-visual-read",
|
|
32805
32810
|
"canonical-topic-list",
|
|
32806
32811
|
"canonical-topic-create",
|
|
32812
|
+
"canonical-topic-create-config",
|
|
32813
|
+
"canonical-topic-config",
|
|
32807
32814
|
"canonical-topic-derive",
|
|
32808
32815
|
"canonical-manager-topic",
|
|
32809
32816
|
...process.env.NEGOTIUM_CRON === "0" ? [] : ["scheduler.cron.gateway.v1"],
|
|
@@ -33098,7 +33105,61 @@ function createNodeControlHandler(options) {
|
|
|
33098
33105
|
const result = listThreadMessages(topicId, rootId);
|
|
33099
33106
|
return Response.json({ ok: true, v: NODE_RUNTIME_CONTRACT_VERSION, ...result });
|
|
33100
33107
|
}
|
|
33108
|
+
const runtimeSystemMessageMatch = runtimePath.match(/^\/topics\/([^/]+)\/messages\/system$/);
|
|
33109
|
+
if (runtimeSystemMessageMatch && req.method === "POST") {
|
|
33110
|
+
const body = await bodyRecord(req);
|
|
33111
|
+
if (body.v !== NODE_RUNTIME_CONTRACT_VERSION)
|
|
33112
|
+
return jsonError(400, "Unsupported v");
|
|
33113
|
+
const topicId = decodeURIComponent(runtimeSystemMessageMatch[1]);
|
|
33114
|
+
const topic = getTopic(topicId);
|
|
33115
|
+
if (!topic || !topicInRequestScope(req, topic))
|
|
33116
|
+
return jsonError(404, "Topic not found");
|
|
33117
|
+
const text2 = requiredText(body.text, "text");
|
|
33118
|
+
const message = {
|
|
33119
|
+
id: randomUUID27(),
|
|
33120
|
+
topicId,
|
|
33121
|
+
authorId: "system",
|
|
33122
|
+
text: text2,
|
|
33123
|
+
kind: "system",
|
|
33124
|
+
createdAt: new Date().toISOString()
|
|
33125
|
+
};
|
|
33126
|
+
appendApiMessage(message, { notify: false });
|
|
33127
|
+
WsHub.get().broadcastMessage(topicId, message);
|
|
33128
|
+
return Response.json({ ok: true, v: NODE_RUNTIME_CONTRACT_VERSION, message });
|
|
33129
|
+
}
|
|
33101
33130
|
const runtimeMessageMatch = runtimePath.match(/^\/topics\/([^/]+)\/messages\/([^/]+)$/);
|
|
33131
|
+
if (runtimeMessageMatch && req.method === "PATCH") {
|
|
33132
|
+
const body = await bodyRecord(req);
|
|
33133
|
+
if (body.v !== NODE_RUNTIME_CONTRACT_VERSION)
|
|
33134
|
+
return jsonError(400, "Unsupported v");
|
|
33135
|
+
const topicId = decodeURIComponent(runtimeMessageMatch[1]);
|
|
33136
|
+
const messageId = decodeURIComponent(runtimeMessageMatch[2]);
|
|
33137
|
+
const topic = getTopic(topicId);
|
|
33138
|
+
if (!topic || !topicInRequestScope(req, topic))
|
|
33139
|
+
return jsonError(404, "Topic not found");
|
|
33140
|
+
const actorUserId = requiredText(body.actorUserId, "actorUserId");
|
|
33141
|
+
const text2 = requiredText(body.text, "text");
|
|
33142
|
+
if (body.allowAdmin !== undefined && typeof body.allowAdmin !== "boolean") {
|
|
33143
|
+
return jsonError(400, "allowAdmin must be boolean");
|
|
33144
|
+
}
|
|
33145
|
+
const existing = getApiMessage(topicId, messageId);
|
|
33146
|
+
if (!existing || existing.deleted)
|
|
33147
|
+
return jsonError(404, "Message not found");
|
|
33148
|
+
if (existing.authorId !== actorUserId && body.allowAdmin !== true) {
|
|
33149
|
+
return jsonError(403, "Not allowed");
|
|
33150
|
+
}
|
|
33151
|
+
const editedAt = new Date().toISOString();
|
|
33152
|
+
const message = updateApiMessageText(topicId, messageId, text2, editedAt);
|
|
33153
|
+
if (!message)
|
|
33154
|
+
return jsonError(404, "Message not found");
|
|
33155
|
+
WsHub.get().broadcastMessageUpdated(topicId, messageId, { text: text2, editedAt });
|
|
33156
|
+
return Response.json({
|
|
33157
|
+
ok: true,
|
|
33158
|
+
v: NODE_RUNTIME_CONTRACT_VERSION,
|
|
33159
|
+
message,
|
|
33160
|
+
previousText: existing.text
|
|
33161
|
+
});
|
|
33162
|
+
}
|
|
33102
33163
|
if (runtimeMessageMatch && req.method === "DELETE") {
|
|
33103
33164
|
const body = await bodyRecord(req);
|
|
33104
33165
|
if (body.v !== NODE_RUNTIME_CONTRACT_VERSION)
|
|
@@ -33128,6 +33189,45 @@ function createNodeControlHandler(options) {
|
|
|
33128
33189
|
message
|
|
33129
33190
|
});
|
|
33130
33191
|
}
|
|
33192
|
+
const runtimeReactionMatch = runtimePath.match(/^\/topics\/([^/]+)\/messages\/([^/]+)\/reactions$/);
|
|
33193
|
+
if (runtimeReactionMatch && req.method === "POST") {
|
|
33194
|
+
const body = await bodyRecord(req);
|
|
33195
|
+
if (body.v !== NODE_RUNTIME_CONTRACT_VERSION)
|
|
33196
|
+
return jsonError(400, "Unsupported v");
|
|
33197
|
+
const topicId = decodeURIComponent(runtimeReactionMatch[1]);
|
|
33198
|
+
const messageId = decodeURIComponent(runtimeReactionMatch[2]);
|
|
33199
|
+
const topic = getTopic(topicId);
|
|
33200
|
+
if (!topic || !topicInRequestScope(req, topic))
|
|
33201
|
+
return jsonError(404, "Topic not found");
|
|
33202
|
+
const actorUserId = requiredText(body.actorUserId, "actorUserId");
|
|
33203
|
+
const emoji = requiredText(body.emoji, "emoji");
|
|
33204
|
+
if (emoji.length > 16)
|
|
33205
|
+
return jsonError(400, "emoji is too long");
|
|
33206
|
+
if (body.actorName !== undefined && typeof body.actorName !== "string") {
|
|
33207
|
+
return jsonError(400, "actorName must be a string");
|
|
33208
|
+
}
|
|
33209
|
+
const existing = getApiMessage(topicId, messageId);
|
|
33210
|
+
if (!existing || existing.deleted)
|
|
33211
|
+
return jsonError(404, "Message not found");
|
|
33212
|
+
const current3 = existing.reactions ?? [];
|
|
33213
|
+
const hasReaction = current3.some((reaction) => reaction.emoji === emoji && reaction.userId === actorUserId);
|
|
33214
|
+
const reactions = hasReaction ? current3.filter((reaction) => !(reaction.emoji === emoji && reaction.userId === actorUserId)) : [
|
|
33215
|
+
...current3,
|
|
33216
|
+
{
|
|
33217
|
+
emoji,
|
|
33218
|
+
userId: actorUserId,
|
|
33219
|
+
userName: typeof body.actorName === "string" ? body.actorName : ""
|
|
33220
|
+
}
|
|
33221
|
+
];
|
|
33222
|
+
const message = setApiMessageReactions(topicId, messageId, reactions);
|
|
33223
|
+
if (!message)
|
|
33224
|
+
return jsonError(404, "Message not found");
|
|
33225
|
+
return Response.json({
|
|
33226
|
+
ok: true,
|
|
33227
|
+
v: NODE_RUNTIME_CONTRACT_VERSION,
|
|
33228
|
+
reactions: message.reactions ?? []
|
|
33229
|
+
});
|
|
33230
|
+
}
|
|
33131
33231
|
if (req.method === "GET" && runtimePath === "/topics") {
|
|
33132
33232
|
const topics = gatewayVisibleTopics(req);
|
|
33133
33233
|
const previews = getLastMessagePreviews(topics.map((topic) => topic.id));
|
|
@@ -33136,7 +33236,11 @@ function createNodeControlHandler(options) {
|
|
|
33136
33236
|
v: NODE_RUNTIME_CONTRACT_VERSION,
|
|
33137
33237
|
topics: topics.map((topic) => {
|
|
33138
33238
|
const preview = previews.get(topic.id);
|
|
33139
|
-
return
|
|
33239
|
+
return {
|
|
33240
|
+
...topic,
|
|
33241
|
+
config: getApiTopicConfig(topic.id) ?? {},
|
|
33242
|
+
...preview ? { lastMessagePreview: preview } : {}
|
|
33243
|
+
};
|
|
33140
33244
|
}),
|
|
33141
33245
|
cursor: latestRuntimeEventSeq()
|
|
33142
33246
|
});
|
|
@@ -33148,16 +33252,27 @@ function createNodeControlHandler(options) {
|
|
|
33148
33252
|
const userId = requiredText(body.userId, "userId");
|
|
33149
33253
|
const title = requiredText(body.title, "title");
|
|
33150
33254
|
const agent = body.agent;
|
|
33151
|
-
if (agent !== undefined && !["claude", "codex", "maestro"].includes(String(agent))) {
|
|
33255
|
+
if (agent !== undefined && agent !== null && !["none", "claude", "codex", "maestro"].includes(String(agent))) {
|
|
33152
33256
|
return jsonError(400, "Invalid agent");
|
|
33153
33257
|
}
|
|
33258
|
+
const kind = body.kind ?? "agent";
|
|
33259
|
+
if (kind !== "agent" && kind !== "channel")
|
|
33260
|
+
return jsonError(400, "Invalid kind");
|
|
33261
|
+
if (body.model !== undefined && typeof body.model !== "string") {
|
|
33262
|
+
return jsonError(400, "model must be a string");
|
|
33263
|
+
}
|
|
33264
|
+
if (body.effort !== undefined && !["low", "medium", "high", "xhigh", "max"].includes(String(body.effort))) {
|
|
33265
|
+
return jsonError(400, "Invalid effort");
|
|
33266
|
+
}
|
|
33154
33267
|
const topic = topicService.create({
|
|
33155
33268
|
title,
|
|
33156
33269
|
userId,
|
|
33157
|
-
kind
|
|
33270
|
+
kind,
|
|
33158
33271
|
surface: "otium",
|
|
33159
33272
|
...requestSurfaceScope(req),
|
|
33160
|
-
...agent ? { agent } : {}
|
|
33273
|
+
...agent === null || agent === "none" ? { agent: "none" } : agent ? { agent } : {},
|
|
33274
|
+
...typeof body.model === "string" ? { model: body.model } : {},
|
|
33275
|
+
...typeof body.effort === "string" ? { effort: body.effort } : {}
|
|
33161
33276
|
});
|
|
33162
33277
|
return Response.json({ ok: true, v: NODE_RUNTIME_CONTRACT_VERSION, topic }, { status: 201 });
|
|
33163
33278
|
}
|
|
@@ -33369,13 +33484,81 @@ function createNodeControlHandler(options) {
|
|
|
33369
33484
|
});
|
|
33370
33485
|
}
|
|
33371
33486
|
const runtimeTopicMatch = runtimePath.match(/^\/topics\/([^/]+)$/);
|
|
33487
|
+
const runtimeTopicConfigMatch = runtimePath.match(/^\/topics\/([^/]+)\/config$/);
|
|
33488
|
+
if (runtimeTopicConfigMatch && req.method === "GET") {
|
|
33489
|
+
const topicId = decodeURIComponent(runtimeTopicConfigMatch[1]);
|
|
33490
|
+
const topic = getTopic(topicId);
|
|
33491
|
+
if (!topic || !topicInRequestScope(req, topic))
|
|
33492
|
+
return jsonError(404, "Topic not found");
|
|
33493
|
+
return Response.json({
|
|
33494
|
+
ok: true,
|
|
33495
|
+
v: NODE_RUNTIME_CONTRACT_VERSION,
|
|
33496
|
+
topic,
|
|
33497
|
+
config: getApiTopicConfig(topicId) ?? {}
|
|
33498
|
+
});
|
|
33499
|
+
}
|
|
33500
|
+
if (runtimeTopicConfigMatch && req.method === "PATCH") {
|
|
33501
|
+
const body = await bodyRecord(req);
|
|
33502
|
+
if (body.v !== NODE_RUNTIME_CONTRACT_VERSION)
|
|
33503
|
+
return jsonError(400, "Unsupported v");
|
|
33504
|
+
const topicId = decodeURIComponent(runtimeTopicConfigMatch[1]);
|
|
33505
|
+
const topic = getTopic(topicId);
|
|
33506
|
+
if (!topic || !topicInRequestScope(req, topic))
|
|
33507
|
+
return jsonError(404, "Topic not found");
|
|
33508
|
+
const next = { ...getApiTopicConfig(topicId) ?? {} };
|
|
33509
|
+
for (const key of ["model", "effort"]) {
|
|
33510
|
+
if (!(key in body))
|
|
33511
|
+
continue;
|
|
33512
|
+
const value = body[key];
|
|
33513
|
+
if (value === null)
|
|
33514
|
+
delete next[key];
|
|
33515
|
+
else if (typeof value === "string" && value.trim()) {
|
|
33516
|
+
if (key === "effort" && !["low", "medium", "high", "xhigh", "max"].includes(value)) {
|
|
33517
|
+
return jsonError(400, "Invalid effort");
|
|
33518
|
+
}
|
|
33519
|
+
next[key] = value;
|
|
33520
|
+
} else
|
|
33521
|
+
return jsonError(400, `${key} must be a string or null`);
|
|
33522
|
+
}
|
|
33523
|
+
if ("mcp" in body) {
|
|
33524
|
+
if (body.mcp === null)
|
|
33525
|
+
delete next.mcp;
|
|
33526
|
+
else if (Array.isArray(body.mcp) && body.mcp.every((item) => typeof item === "string")) {
|
|
33527
|
+
next.mcp = [...new Set(body.mcp.map((item) => item.trim()).filter(Boolean))];
|
|
33528
|
+
} else
|
|
33529
|
+
return jsonError(400, "mcp must be an array of strings or null");
|
|
33530
|
+
}
|
|
33531
|
+
for (const key of ["agentLocked", "modelLocked", "effortLocked"]) {
|
|
33532
|
+
if (!(key in body))
|
|
33533
|
+
continue;
|
|
33534
|
+
const value = body[key];
|
|
33535
|
+
if (value === null || value === false)
|
|
33536
|
+
delete next[key];
|
|
33537
|
+
else if (value === true)
|
|
33538
|
+
next[key] = true;
|
|
33539
|
+
else
|
|
33540
|
+
return jsonError(400, `${key} must be a boolean or null`);
|
|
33541
|
+
}
|
|
33542
|
+
setApiTopicConfig(topicId, next);
|
|
33543
|
+
return Response.json({
|
|
33544
|
+
ok: true,
|
|
33545
|
+
v: NODE_RUNTIME_CONTRACT_VERSION,
|
|
33546
|
+
topic,
|
|
33547
|
+
config: getApiTopicConfig(topicId) ?? {}
|
|
33548
|
+
});
|
|
33549
|
+
}
|
|
33372
33550
|
if (runtimeTopicMatch && req.method === "GET") {
|
|
33373
33551
|
const topic = getTopic(decodeURIComponent(runtimeTopicMatch[1]));
|
|
33374
33552
|
if (topic && !topicInRequestScope(req, topic))
|
|
33375
33553
|
return jsonError(404, "Topic not found");
|
|
33376
33554
|
if (!topic)
|
|
33377
33555
|
return jsonError(404, "Topic not found");
|
|
33378
|
-
return Response.json({
|
|
33556
|
+
return Response.json({
|
|
33557
|
+
ok: true,
|
|
33558
|
+
v: NODE_RUNTIME_CONTRACT_VERSION,
|
|
33559
|
+
topic,
|
|
33560
|
+
config: getApiTopicConfig(topic.id) ?? {}
|
|
33561
|
+
});
|
|
33379
33562
|
}
|
|
33380
33563
|
if (runtimeTopicMatch && req.method === "DELETE") {
|
|
33381
33564
|
const topicId = decodeURIComponent(runtimeTopicMatch[1]);
|
|
@@ -46914,7 +47097,9 @@ function allowedRuntimePath(path, method) {
|
|
|
46914
47097
|
return true;
|
|
46915
47098
|
if (path === "/cron/scripts" || path === "/cron/jobs")
|
|
46916
47099
|
return true;
|
|
46917
|
-
if (/^\/topics\/[^/]+(\/messages|\/usage)?$/.test(path))
|
|
47100
|
+
if (/^\/topics\/[^/]+(\/messages|\/usage|\/config)?$/.test(path))
|
|
47101
|
+
return true;
|
|
47102
|
+
if (/^\/topics\/[^/]+\/messages\/[^/]+\/thread$/.test(path))
|
|
46918
47103
|
return true;
|
|
46919
47104
|
if (/^\/topics\/[^/]+\/files\/[^/]+$/.test(path))
|
|
46920
47105
|
return true;
|
|
@@ -46929,11 +47114,19 @@ function allowedRuntimePath(path, method) {
|
|
|
46929
47114
|
return true;
|
|
46930
47115
|
if (/^\/topics\/[^/]+\/messages\/[^/]+\/ask-answer$/.test(path))
|
|
46931
47116
|
return true;
|
|
47117
|
+
if (/^\/topics\/[^/]+\/messages\/system$/.test(path))
|
|
47118
|
+
return true;
|
|
47119
|
+
if (/^\/topics\/[^/]+\/messages\/[^/]+\/reactions$/.test(path))
|
|
47120
|
+
return true;
|
|
46932
47121
|
return /^\/topics\/[^/]+\/(abort|session\/(reset|compact))$/.test(path);
|
|
46933
47122
|
}
|
|
46934
47123
|
if (method === "DELETE" || method === "PATCH") {
|
|
46935
47124
|
if (method === "DELETE" && /^\/topics\/[^/]+\/messages\/[^/]+$/.test(path))
|
|
46936
47125
|
return true;
|
|
47126
|
+
if (method === "PATCH" && /^\/topics\/[^/]+\/messages\/[^/]+$/.test(path))
|
|
47127
|
+
return true;
|
|
47128
|
+
if (method === "PATCH" && /^\/topics\/[^/]+\/config$/.test(path))
|
|
47129
|
+
return true;
|
|
46937
47130
|
return /^\/topics\/[^/]+$/.test(path) || /^\/cron\/jobs\/[^/]+$/.test(path);
|
|
46938
47131
|
}
|
|
46939
47132
|
return false;
|
|
@@ -48984,4 +49177,4 @@ switch (command) {
|
|
|
48984
49177
|
}
|
|
48985
49178
|
}
|
|
48986
49179
|
|
|
48987
|
-
//# debugId=
|
|
49180
|
+
//# debugId=B2409FC66A8292B364756E2164756E21
|