negotium 0.2.24 → 0.2.26
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 +82 -29
- package/dist/agent-helpers.js.map +5 -5
- package/dist/hosted-agent.js +2 -2
- package/dist/hosted-agent.js.map +2 -2
- package/dist/main.js +167 -364
- package/dist/main.js.map +26 -27
- package/dist/mcp-factories.js +84 -30
- package/dist/mcp-factories.js.map +6 -6
- package/dist/registry.js +2 -2
- package/dist/registry.js.map +2 -2
- package/dist/runtime/src/index.ts +3 -7
- package/dist/runtime/src/mcp/session-comm/default-host.ts +6 -1
- package/dist/runtime/src/mcp/session-comm/topic-catalog.ts +17 -1
- package/dist/runtime/src/mcp/session-comm/topics.ts +23 -1
- package/dist/runtime/src/node-host.ts +2 -3
- package/dist/runtime/src/storage/api-topics.ts +164 -52
- package/dist/runtime/src/storage/storage-public.ts +0 -1
- package/dist/runtime/src/topics/create.ts +12 -6
- package/dist/runtime/src/topics/derive.ts +20 -11
- package/dist/runtime/src/types/api.ts +8 -4
- package/dist/runtime/src/version.ts +1 -1
- package/dist/storage.js +92 -38
- package/dist/storage.js.map +3 -3
- package/dist/types/packages/core/src/mcp/session-comm/topic-catalog.d.ts +7 -0
- package/dist/types/packages/core/src/storage/api-topics.d.ts +34 -19
- package/dist/types/packages/core/src/storage/storage-public.d.ts +1 -1
- package/dist/types/packages/core/src/topics/derive.d.ts +13 -4
- package/dist/types/packages/core/src/types/api.d.ts +8 -4
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/runtime/src/application/switch-topic-access-mode.ts +0 -110
package/dist/agent-helpers.js
CHANGED
|
@@ -2395,7 +2395,7 @@ var init_claude_registry = __esm(() => {
|
|
|
2395
2395
|
});
|
|
2396
2396
|
|
|
2397
2397
|
// ../../packages/core/src/version.ts
|
|
2398
|
-
var NEGOTIUM_VERSION = "0.2.
|
|
2398
|
+
var NEGOTIUM_VERSION = "0.2.26";
|
|
2399
2399
|
|
|
2400
2400
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
2401
2401
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -7341,6 +7341,12 @@ var init_api_topic_config = __esm(async () => {
|
|
|
7341
7341
|
});
|
|
7342
7342
|
|
|
7343
7343
|
// ../../packages/core/src/storage/api-topics.ts
|
|
7344
|
+
function defaultTopicSurface() {
|
|
7345
|
+
return normalizeTopicSurface(process.env.NEGOTIUM_DEFAULT_SURFACE);
|
|
7346
|
+
}
|
|
7347
|
+
function normalizeTopicSurface(value) {
|
|
7348
|
+
return value === "telegram" || value === "otium" || value === "terminal" ? value : "terminal";
|
|
7349
|
+
}
|
|
7344
7350
|
function tableColumns2(table) {
|
|
7345
7351
|
const rows = db.query(`PRAGMA table_info(${table})`).all();
|
|
7346
7352
|
return new Set(rows.map((row) => row.name));
|
|
@@ -7471,7 +7477,7 @@ function initializeApiTopicsSchema() {
|
|
|
7471
7477
|
is_fork INTEGER NOT NULL DEFAULT 0 CHECK (is_fork IN (0,1)),
|
|
7472
7478
|
is_subagent INTEGER NOT NULL DEFAULT 0 CHECK (is_subagent IN (0,1)),
|
|
7473
7479
|
visibility TEXT NOT NULL DEFAULT 'visible' CHECK (visibility IN ('visible','hidden')),
|
|
7474
|
-
|
|
7480
|
+
surface TEXT NOT NULL DEFAULT 'terminal' CHECK (surface IN ('terminal','telegram','otium')),
|
|
7475
7481
|
browser_profile TEXT NOT NULL DEFAULT 'default',
|
|
7476
7482
|
browser_profile_owner TEXT,
|
|
7477
7483
|
session_id TEXT,
|
|
@@ -7517,8 +7523,8 @@ function initializeApiTopicsSchema() {
|
|
|
7517
7523
|
const legacyBaseEffort = row.base_effort ?? row.default_effort;
|
|
7518
7524
|
db.query(`INSERT INTO api_topics_next
|
|
7519
7525
|
(id,title,kind,description,agent,base_model,base_effort,response_policy,
|
|
7520
|
-
created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,
|
|
7521
|
-
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`).run(String(row.id), String(row.title), normalized.kind, typeof row.description === "string" ? row.description : null, normalized.agent ?? null, typeof legacyBaseModel === "string" ? legacyBaseModel : null, typeof legacyBaseEffort === "string" ? legacyBaseEffort : null, normalized.aiMode, String(row.created_at), typeof row.last_message_at === "string" ? row.last_message_at : null, typeof row.parent_topic_id === "string" ? row.parent_topic_id : null, typeof row.memory_topic_id === "string" ? row.memory_topic_id : null, typeof row.memory_key === "string" ? row.memory_key : null, Number(row.is_fork ?? 0) !== 0 ? 1 : 0, Number(row.is_subagent ?? 0) !== 0 ? 1 : 0, row.visibility === "hidden" ? "hidden" : "visible", row.
|
|
7526
|
+
created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,surface,session_id)
|
|
7527
|
+
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`).run(String(row.id), String(row.title), normalized.kind, typeof row.description === "string" ? row.description : null, normalized.agent ?? null, typeof legacyBaseModel === "string" ? legacyBaseModel : null, typeof legacyBaseEffort === "string" ? legacyBaseEffort : null, normalized.aiMode, String(row.created_at), typeof row.last_message_at === "string" ? row.last_message_at : null, typeof row.parent_topic_id === "string" ? row.parent_topic_id : null, typeof row.memory_topic_id === "string" ? row.memory_topic_id : null, typeof row.memory_key === "string" ? row.memory_key : null, Number(row.is_fork ?? 0) !== 0 ? 1 : 0, Number(row.is_subagent ?? 0) !== 0 ? 1 : 0, row.visibility === "hidden" ? "hidden" : "visible", row.surface === undefined ? defaultTopicSurface() : normalizeTopicSurface(row.surface), typeof row.session_id === "string" ? row.session_id : null);
|
|
7522
7528
|
}
|
|
7523
7529
|
db.exec("DROP TABLE IF EXISTS topic_members");
|
|
7524
7530
|
db.exec("DROP TABLE api_topics");
|
|
@@ -7572,8 +7578,15 @@ function initializeApiTopicsSchema() {
|
|
|
7572
7578
|
if (!tableColumns2("api_topics").has("visibility")) {
|
|
7573
7579
|
db.exec("ALTER TABLE api_topics ADD COLUMN visibility TEXT NOT NULL DEFAULT 'visible'");
|
|
7574
7580
|
}
|
|
7575
|
-
if (!tableColumns2("api_topics").has("
|
|
7576
|
-
db.exec("ALTER TABLE api_topics ADD COLUMN
|
|
7581
|
+
if (!tableColumns2("api_topics").has("surface")) {
|
|
7582
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN surface TEXT NOT NULL DEFAULT 'terminal'");
|
|
7583
|
+
}
|
|
7584
|
+
if (tableColumns2("api_topics").has("access_mode")) {
|
|
7585
|
+
try {
|
|
7586
|
+
db.exec("ALTER TABLE api_topics DROP COLUMN access_mode");
|
|
7587
|
+
} catch (err) {
|
|
7588
|
+
logger.warn({ err }, "api_topics: could not drop the retired access_mode column");
|
|
7589
|
+
}
|
|
7577
7590
|
}
|
|
7578
7591
|
if (!tableColumns2("api_topics").has("browser_profile")) {
|
|
7579
7592
|
db.exec("ALTER TABLE api_topics ADD COLUMN browser_profile TEXT NOT NULL DEFAULT 'default'");
|
|
@@ -7600,7 +7613,48 @@ function initializeApiTopicsSchema() {
|
|
|
7600
7613
|
)
|
|
7601
7614
|
WHERE browser_profile_owner IS NULL
|
|
7602
7615
|
`);
|
|
7616
|
+
backfillTopicSurfaces();
|
|
7603
7617
|
db.exec("CREATE INDEX IF NOT EXISTS idx_api_topics_last_message ON api_topics(last_message_at DESC)");
|
|
7618
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_api_topics_surface ON api_topics(surface)");
|
|
7619
|
+
}
|
|
7620
|
+
function backfillTopicSurfaces() {
|
|
7621
|
+
db.exec(`
|
|
7622
|
+
CREATE TABLE IF NOT EXISTS api_schema_migrations (
|
|
7623
|
+
key TEXT PRIMARY KEY,
|
|
7624
|
+
applied_at TEXT NOT NULL
|
|
7625
|
+
)
|
|
7626
|
+
`);
|
|
7627
|
+
const applied = db.query("SELECT key FROM api_schema_migrations WHERE key = ?").get(SURFACE_BACKFILL_MIGRATION);
|
|
7628
|
+
if (applied)
|
|
7629
|
+
return;
|
|
7630
|
+
const surface = defaultTopicSurface();
|
|
7631
|
+
db.transaction(() => {
|
|
7632
|
+
db.query("UPDATE api_topics SET surface = ?").run(surface);
|
|
7633
|
+
renameSurfaceTitleCollisions();
|
|
7634
|
+
db.query("INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)").run(SURFACE_BACKFILL_MIGRATION, new Date().toISOString());
|
|
7635
|
+
})();
|
|
7636
|
+
logger.info({ surface }, "api_topics: surface backfilled");
|
|
7637
|
+
}
|
|
7638
|
+
function renameSurfaceTitleCollisions() {
|
|
7639
|
+
const rows = db.query("SELECT id, title, kind, surface FROM api_topics ORDER BY created_at ASC, rowid ASC").all();
|
|
7640
|
+
const taken = new Set;
|
|
7641
|
+
const update = db.query("UPDATE api_topics SET title = ? WHERE id = ?");
|
|
7642
|
+
for (const row of rows) {
|
|
7643
|
+
const key = (title) => [row.surface, row.kind, normalizedTitle(title)].join("\x00");
|
|
7644
|
+
if (!taken.has(key(row.title))) {
|
|
7645
|
+
taken.add(key(row.title));
|
|
7646
|
+
continue;
|
|
7647
|
+
}
|
|
7648
|
+
let suffix = 2;
|
|
7649
|
+
let candidate = `${row.title} (${suffix})`;
|
|
7650
|
+
while (taken.has(key(candidate))) {
|
|
7651
|
+
suffix += 1;
|
|
7652
|
+
candidate = `${row.title} (${suffix})`;
|
|
7653
|
+
}
|
|
7654
|
+
taken.add(key(candidate));
|
|
7655
|
+
update.run(candidate, row.id);
|
|
7656
|
+
logger.warn({ topicId: row.id, surface: row.surface, from: row.title, to: candidate }, "api_topics: renamed a duplicate title for surface-scoped uniqueness");
|
|
7657
|
+
}
|
|
7604
7658
|
}
|
|
7605
7659
|
function shortSessionId(sessionId) {
|
|
7606
7660
|
return sessionId ? sessionId.slice(0, 8) : null;
|
|
@@ -7660,12 +7714,9 @@ function rowToDto2(r, participants = getTopicParticipants(r.id), tellTargets) {
|
|
|
7660
7714
|
subagentReportMode: r.subagent_report_mode === "tell" || r.subagent_report_mode === "status-only" ? r.subagent_report_mode : "auto"
|
|
7661
7715
|
} : {},
|
|
7662
7716
|
visibility: normalizeTopicVisibility(r.visibility),
|
|
7663
|
-
|
|
7717
|
+
surface: normalizeTopicSurface(r.surface)
|
|
7664
7718
|
};
|
|
7665
7719
|
}
|
|
7666
|
-
function normalizeTopicAccessMode(value) {
|
|
7667
|
-
return value === "shared" ? "shared" : "private";
|
|
7668
|
-
}
|
|
7669
7720
|
function normalizeTopicVisibility(value) {
|
|
7670
7721
|
return value === "hidden" ? "hidden" : "visible";
|
|
7671
7722
|
}
|
|
@@ -7722,7 +7773,7 @@ function upsertTopic(t) {
|
|
|
7722
7773
|
db.transaction(() => {
|
|
7723
7774
|
db.query(`INSERT INTO api_topics
|
|
7724
7775
|
(id,title,kind,description,agent,base_model,base_effort,response_policy,
|
|
7725
|
-
created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,
|
|
7776
|
+
created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,surface,
|
|
7726
7777
|
subagent_report_mode)
|
|
7727
7778
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
|
7728
7779
|
ON CONFLICT(id) DO UPDATE SET
|
|
@@ -7741,8 +7792,8 @@ function upsertTopic(t) {
|
|
|
7741
7792
|
is_fork = excluded.is_fork,
|
|
7742
7793
|
is_subagent = excluded.is_subagent,
|
|
7743
7794
|
visibility = excluded.visibility,
|
|
7744
|
-
|
|
7745
|
-
subagent_report_mode = excluded.subagent_report_mode`).run(t.id, t.title, normalized.kind, t.description ?? null, normalized.agent ?? null, t.defaultModel ?? null, t.defaultEffort ?? null, normalized.aiMode, t.createdAt, t.lastMessageAt ?? null, t.parentTopicId ?? null, t.memoryTopicId ?? null, t.memoryKey ?? null, t.isFork ? 1 : 0, t.isSubagent ? 1 : 0, normalizeTopicVisibility(t.visibility),
|
|
7795
|
+
surface = excluded.surface,
|
|
7796
|
+
subagent_report_mode = excluded.subagent_report_mode`).run(t.id, t.title, normalized.kind, t.description ?? null, normalized.agent ?? null, t.defaultModel ?? null, t.defaultEffort ?? null, normalized.aiMode, t.createdAt, t.lastMessageAt ?? null, t.parentTopicId ?? null, t.memoryTopicId ?? null, t.memoryKey ?? null, t.isFork ? 1 : 0, t.isSubagent ? 1 : 0, normalizeTopicVisibility(t.visibility), normalizeTopicSurface(t.surface ?? defaultTopicSurface()), t.subagentReportMode ?? "auto");
|
|
7746
7797
|
db.query("DELETE FROM topic_members WHERE topic_id = ?").run(t.id);
|
|
7747
7798
|
for (const participant of t.participants) {
|
|
7748
7799
|
db.query("INSERT INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)").run(t.id, participant.userId, participant.role);
|
|
@@ -7755,8 +7806,8 @@ function upsertTopic(t) {
|
|
|
7755
7806
|
}
|
|
7756
7807
|
})();
|
|
7757
7808
|
}
|
|
7758
|
-
function listTopics() {
|
|
7759
|
-
const rows = db.query("SELECT * FROM api_topics ORDER BY last_message_at DESC").all();
|
|
7809
|
+
function listTopics(opts = {}) {
|
|
7810
|
+
const rows = opts.surface ? db.query("SELECT * FROM api_topics WHERE surface = ? ORDER BY last_message_at DESC").all(normalizeTopicSurface(opts.surface)) : db.query("SELECT * FROM api_topics ORDER BY last_message_at DESC").all();
|
|
7760
7811
|
const participants = getAllTopicParticipants();
|
|
7761
7812
|
const tellTargets = rows.some((row) => row.is_subagent !== 0) ? getAllSubagentTellTargets() : undefined;
|
|
7762
7813
|
return rows.map((row) => rowToDto2(row, participants.get(row.id) ?? [], tellTargets));
|
|
@@ -7799,14 +7850,15 @@ function getTopicMemoryOrigin(id) {
|
|
|
7799
7850
|
}
|
|
7800
7851
|
function findTopicTitleConflict(title, kind, opts = {}) {
|
|
7801
7852
|
const wanted = normalizedTitle(title);
|
|
7853
|
+
const surface = normalizeTopicSurface(opts.surface ?? defaultTopicSurface());
|
|
7802
7854
|
const generalTitleRequested = wanted === normalizedTitle(GENERAL_TOPIC_ID);
|
|
7803
7855
|
if (generalTitleRequested && opts.excludeTopicId !== GENERAL_TOPIC_ID) {
|
|
7804
7856
|
const general = db.query("SELECT * FROM api_topics WHERE id = ?").get(GENERAL_TOPIC_ID);
|
|
7805
7857
|
if (general)
|
|
7806
7858
|
return rowToDto2(general);
|
|
7807
7859
|
}
|
|
7808
|
-
const params = [wanted];
|
|
7809
|
-
let sql = "SELECT * FROM api_topics WHERE LOWER(TRIM(title)) = ?";
|
|
7860
|
+
const params = [wanted, surface];
|
|
7861
|
+
let sql = "SELECT * FROM api_topics WHERE LOWER(TRIM(title)) = ? AND surface = ?";
|
|
7810
7862
|
if (kind !== "manager") {
|
|
7811
7863
|
sql += " AND (kind = ? OR id = ?)";
|
|
7812
7864
|
params.push(kind, GENERAL_TOPIC_ID);
|
|
@@ -7891,7 +7943,7 @@ function reparentTopicChildren(deletedTopicId, replacementParentTopicId) {
|
|
|
7891
7943
|
}
|
|
7892
7944
|
return rows.map((row) => row.id);
|
|
7893
7945
|
}
|
|
7894
|
-
var DEFAULT_AGENT_ROOM_AGENT = "maestro";
|
|
7946
|
+
var DEFAULT_AGENT_ROOM_AGENT = "maestro", SURFACE_BACKFILL_MIGRATION = "api_topics_surface_backfill_20260808";
|
|
7895
7947
|
var init_api_topics = __esm(async () => {
|
|
7896
7948
|
init_constants();
|
|
7897
7949
|
init_logger();
|
|
@@ -12618,11 +12670,11 @@ __export(exports_derive, {
|
|
|
12618
12670
|
});
|
|
12619
12671
|
import { createHash as createHash5, randomUUID as randomUUID12 } from "crypto";
|
|
12620
12672
|
import { mkdirSync as mkdirSync13, rmSync as rmSync5, unlinkSync as unlinkSync13 } from "fs";
|
|
12621
|
-
function getTopics() {
|
|
12622
|
-
return listTopics().filter((topic) => !isLegacySharedGeneral(topic.id));
|
|
12673
|
+
function getTopics(opts = {}) {
|
|
12674
|
+
return listTopics(opts).filter((topic) => !isLegacySharedGeneral(topic.id));
|
|
12623
12675
|
}
|
|
12624
|
-
function getVisibleTopics() {
|
|
12625
|
-
return getTopics().filter(isTopicVisible).map((topic) => {
|
|
12676
|
+
function getVisibleTopics(opts = {}) {
|
|
12677
|
+
return getTopics(opts).filter(isTopicVisible).map((topic) => {
|
|
12626
12678
|
if (!topic.agent)
|
|
12627
12679
|
return topic;
|
|
12628
12680
|
const registry = getRegistry(topic.agent);
|
|
@@ -12647,8 +12699,8 @@ function updateTopic(topicId, patch) {
|
|
|
12647
12699
|
function isParticipant(topic, userId) {
|
|
12648
12700
|
return topic.participants.some((p) => p.userId === userId);
|
|
12649
12701
|
}
|
|
12650
|
-
function nextDerivedTopicTitle(sourceTitle, kind, suffix) {
|
|
12651
|
-
const visibleTitles = new Set(listTopics().filter((topic) => topic.kind === kind).map((topic) => topic.title.toLowerCase()));
|
|
12702
|
+
function nextDerivedTopicTitle(sourceTitle, kind, suffix, surface) {
|
|
12703
|
+
const visibleTitles = new Set(listTopics(surface ? { surface } : {}).filter((topic) => topic.kind === kind).map((topic) => topic.title.toLowerCase()));
|
|
12652
12704
|
let n = 1;
|
|
12653
12705
|
let title = `${sourceTitle}-${suffix}-${n}`;
|
|
12654
12706
|
while (visibleTitles.has(title.toLowerCase())) {
|
|
@@ -12712,8 +12764,9 @@ async function createDerivedTopicImpl(topic, sourceTopicId, userId, copyHistory,
|
|
|
12712
12764
|
{ userId, role: "owner" }
|
|
12713
12765
|
] : [{ userId, role: "owner" }];
|
|
12714
12766
|
const kind = topic.kind ?? inferTopicKind(topic);
|
|
12715
|
-
const
|
|
12716
|
-
const
|
|
12767
|
+
const surface = topic.surface ?? defaultTopicSurface();
|
|
12768
|
+
const title = opts?.name?.trim() || nextDerivedTopicTitle(topic.title, kind, suffix, surface);
|
|
12769
|
+
const conflict = findTopicTitleConflict(title, kind, { surface });
|
|
12717
12770
|
if (conflict) {
|
|
12718
12771
|
logger.info({ sourceTopicId, title, kind, conflictTopicId: conflict.id }, "createDerivedTopic: title conflict");
|
|
12719
12772
|
throw new TopicTitleConflictError(title);
|
|
@@ -12736,7 +12789,7 @@ async function createDerivedTopicImpl(topic, sourceTopicId, userId, copyHistory,
|
|
|
12736
12789
|
isFork: copyHistory,
|
|
12737
12790
|
...subagent ? { isSubagent: true } : {},
|
|
12738
12791
|
visibility: topic.visibility,
|
|
12739
|
-
|
|
12792
|
+
surface
|
|
12740
12793
|
};
|
|
12741
12794
|
let sessionId;
|
|
12742
12795
|
let rollbackHandle;
|
|
@@ -12844,7 +12897,7 @@ async function createDerivedTopicImpl(topic, sourceTopicId, userId, copyHistory,
|
|
|
12844
12897
|
if (!currentSource || currentSource.kind === "manager" || !isParticipant(currentSource, userId) || subagent && isRuntimeTopicMaintenance(sourceTopicId)) {
|
|
12845
12898
|
throw new TopicDeriveBusyError("Source topic changed while deriving; try again");
|
|
12846
12899
|
}
|
|
12847
|
-
const transactionalConflict = findTopicTitleConflict(title, kind);
|
|
12900
|
+
const transactionalConflict = findTopicTitleConflict(title, kind, { surface });
|
|
12848
12901
|
if (transactionalConflict)
|
|
12849
12902
|
throw new TopicTitleConflictError(title);
|
|
12850
12903
|
upsertTopic(derived);
|
|
@@ -18757,4 +18810,4 @@ export {
|
|
|
18757
18810
|
DEFAULT_SELF_CONFIG_PRODUCT
|
|
18758
18811
|
};
|
|
18759
18812
|
|
|
18760
|
-
//# debugId=
|
|
18813
|
+
//# debugId=88F335565B80EFA364756E2164756E21
|