negotium 0.13.1 → 0.14.1

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.
Files changed (69) hide show
  1. package/dist/agent-helpers.js +203 -9
  2. package/dist/agent-helpers.js.map +17 -15
  3. package/dist/background-bash.js +13 -2
  4. package/dist/background-bash.js.map +4 -4
  5. package/dist/browser-runtime.js +38 -4
  6. package/dist/browser-runtime.js.map +7 -7
  7. package/dist/{chunk-j40vv7yx.js → chunk-5m3kd08d.js} +3 -3
  8. package/dist/{chunk-j40vv7yx.js.map → chunk-5m3kd08d.js.map} +2 -2
  9. package/dist/{chunk-bby846gb.js → chunk-m6aw1tb3.js} +1 -1
  10. package/dist/{chunk-7m4ejc7c.js → chunk-z1nb140t.js} +22 -4
  11. package/dist/chunk-z1nb140t.js.map +37 -0
  12. package/dist/hosted-agent.js +23 -5
  13. package/dist/hosted-agent.js.map +8 -8
  14. package/dist/main.js +516 -34
  15. package/dist/main.js.map +25 -22
  16. package/dist/mcp-factories.js +133 -9
  17. package/dist/mcp-factories.js.map +12 -12
  18. package/dist/media.js +13 -2
  19. package/dist/media.js.map +4 -4
  20. package/dist/prompts.js +13 -2
  21. package/dist/prompts.js.map +4 -4
  22. package/dist/query-runtime.js +13 -2
  23. package/dist/query-runtime.js.map +4 -4
  24. package/dist/registry.js +3 -3
  25. package/dist/rollout.js +2 -2
  26. package/dist/runtime/src/agents/archiver.ts +4 -0
  27. package/dist/runtime/src/agents/mcp-tools/self-config.ts +62 -3
  28. package/dist/runtime/src/agents/public-helpers.ts +12 -0
  29. package/dist/runtime/src/agents/topic-defaults.ts +128 -0
  30. package/dist/runtime/src/application/topic-service.ts +11 -1
  31. package/dist/runtime/src/index.ts +6 -2
  32. package/dist/runtime/src/mcp/runtime-spec.ts +6 -0
  33. package/dist/runtime/src/mcp/wiki-server.ts +148 -2
  34. package/dist/runtime/src/mcp-runtime-host.ts +7 -1
  35. package/dist/runtime/src/platform/config.ts +15 -2
  36. package/dist/runtime/src/platform/mcp-config.ts +10 -1
  37. package/dist/runtime/src/platform/playwright/manager-utils.ts +20 -0
  38. package/dist/runtime/src/platform/playwright/manager.ts +33 -2
  39. package/dist/runtime/src/prompts/agents/wiki-archiver.md +27 -3
  40. package/dist/runtime/src/storage/storage-public.ts +2 -0
  41. package/dist/runtime/src/storage/topic-default-assignments.ts +140 -0
  42. package/dist/runtime/src/storage/vault.ts +63 -2
  43. package/dist/runtime/src/topics/create.ts +81 -6
  44. package/dist/runtime/src/types.ts +6 -0
  45. package/dist/runtime/src/version.ts +1 -1
  46. package/dist/runtime-helpers.js +6 -2
  47. package/dist/runtime-helpers.js.map +4 -4
  48. package/dist/storage.js +81 -1
  49. package/dist/storage.js.map +5 -4
  50. package/dist/types/packages/core/src/agents/mcp-tools/self-config.d.ts +30 -2
  51. package/dist/types/packages/core/src/agents/public-helpers.d.ts +2 -1
  52. package/dist/types/packages/core/src/agents/topic-defaults.d.ts +41 -0
  53. package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +2 -0
  54. package/dist/types/packages/core/src/mcp/wiki-server.d.ts +20 -0
  55. package/dist/types/packages/core/src/platform/config.d.ts +9 -2
  56. package/dist/types/packages/core/src/platform/mcp-config.d.ts +3 -0
  57. package/dist/types/packages/core/src/platform/playwright/manager-utils.d.ts +13 -0
  58. package/dist/types/packages/core/src/platform/playwright/manager.d.ts +1 -1
  59. package/dist/types/packages/core/src/storage/storage-public.d.ts +2 -0
  60. package/dist/types/packages/core/src/storage/topic-default-assignments.d.ts +34 -0
  61. package/dist/types/packages/core/src/storage/vault.d.ts +2 -0
  62. package/dist/types/packages/core/src/types.d.ts +6 -0
  63. package/dist/types/packages/core/src/version.d.ts +1 -1
  64. package/dist/vault.js +59 -3
  65. package/dist/vault.js.map +5 -5
  66. package/install-browser-rs.mjs +3 -3
  67. package/package.json +1 -1
  68. package/dist/chunk-7m4ejc7c.js.map +0 -37
  69. /package/dist/{chunk-bby846gb.js.map → chunk-m6aw1tb3.js.map} +0 -0
@@ -343,7 +343,7 @@ function resolveWhisperBackend() {
343
343
  function codexAuthFilePath() {
344
344
  return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
345
345
  }
346
- var HOME, PROJECT_ROOT, STATE_DIR, WORKSPACE_DIR, TOPIC_WORKSPACE_DIR, SHARED_WIKI_DIR, CRON_WORKSPACE_DIR, BROWSER_DIR, BROWSER_PROFILES_DIR, BINARIES_DIR, SECRETS_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BROWSER_RS_VERSION = "v0.3.1", BROWSER_RS_MIN_SECURE_VERSION = "0.2.1", BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000, SNIPPETS_API_URL, BROWSER_RS_BIN, BASH_RS_VERSION = "v0.1.7", BASH_RS_BIN, PLAYWRIGHT_MCP_BIN, TSX_BIN, TSX_LOADER, TSCONFIG_PATH, SESSION_COMM_SERVER, TASK_SERVER, DECISION_SERVER, CANONICAL_MCP_PROXY_SERVER, WIKI_SERVER, TOKEN_STATS_SERVER, COMPACTION_LOG_SERVER, SYSTEM_HEALTH_SERVER, AGENT_HEALTH_SERVER, VAULT_SERVER, BG_BASH_BASE_PORT, BG_BASH_MAX_PORT, RUNTIME_MCP_SECRET, NODE_CONTROL_TOKEN, NODE_ID, VAULT_MASTER_KEY, NEGOTIUM_PORT, hostname, DATA_DIR, LOG_DIR, UPLOADS_DIR, VAULT_DIR, SESSIONS_DB, DEBUG_FILE, USERS_LOG_DIR, RUN_DIR, PROGRESS_DIR, DM_CMD_DIR, DM_RESP_DIR, SESSION_INBOX_DIR, SESSION_ASKS_DIR, BASHRS_SPILL_ROOT, PLAYWRIGHT_BASE_PORT, PLAYWRIGHT_MAX_PORT, PLAYWRIGHT_PORTS_DIR, ACTIVE_QUERY_STALE_MS, AGENTS_PROMPTS_DIR, RESOURCES_DIR, FILE_TAG_REGEX, MODEL_SONNET = "claude-sonnet-5", MODEL_OPUS = "claude-opus-5", MODEL_FABLE = "claude-fable-5-1", FALLBACK_AGENT, SESSION_AGENT, GATEWAY_AGENT, FALLBACK_MODEL, SESSION_MODEL, GATEWAY_MODEL, FFMPEG_BIN, FFPROBE_BIN, PYTHON_BIN, FASTER_WHISPER_WRAPPER, WHISPER_MODEL, TESSERACT_BIN, PDFTOTEXT_BIN, WHISPER_BACKEND, MLX_WHISPER_BIN, WHISPER_MODEL_MLX, _envMaxTellDepth, MAX_TELL_DEPTH;
346
+ var HOME, PROJECT_ROOT, STATE_DIR, WORKSPACE_DIR, TOPIC_WORKSPACE_DIR, SHARED_WIKI_DIR, CRON_WORKSPACE_DIR, BROWSER_DIR, BROWSER_PROFILES_DIR, BINARIES_DIR, SECRETS_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BROWSER_RS_VERSION = "v0.3.2", BROWSER_RS_MIN_SECURE_VERSION = "0.2.1", BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000, SNIPPETS_API_URL, BROWSER_RS_BIN, BASH_RS_VERSION = "v0.1.7", BASH_RS_BIN, PLAYWRIGHT_MCP_BIN, TSX_BIN, TSX_LOADER, TSCONFIG_PATH, SESSION_COMM_SERVER, TASK_SERVER, DECISION_SERVER, CANONICAL_MCP_PROXY_SERVER, WIKI_SERVER, TOKEN_STATS_SERVER, COMPACTION_LOG_SERVER, SYSTEM_HEALTH_SERVER, AGENT_HEALTH_SERVER, VAULT_SERVER, BG_BASH_BASE_PORT, BG_BASH_MAX_PORT, RUNTIME_MCP_SECRET, NODE_CONTROL_TOKEN, NODE_ID, VAULT_MASTER_KEY, NEGOTIUM_PORT, hostname, DATA_DIR, LOG_DIR, UPLOADS_DIR, VAULT_DIR, SESSIONS_DB, DEBUG_FILE, USERS_LOG_DIR, RUN_DIR, PROGRESS_DIR, DM_CMD_DIR, DM_RESP_DIR, SESSION_INBOX_DIR, SESSION_ASKS_DIR, BASHRS_SPILL_ROOT, PLAYWRIGHT_BASE_PORT, PLAYWRIGHT_MAX_PORT, PLAYWRIGHT_PORTS_DIR, ACTIVE_QUERY_STALE_MS, AGENTS_PROMPTS_DIR, RESOURCES_DIR, FILE_TAG_REGEX, MODEL_SONNET = "claude-sonnet-5", MODEL_OPUS = "claude-opus-5", MODEL_FABLE = "claude-fable-5-1", FALLBACK_AGENT, SESSION_AGENT, GATEWAY_AGENT, FALLBACK_MODEL, SESSION_MODEL, GATEWAY_MODEL, DEFAULT_TOPIC_EFFORT, FFMPEG_BIN, FFPROBE_BIN, PYTHON_BIN, FASTER_WHISPER_WRAPPER, WHISPER_MODEL, TESSERACT_BIN, PDFTOTEXT_BIN, WHISPER_BACKEND, MLX_WHISPER_BIN, WHISPER_MODEL_MLX, _envMaxTellDepth, MAX_TELL_DEPTH;
347
347
  var init_config = __esm(() => {
348
348
  init_config_helpers();
349
349
  init_logger();
@@ -437,6 +437,10 @@ var init_config = __esm(() => {
437
437
  FALLBACK_MODEL = envText("FALLBACK_MODEL") ?? envText("DEFAULT_MODEL");
438
438
  SESSION_MODEL = resolveModelEnv("SESSION_MODEL", SESSION_AGENT);
439
439
  GATEWAY_MODEL = resolveModelEnv("GATEWAY_MODEL", GATEWAY_AGENT);
440
+ DEFAULT_TOPIC_EFFORT = (() => {
441
+ const raw = envText("NEGOTIUM_DEFAULT_EFFORT")?.toLowerCase();
442
+ return raw && EFFORT_VALUES.includes(raw) ? raw : "medium";
443
+ })();
440
444
  FFMPEG_BIN = envText("FFMPEG_BIN");
441
445
  FFPROBE_BIN = envText("FFPROBE_BIN");
442
446
  PYTHON_BIN = envText("PYTHON_BIN") ?? "python3";
@@ -537,7 +541,8 @@ function hostedMcpCacheIdentity(surface, ctx) {
537
541
  case "skills":
538
542
  semanticContext = {
539
543
  userId: ctx.userId,
540
- topicId: ctx.wikiTopicId ?? ctx.topicId ?? null
544
+ topicId: ctx.wikiTopicId ?? ctx.topicId ?? null,
545
+ memoryKey: ctx.wikiMemoryKey ?? null
541
546
  };
542
547
  break;
543
548
  case "vault":
@@ -924,6 +929,7 @@ function buildBuiltinMcpServer(surface, ctx, stdio) {
924
929
  ...ctx.topicId ? { topicId: ctx.topicId } : {},
925
930
  ...ctx.queryId ? { queryId: ctx.queryId } : {},
926
931
  ...ctx.wikiTopicId ? { wikiTopicId: ctx.wikiTopicId } : {},
932
+ ...ctx.wikiMemoryKey ? { wikiMemoryKey: ctx.wikiMemoryKey } : {},
927
933
  ...ctx.subagentParentTopicId ? { subagentParentTopicId: ctx.subagentParentTopicId } : {},
928
934
  ...ctx.threadRootId ? { threadRootId: ctx.threadRootId } : {},
929
935
  cwd: ctx.cwd ?? (ctx.topicId ? resolveTopicWorkspaceDir(ctx.topicId) : process.cwd()),
@@ -1073,6 +1079,7 @@ function getForumMcpServers(opts) {
1073
1079
  subagentParentTopicId,
1074
1080
  queryId,
1075
1081
  wikiTopicId,
1082
+ wikiMemoryKey,
1076
1083
  agent,
1077
1084
  cwd,
1078
1085
  model,
@@ -1106,6 +1113,7 @@ function getForumMcpServers(opts) {
1106
1113
  subagentParentTopicId,
1107
1114
  queryId,
1108
1115
  wikiTopicId,
1116
+ wikiMemoryKey,
1109
1117
  agent,
1110
1118
  cwd,
1111
1119
  model,
@@ -1202,6 +1210,7 @@ function getMcpServersForQuery(opts) {
1202
1210
  subagentParentTopicId: opts.subagentParentTopicId,
1203
1211
  queryId: opts.queryId,
1204
1212
  wikiTopicId: opts.wikiTopicId,
1213
+ wikiMemoryKey: opts.wikiMemoryKey,
1205
1214
  agent: opts.agent,
1206
1215
  cwd: opts.cwd,
1207
1216
  model: opts.model,
@@ -1379,7 +1388,7 @@ var init_mcp_config = __esm(() => {
1379
1388
  wiki: {
1380
1389
  ...commonRuntimeMcpPolicy("wiki"),
1381
1390
  build(ctx) {
1382
- const { userId, session, topicId, queryId, wikiTopicId, agent, peerBridge } = ctx;
1391
+ const { userId, session, topicId, queryId, wikiTopicId, wikiMemoryKey, agent, peerBridge } = ctx;
1383
1392
  if (peerBridge) {
1384
1393
  if (!topicId || !queryId)
1385
1394
  return null;
@@ -1398,6 +1407,8 @@ var init_mcp_config = __esm(() => {
1398
1407
  const resolvedWikiTopicId = wikiTopicId ?? topicId ?? (session !== "dm" ? session : undefined);
1399
1408
  if (resolvedWikiTopicId)
1400
1409
  args.push(`--topic-id=${resolvedWikiTopicId}`);
1410
+ if (wikiMemoryKey)
1411
+ args.push(`--memory-key=${wikiMemoryKey}`);
1401
1412
  args.push("--surface=wiki");
1402
1413
  return buildBuiltinMcpServer("wiki", { ...ctx, wikiTopicId: resolvedWikiTopicId }, () => buildStdioMcpServer(agent, WIKI_SERVER, args));
1403
1414
  }
@@ -3061,7 +3072,7 @@ var init_codex = __esm(async () => {
3061
3072
  });
3062
3073
 
3063
3074
  // ../../packages/core/src/version.ts
3064
- var NEGOTIUM_VERSION = "0.13.1";
3075
+ var NEGOTIUM_VERSION = "0.14.1";
3065
3076
 
3066
3077
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
3067
3078
  import { spawn as spawn2 } from "child_process";
@@ -8664,6 +8675,7 @@ function createArchiverRuntime(host) {
8664
8675
  session: `__archiver_${safeTopic}`,
8665
8676
  sessionType: "forum",
8666
8677
  topicId,
8678
+ wikiMemoryKey: topicTitle,
8667
8679
  abortController: new AbortController,
8668
8680
  model,
8669
8681
  mcpEnabled: ["wiki"],
@@ -10928,6 +10940,15 @@ function matchesSpawnedBrowserHealth(health, expectedSpawnNonce) {
10928
10940
  const candidate = health;
10929
10941
  return candidate.ok === true && candidate.name === "negotium-browser-gateway" && candidate.spawnNonce === expectedSpawnNonce;
10930
10942
  }
10943
+ function browserCdpIsLost(health) {
10944
+ if (!health || typeof health !== "object")
10945
+ return false;
10946
+ const browser = health.browser;
10947
+ if (!browser || typeof browser !== "object")
10948
+ return false;
10949
+ const candidate = browser;
10950
+ return candidate.launched === true && candidate.connected === false;
10951
+ }
10931
10952
  function selectIdleEvictionKey(candidates, pinnedKeys, busyKeys, now, maxIdleMs) {
10932
10953
  const pinned = new Set(pinnedKeys);
10933
10954
  const busy = new Set(busyKeys);
@@ -12005,7 +12026,7 @@ async function ensurePlaywright(userId, topic) {
12005
12026
  const existing = instances.get(instanceKey);
12006
12027
  assertInstanceOwner(instanceKey, ownerId);
12007
12028
  if (existing && !existing.process.killed && existing.process.exitCode === null) {
12008
- if (await probePlaywrightMcpTransports(existing.port, existing.capability)) {
12029
+ if (await probePlaywrightMcpTransports(existing.port, existing.capability) && !await browserTransportLost(existing.port)) {
12009
12030
  existing.lastUsedAt = Date.now();
12010
12031
  return existing.port;
12011
12032
  }
@@ -12061,6 +12082,20 @@ async function closeBrowserOwnerTabs(ownerId, rawProfile, owner) {
12061
12082
  const result = await response.json();
12062
12083
  return typeof result.closed === "number" ? result.closed : 0;
12063
12084
  }
12085
+ async function browserTransportLost(port) {
12086
+ try {
12087
+ const response = await fetch(`http://127.0.0.1:${port}/health`, {
12088
+ signal: AbortSignal.timeout(1000)
12089
+ });
12090
+ if (!response.ok) {
12091
+ await response.body?.cancel();
12092
+ return false;
12093
+ }
12094
+ return browserCdpIsLost(await response.json());
12095
+ } catch {
12096
+ return false;
12097
+ }
12098
+ }
12064
12099
  async function waitForServer(port, expectedSpawnNonce, timeoutMs) {
12065
12100
  const start = Date.now();
12066
12101
  while (Date.now() - start < timeoutMs) {
@@ -20062,6 +20097,33 @@ var defaultSelfConfigCore = createSelfConfigCore(defaultSelfConfigHost);
20062
20097
 
20063
20098
  // ../../packages/core/src/agents/mcp-tools/self-config.ts
20064
20099
  init_types();
20100
+ var SELF_CONFIG_CAPABILITIES = {
20101
+ model: ["get_model", "set_model"],
20102
+ agent: ["get_agent", "set_agent"],
20103
+ effort: ["get_effort", "set_effort"],
20104
+ schedules: ["schedule_self", "get_self_schedule", "update_self_schedule", "cancel_self_schedule"],
20105
+ "derived-topics": ["spawn_topic", "fork_topic"]
20106
+ };
20107
+ function expandCapabilitySelectors(selectors) {
20108
+ const names = new Set;
20109
+ for (const selector of selectors) {
20110
+ const group = SELF_CONFIG_CAPABILITIES[selector];
20111
+ if (group) {
20112
+ for (const name of group)
20113
+ names.add(name);
20114
+ continue;
20115
+ }
20116
+ names.add(selector);
20117
+ }
20118
+ return names;
20119
+ }
20120
+ function applySelfConfigCapabilityFilter(tools, filter) {
20121
+ if (!filter?.include && !filter?.exclude)
20122
+ return tools;
20123
+ const included = filter.include ? expandCapabilitySelectors(filter.include) : undefined;
20124
+ const excluded = filter.exclude ? expandCapabilitySelectors(filter.exclude) : undefined;
20125
+ return tools.filter((tool) => (!included || included.has(tool.name)) && !(excluded?.has(tool.name) ?? false));
20126
+ }
20065
20127
  var AGENT_VALUES = SUPPORTED_AGENTS;
20066
20128
  function mcpResult(result) {
20067
20129
  return {
@@ -20080,11 +20142,12 @@ function createSelfConfigRuntime(options) {
20080
20142
  const runtime = {
20081
20143
  core,
20082
20144
  mcpKey: core.product.mcpKey,
20083
- createToolDefinitions: (ctx) => createSelfConfigToolDefinitionsForCore(core, ctx)
20145
+ ...options.capabilities ? { capabilities: options.capabilities } : {},
20146
+ createToolDefinitions: (ctx) => createSelfConfigToolDefinitionsForCore(core, ctx, options.capabilities)
20084
20147
  };
20085
20148
  return Object.freeze(runtime);
20086
20149
  }
20087
- function createSelfConfigToolDefinitionsForCore(core, ctx) {
20150
+ function createSelfConfigToolDefinitionsForCore(core, ctx, capabilities) {
20088
20151
  const getCtx = contextGetter(ctx);
20089
20152
  let derivedCount = 0;
20090
20153
  const tools = [
@@ -20225,7 +20288,7 @@ function createSelfConfigToolDefinitionsForCore(core, ctx) {
20225
20288
  }
20226
20289
  });
20227
20290
  }
20228
- return tools;
20291
+ return applySelfConfigCapabilityFilter(tools, capabilities);
20229
20292
  }
20230
20293
 
20231
20294
  // ../../packages/core/src/agents/public-helpers.ts
@@ -20294,10 +20357,137 @@ var otiumVisualToolDefinitions = [
20294
20357
  await init_task_events();
20295
20358
  init_tool_format();
20296
20359
  await init_topic_cleanup();
20360
+
20361
+ // ../../packages/core/src/agents/topic-defaults.ts
20362
+ init_model_catalog();
20363
+ await init_registry();
20364
+ init_config();
20365
+ init_logger();
20366
+
20367
+ // ../../packages/core/src/storage/topic-default-assignments.ts
20368
+ await init_forum_db();
20369
+ await init_storage_host();
20370
+ init_wiki_summary_names();
20371
+ registerStorageSchemaInitializer((database) => {
20372
+ database.exec(`
20373
+ CREATE TABLE IF NOT EXISTS topic_default_assignments (
20374
+ memory_key TEXT PRIMARY KEY,
20375
+ model TEXT NOT NULL,
20376
+ effort TEXT,
20377
+ reason TEXT,
20378
+ assign_count INTEGER NOT NULL DEFAULT 1,
20379
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
20380
+ )
20381
+ `);
20382
+ }, 31);
20383
+ function normalizeMemoryKey(memoryKey) {
20384
+ const raw = memoryKey.trim().replace(/^topic\//, "").replace(/\.md$/i, "").trim();
20385
+ if (!raw)
20386
+ return "";
20387
+ return wikiSummarySlug(raw).toLowerCase();
20388
+ }
20389
+ function rowToAssignment(row) {
20390
+ return {
20391
+ memoryKey: row.memory_key,
20392
+ model: row.model,
20393
+ effort: row.effort ?? undefined,
20394
+ reason: row.reason ?? undefined,
20395
+ assignCount: row.assign_count,
20396
+ updatedAt: row.updated_at
20397
+ };
20398
+ }
20399
+ var SELECT_COLUMNS = "memory_key, model, effort, reason, assign_count, updated_at";
20400
+ function getTopicDefaultAssignment(memoryKey) {
20401
+ const key = normalizeMemoryKey(memoryKey);
20402
+ if (!key)
20403
+ return null;
20404
+ const row = db.query(`SELECT ${SELECT_COLUMNS} FROM topic_default_assignments WHERE memory_key = ?`).get(key);
20405
+ return row ? rowToAssignment(row) : null;
20406
+ }
20407
+ function upsertTopicDefaultAssignment(input) {
20408
+ const key = normalizeMemoryKey(input.memoryKey);
20409
+ const model = input.model.trim();
20410
+ if (!key || !model)
20411
+ return null;
20412
+ db.query(`INSERT INTO topic_default_assignments (memory_key, model, effort, reason, assign_count, updated_at)
20413
+ VALUES (?, ?, ?, ?, 1, ?)
20414
+ ON CONFLICT(memory_key) DO UPDATE SET
20415
+ model = excluded.model,
20416
+ effort = excluded.effort,
20417
+ reason = excluded.reason,
20418
+ assign_count = topic_default_assignments.assign_count + 1,
20419
+ updated_at = excluded.updated_at`).run(key, model, input.effort?.trim() || null, input.reason?.trim() || null, new Date().toISOString());
20420
+ return getTopicDefaultAssignment(key);
20421
+ }
20422
+
20423
+ // ../../packages/core/src/agents/topic-defaults.ts
20424
+ function validateAssignedDefaults(model, effort) {
20425
+ const candidate = canonicalModelId(model.trim());
20426
+ if (!candidate)
20427
+ return null;
20428
+ const agent = modelOwner(candidate);
20429
+ if (!agent)
20430
+ return null;
20431
+ let registry;
20432
+ try {
20433
+ registry = getRegistry(agent);
20434
+ } catch {
20435
+ return null;
20436
+ }
20437
+ if (!registry?.validateModel(candidate))
20438
+ return null;
20439
+ const requestedEffort = effort?.trim().toLowerCase();
20440
+ const resolvedEffort = requestedEffort && registry.validateEffort(requestedEffort) ? requestedEffort : registry.validateEffort(DEFAULT_TOPIC_EFFORT) ? DEFAULT_TOPIC_EFFORT : undefined;
20441
+ if (!resolvedEffort)
20442
+ return null;
20443
+ return { agent, model: candidate, effort: resolvedEffort };
20444
+ }
20445
+ function resolveAssignedTopicDefaults(memoryKey) {
20446
+ const key = memoryKey ? normalizeMemoryKey(memoryKey) : "";
20447
+ if (!key)
20448
+ return null;
20449
+ let stored;
20450
+ try {
20451
+ stored = getTopicDefaultAssignment(key);
20452
+ } catch (err2) {
20453
+ logger.warn({ err: err2, memoryKey: key }, "topic-defaults: assignment lookup failed");
20454
+ return null;
20455
+ }
20456
+ if (!stored)
20457
+ return null;
20458
+ const validated = validateAssignedDefaults(stored.model, stored.effort);
20459
+ if (!validated) {
20460
+ logger.info({ memoryKey: key, model: stored.model, effort: stored.effort }, "topic-defaults: stored assignment is stale - falling back to node defaults");
20461
+ return null;
20462
+ }
20463
+ return {
20464
+ memoryKey: key,
20465
+ ...validated,
20466
+ ...stored.reason ? { reason: stored.reason } : {}
20467
+ };
20468
+ }
20469
+ function assignTopicDefaults(input) {
20470
+ const validated = validateAssignedDefaults(input.model, input.effort);
20471
+ if (!validated)
20472
+ return null;
20473
+ try {
20474
+ const stored = upsertTopicDefaultAssignment({
20475
+ memoryKey: input.memoryKey,
20476
+ model: validated.model,
20477
+ effort: validated.effort,
20478
+ ...input.reason ? { reason: input.reason } : {}
20479
+ });
20480
+ return stored ? { ...validated, assignCount: stored.assignCount } : null;
20481
+ } catch (err2) {
20482
+ logger.warn({ err: err2, memoryKey: input.memoryKey }, "topic-defaults: assignment write failed");
20483
+ return null;
20484
+ }
20485
+ }
20297
20486
  export {
20298
20487
  withTaskSnapshots,
20299
20488
  withCodexSpawnSerial,
20300
20489
  visualToolDefinitions,
20490
+ validateAssignedDefaults,
20301
20491
  unregisterOwnedCodexPids,
20302
20492
  summarizeToolInput,
20303
20493
  summarizeShellCommand,
@@ -20309,6 +20499,7 @@ export {
20309
20499
  showHtmlTool,
20310
20500
  rotateTopicLogs,
20311
20501
  resolveTaskEventScope,
20502
+ resolveAssignedTopicDefaults,
20312
20503
  registerOwnedCodexPids,
20313
20504
  purgeTopicLogs,
20314
20505
  otiumVisualToolDefinitions,
@@ -20337,11 +20528,14 @@ export {
20337
20528
  checkAgentModelAuth,
20338
20529
  checkAgentAuth,
20339
20530
  buildNumberedDiffSummary,
20531
+ assignTopicDefaults,
20340
20532
  archiveActiveTopicForMemory,
20533
+ applySelfConfigCapabilityFilter,
20341
20534
  acquireCodexSpawnLock,
20342
20535
  VISUALS_MCP_KEY,
20536
+ SELF_CONFIG_CAPABILITIES,
20343
20537
  MIN_MEMORY_ARCHIVE_EXCHANGES,
20344
20538
  DEFAULT_SELF_CONFIG_PRODUCT
20345
20539
  };
20346
20540
 
20347
- //# debugId=2418AB0B47A5458A64756E2164756E21
20541
+ //# debugId=1CB223B725013DCF64756E2164756E21