negotium 0.6.5 → 0.6.7
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 +193 -172
- package/dist/agent-helpers.js.map +13 -13
- package/dist/{chunk-rzef19v4.js → chunk-f124y9d0.js} +2 -2
- package/dist/{chunk-rzef19v4.js.map → chunk-f124y9d0.js.map} +2 -2
- package/dist/hosted-agent.js +2 -2
- package/dist/hosted-agent.js.map +2 -2
- package/dist/main.js +126 -41
- package/dist/main.js.map +18 -18
- package/dist/mcp-factories.js +45 -24
- package/dist/mcp-factories.js.map +11 -11
- package/dist/registry.js +1 -1
- package/dist/runtime/src/agents/archiver.ts +68 -32
- package/dist/runtime/src/agents/idle-archiver.ts +1 -0
- package/dist/runtime/src/application/topic-service.ts +5 -1
- package/dist/runtime/src/index.ts +1 -1
- package/dist/runtime/src/mcp-runtime-host.ts +1 -1
- package/dist/runtime/src/platform/constants.ts +12 -0
- package/dist/runtime/src/runtime/turn-event-stream.ts +2 -1
- package/dist/runtime/src/runtime/turn-runner.ts +8 -1
- package/dist/runtime/src/runtime-gateway.ts +6 -2
- package/dist/runtime/src/storage/conversations.ts +24 -4
- package/dist/runtime/src/topics/lifecycle.ts +4 -1
- package/dist/runtime/src/topics/session.ts +15 -9
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-gateway.js +7 -6
- package/dist/runtime-gateway.js.map +3 -3
- package/dist/storage.js +12 -4
- package/dist/storage.js.map +4 -4
- package/dist/types/packages/core/src/agents/archiver.d.ts +7 -2
- package/dist/types/packages/core/src/platform/constants.d.ts +10 -0
- package/dist/types/packages/core/src/runtime/turn-event-stream.d.ts +1 -0
- package/dist/types/packages/core/src/runtime/turn-runner.d.ts +1 -0
- package/dist/types/packages/core/src/runtime-gateway.d.ts +2 -2
- package/dist/types/packages/core/src/storage/conversations.d.ts +3 -0
- package/dist/types/packages/core/src/topics/lifecycle.d.ts +2 -0
- package/dist/types/packages/core/src/topics/session.d.ts +2 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -3674,7 +3674,7 @@ var exports_version = {};
|
|
|
3674
3674
|
__export(exports_version, {
|
|
3675
3675
|
NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
|
|
3676
3676
|
});
|
|
3677
|
-
var NEGOTIUM_VERSION = "0.6.
|
|
3677
|
+
var NEGOTIUM_VERSION = "0.6.7";
|
|
3678
3678
|
|
|
3679
3679
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
3680
3680
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -4519,6 +4519,16 @@ var init_task_events = __esm(async () => {
|
|
|
4519
4519
|
defaultTaskEventHost = { readTasks, taskFileMtimeNs, taskScopeKey };
|
|
4520
4520
|
});
|
|
4521
4521
|
|
|
4522
|
+
// ../../packages/core/src/platform/constants.ts
|
|
4523
|
+
var FROM_AUTO_CONTINUE = "auto-continue", FROM_SELF_SCHEDULE = "self-schedule", RESERVED_TOPIC_NAMES, GENERAL_TOPIC_ID = "general", MANAGER_TOPIC_LOG_NAME = "general", NODE_LOCAL_USER_ID = "local";
|
|
4524
|
+
var init_constants = __esm(() => {
|
|
4525
|
+
RESERVED_TOPIC_NAMES = new Set([
|
|
4526
|
+
FROM_AUTO_CONTINUE,
|
|
4527
|
+
FROM_SELF_SCHEDULE,
|
|
4528
|
+
"general"
|
|
4529
|
+
]);
|
|
4530
|
+
});
|
|
4531
|
+
|
|
4522
4532
|
// ../../packages/core/src/storage/conversations.ts
|
|
4523
4533
|
var exports_conversations = {};
|
|
4524
4534
|
__export(exports_conversations, {
|
|
@@ -4548,12 +4558,15 @@ import { dirname as dirname8, join as join13 } from "path";
|
|
|
4548
4558
|
function conversationDir(_userId) {
|
|
4549
4559
|
return join13(resolveStorageDataDir(), "conversations");
|
|
4550
4560
|
}
|
|
4551
|
-
function topicFilename(topicName) {
|
|
4561
|
+
function topicFilename(userId, topicName) {
|
|
4552
4562
|
const t = sanitizeTopicName(topicName, true);
|
|
4553
|
-
|
|
4563
|
+
const owner = String(userId);
|
|
4564
|
+
if (t !== MANAGER_TOPIC_LOG_NAME || owner === NODE_LOCAL_USER_ID)
|
|
4565
|
+
return `${t}.jsonl`;
|
|
4566
|
+
return `${t}.${sanitizeId(owner)}.jsonl`;
|
|
4554
4567
|
}
|
|
4555
4568
|
function getConversationPath(userId, topicName) {
|
|
4556
|
-
return join13(conversationDir(userId), topicFilename(topicName));
|
|
4569
|
+
return join13(conversationDir(userId), topicFilename(userId, topicName));
|
|
4557
4570
|
}
|
|
4558
4571
|
function getActiveConversationPath(userId, topicName) {
|
|
4559
4572
|
const rawPath = getConversationPath(userId, topicName);
|
|
@@ -4687,6 +4700,7 @@ function findLastSessionIdForAgent(entries, agent) {
|
|
|
4687
4700
|
}
|
|
4688
4701
|
var ConversationLogDivergedError;
|
|
4689
4702
|
var init_conversations = __esm(async () => {
|
|
4703
|
+
init_constants();
|
|
4690
4704
|
init_jsonl();
|
|
4691
4705
|
init_logger();
|
|
4692
4706
|
await init_storage_host();
|
|
@@ -7769,16 +7783,6 @@ var init_api_topic_config = __esm(async () => {
|
|
|
7769
7783
|
registerStorageSchemaInitializer(initializeApiTopicConfigSchema, 40);
|
|
7770
7784
|
});
|
|
7771
7785
|
|
|
7772
|
-
// ../../packages/core/src/platform/constants.ts
|
|
7773
|
-
var FROM_AUTO_CONTINUE = "auto-continue", FROM_SELF_SCHEDULE = "self-schedule", RESERVED_TOPIC_NAMES, GENERAL_TOPIC_ID = "general";
|
|
7774
|
-
var init_constants = __esm(() => {
|
|
7775
|
-
RESERVED_TOPIC_NAMES = new Set([
|
|
7776
|
-
FROM_AUTO_CONTINUE,
|
|
7777
|
-
FROM_SELF_SCHEDULE,
|
|
7778
|
-
"general"
|
|
7779
|
-
]);
|
|
7780
|
-
});
|
|
7781
|
-
|
|
7782
7786
|
// ../../packages/core/src/storage/api-topics.ts
|
|
7783
7787
|
var exports_api_topics = {};
|
|
7784
7788
|
__export(exports_api_topics, {
|
|
@@ -12475,6 +12479,7 @@ function createArchiverRuntime(host) {
|
|
|
12475
12479
|
const runTurn = (params) => {
|
|
12476
12480
|
const {
|
|
12477
12481
|
userId,
|
|
12482
|
+
sourceTopicId,
|
|
12478
12483
|
topicId,
|
|
12479
12484
|
topicTitle,
|
|
12480
12485
|
archivePath,
|
|
@@ -12482,6 +12487,7 @@ function createArchiverRuntime(host) {
|
|
|
12482
12487
|
messageCount,
|
|
12483
12488
|
mode = "deleted-topic"
|
|
12484
12489
|
} = params;
|
|
12490
|
+
const generalTopicId = host.storage.getGeneralTopicId(userId, sourceTopicId);
|
|
12485
12491
|
let definition;
|
|
12486
12492
|
try {
|
|
12487
12493
|
definition = getAgentDefinition();
|
|
@@ -12494,12 +12500,15 @@ function createArchiverRuntime(host) {
|
|
|
12494
12500
|
const agent = params.agent ?? "claude";
|
|
12495
12501
|
const model = params.model;
|
|
12496
12502
|
const outputLanguage = resolveMemoryLanguage();
|
|
12503
|
+
const generalReplyInstruction = `Reply with a short completion message in ${outputLanguage} for display in #General. ` + "Do not include tool-call logs or raw transcripts \u2014 just briefly name the summary / brief / articles you saved.";
|
|
12497
12504
|
const prompt = mode === "active-topic" ? [
|
|
12498
12505
|
`Recent idle conversation snapshot of session "${topicTitle}". Extract durable memory from the archive below and save it into this topic's wiki.`,
|
|
12499
12506
|
`archive_path: ${archivePath}`,
|
|
12500
12507
|
...rawArchivePaths.map((path) => `raw_archive_path: ${path}`),
|
|
12501
12508
|
`wiki_dir: ${wikiDir}`,
|
|
12502
|
-
`output_language: ${outputLanguage}
|
|
12509
|
+
`output_language: ${outputLanguage}`,
|
|
12510
|
+
"",
|
|
12511
|
+
generalReplyInstruction
|
|
12503
12512
|
].join(`
|
|
12504
12513
|
`) : [
|
|
12505
12514
|
`Session "${topicTitle}" was deleted. Extract durable memory from the archive below and save it into the wiki.`,
|
|
@@ -12508,7 +12517,7 @@ function createArchiverRuntime(host) {
|
|
|
12508
12517
|
`wiki_dir: ${wikiDir}`,
|
|
12509
12518
|
`output_language: ${outputLanguage}`,
|
|
12510
12519
|
"",
|
|
12511
|
-
|
|
12520
|
+
generalReplyInstruction
|
|
12512
12521
|
].join(`
|
|
12513
12522
|
`);
|
|
12514
12523
|
const activeSessionId = `memory:${host.config.createId()}`;
|
|
@@ -12636,10 +12645,8 @@ function createArchiverRuntime(host) {
|
|
|
12636
12645
|
host.config.warn({ err, userId, topicTitle }, "archiver: settlement callback failed");
|
|
12637
12646
|
}
|
|
12638
12647
|
}
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs, ok, topicId, ok && text ? { text, agent, model, usage } : undefined);
|
|
12642
|
-
}
|
|
12648
|
+
const text = finalText.trimEnd();
|
|
12649
|
+
finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs, ok, mode, topicId, generalTopicId, ok && text ? { text, agent, model, usage } : undefined);
|
|
12643
12650
|
});
|
|
12644
12651
|
topicQueues.set(safeTopic, work);
|
|
12645
12652
|
work.finally(() => {
|
|
@@ -12685,14 +12692,14 @@ function findSummaryFile(storage, topicTitle, date, sinceMs, topicId) {
|
|
|
12685
12692
|
}
|
|
12686
12693
|
return best?.path ?? null;
|
|
12687
12694
|
}
|
|
12688
|
-
function finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs, ok, topicId, generalReply) {
|
|
12689
|
-
const
|
|
12695
|
+
function finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs, ok, mode, topicId, generalTopicId, generalReply) {
|
|
12696
|
+
const resolvedGeneralTopicId = generalTopicId ?? host.storage.getGeneralTopicId(userId, topicId);
|
|
12690
12697
|
const date = host.config.now().toISOString().slice(0, 10);
|
|
12691
12698
|
try {
|
|
12692
12699
|
const summaryPath = ok ? findSummaryFile(host.storage, topicTitle, date, startMs, topicId) : null;
|
|
12693
12700
|
const summaryMd = summaryPath ? host.storage.readTextFile(summaryPath) : "";
|
|
12694
12701
|
const oneLine = summaryMd && distillOneLine(summaryMd) || `Archived ${messageCount} messages`;
|
|
12695
|
-
const prev = host.storage.getTopicBrief(
|
|
12702
|
+
const prev = host.storage.getTopicBrief(resolvedGeneralTopicId);
|
|
12696
12703
|
const prevEntries = (prev?.briefMd ?? "").split(`
|
|
12697
12704
|
`).map((l) => l.trim()).filter((l) => l.startsWith("- "));
|
|
12698
12705
|
const newEntry = `- **${topicTitle}** (${date}): ${oneLine}`;
|
|
@@ -12702,12 +12709,12 @@ function finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs,
|
|
|
12702
12709
|
].slice(0, MAX_BRIEF_ENTRIES);
|
|
12703
12710
|
const briefMd = `# Workspace Memory Hub
|
|
12704
12711
|
|
|
12705
|
-
Recent memory digest distilled from
|
|
12712
|
+
Recent memory digest distilled from archived topics (deletions and idle/session-reset snapshots). Use \`wiki_query\` for details.
|
|
12706
12713
|
|
|
12707
12714
|
## Recent Archives
|
|
12708
12715
|
${rolled.join(`
|
|
12709
12716
|
`)}`;
|
|
12710
|
-
host.storage.setTopicBrief(
|
|
12717
|
+
host.storage.setTopicBrief(resolvedGeneralTopicId, {
|
|
12711
12718
|
briefMd,
|
|
12712
12719
|
...summaryMd ? { latestSummaryMd: summaryMd, summaryDate: date } : {}
|
|
12713
12720
|
});
|
|
@@ -12717,7 +12724,7 @@ ${rolled.join(`
|
|
|
12717
12724
|
}
|
|
12718
12725
|
try {
|
|
12719
12726
|
const replyText = generalReply?.text.trim();
|
|
12720
|
-
const text = replyText || (ok ? `\uD83D\uDDC2 Topic "${topicTitle}" was deleted and archived into #General memory.` : `\uD83D\uDDC2 Archived topic "${topicTitle}" (summary extraction failed \u2014 raw log preserved in wiki/archive).`);
|
|
12727
|
+
const text = replyText || (mode === "deleted-topic" ? ok ? `\uD83D\uDDC2 Topic "${topicTitle}" was deleted and archived into #General memory.` : `\uD83D\uDDC2 Archived topic "${topicTitle}" (summary extraction failed \u2014 raw log preserved in wiki/archive).` : ok ? `\uD83D\uDDC2 Session "${topicTitle}" was snapshotted and archived into #General memory.` : `\uD83D\uDDC2 Archived a snapshot of "${topicTitle}" (summary extraction failed \u2014 raw log preserved in wiki/archive).`);
|
|
12721
12728
|
const replyMeta = generalReply && replyText ? {
|
|
12722
12729
|
authorId: "ai",
|
|
12723
12730
|
agentType: generalReply.agent,
|
|
@@ -12726,13 +12733,13 @@ ${rolled.join(`
|
|
|
12726
12733
|
} : { authorId: "system" };
|
|
12727
12734
|
const msg = {
|
|
12728
12735
|
id: host.config.createId(),
|
|
12729
|
-
topicId:
|
|
12736
|
+
topicId: resolvedGeneralTopicId,
|
|
12730
12737
|
text,
|
|
12731
12738
|
...replyMeta,
|
|
12732
12739
|
createdAt: host.config.now().toISOString()
|
|
12733
12740
|
};
|
|
12734
12741
|
host.messaging.appendMessage(msg);
|
|
12735
|
-
host.messaging.broadcastMessage(
|
|
12742
|
+
host.messaging.broadcastMessage(resolvedGeneralTopicId, msg);
|
|
12736
12743
|
} catch (err) {
|
|
12737
12744
|
host.config.warn({ err, topicTitle }, "archiver: failed to post #General notification");
|
|
12738
12745
|
}
|
|
@@ -12754,6 +12761,7 @@ var init_archiver = __esm(async () => {
|
|
|
12754
12761
|
init_background_session_policy();
|
|
12755
12762
|
await init_api_messages();
|
|
12756
12763
|
await init_api_topic_brief();
|
|
12764
|
+
await init_api_topics();
|
|
12757
12765
|
await init_wiki();
|
|
12758
12766
|
init_wiki_summary_names();
|
|
12759
12767
|
await init_personal_general();
|
|
@@ -12765,7 +12773,12 @@ var init_archiver = __esm(async () => {
|
|
|
12765
12773
|
readTextFile: (path) => readFileSync14(path, "utf-8"),
|
|
12766
12774
|
fileSize: (path) => statSync7(path).size,
|
|
12767
12775
|
fileModifiedAt: (path) => statSync7(path).mtimeMs,
|
|
12768
|
-
getGeneralTopicId: (userId) =>
|
|
12776
|
+
getGeneralTopicId: (userId, sourceTopicId) => {
|
|
12777
|
+
const source = sourceTopicId ? getTopic(sourceTopicId) : null;
|
|
12778
|
+
return source ? ensurePersonalGeneral(userId, source.surface, {
|
|
12779
|
+
surfaceScope: source.surfaceScope ?? null
|
|
12780
|
+
}).id : ensurePersonalGeneral(userId).id;
|
|
12781
|
+
},
|
|
12769
12782
|
getTopicBrief,
|
|
12770
12783
|
setTopicBrief: (topicId, fields) => {
|
|
12771
12784
|
setTopicBrief(topicId, fields);
|
|
@@ -13265,6 +13278,7 @@ function archiveActiveTopicForMemory(topicId, userId, options) {
|
|
|
13265
13278
|
const memoryTitle = memoryTopic.memoryKey?.trim() || memoryTopic.title;
|
|
13266
13279
|
const launched = (options.launchArchiver ?? runArchiverTurn)({
|
|
13267
13280
|
userId,
|
|
13281
|
+
sourceTopicId: topic.id,
|
|
13268
13282
|
topicId: memoryTopic.id,
|
|
13269
13283
|
topicTitle: memoryTitle,
|
|
13270
13284
|
archivePath: job.archivePath,
|
|
@@ -14069,7 +14083,7 @@ async function restartTopicSession(topicId, userId, reason = "topic-session-rest
|
|
|
14069
14083
|
const memoryArchiveSettled = new Promise((resolve15) => {
|
|
14070
14084
|
settleMemoryArchive = resolve15;
|
|
14071
14085
|
});
|
|
14072
|
-
const archiveStatus = (options.archiveMemory ?? archiveActiveTopicForMemory)(topicId, userId, {
|
|
14086
|
+
const archiveStatus = (options.archiveMemory ?? archiveActiveTopicForMemory)(topicId, options.memoryUserId ?? userId, {
|
|
14073
14087
|
reason: "reset",
|
|
14074
14088
|
minMessages: 1,
|
|
14075
14089
|
minExchanges: MIN_MEMORY_ARCHIVE_EXCHANGES,
|
|
@@ -17060,7 +17074,8 @@ async function deleteTopicCascadeImpl(topic, userId, options, deletingAncestorId
|
|
|
17060
17074
|
const memoryTopic = topic.memoryKey ? topic : getTopicMemoryOrigin(topicId) ?? topic;
|
|
17061
17075
|
const memoryTitle = memoryTopic.memoryKey?.trim() || memoryTopic.title;
|
|
17062
17076
|
runArchiverTurn({
|
|
17063
|
-
userId,
|
|
17077
|
+
userId: options.memoryUserId ?? userId,
|
|
17078
|
+
sourceTopicId: topicId,
|
|
17064
17079
|
...memoryTopic.id !== topicId && !deletingTopicIds.has(memoryTopic.id) ? { topicId: memoryTopic.id } : {},
|
|
17065
17080
|
topicTitle: memoryTitle,
|
|
17066
17081
|
archivePath: archived.path,
|
|
@@ -18330,7 +18345,7 @@ ${JSON.stringify(event.input ?? {})}`);
|
|
|
18330
18345
|
}
|
|
18331
18346
|
}
|
|
18332
18347
|
if (!silent) {
|
|
18333
|
-
scheduleIdleArchiveForTopic(topicId, userId);
|
|
18348
|
+
scheduleIdleArchiveForTopic(topicId, execution?.actorUserId ?? userId);
|
|
18334
18349
|
hub.broadcastDone(topicId, queryId, event.usage ? {
|
|
18335
18350
|
input: event.usage.inputTokens,
|
|
18336
18351
|
output: event.usage.outputTokens,
|
|
@@ -19716,7 +19731,13 @@ function startAiTurn(params) {
|
|
|
19716
19731
|
WsHub.get().broadcastTyping(topicId, "ai");
|
|
19717
19732
|
WsHub.get().broadcastAiActive(topicId, queryId);
|
|
19718
19733
|
}
|
|
19719
|
-
streamAgentEvents(topicId, topic.title, queryId, events, control, agentKind, resolvedModel, resolvedEffort, userId, !sessionRetried, onSessionId, {
|
|
19734
|
+
streamAgentEvents(topicId, topic.title, queryId, events, control, agentKind, resolvedModel, resolvedEffort, userId, !sessionRetried, onSessionId, {
|
|
19735
|
+
silent,
|
|
19736
|
+
actorUserId: params.actorUserId,
|
|
19737
|
+
peerBridge,
|
|
19738
|
+
sourceNode,
|
|
19739
|
+
...threadRootId ? { threadRootId } : {}
|
|
19740
|
+
}).then(async (streamOutcome) => {
|
|
19720
19741
|
let outcome = streamOutcome;
|
|
19721
19742
|
if (outcome.kind === "session-expired") {
|
|
19722
19743
|
const retry = resolveSessionRetry({
|
|
@@ -21401,6 +21422,7 @@ var init_topic_service = __esm(async () => {
|
|
|
21401
21422
|
}
|
|
21402
21423
|
await deleteTopicCascade(topic, params.userId, {
|
|
21403
21424
|
...params.force !== undefined ? { force: params.force } : {},
|
|
21425
|
+
...params.memoryUserId !== undefined ? { memoryUserId: params.memoryUserId } : {},
|
|
21404
21426
|
...params.allowManager !== undefined ? { allowManager: params.allowManager } : {},
|
|
21405
21427
|
...params.skipArchive !== undefined ? { skipArchive: params.skipArchive } : {},
|
|
21406
21428
|
...params.purgeLogs !== undefined ? { purgeLogs: params.purgeLogs } : {}
|
|
@@ -21408,7 +21430,9 @@ var init_topic_service = __esm(async () => {
|
|
|
21408
21430
|
},
|
|
21409
21431
|
async reset(params) {
|
|
21410
21432
|
ownerTopic(params.topicId, params.userId);
|
|
21411
|
-
return restartTopicSession(params.topicId, params.userId, params.reason
|
|
21433
|
+
return restartTopicSession(params.topicId, params.userId, params.reason, {
|
|
21434
|
+
memoryUserId: params.actorUserId
|
|
21435
|
+
});
|
|
21412
21436
|
},
|
|
21413
21437
|
async compact(params) {
|
|
21414
21438
|
ownerTopic(params.topicId, params.userId);
|
|
@@ -23679,6 +23703,7 @@ __export(exports_src, {
|
|
|
23679
23703
|
PROCESS_LEASE_STALE_MS: () => PROCESS_LEASE_STALE_MS,
|
|
23680
23704
|
PROCESS_LEASE_HEARTBEAT_MS: () => PROCESS_LEASE_HEARTBEAT_MS,
|
|
23681
23705
|
OPTIONAL_FORUM_MCP_SERVERS: () => OPTIONAL_FORUM_MCP_SERVERS,
|
|
23706
|
+
NODE_LOCAL_USER_ID: () => NODE_LOCAL_USER_ID,
|
|
23682
23707
|
NODE_CONTROL_TOKEN: () => NODE_CONTROL_TOKEN,
|
|
23683
23708
|
NEGOTIUM_VERSION: () => NEGOTIUM_VERSION,
|
|
23684
23709
|
NEGOTIUM_PORT: () => NEGOTIUM_PORT,
|
|
@@ -24509,6 +24534,7 @@ __export(exports_mcp_runtime_host, {
|
|
|
24509
24534
|
RUNTIME_MCP_BASE_PATH: () => RUNTIME_MCP_BASE_PATH,
|
|
24510
24535
|
REQUIRED_FORUM_MCP_SERVERS: () => REQUIRED_FORUM_MCP_SERVERS,
|
|
24511
24536
|
OPTIONAL_FORUM_MCP_SERVERS: () => OPTIONAL_FORUM_MCP_SERVERS,
|
|
24537
|
+
NODE_LOCAL_USER_ID: () => NODE_LOCAL_USER_ID,
|
|
24512
24538
|
HOSTED_MCP_SURFACES: () => HOSTED_MCP_SURFACES,
|
|
24513
24539
|
FROM_AUTO_CONTINUE: () => FROM_AUTO_CONTINUE,
|
|
24514
24540
|
EFFORT_VALUES: () => EFFORT_VALUES
|
|
@@ -24549,12 +24575,31 @@ import { z as z6 } from "zod";
|
|
|
24549
24575
|
function callerSurface(ctx) {
|
|
24550
24576
|
return getTopic(ctx.topicId)?.surface ?? defaultTopicSurface();
|
|
24551
24577
|
}
|
|
24578
|
+
function callerSurfaceScope(ctx) {
|
|
24579
|
+
return getTopic(ctx.topicId)?.surfaceScope ?? null;
|
|
24580
|
+
}
|
|
24581
|
+
function topicsForCaller(ctx) {
|
|
24582
|
+
const surface = callerSurface(ctx);
|
|
24583
|
+
if (surface !== "otium") {
|
|
24584
|
+
return getTopics({ surface }).filter((topic) => isParticipant(topic, ctx.userId));
|
|
24585
|
+
}
|
|
24586
|
+
return getTopics({ surface, surfaceScope: callerSurfaceScope(ctx) }).filter((topic) => topic.kind !== "manager" || topic.id === ctx.topicId || isParticipant(topic, ctx.userId));
|
|
24587
|
+
}
|
|
24552
24588
|
function resolveTopicForUser(ctx, ref) {
|
|
24553
24589
|
const trimmed = ref.trim();
|
|
24554
24590
|
if (!trimmed)
|
|
24555
24591
|
return { error: "Error: topic is required." };
|
|
24556
24592
|
const notFound = `Error: topic '${trimmed}' not found (or not uniquely named). Use list_topics to see available topics.`;
|
|
24557
24593
|
const surface = callerSurface(ctx);
|
|
24594
|
+
if (surface === "otium") {
|
|
24595
|
+
const visible = topicsForCaller(ctx);
|
|
24596
|
+
const byId2 = visible.find((topic) => topic.id === trimmed);
|
|
24597
|
+
if (byId2)
|
|
24598
|
+
return { topic: byId2 };
|
|
24599
|
+
const wanted = trimmed.toLowerCase();
|
|
24600
|
+
const byTitle2 = visible.filter((topic) => topic.title.toLowerCase() === wanted);
|
|
24601
|
+
return byTitle2.length === 1 ? { topic: byTitle2[0] } : { error: notFound };
|
|
24602
|
+
}
|
|
24558
24603
|
const byId = getTopic(trimmed);
|
|
24559
24604
|
if (byId) {
|
|
24560
24605
|
if (!isParticipant(byId, ctx.userId) || byId.surface !== surface)
|
|
@@ -24566,6 +24611,12 @@ function resolveTopicForUser(ctx, ref) {
|
|
|
24566
24611
|
return { topic: byTitle };
|
|
24567
24612
|
return { error: notFound };
|
|
24568
24613
|
}
|
|
24614
|
+
function actingUserFor(ctx, target) {
|
|
24615
|
+
const owner = target.participants.find((p) => p.role === "owner")?.userId;
|
|
24616
|
+
if (callerSurface(ctx) !== "otium" || owner !== NODE_LOCAL_USER_ID)
|
|
24617
|
+
return ctx.userId;
|
|
24618
|
+
return owner;
|
|
24619
|
+
}
|
|
24569
24620
|
function describeTopic(topic) {
|
|
24570
24621
|
const running = getRoomQuery(topic.id) ? "turn running" : "idle";
|
|
24571
24622
|
const agent = topic.agent ? `agent: ${topic.agent}` : "no agent";
|
|
@@ -24604,8 +24655,8 @@ function registerNodeTools(server, ctx) {
|
|
|
24604
24655
|
return errorResult(`Error: failed to register topic: ${errMsg(err2)}`);
|
|
24605
24656
|
}
|
|
24606
24657
|
});
|
|
24607
|
-
server.tool("list_topics", "List the
|
|
24608
|
-
const topics =
|
|
24658
|
+
server.tool("list_topics", "List the topics this turn can reach on this negotium node: title, id, kind, agent, and whether a turn is currently running.", {}, async () => {
|
|
24659
|
+
const topics = topicsForCaller(ctx);
|
|
24609
24660
|
if (topics.length === 0) {
|
|
24610
24661
|
return textResult("No topics found. Use register_topic to create one.");
|
|
24611
24662
|
}
|
|
@@ -24650,7 +24701,7 @@ function registerNodeTools(server, ctx) {
|
|
|
24650
24701
|
if (target.kind === "manager") {
|
|
24651
24702
|
return errorResult("Error: manager rooms are system-managed and cannot be restarted.");
|
|
24652
24703
|
}
|
|
24653
|
-
const result = await restartTopicSession(target.id, ctx
|
|
24704
|
+
const result = await restartTopicSession(target.id, actingUserFor(ctx, target), "runtime-mcp-session-reset");
|
|
24654
24705
|
return result.isError ? errorResult(`Error: ${result.text}`) : textResult(result.text);
|
|
24655
24706
|
});
|
|
24656
24707
|
server.tool("delete_topic", "Delete a topic owned by the calling user after archiving its conversation history. Deletion is blocked " + "when the archive cannot be written; pass force: true only as an explicit escape hatch that accepts losing history.", {
|
|
@@ -24667,12 +24718,13 @@ function registerNodeTools(server, ctx) {
|
|
|
24667
24718
|
if (target.kind === "manager") {
|
|
24668
24719
|
return errorResult("Error: manager rooms are system-managed and cannot be deleted.");
|
|
24669
24720
|
}
|
|
24670
|
-
const
|
|
24721
|
+
const actingUser = actingUserFor(ctx, target);
|
|
24722
|
+
const isOwner = target.participants.some((participant) => participant.userId === actingUser && participant.role === "owner");
|
|
24671
24723
|
if (!isOwner) {
|
|
24672
24724
|
return errorResult("Error: only the topic owner can delete it.");
|
|
24673
24725
|
}
|
|
24674
24726
|
try {
|
|
24675
|
-
await deleteTopicCascade(target,
|
|
24727
|
+
await deleteTopicCascade(target, actingUser, { force: force === true });
|
|
24676
24728
|
} catch (err2) {
|
|
24677
24729
|
if (err2 instanceof TopicArchiveRequiredError) {
|
|
24678
24730
|
return errorResult([
|
|
@@ -32877,6 +32929,34 @@ function createNodeControlHandler(options) {
|
|
|
32877
32929
|
});
|
|
32878
32930
|
return Response.json({ ok: true, v: NODE_RUNTIME_CONTRACT_VERSION, topic }, { status: 201 });
|
|
32879
32931
|
}
|
|
32932
|
+
const runtimeDeriveMatch = runtimePath.match(/^\/topics\/([^/]+)\/derive$/);
|
|
32933
|
+
if (runtimeDeriveMatch && req.method === "POST") {
|
|
32934
|
+
const body = await bodyRecord(req);
|
|
32935
|
+
if (body.v !== NODE_RUNTIME_CONTRACT_VERSION)
|
|
32936
|
+
return jsonError(400, "Unsupported v");
|
|
32937
|
+
const topicId = decodeURIComponent(runtimeDeriveMatch[1]);
|
|
32938
|
+
const userId = requiredText(body.userId, "userId");
|
|
32939
|
+
if (typeof body.copyHistory !== "boolean") {
|
|
32940
|
+
return jsonError(400, "copyHistory must be a boolean");
|
|
32941
|
+
}
|
|
32942
|
+
if (body.name !== undefined && typeof body.name !== "string") {
|
|
32943
|
+
return jsonError(400, "name must be a string");
|
|
32944
|
+
}
|
|
32945
|
+
const source = topicForUser(topicId, userId);
|
|
32946
|
+
if (!source || source.kind === "manager" || !topicInRequestScope(req, source)) {
|
|
32947
|
+
return jsonError(404, "Topic not found");
|
|
32948
|
+
}
|
|
32949
|
+
const name = typeof body.name === "string" && body.name.trim() ? body.name.trim() : "";
|
|
32950
|
+
const derived = await topicService.derive({
|
|
32951
|
+
sourceTopicId: topicId,
|
|
32952
|
+
userId,
|
|
32953
|
+
copyHistory: body.copyHistory,
|
|
32954
|
+
...name ? { name } : {}
|
|
32955
|
+
});
|
|
32956
|
+
if (!derived)
|
|
32957
|
+
return jsonError(500, "Failed to derive topic");
|
|
32958
|
+
return Response.json({ ok: true, v: NODE_RUNTIME_CONTRACT_VERSION, topic: derived }, { status: 201 });
|
|
32959
|
+
}
|
|
32880
32960
|
const importMatch = runtimePath.match(/^\/topics\/([^/]+)\/import$/);
|
|
32881
32961
|
if (importMatch && req.method === "POST") {
|
|
32882
32962
|
const body = await bodyRecord(req);
|
|
@@ -32952,10 +33032,12 @@ function createNodeControlHandler(options) {
|
|
|
32952
33032
|
if (!topic || !topicInRequestScope(req, topic))
|
|
32953
33033
|
return jsonError(404, "Topic not found");
|
|
32954
33034
|
const userId = requiredText(body.userId, "userId");
|
|
33035
|
+
const actorUserId = body.actorUserId === undefined ? undefined : requiredText(body.actorUserId, "actorUserId");
|
|
32955
33036
|
const reason = body.reason === undefined ? undefined : requiredText(body.reason, "reason");
|
|
32956
33037
|
const result = await topicService.reset({
|
|
32957
33038
|
topicId,
|
|
32958
33039
|
userId,
|
|
33040
|
+
actorUserId,
|
|
32959
33041
|
reason: reason ?? "runtime-contract-session-reset"
|
|
32960
33042
|
});
|
|
32961
33043
|
if (result.isError)
|
|
@@ -32976,10 +33058,12 @@ function createNodeControlHandler(options) {
|
|
|
32976
33058
|
if (!topic || !topicInRequestScope(req, topic))
|
|
32977
33059
|
return jsonError(404, "Topic not found");
|
|
32978
33060
|
const userId = requiredText(body.userId, "userId");
|
|
33061
|
+
const actorUserId = body.actorUserId === undefined ? undefined : requiredText(body.actorUserId, "actorUserId");
|
|
32979
33062
|
const reason = body.reason === undefined ? undefined : requiredText(body.reason, "reason");
|
|
32980
33063
|
const result = await topicService.compact({
|
|
32981
33064
|
topicId,
|
|
32982
33065
|
userId,
|
|
33066
|
+
actorUserId,
|
|
32983
33067
|
reason: reason ?? "runtime-contract-session-compact",
|
|
32984
33068
|
compactSession: options.compactSession
|
|
32985
33069
|
});
|
|
@@ -33067,8 +33151,9 @@ function createNodeControlHandler(options) {
|
|
|
33067
33151
|
if (!topic || !topicInRequestScope(req, topic))
|
|
33068
33152
|
return jsonError(404, "Topic not found");
|
|
33069
33153
|
const userId = requiredText(url.searchParams.get("user"), "user");
|
|
33154
|
+
const actorUserId = url.searchParams.get("actor")?.trim() || undefined;
|
|
33070
33155
|
try {
|
|
33071
|
-
await topicService.delete({ topicId, userId });
|
|
33156
|
+
await topicService.delete({ topicId, userId, memoryUserId: actorUserId });
|
|
33072
33157
|
} catch (err2) {
|
|
33073
33158
|
if (err2 instanceof TopicServiceError) {
|
|
33074
33159
|
const status = err2.code === "TOPIC_NOT_FOUND" ? 404 : err2.code === "TOPIC_FORBIDDEN" ? 403 : 400;
|
|
@@ -48666,4 +48751,4 @@ switch (command) {
|
|
|
48666
48751
|
}
|
|
48667
48752
|
}
|
|
48668
48753
|
|
|
48669
|
-
//# debugId=
|
|
48754
|
+
//# debugId=E5965A3EFE680BBE64756E2164756E21
|