negotium 0.5.9 → 0.5.12

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 (47) hide show
  1. package/dist/agent-helpers.js +72 -42
  2. package/dist/agent-helpers.js.map +11 -10
  3. package/dist/background-bash.js +7 -3
  4. package/dist/background-bash.js.map +3 -3
  5. package/dist/browser-runtime.js +7 -3
  6. package/dist/browser-runtime.js.map +3 -3
  7. package/dist/{chunk-n9g0wk3p.js → chunk-qgm6m2hc.js} +7 -3
  8. package/dist/{chunk-n9g0wk3p.js.map → chunk-qgm6m2hc.js.map} +3 -3
  9. package/dist/hosted-agent.js +13 -32
  10. package/dist/hosted-agent.js.map +5 -5
  11. package/dist/main.js +464 -247
  12. package/dist/main.js.map +22 -21
  13. package/dist/mcp-factories.js +72 -42
  14. package/dist/mcp-factories.js.map +11 -10
  15. package/dist/media.js +7 -3
  16. package/dist/media.js.map +3 -3
  17. package/dist/prompts.js +7 -3
  18. package/dist/prompts.js.map +3 -3
  19. package/dist/query-runtime.js +7 -3
  20. package/dist/query-runtime.js.map +3 -3
  21. package/dist/registry.js +3 -3
  22. package/dist/registry.js.map +2 -2
  23. package/dist/rollout.js +1 -1
  24. package/dist/runtime/src/agents/maestro-provider.ts +8 -35
  25. package/dist/runtime/src/index.ts +6 -0
  26. package/dist/runtime/src/mcp/session-comm/default-host.ts +35 -23
  27. package/dist/runtime/src/mcp/session-comm/server.ts +24 -20
  28. package/dist/runtime/src/mcp-runtime-host.ts +1 -0
  29. package/dist/runtime/src/platform/config.ts +11 -2
  30. package/dist/runtime/src/platform/lifecycle.ts +3 -0
  31. package/dist/runtime/src/query/session-inbox-cleanup.ts +2 -1
  32. package/dist/runtime/src/query/session-inbox-path.ts +1 -1
  33. package/dist/runtime/src/runtime/bashrs-completions.ts +13 -9
  34. package/dist/runtime/src/runtime/inbox.ts +175 -106
  35. package/dist/runtime/src/runtime/turn-event-stream.ts +19 -3
  36. package/dist/runtime/src/runtime/turn-runner.ts +10 -4
  37. package/dist/runtime/src/storage/session-inbox.ts +157 -0
  38. package/dist/runtime/src/version.ts +1 -1
  39. package/dist/runtime-helpers.js +64 -31
  40. package/dist/runtime-helpers.js.map +7 -7
  41. package/dist/types/packages/core/src/agents/maestro-provider.d.ts +3 -4
  42. package/dist/types/packages/core/src/query/session-inbox-path.d.ts +1 -1
  43. package/dist/types/packages/core/src/storage/session-inbox.d.ts +36 -0
  44. package/dist/types/packages/core/src/version.d.ts +1 -1
  45. package/dist/vault.js +7 -3
  46. package/dist/vault.js.map +3 -3
  47. package/package.json +2 -2
@@ -175,6 +175,11 @@ function resolveAgentEnv(envKey, fallback, legacyEnvKey) {
175
175
  const value = envText(envKey) ?? (legacyEnvKey ? envText(legacyEnvKey) : undefined);
176
176
  return isAgentKind(value) ? value : fallback;
177
177
  }
178
+ function resolveStateDir() {
179
+ const configured = envText("NEGOTIUM_STATE_DIR");
180
+ if (false) {}
181
+ return configured ? resolve2(configured) : resolve2(HOME, ".negotium");
182
+ }
178
183
  function resolveProjectRoot() {
179
184
  const moduleDir = dirname(fileURLToPath(import.meta.url));
180
185
  const packagedRuntime = resolve2(moduleDir, "runtime");
@@ -338,15 +343,14 @@ function resolveWhisperBackend() {
338
343
  function codexAuthFilePath() {
339
344
  return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
340
345
  }
341
- var HOME, PROJECT_ROOT, STATE_DIR_ENV, 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.1.23", BROWSER_RS_MIN_SECURE_VERSION = "0.1.15", 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", 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.1.23", BROWSER_RS_MIN_SECURE_VERSION = "0.1.15", 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", 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;
342
347
  var init_config = __esm(() => {
343
348
  init_config_helpers();
344
349
  init_logger();
345
350
  init_types();
346
351
  HOME = homedir();
347
352
  PROJECT_ROOT = resolveProjectRoot();
348
- STATE_DIR_ENV = envText("NEGOTIUM_STATE_DIR");
349
- STATE_DIR = STATE_DIR_ENV ? resolve2(STATE_DIR_ENV) : resolve2(HOME, ".negotium");
353
+ STATE_DIR = resolveStateDir();
350
354
  WORKSPACE_DIR = resolveLocalStateDir("NEGOTIUM_WORKSPACE_DIR", "workspace");
351
355
  TOPIC_WORKSPACE_DIR = resolve2(WORKSPACE_DIR, "topics");
352
356
  SHARED_WIKI_DIR = resolve2(WORKSPACE_DIR, "wiki");
@@ -2439,7 +2443,7 @@ var init_claude_registry = __esm(() => {
2439
2443
  });
2440
2444
 
2441
2445
  // ../../packages/core/src/version.ts
2442
- var NEGOTIUM_VERSION = "0.5.9";
2446
+ var NEGOTIUM_VERSION = "0.5.12";
2443
2447
 
2444
2448
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
2445
2449
  import { spawn as spawn2 } from "child_process";
@@ -6023,14 +6027,8 @@ function buildVaultHook(userId) {
6023
6027
  function buildMaestroToolHooks(userId) {
6024
6028
  return [buildVaultHook(userId), buildProviderOwnedToolBlockHook()];
6025
6029
  }
6026
- function providerOwnedToolRedirect(toolName) {
6027
- if (toolName === PROVIDER_ASK_USER_TOOL) {
6028
- return "Use the runtime ask_user_question MCP tool instead.";
6029
- }
6030
- if (toolName === PROVIDER_SUBAGENT_TOOL) {
6031
- return "Use the runtime spawn_subagent MCP tool instead.";
6032
- }
6033
- return "Use the shared task MCP tools instead " + "(mcp__task__task_create / task_update / task_list / task_get / task_delete).";
6030
+ function providerOwnedToolRedirect() {
6031
+ return "Use the runtime ask_user_question MCP tool instead.";
6034
6032
  }
6035
6033
  function resolveMaestroApiKeyOverrides(userId) {
6036
6034
  if (!userId)
@@ -6052,7 +6050,7 @@ function buildProviderOwnedToolBlockHook() {
6052
6050
  return { decision: "allow" };
6053
6051
  return {
6054
6052
  decision: "block",
6055
- error: `${toolName} is disabled in this environment. ${providerOwnedToolRedirect(toolName)}`
6053
+ error: `${toolName} is disabled in this environment. ${providerOwnedToolRedirect()}`
6056
6054
  };
6057
6055
  }
6058
6056
  };
@@ -6088,31 +6086,15 @@ function maestroProvider(opts) {
6088
6086
  };
6089
6087
  return sdkMaestroProvider(sdkOpts);
6090
6088
  }
6091
- var MAESTRO_DEFAULT_MAX_TOKENS = 32768, PROVIDER_ASK_USER_TOOL = "AskUserQuestion", PROVIDER_SUBAGENT_TOOL = "Agent", MAESTRO_NATIVE_TASK_TOOLS, MAESTRO_PROVIDER_OWNED_TOOL_SET, DEFAULT_MAESTRO_DISALLOWED_TOOLS, MAESTRO_ALL_BUILTIN_TOOLS, MAESTRO_TOOL_OUTPUT_DIR;
6089
+ var MAESTRO_DEFAULT_MAX_TOKENS = 32768, PROVIDER_ASK_USER_TOOL = "AskUserQuestion", MAESTRO_PROVIDER_OWNED_TOOL_SET, DEFAULT_MAESTRO_DISALLOWED_TOOLS, MAESTRO_ALL_BUILTIN_TOOLS, MAESTRO_TOOL_OUTPUT_DIR;
6092
6090
  var init_maestro_provider = __esm(async () => {
6093
6091
  init_maestro_bootstrap_env();
6094
6092
  await init_execution_host();
6095
6093
  init_vault_tool_policy();
6096
6094
  init_config();
6097
6095
  await init_vault();
6098
- MAESTRO_NATIVE_TASK_TOOLS = [
6099
- "TaskCreate",
6100
- "TaskUpdate",
6101
- "TaskList",
6102
- "TaskGet",
6103
- "TaskOutput",
6104
- "TaskStop"
6105
- ];
6106
- MAESTRO_PROVIDER_OWNED_TOOL_SET = new Set([
6107
- PROVIDER_ASK_USER_TOOL,
6108
- PROVIDER_SUBAGENT_TOOL,
6109
- ...MAESTRO_NATIVE_TASK_TOOLS
6110
- ]);
6111
- DEFAULT_MAESTRO_DISALLOWED_TOOLS = [
6112
- PROVIDER_ASK_USER_TOOL,
6113
- PROVIDER_SUBAGENT_TOOL,
6114
- ...MAESTRO_NATIVE_TASK_TOOLS
6115
- ];
6096
+ MAESTRO_PROVIDER_OWNED_TOOL_SET = new Set([PROVIDER_ASK_USER_TOOL]);
6097
+ DEFAULT_MAESTRO_DISALLOWED_TOOLS = [PROVIDER_ASK_USER_TOOL];
6116
6098
  MAESTRO_ALL_BUILTIN_TOOLS = [
6117
6099
  "Bash",
6118
6100
  "Read",
@@ -13326,6 +13308,35 @@ var init_session_inbox_path = __esm(() => {
13326
13308
  init_config();
13327
13309
  });
13328
13310
 
13311
+ // ../../packages/core/src/storage/session-inbox.ts
13312
+ function deleteSessionInboxForTopic(topicId) {
13313
+ return Number(db.run("DELETE FROM session_inbox WHERE topic_id = ?", [topicId]).changes ?? 0);
13314
+ }
13315
+ var init_session_inbox = __esm(async () => {
13316
+ await init_forum_db();
13317
+ await init_storage_host();
13318
+ registerStorageSchemaInitializer((database) => {
13319
+ database.exec(`
13320
+ CREATE TABLE IF NOT EXISTS session_inbox (
13321
+ sequence INTEGER PRIMARY KEY AUTOINCREMENT,
13322
+ id TEXT NOT NULL UNIQUE,
13323
+ user_id TEXT NOT NULL,
13324
+ topic_id TEXT NOT NULL,
13325
+ payload TEXT NOT NULL,
13326
+ status TEXT NOT NULL DEFAULT 'pending'
13327
+ CHECK (status IN ('pending', 'processing')),
13328
+ claimed_by TEXT,
13329
+ claimed_at INTEGER,
13330
+ created_at INTEGER NOT NULL
13331
+ );
13332
+ CREATE INDEX IF NOT EXISTS idx_session_inbox_ready
13333
+ ON session_inbox(status, user_id, topic_id, sequence);
13334
+ CREATE INDEX IF NOT EXISTS idx_session_inbox_topic
13335
+ ON session_inbox(topic_id);
13336
+ `);
13337
+ }, 35);
13338
+ });
13339
+
13329
13340
  // ../../packages/core/src/query/session-inbox-cleanup.ts
13330
13341
  import { unlinkSync as unlinkSync14 } from "fs";
13331
13342
  import { basename as basename3, join as join23 } from "path";
@@ -13339,7 +13350,7 @@ function cleanupSessionInboxFiles(userId, topicId, legacyTopicTitle) {
13339
13350
  candidates.add(`${legacyBase}${suffix}`);
13340
13351
  }
13341
13352
  }
13342
- let deleted = 0;
13353
+ let deleted = deleteSessionInboxForTopic(topicId);
13343
13354
  for (const path of candidates) {
13344
13355
  try {
13345
13356
  unlinkSync14(path);
@@ -13352,10 +13363,11 @@ function cleanupSessionInboxFiles(userId, topicId, legacyTopicTitle) {
13352
13363
  }
13353
13364
  return deleted;
13354
13365
  }
13355
- var init_session_inbox_cleanup = __esm(() => {
13366
+ var init_session_inbox_cleanup = __esm(async () => {
13356
13367
  init_config();
13357
13368
  init_logger();
13358
13369
  init_session_inbox_path();
13370
+ await init_session_inbox();
13359
13371
  });
13360
13372
 
13361
13373
  // ../../packages/core/src/query/state.ts
@@ -14535,7 +14547,7 @@ var init_lifecycle = __esm(async () => {
14535
14547
  init_logger();
14536
14548
  await init_manager2();
14537
14549
  await init_active_rooms();
14538
- init_session_inbox_cleanup();
14550
+ await init_session_inbox_cleanup();
14539
14551
  init_state();
14540
14552
  await init_ask_callbacks();
14541
14553
  init_file_hooks();
@@ -15321,6 +15333,7 @@ async function runTurnEventStream(topicId, topicTitle, queryId, events, control,
15321
15333
  const peerBridge = execution?.peerBridge ?? control.injectParams?.peerBridge;
15322
15334
  let errorOccurred = false;
15323
15335
  let terminalEmitted = false;
15336
+ let lastEventType = null;
15324
15337
  let pendingSawDelta = false;
15325
15338
  let accumulatedText = "";
15326
15339
  let pendingText = "";
@@ -15454,6 +15467,7 @@ async function runTurnEventStream(topicId, topicTitle, queryId, events, control,
15454
15467
  for await (const event of events) {
15455
15468
  if (abortController.signal.aborted)
15456
15469
  break;
15470
+ lastEventType = event.type;
15457
15471
  if (!control.providerTurnContentObserved && (event.type === "text_delta" || event.type === "text" || event.type === "reasoning" || event.type === "tool_use" || event.type === "tool_result" || event.type === "file" || event.type === "result")) {
15458
15472
  control.providerTurnContentObserved = true;
15459
15473
  if (control.sessionId) {
@@ -15842,12 +15856,23 @@ ${JSON.stringify(event.input ?? {})}`);
15842
15856
  deliverAskError(queryId, topicTitle, msg);
15843
15857
  }
15844
15858
  } finally {
15859
+ if (!terminalEmitted && !abortController.signal.aborted) {
15860
+ const error = "Provider stream ended without a terminal event";
15861
+ outcome = { kind: "provider-error", error };
15862
+ logger.warn({
15863
+ topicId,
15864
+ queryId,
15865
+ agentType,
15866
+ model,
15867
+ silent,
15868
+ lastEventType,
15869
+ hadAssistantOutput: visibleMessageIds.length > 0 || pendingText.length > 0,
15870
+ hadToolActivity: syntheticToolCounter > 0 || providerToolIds.size > 0
15871
+ }, "ai: provider stream ended without result, error, or abort");
15872
+ }
15845
15873
  const discardIncompleteSegments = outcome.kind === "session-expired" || outcome.kind === "provider-error" || !terminalEmitted && !abortController.signal.aborted;
15846
15874
  if (discardIncompleteSegments)
15847
15875
  discardVisibleAssistantMessages();
15848
- if (!terminalEmitted && !silent) {
15849
- hub.broadcastDone(topicId, queryId, undefined, { agent: agentType, model });
15850
- }
15851
15876
  const stillCurrent = getRoomQuery(roomId)?.queryId === queryId;
15852
15877
  clearRoomQuery(roomId, queryId);
15853
15878
  cancelPendingAskUserQuestions(topicId, queryId);
@@ -17203,7 +17228,7 @@ function triggerTopicAiTurn(topicId, userId, prompt, agentType, opts) {
17203
17228
  if (!opts?.silent && !opts?.hideInjectMessage) {
17204
17229
  const now = new Date().toISOString();
17205
17230
  const injectMsg = {
17206
- id: `tell-${randomUUID16()}`,
17231
+ id: opts?.requestId ? `tell-${opts.requestId}` : `tell-${randomUUID16()}`,
17207
17232
  topicId,
17208
17233
  authorId: opts?.injectAuthorId ?? userId,
17209
17234
  sourceAdapter: opts?.injectSourceAdapter,
@@ -17215,8 +17240,13 @@ function triggerTopicAiTurn(topicId, userId, prompt, agentType, opts) {
17215
17240
  model: execution.model,
17216
17241
  createdAt: now
17217
17242
  };
17218
- appendApiMessage(injectMsg);
17219
- WsHub.get().broadcastMessage(topicId, injectMsg);
17243
+ try {
17244
+ appendApiMessage(injectMsg);
17245
+ WsHub.get().broadcastMessage(topicId, injectMsg);
17246
+ } catch (error) {
17247
+ if (!opts?.requestId || !getApiMessage(topicId, injectMsg.id))
17248
+ throw error;
17249
+ }
17220
17250
  }
17221
17251
  return startAiTurn({
17222
17252
  topic: topicCfg,
@@ -19189,4 +19219,4 @@ export {
19189
19219
  DEFAULT_SELF_CONFIG_PRODUCT
19190
19220
  };
19191
19221
 
19192
- //# debugId=5C27F540959207AC64756E2164756E21
19222
+ //# debugId=751F37A04AE5257A64756E2164756E21