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/agent-helpers.js
CHANGED
|
@@ -2980,7 +2980,7 @@ var init_codex = __esm(async () => {
|
|
|
2980
2980
|
});
|
|
2981
2981
|
|
|
2982
2982
|
// ../../packages/core/src/version.ts
|
|
2983
|
-
var NEGOTIUM_VERSION = "0.6.
|
|
2983
|
+
var NEGOTIUM_VERSION = "0.6.7";
|
|
2984
2984
|
|
|
2985
2985
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
2986
2986
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -3670,6 +3670,16 @@ var init_task_events = __esm(async () => {
|
|
|
3670
3670
|
defaultTaskEventHost = { readTasks, taskFileMtimeNs, taskScopeKey };
|
|
3671
3671
|
});
|
|
3672
3672
|
|
|
3673
|
+
// ../../packages/core/src/platform/constants.ts
|
|
3674
|
+
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";
|
|
3675
|
+
var init_constants = __esm(() => {
|
|
3676
|
+
RESERVED_TOPIC_NAMES = new Set([
|
|
3677
|
+
FROM_AUTO_CONTINUE,
|
|
3678
|
+
FROM_SELF_SCHEDULE,
|
|
3679
|
+
"general"
|
|
3680
|
+
]);
|
|
3681
|
+
});
|
|
3682
|
+
|
|
3673
3683
|
// ../../packages/core/src/storage/conversations.ts
|
|
3674
3684
|
import {
|
|
3675
3685
|
existsSync as existsSync9,
|
|
@@ -3683,12 +3693,15 @@ import { dirname as dirname8, join as join11 } from "path";
|
|
|
3683
3693
|
function conversationDir(_userId) {
|
|
3684
3694
|
return join11(resolveStorageDataDir(), "conversations");
|
|
3685
3695
|
}
|
|
3686
|
-
function topicFilename(topicName) {
|
|
3696
|
+
function topicFilename(userId, topicName) {
|
|
3687
3697
|
const t = sanitizeTopicName(topicName, true);
|
|
3688
|
-
|
|
3698
|
+
const owner = String(userId);
|
|
3699
|
+
if (t !== MANAGER_TOPIC_LOG_NAME || owner === NODE_LOCAL_USER_ID)
|
|
3700
|
+
return `${t}.jsonl`;
|
|
3701
|
+
return `${t}.${sanitizeId(owner)}.jsonl`;
|
|
3689
3702
|
}
|
|
3690
3703
|
function getConversationPath(userId, topicName) {
|
|
3691
|
-
return join11(conversationDir(userId), topicFilename(topicName));
|
|
3704
|
+
return join11(conversationDir(userId), topicFilename(userId, topicName));
|
|
3692
3705
|
}
|
|
3693
3706
|
function getActiveConversationPath(userId, topicName) {
|
|
3694
3707
|
const rawPath = getConversationPath(userId, topicName);
|
|
@@ -3789,6 +3802,7 @@ function findLastSessionIdForAgent(entries, agent) {
|
|
|
3789
3802
|
}
|
|
3790
3803
|
var ConversationLogDivergedError;
|
|
3791
3804
|
var init_conversations = __esm(async () => {
|
|
3805
|
+
init_constants();
|
|
3792
3806
|
init_jsonl();
|
|
3793
3807
|
init_logger();
|
|
3794
3808
|
await init_storage_host();
|
|
@@ -7449,142 +7463,6 @@ var init_api_topic_brief = __esm(async () => {
|
|
|
7449
7463
|
}, 30);
|
|
7450
7464
|
});
|
|
7451
7465
|
|
|
7452
|
-
// ../../packages/core/src/storage/wiki.ts
|
|
7453
|
-
import { basename as basename2, dirname as dirname11, join as join15 } from "path";
|
|
7454
|
-
function getSharedWikiDir(workspaceDir = resolveStorageWorkspaceDir()) {
|
|
7455
|
-
return workspaceDir === resolveStorageWorkspaceDir() ? resolveStorageSharedWikiDir() : join15(workspaceDir, "wiki");
|
|
7456
|
-
}
|
|
7457
|
-
var init_wiki = __esm(async () => {
|
|
7458
|
-
await init_storage_host();
|
|
7459
|
-
});
|
|
7460
|
-
|
|
7461
|
-
// ../../packages/core/src/platform/constants.ts
|
|
7462
|
-
var FROM_AUTO_CONTINUE = "auto-continue", FROM_SELF_SCHEDULE = "self-schedule", RESERVED_TOPIC_NAMES, GENERAL_TOPIC_ID = "general";
|
|
7463
|
-
var init_constants = __esm(() => {
|
|
7464
|
-
RESERVED_TOPIC_NAMES = new Set([
|
|
7465
|
-
FROM_AUTO_CONTINUE,
|
|
7466
|
-
FROM_SELF_SCHEDULE,
|
|
7467
|
-
"general"
|
|
7468
|
-
]);
|
|
7469
|
-
});
|
|
7470
|
-
|
|
7471
|
-
// ../../packages/core/src/storage/api-topic-config.ts
|
|
7472
|
-
function tableColumns(table) {
|
|
7473
|
-
const rows = db.query(`PRAGMA table_info(${table})`).all();
|
|
7474
|
-
return new Set(rows.map((row) => row.name));
|
|
7475
|
-
}
|
|
7476
|
-
function createCanonicalConfigTable(name = "api_topic_config") {
|
|
7477
|
-
db.exec(`
|
|
7478
|
-
CREATE TABLE IF NOT EXISTS ${name} (
|
|
7479
|
-
topic_id TEXT PRIMARY KEY REFERENCES api_topics(id) ON DELETE CASCADE,
|
|
7480
|
-
model TEXT,
|
|
7481
|
-
effort TEXT CHECK (effort IS NULL OR effort IN ('low','medium','high','xhigh','max')),
|
|
7482
|
-
mcp TEXT,
|
|
7483
|
-
agent_locked INTEGER NOT NULL DEFAULT 0 CHECK (agent_locked IN (0,1)),
|
|
7484
|
-
model_locked INTEGER NOT NULL DEFAULT 0 CHECK (model_locked IN (0,1)),
|
|
7485
|
-
effort_locked INTEGER NOT NULL DEFAULT 0 CHECK (effort_locked IN (0,1))
|
|
7486
|
-
)
|
|
7487
|
-
`);
|
|
7488
|
-
}
|
|
7489
|
-
function initializeApiTopicConfigSchema() {
|
|
7490
|
-
const existingConfigColumns = tableColumns("api_topic_config");
|
|
7491
|
-
if (existingConfigColumns.size === 0) {
|
|
7492
|
-
createCanonicalConfigTable();
|
|
7493
|
-
} 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")) {
|
|
7494
|
-
const topicColumns = tableColumns("api_topics");
|
|
7495
|
-
const agentColumn = topicColumns.has("agent") ? "agent" : topicColumns.has("runtime_agent") ? "runtime_agent" : null;
|
|
7496
|
-
if (agentColumn && existingConfigColumns.has("agent")) {
|
|
7497
|
-
db.exec(`UPDATE api_topics
|
|
7498
|
-
SET ${agentColumn} = (
|
|
7499
|
-
SELECT c.agent FROM api_topic_config c WHERE c.topic_id = api_topics.id
|
|
7500
|
-
)
|
|
7501
|
-
WHERE ${agentColumn} IS NULL
|
|
7502
|
-
AND EXISTS (
|
|
7503
|
-
SELECT 1 FROM api_topic_config c
|
|
7504
|
-
WHERE c.topic_id = api_topics.id AND c.agent IS NOT NULL
|
|
7505
|
-
)`);
|
|
7506
|
-
}
|
|
7507
|
-
const previousForeignKeys = db.query("PRAGMA foreign_keys").get()?.foreign_keys;
|
|
7508
|
-
db.exec("PRAGMA foreign_keys = OFF");
|
|
7509
|
-
try {
|
|
7510
|
-
const agentLockSource = existingConfigColumns.has("runtime_locked") ? "runtime_locked" : existingConfigColumns.has("agent_pinned") ? "agent_pinned" : "0";
|
|
7511
|
-
const modelLockSource = existingConfigColumns.has("model_locked") ? "model_locked" : existingConfigColumns.has("model_pinned") ? "model_pinned" : "0";
|
|
7512
|
-
const effortLockSource = existingConfigColumns.has("effort_locked") ? "effort_locked" : existingConfigColumns.has("effort_pinned") ? "effort_pinned" : "0";
|
|
7513
|
-
db.transaction(() => {
|
|
7514
|
-
createCanonicalConfigTable("api_topic_config_next");
|
|
7515
|
-
db.exec(`
|
|
7516
|
-
INSERT INTO api_topic_config_next
|
|
7517
|
-
(topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
|
|
7518
|
-
SELECT
|
|
7519
|
-
topic_id,
|
|
7520
|
-
model,
|
|
7521
|
-
effort,
|
|
7522
|
-
mcp,
|
|
7523
|
-
COALESCE(${agentLockSource}, 0),
|
|
7524
|
-
COALESCE(${modelLockSource}, 0),
|
|
7525
|
-
COALESCE(${effortLockSource}, 0)
|
|
7526
|
-
FROM api_topic_config
|
|
7527
|
-
WHERE EXISTS (SELECT 1 FROM api_topics t WHERE t.id = api_topic_config.topic_id)
|
|
7528
|
-
`);
|
|
7529
|
-
db.exec("DROP TABLE api_topic_config");
|
|
7530
|
-
db.exec("ALTER TABLE api_topic_config_next RENAME TO api_topic_config");
|
|
7531
|
-
})();
|
|
7532
|
-
} finally {
|
|
7533
|
-
db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? "ON" : "OFF"}`);
|
|
7534
|
-
}
|
|
7535
|
-
} else {
|
|
7536
|
-
createCanonicalConfigTable();
|
|
7537
|
-
}
|
|
7538
|
-
}
|
|
7539
|
-
function rowToConfig(r) {
|
|
7540
|
-
const cfg = {};
|
|
7541
|
-
if (r.model)
|
|
7542
|
-
cfg.model = r.model;
|
|
7543
|
-
if (r.effort)
|
|
7544
|
-
cfg.effort = r.effort;
|
|
7545
|
-
if (r.mcp) {
|
|
7546
|
-
try {
|
|
7547
|
-
const parsed = JSON.parse(r.mcp);
|
|
7548
|
-
if (Array.isArray(parsed))
|
|
7549
|
-
cfg.mcp = parsed;
|
|
7550
|
-
} catch {}
|
|
7551
|
-
}
|
|
7552
|
-
if (r.agent_locked)
|
|
7553
|
-
cfg.agentLocked = true;
|
|
7554
|
-
if (r.model_locked)
|
|
7555
|
-
cfg.modelLocked = true;
|
|
7556
|
-
if (r.effort_locked)
|
|
7557
|
-
cfg.effortLocked = true;
|
|
7558
|
-
return cfg;
|
|
7559
|
-
}
|
|
7560
|
-
function getApiTopicConfig(topicId) {
|
|
7561
|
-
const row = db.query("SELECT topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked FROM api_topic_config WHERE topic_id = ?").get(topicId);
|
|
7562
|
-
if (!row)
|
|
7563
|
-
return;
|
|
7564
|
-
const config = rowToConfig(row);
|
|
7565
|
-
return Object.keys(config).length > 0 ? config : undefined;
|
|
7566
|
-
}
|
|
7567
|
-
function setApiTopicConfig(topicId, config) {
|
|
7568
|
-
db.query(`INSERT INTO api_topic_config
|
|
7569
|
-
(topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
|
|
7570
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
7571
|
-
ON CONFLICT(topic_id) DO UPDATE SET
|
|
7572
|
-
model = excluded.model,
|
|
7573
|
-
effort = excluded.effort,
|
|
7574
|
-
mcp = excluded.mcp,
|
|
7575
|
-
agent_locked = excluded.agent_locked,
|
|
7576
|
-
model_locked = excluded.model_locked,
|
|
7577
|
-
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);
|
|
7578
|
-
}
|
|
7579
|
-
function deleteApiTopicConfig(topicId) {
|
|
7580
|
-
db.query("DELETE FROM api_topic_config WHERE topic_id = ?").run(topicId);
|
|
7581
|
-
}
|
|
7582
|
-
var init_api_topic_config = __esm(async () => {
|
|
7583
|
-
await init_forum_db();
|
|
7584
|
-
await init_storage_host();
|
|
7585
|
-
registerStorageSchemaInitializer(initializeApiTopicConfigSchema, 40);
|
|
7586
|
-
});
|
|
7587
|
-
|
|
7588
7466
|
// ../../packages/core/src/storage/api-topics.ts
|
|
7589
7467
|
function defaultTopicSurface() {
|
|
7590
7468
|
return normalizeTopicSurface(process.env.NEGOTIUM_DEFAULT_SURFACE);
|
|
@@ -7601,7 +7479,7 @@ function normalizeSurfaceScope(value) {
|
|
|
7601
7479
|
function defaultSurfaceScope() {
|
|
7602
7480
|
return activeSurfaceScope ?? normalizeSurfaceScope(process.env.NEGOTIUM_SURFACE_SCOPE);
|
|
7603
7481
|
}
|
|
7604
|
-
function
|
|
7482
|
+
function tableColumns(table) {
|
|
7605
7483
|
const rows = db.query(`PRAGMA table_info(${table})`).all();
|
|
7606
7484
|
return new Set(rows.map((row) => row.name));
|
|
7607
7485
|
}
|
|
@@ -7630,7 +7508,7 @@ function initializeApiTopicsSchema() {
|
|
|
7630
7508
|
ai_mode TEXT
|
|
7631
7509
|
)
|
|
7632
7510
|
`);
|
|
7633
|
-
const initialTopicColumns =
|
|
7511
|
+
const initialTopicColumns = tableColumns("api_topics");
|
|
7634
7512
|
const legacyTopicSchema = !initialTopicColumns.has("response_policy");
|
|
7635
7513
|
const needsCanonicalTopicRebuild = legacyTopicSchema || !initialTopicColumns.has("agent");
|
|
7636
7514
|
if (legacyTopicSchema) {
|
|
@@ -7757,8 +7635,8 @@ function initializeApiTopicsSchema() {
|
|
|
7757
7635
|
}
|
|
7758
7636
|
if (needsCanonicalTopicRebuild) {
|
|
7759
7637
|
const legacyRows = db.query("SELECT * FROM api_topics").all();
|
|
7760
|
-
const existingMemberRows =
|
|
7761
|
-
const configColumns =
|
|
7638
|
+
const existingMemberRows = tableColumns("topic_members").has("topic_id") ? db.query("SELECT topic_id, user_id, role FROM topic_members").all() : [];
|
|
7639
|
+
const configColumns = tableColumns("api_topic_config");
|
|
7762
7640
|
const legacyAgentOverrides = configColumns.has("agent") ? new Map(db.query("SELECT topic_id, agent FROM api_topic_config WHERE agent IS NOT NULL").all().map((row) => [row.topic_id, row.agent])) : new Map;
|
|
7763
7641
|
const previousForeignKeys = db.query("PRAGMA foreign_keys").get()?.foreign_keys;
|
|
7764
7642
|
db.exec("PRAGMA foreign_keys = OFF");
|
|
@@ -7830,35 +7708,35 @@ function initializeApiTopicsSchema() {
|
|
|
7830
7708
|
OR granted_by_topic_id NOT IN (SELECT id FROM api_topics)
|
|
7831
7709
|
`);
|
|
7832
7710
|
db.exec("DELETE FROM topic_members WHERE topic_id NOT IN (SELECT id FROM api_topics)");
|
|
7833
|
-
if (!
|
|
7711
|
+
if (!tableColumns("api_topics").has("visibility")) {
|
|
7834
7712
|
db.exec("ALTER TABLE api_topics ADD COLUMN visibility TEXT NOT NULL DEFAULT 'visible'");
|
|
7835
7713
|
}
|
|
7836
|
-
if (!
|
|
7714
|
+
if (!tableColumns("api_topics").has("surface")) {
|
|
7837
7715
|
db.exec("ALTER TABLE api_topics ADD COLUMN surface TEXT NOT NULL DEFAULT 'terminal'");
|
|
7838
7716
|
}
|
|
7839
|
-
if (!
|
|
7717
|
+
if (!tableColumns("api_topics").has("surface_scope")) {
|
|
7840
7718
|
db.exec("ALTER TABLE api_topics ADD COLUMN surface_scope TEXT");
|
|
7841
7719
|
}
|
|
7842
|
-
if (
|
|
7720
|
+
if (tableColumns("api_topics").has("access_mode")) {
|
|
7843
7721
|
try {
|
|
7844
7722
|
db.exec("ALTER TABLE api_topics DROP COLUMN access_mode");
|
|
7845
7723
|
} catch (err) {
|
|
7846
7724
|
logger.warn({ err }, "api_topics: could not drop the retired access_mode column");
|
|
7847
7725
|
}
|
|
7848
7726
|
}
|
|
7849
|
-
if (!
|
|
7727
|
+
if (!tableColumns("api_topics").has("browser_profile")) {
|
|
7850
7728
|
db.exec("ALTER TABLE api_topics ADD COLUMN browser_profile TEXT NOT NULL DEFAULT 'default'");
|
|
7851
7729
|
}
|
|
7852
|
-
if (!
|
|
7730
|
+
if (!tableColumns("api_topics").has("browser_profile_owner")) {
|
|
7853
7731
|
db.exec("ALTER TABLE api_topics ADD COLUMN browser_profile_owner TEXT");
|
|
7854
7732
|
}
|
|
7855
|
-
if (!
|
|
7733
|
+
if (!tableColumns("api_topics").has("subagent_report_mode")) {
|
|
7856
7734
|
db.exec("ALTER TABLE api_topics ADD COLUMN subagent_report_mode TEXT NOT NULL DEFAULT 'auto'");
|
|
7857
7735
|
}
|
|
7858
|
-
if (!
|
|
7736
|
+
if (!tableColumns("api_topics").has("memory_topic_id")) {
|
|
7859
7737
|
db.exec("ALTER TABLE api_topics ADD COLUMN memory_topic_id TEXT");
|
|
7860
7738
|
}
|
|
7861
|
-
if (!
|
|
7739
|
+
if (!tableColumns("api_topics").has("memory_key")) {
|
|
7862
7740
|
db.exec("ALTER TABLE api_topics ADD COLUMN memory_key TEXT");
|
|
7863
7741
|
}
|
|
7864
7742
|
db.exec(`
|
|
@@ -8234,6 +8112,132 @@ var init_api_topics = __esm(async () => {
|
|
|
8234
8112
|
registerStorageSchemaInitializer(initializeApiTopicsSchema, 20);
|
|
8235
8113
|
});
|
|
8236
8114
|
|
|
8115
|
+
// ../../packages/core/src/storage/wiki.ts
|
|
8116
|
+
import { basename as basename2, dirname as dirname11, join as join15 } from "path";
|
|
8117
|
+
function getSharedWikiDir(workspaceDir = resolveStorageWorkspaceDir()) {
|
|
8118
|
+
return workspaceDir === resolveStorageWorkspaceDir() ? resolveStorageSharedWikiDir() : join15(workspaceDir, "wiki");
|
|
8119
|
+
}
|
|
8120
|
+
var init_wiki = __esm(async () => {
|
|
8121
|
+
await init_storage_host();
|
|
8122
|
+
});
|
|
8123
|
+
|
|
8124
|
+
// ../../packages/core/src/storage/api-topic-config.ts
|
|
8125
|
+
function tableColumns2(table) {
|
|
8126
|
+
const rows = db.query(`PRAGMA table_info(${table})`).all();
|
|
8127
|
+
return new Set(rows.map((row) => row.name));
|
|
8128
|
+
}
|
|
8129
|
+
function createCanonicalConfigTable(name = "api_topic_config") {
|
|
8130
|
+
db.exec(`
|
|
8131
|
+
CREATE TABLE IF NOT EXISTS ${name} (
|
|
8132
|
+
topic_id TEXT PRIMARY KEY REFERENCES api_topics(id) ON DELETE CASCADE,
|
|
8133
|
+
model TEXT,
|
|
8134
|
+
effort TEXT CHECK (effort IS NULL OR effort IN ('low','medium','high','xhigh','max')),
|
|
8135
|
+
mcp TEXT,
|
|
8136
|
+
agent_locked INTEGER NOT NULL DEFAULT 0 CHECK (agent_locked IN (0,1)),
|
|
8137
|
+
model_locked INTEGER NOT NULL DEFAULT 0 CHECK (model_locked IN (0,1)),
|
|
8138
|
+
effort_locked INTEGER NOT NULL DEFAULT 0 CHECK (effort_locked IN (0,1))
|
|
8139
|
+
)
|
|
8140
|
+
`);
|
|
8141
|
+
}
|
|
8142
|
+
function initializeApiTopicConfigSchema() {
|
|
8143
|
+
const existingConfigColumns = tableColumns2("api_topic_config");
|
|
8144
|
+
if (existingConfigColumns.size === 0) {
|
|
8145
|
+
createCanonicalConfigTable();
|
|
8146
|
+
} 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")) {
|
|
8147
|
+
const topicColumns = tableColumns2("api_topics");
|
|
8148
|
+
const agentColumn = topicColumns.has("agent") ? "agent" : topicColumns.has("runtime_agent") ? "runtime_agent" : null;
|
|
8149
|
+
if (agentColumn && existingConfigColumns.has("agent")) {
|
|
8150
|
+
db.exec(`UPDATE api_topics
|
|
8151
|
+
SET ${agentColumn} = (
|
|
8152
|
+
SELECT c.agent FROM api_topic_config c WHERE c.topic_id = api_topics.id
|
|
8153
|
+
)
|
|
8154
|
+
WHERE ${agentColumn} IS NULL
|
|
8155
|
+
AND EXISTS (
|
|
8156
|
+
SELECT 1 FROM api_topic_config c
|
|
8157
|
+
WHERE c.topic_id = api_topics.id AND c.agent IS NOT NULL
|
|
8158
|
+
)`);
|
|
8159
|
+
}
|
|
8160
|
+
const previousForeignKeys = db.query("PRAGMA foreign_keys").get()?.foreign_keys;
|
|
8161
|
+
db.exec("PRAGMA foreign_keys = OFF");
|
|
8162
|
+
try {
|
|
8163
|
+
const agentLockSource = existingConfigColumns.has("runtime_locked") ? "runtime_locked" : existingConfigColumns.has("agent_pinned") ? "agent_pinned" : "0";
|
|
8164
|
+
const modelLockSource = existingConfigColumns.has("model_locked") ? "model_locked" : existingConfigColumns.has("model_pinned") ? "model_pinned" : "0";
|
|
8165
|
+
const effortLockSource = existingConfigColumns.has("effort_locked") ? "effort_locked" : existingConfigColumns.has("effort_pinned") ? "effort_pinned" : "0";
|
|
8166
|
+
db.transaction(() => {
|
|
8167
|
+
createCanonicalConfigTable("api_topic_config_next");
|
|
8168
|
+
db.exec(`
|
|
8169
|
+
INSERT INTO api_topic_config_next
|
|
8170
|
+
(topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
|
|
8171
|
+
SELECT
|
|
8172
|
+
topic_id,
|
|
8173
|
+
model,
|
|
8174
|
+
effort,
|
|
8175
|
+
mcp,
|
|
8176
|
+
COALESCE(${agentLockSource}, 0),
|
|
8177
|
+
COALESCE(${modelLockSource}, 0),
|
|
8178
|
+
COALESCE(${effortLockSource}, 0)
|
|
8179
|
+
FROM api_topic_config
|
|
8180
|
+
WHERE EXISTS (SELECT 1 FROM api_topics t WHERE t.id = api_topic_config.topic_id)
|
|
8181
|
+
`);
|
|
8182
|
+
db.exec("DROP TABLE api_topic_config");
|
|
8183
|
+
db.exec("ALTER TABLE api_topic_config_next RENAME TO api_topic_config");
|
|
8184
|
+
})();
|
|
8185
|
+
} finally {
|
|
8186
|
+
db.exec(`PRAGMA foreign_keys = ${previousForeignKeys ? "ON" : "OFF"}`);
|
|
8187
|
+
}
|
|
8188
|
+
} else {
|
|
8189
|
+
createCanonicalConfigTable();
|
|
8190
|
+
}
|
|
8191
|
+
}
|
|
8192
|
+
function rowToConfig(r) {
|
|
8193
|
+
const cfg = {};
|
|
8194
|
+
if (r.model)
|
|
8195
|
+
cfg.model = r.model;
|
|
8196
|
+
if (r.effort)
|
|
8197
|
+
cfg.effort = r.effort;
|
|
8198
|
+
if (r.mcp) {
|
|
8199
|
+
try {
|
|
8200
|
+
const parsed = JSON.parse(r.mcp);
|
|
8201
|
+
if (Array.isArray(parsed))
|
|
8202
|
+
cfg.mcp = parsed;
|
|
8203
|
+
} catch {}
|
|
8204
|
+
}
|
|
8205
|
+
if (r.agent_locked)
|
|
8206
|
+
cfg.agentLocked = true;
|
|
8207
|
+
if (r.model_locked)
|
|
8208
|
+
cfg.modelLocked = true;
|
|
8209
|
+
if (r.effort_locked)
|
|
8210
|
+
cfg.effortLocked = true;
|
|
8211
|
+
return cfg;
|
|
8212
|
+
}
|
|
8213
|
+
function getApiTopicConfig(topicId) {
|
|
8214
|
+
const row = db.query("SELECT topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked FROM api_topic_config WHERE topic_id = ?").get(topicId);
|
|
8215
|
+
if (!row)
|
|
8216
|
+
return;
|
|
8217
|
+
const config = rowToConfig(row);
|
|
8218
|
+
return Object.keys(config).length > 0 ? config : undefined;
|
|
8219
|
+
}
|
|
8220
|
+
function setApiTopicConfig(topicId, config) {
|
|
8221
|
+
db.query(`INSERT INTO api_topic_config
|
|
8222
|
+
(topic_id, model, effort, mcp, agent_locked, model_locked, effort_locked)
|
|
8223
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
8224
|
+
ON CONFLICT(topic_id) DO UPDATE SET
|
|
8225
|
+
model = excluded.model,
|
|
8226
|
+
effort = excluded.effort,
|
|
8227
|
+
mcp = excluded.mcp,
|
|
8228
|
+
agent_locked = excluded.agent_locked,
|
|
8229
|
+
model_locked = excluded.model_locked,
|
|
8230
|
+
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);
|
|
8231
|
+
}
|
|
8232
|
+
function deleteApiTopicConfig(topicId) {
|
|
8233
|
+
db.query("DELETE FROM api_topic_config WHERE topic_id = ?").run(topicId);
|
|
8234
|
+
}
|
|
8235
|
+
var init_api_topic_config = __esm(async () => {
|
|
8236
|
+
await init_forum_db();
|
|
8237
|
+
await init_storage_host();
|
|
8238
|
+
registerStorageSchemaInitializer(initializeApiTopicConfigSchema, 40);
|
|
8239
|
+
});
|
|
8240
|
+
|
|
8237
8241
|
// ../../packages/core/src/topics/personal-general.ts
|
|
8238
8242
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
8239
8243
|
function ensurePersonalGeneral(userId, surface, opts = {}) {
|
|
@@ -8348,6 +8352,7 @@ function createArchiverRuntime(host) {
|
|
|
8348
8352
|
const runTurn = (params) => {
|
|
8349
8353
|
const {
|
|
8350
8354
|
userId,
|
|
8355
|
+
sourceTopicId,
|
|
8351
8356
|
topicId,
|
|
8352
8357
|
topicTitle,
|
|
8353
8358
|
archivePath,
|
|
@@ -8355,6 +8360,7 @@ function createArchiverRuntime(host) {
|
|
|
8355
8360
|
messageCount,
|
|
8356
8361
|
mode = "deleted-topic"
|
|
8357
8362
|
} = params;
|
|
8363
|
+
const generalTopicId = host.storage.getGeneralTopicId(userId, sourceTopicId);
|
|
8358
8364
|
let definition;
|
|
8359
8365
|
try {
|
|
8360
8366
|
definition = getAgentDefinition();
|
|
@@ -8367,12 +8373,15 @@ function createArchiverRuntime(host) {
|
|
|
8367
8373
|
const agent = params.agent ?? "claude";
|
|
8368
8374
|
const model = params.model;
|
|
8369
8375
|
const outputLanguage = resolveMemoryLanguage();
|
|
8376
|
+
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.";
|
|
8370
8377
|
const prompt = mode === "active-topic" ? [
|
|
8371
8378
|
`Recent idle conversation snapshot of session "${topicTitle}". Extract durable memory from the archive below and save it into this topic's wiki.`,
|
|
8372
8379
|
`archive_path: ${archivePath}`,
|
|
8373
8380
|
...rawArchivePaths.map((path) => `raw_archive_path: ${path}`),
|
|
8374
8381
|
`wiki_dir: ${wikiDir}`,
|
|
8375
|
-
`output_language: ${outputLanguage}
|
|
8382
|
+
`output_language: ${outputLanguage}`,
|
|
8383
|
+
"",
|
|
8384
|
+
generalReplyInstruction
|
|
8376
8385
|
].join(`
|
|
8377
8386
|
`) : [
|
|
8378
8387
|
`Session "${topicTitle}" was deleted. Extract durable memory from the archive below and save it into the wiki.`,
|
|
@@ -8381,7 +8390,7 @@ function createArchiverRuntime(host) {
|
|
|
8381
8390
|
`wiki_dir: ${wikiDir}`,
|
|
8382
8391
|
`output_language: ${outputLanguage}`,
|
|
8383
8392
|
"",
|
|
8384
|
-
|
|
8393
|
+
generalReplyInstruction
|
|
8385
8394
|
].join(`
|
|
8386
8395
|
`);
|
|
8387
8396
|
const activeSessionId = `memory:${host.config.createId()}`;
|
|
@@ -8509,10 +8518,8 @@ function createArchiverRuntime(host) {
|
|
|
8509
8518
|
host.config.warn({ err, userId, topicTitle }, "archiver: settlement callback failed");
|
|
8510
8519
|
}
|
|
8511
8520
|
}
|
|
8512
|
-
|
|
8513
|
-
|
|
8514
|
-
finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs, ok, topicId, ok && text ? { text, agent, model, usage } : undefined);
|
|
8515
|
-
}
|
|
8521
|
+
const text = finalText.trimEnd();
|
|
8522
|
+
finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs, ok, mode, topicId, generalTopicId, ok && text ? { text, agent, model, usage } : undefined);
|
|
8516
8523
|
});
|
|
8517
8524
|
topicQueues.set(safeTopic, work);
|
|
8518
8525
|
work.finally(() => {
|
|
@@ -8558,14 +8565,14 @@ function findSummaryFile(storage, topicTitle, date, sinceMs, topicId) {
|
|
|
8558
8565
|
}
|
|
8559
8566
|
return best?.path ?? null;
|
|
8560
8567
|
}
|
|
8561
|
-
function finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs, ok, topicId, generalReply) {
|
|
8562
|
-
const
|
|
8568
|
+
function finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs, ok, mode, topicId, generalTopicId, generalReply) {
|
|
8569
|
+
const resolvedGeneralTopicId = generalTopicId ?? host.storage.getGeneralTopicId(userId, topicId);
|
|
8563
8570
|
const date = host.config.now().toISOString().slice(0, 10);
|
|
8564
8571
|
try {
|
|
8565
8572
|
const summaryPath = ok ? findSummaryFile(host.storage, topicTitle, date, startMs, topicId) : null;
|
|
8566
8573
|
const summaryMd = summaryPath ? host.storage.readTextFile(summaryPath) : "";
|
|
8567
8574
|
const oneLine = summaryMd && distillOneLine(summaryMd) || `Archived ${messageCount} messages`;
|
|
8568
|
-
const prev = host.storage.getTopicBrief(
|
|
8575
|
+
const prev = host.storage.getTopicBrief(resolvedGeneralTopicId);
|
|
8569
8576
|
const prevEntries = (prev?.briefMd ?? "").split(`
|
|
8570
8577
|
`).map((l) => l.trim()).filter((l) => l.startsWith("- "));
|
|
8571
8578
|
const newEntry = `- **${topicTitle}** (${date}): ${oneLine}`;
|
|
@@ -8575,12 +8582,12 @@ function finalizeGeneralMemory(host, userId, topicTitle, messageCount, startMs,
|
|
|
8575
8582
|
].slice(0, MAX_BRIEF_ENTRIES);
|
|
8576
8583
|
const briefMd = `# Workspace Memory Hub
|
|
8577
8584
|
|
|
8578
|
-
Recent memory digest distilled from
|
|
8585
|
+
Recent memory digest distilled from archived topics (deletions and idle/session-reset snapshots). Use \`wiki_query\` for details.
|
|
8579
8586
|
|
|
8580
8587
|
## Recent Archives
|
|
8581
8588
|
${rolled.join(`
|
|
8582
8589
|
`)}`;
|
|
8583
|
-
host.storage.setTopicBrief(
|
|
8590
|
+
host.storage.setTopicBrief(resolvedGeneralTopicId, {
|
|
8584
8591
|
briefMd,
|
|
8585
8592
|
...summaryMd ? { latestSummaryMd: summaryMd, summaryDate: date } : {}
|
|
8586
8593
|
});
|
|
@@ -8590,7 +8597,7 @@ ${rolled.join(`
|
|
|
8590
8597
|
}
|
|
8591
8598
|
try {
|
|
8592
8599
|
const replyText = generalReply?.text.trim();
|
|
8593
|
-
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).`);
|
|
8600
|
+
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).`);
|
|
8594
8601
|
const replyMeta = generalReply && replyText ? {
|
|
8595
8602
|
authorId: "ai",
|
|
8596
8603
|
agentType: generalReply.agent,
|
|
@@ -8599,13 +8606,13 @@ ${rolled.join(`
|
|
|
8599
8606
|
} : { authorId: "system" };
|
|
8600
8607
|
const msg = {
|
|
8601
8608
|
id: host.config.createId(),
|
|
8602
|
-
topicId:
|
|
8609
|
+
topicId: resolvedGeneralTopicId,
|
|
8603
8610
|
text,
|
|
8604
8611
|
...replyMeta,
|
|
8605
8612
|
createdAt: host.config.now().toISOString()
|
|
8606
8613
|
};
|
|
8607
8614
|
host.messaging.appendMessage(msg);
|
|
8608
|
-
host.messaging.broadcastMessage(
|
|
8615
|
+
host.messaging.broadcastMessage(resolvedGeneralTopicId, msg);
|
|
8609
8616
|
} catch (err) {
|
|
8610
8617
|
host.config.warn({ err, topicTitle }, "archiver: failed to post #General notification");
|
|
8611
8618
|
}
|
|
@@ -8624,6 +8631,7 @@ var init_archiver = __esm(async () => {
|
|
|
8624
8631
|
init_background_session_policy();
|
|
8625
8632
|
await init_api_messages();
|
|
8626
8633
|
await init_api_topic_brief();
|
|
8634
|
+
await init_api_topics();
|
|
8627
8635
|
await init_wiki();
|
|
8628
8636
|
init_wiki_summary_names();
|
|
8629
8637
|
await init_personal_general();
|
|
@@ -8635,7 +8643,12 @@ var init_archiver = __esm(async () => {
|
|
|
8635
8643
|
readTextFile: (path) => readFileSync13(path, "utf-8"),
|
|
8636
8644
|
fileSize: (path) => statSync6(path).size,
|
|
8637
8645
|
fileModifiedAt: (path) => statSync6(path).mtimeMs,
|
|
8638
|
-
getGeneralTopicId: (userId) =>
|
|
8646
|
+
getGeneralTopicId: (userId, sourceTopicId) => {
|
|
8647
|
+
const source = sourceTopicId ? getTopic(sourceTopicId) : null;
|
|
8648
|
+
return source ? ensurePersonalGeneral(userId, source.surface, {
|
|
8649
|
+
surfaceScope: source.surfaceScope ?? null
|
|
8650
|
+
}).id : ensurePersonalGeneral(userId).id;
|
|
8651
|
+
},
|
|
8639
8652
|
getTopicBrief,
|
|
8640
8653
|
setTopicBrief: (topicId, fields) => {
|
|
8641
8654
|
setTopicBrief(topicId, fields);
|
|
@@ -9823,6 +9836,7 @@ function archiveActiveTopicForMemory(topicId, userId, options) {
|
|
|
9823
9836
|
const memoryTitle = memoryTopic.memoryKey?.trim() || memoryTopic.title;
|
|
9824
9837
|
const launched = (options.launchArchiver ?? runArchiverTurn)({
|
|
9825
9838
|
userId,
|
|
9839
|
+
sourceTopicId: topic.id,
|
|
9826
9840
|
topicId: memoryTopic.id,
|
|
9827
9841
|
topicTitle: memoryTitle,
|
|
9828
9842
|
archivePath: job.archivePath,
|
|
@@ -14497,7 +14511,8 @@ async function deleteTopicCascadeImpl(topic, userId, options, deletingAncestorId
|
|
|
14497
14511
|
const memoryTopic = topic.memoryKey ? topic : getTopicMemoryOrigin(topicId) ?? topic;
|
|
14498
14512
|
const memoryTitle = memoryTopic.memoryKey?.trim() || memoryTopic.title;
|
|
14499
14513
|
runArchiverTurn({
|
|
14500
|
-
userId,
|
|
14514
|
+
userId: options.memoryUserId ?? userId,
|
|
14515
|
+
sourceTopicId: topicId,
|
|
14501
14516
|
...memoryTopic.id !== topicId && !deletingTopicIds.has(memoryTopic.id) ? { topicId: memoryTopic.id } : {},
|
|
14502
14517
|
topicTitle: memoryTitle,
|
|
14503
14518
|
archivePath: archived.path,
|
|
@@ -15751,7 +15766,7 @@ ${JSON.stringify(event.input ?? {})}`);
|
|
|
15751
15766
|
}
|
|
15752
15767
|
}
|
|
15753
15768
|
if (!silent) {
|
|
15754
|
-
scheduleIdleArchiveForTopic(topicId, userId);
|
|
15769
|
+
scheduleIdleArchiveForTopic(topicId, execution?.actorUserId ?? userId);
|
|
15755
15770
|
hub.broadcastDone(topicId, queryId, event.usage ? {
|
|
15756
15771
|
input: event.usage.inputTokens,
|
|
15757
15772
|
output: event.usage.outputTokens,
|
|
@@ -17122,7 +17137,13 @@ function startAiTurn(params) {
|
|
|
17122
17137
|
WsHub.get().broadcastTyping(topicId, "ai");
|
|
17123
17138
|
WsHub.get().broadcastAiActive(topicId, queryId);
|
|
17124
17139
|
}
|
|
17125
|
-
streamAgentEvents(topicId, topic.title, queryId, events, control, agentKind, resolvedModel, resolvedEffort, userId, !sessionRetried, onSessionId, {
|
|
17140
|
+
streamAgentEvents(topicId, topic.title, queryId, events, control, agentKind, resolvedModel, resolvedEffort, userId, !sessionRetried, onSessionId, {
|
|
17141
|
+
silent,
|
|
17142
|
+
actorUserId: params.actorUserId,
|
|
17143
|
+
peerBridge,
|
|
17144
|
+
sourceNode,
|
|
17145
|
+
...threadRootId ? { threadRootId } : {}
|
|
17146
|
+
}).then(async (streamOutcome) => {
|
|
17126
17147
|
let outcome = streamOutcome;
|
|
17127
17148
|
if (outcome.kind === "session-expired") {
|
|
17128
17149
|
const retry = resolveSessionRetry({
|
|
@@ -19294,4 +19315,4 @@ export {
|
|
|
19294
19315
|
DEFAULT_SELF_CONFIG_PRODUCT
|
|
19295
19316
|
};
|
|
19296
19317
|
|
|
19297
|
-
//# debugId=
|
|
19318
|
+
//# debugId=E2BEA0E09AFF549864756E2164756E21
|