negotium 0.23.3 → 0.23.5

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 (66) hide show
  1. package/dist/agent-helpers.js +198 -14
  2. package/dist/agent-helpers.js.map +14 -13
  3. package/dist/background-bash.js +2 -1
  4. package/dist/background-bash.js.map +3 -3
  5. package/dist/browser-runtime.js +2 -1
  6. package/dist/browser-runtime.js.map +3 -3
  7. package/dist/{chunk-6gt62j1j.js → chunk-0hmrwxks.js} +3 -3
  8. package/dist/{chunk-6gt62j1j.js.map → chunk-0hmrwxks.js.map} +2 -2
  9. package/dist/{chunk-q5djsg78.js → chunk-ad7kxsaq.js} +4 -2
  10. package/dist/{chunk-q5djsg78.js.map → chunk-ad7kxsaq.js.map} +1 -1
  11. package/dist/chunk-f7p0h1gs.js.map +1 -1
  12. package/dist/{chunk-9zn0bkc9.js → chunk-mxxwx5mg.js} +3 -2
  13. package/dist/{chunk-9zn0bkc9.js.map → chunk-mxxwx5mg.js.map} +3 -3
  14. package/dist/{chunk-6cnpkzkb.js → chunk-n6crwk1s.js} +26 -2
  15. package/dist/{chunk-6cnpkzkb.js.map → chunk-n6crwk1s.js.map} +8 -8
  16. package/dist/{chunk-cez5m5hm.js → chunk-ztcj9grz.js} +1 -1
  17. package/dist/hosted-agent.js +191 -14
  18. package/dist/hosted-agent.js.map +11 -10
  19. package/dist/main.js +556 -46
  20. package/dist/main.js.map +18 -16
  21. package/dist/mcp-catalog.js +3 -2
  22. package/dist/mcp-catalog.js.map +3 -3
  23. package/dist/mcp-factories.js +513 -42
  24. package/dist/mcp-factories.js.map +15 -13
  25. package/dist/media.js +2 -1
  26. package/dist/media.js.map +3 -3
  27. package/dist/prompts.js +2 -1
  28. package/dist/prompts.js.map +3 -3
  29. package/dist/query-runtime.js +2 -1
  30. package/dist/query-runtime.js.map +3 -3
  31. package/dist/registry.js +3 -3
  32. package/dist/rollout.js +2 -2
  33. package/dist/runtime/src/agents/claude-notices.ts +130 -0
  34. package/dist/runtime/src/agents/claude-provider.ts +9 -11
  35. package/dist/runtime/src/agents/codex-provider.ts +51 -6
  36. package/dist/runtime/src/agents/rollout/codex.ts +58 -0
  37. package/dist/runtime/src/mcp/canonical-bridge-config.ts +1 -1
  38. package/dist/runtime/src/mcp/canonical-proxy-server.ts +39 -1
  39. package/dist/runtime/src/mcp/factories/index.ts +4 -0
  40. package/dist/runtime/src/mcp/factories/session-history.ts +388 -0
  41. package/dist/runtime/src/mcp/runtime-spec.ts +1 -0
  42. package/dist/runtime/src/mcp/session-history-server.ts +27 -0
  43. package/dist/runtime/src/platform/config.ts +2 -0
  44. package/dist/runtime/src/platform/mcp-catalog-policy.ts +5 -0
  45. package/dist/runtime/src/platform/mcp-config.ts +30 -0
  46. package/dist/runtime/src/storage/topic-archive.ts +4 -2
  47. package/dist/runtime/src/version.ts +1 -1
  48. package/dist/runtime-helpers.js +2 -1
  49. package/dist/runtime-helpers.js.map +3 -3
  50. package/dist/storage.js +5 -1
  51. package/dist/storage.js.map +3 -3
  52. package/dist/types/packages/core/src/agents/claude-notices.d.ts +15 -0
  53. package/dist/types/packages/core/src/agents/codex-provider.d.ts +6 -0
  54. package/dist/types/packages/core/src/agents/rollout/codex.d.ts +12 -0
  55. package/dist/types/packages/core/src/mcp/canonical-bridge-config.d.ts +1 -1
  56. package/dist/types/packages/core/src/mcp/factories/index.d.ts +1 -0
  57. package/dist/types/packages/core/src/mcp/factories/session-history.d.ts +11 -0
  58. package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +1 -1
  59. package/dist/types/packages/core/src/platform/config.d.ts +1 -0
  60. package/dist/types/packages/core/src/platform/mcp-catalog-policy.d.ts +4 -0
  61. package/dist/types/packages/core/src/storage/topic-archive.d.ts +5 -0
  62. package/dist/types/packages/core/src/version.d.ts +1 -1
  63. package/dist/vault.js +2 -1
  64. package/dist/vault.js.map +3 -3
  65. package/package.json +1 -1
  66. /package/dist/{chunk-cez5m5hm.js.map → chunk-ztcj9grz.js.map} +0 -0
@@ -8,7 +8,7 @@ import {
8
8
  logger,
9
9
  parseJsonlText,
10
10
  writeJsonlFile
11
- } from "./chunk-6cnpkzkb.js";
11
+ } from "./chunk-n6crwk1s.js";
12
12
 
13
13
  // ../../packages/core/src/agents/rollout/claude.ts
14
14
  import { randomUUID } from "crypto";
@@ -25,6 +25,7 @@ import {
25
25
  RUNTIME_MCP_SECRET,
26
26
  RUN_DIR,
27
27
  SESSION_COMM_SERVER,
28
+ SESSION_HISTORY_SERVER,
28
29
  SESSION_WORKSPACE_DIR,
29
30
  SUPPORTED_AGENTS,
30
31
  SYSTEM_HEALTH_SERVER,
@@ -42,7 +43,7 @@ import {
42
43
  logger,
43
44
  resolveFallbackAgent,
44
45
  resolveTopicWorkspaceDir
45
- } from "./chunk-9zn0bkc9.js";
46
+ } from "./chunk-mxxwx5mg.js";
46
47
  import {
47
48
  __require
48
49
  } from "./chunk-2mx7fq49.js";
@@ -52,6 +53,93 @@ import { spawn as spawn2 } from "child_process";
52
53
  import { existsSync, readFileSync as readFileSync2 } from "fs";
53
54
  import { query } from "@anthropic-ai/claude-agent-sdk";
54
55
 
56
+ // ../../packages/core/src/agents/claude-notices.ts
57
+ var API_ERROR_TEXT = {
58
+ overloaded: "Claude is overloaded",
59
+ rate_limit: "Claude rate limit hit",
60
+ server_error: "Claude API error",
61
+ unknown: "Claude request failed",
62
+ authentication_failed: "Claude sign-in failed",
63
+ oauth_org_not_allowed: "Organization not allowed for Claude",
64
+ account_on_hold: "Claude account is on hold",
65
+ verification_required: "Claude account needs verification",
66
+ billing_error: "Claude billing issue",
67
+ invalid_request: "Claude rejected the request",
68
+ model_not_found: "Claude model not found",
69
+ max_output_tokens: "Claude reply hit the length limit",
70
+ cloud_credential_error: "Cloud credentials failed"
71
+ };
72
+ var RATE_LIMIT_TEXT = {
73
+ five_hour: "5-hour",
74
+ seven_day: "weekly",
75
+ seven_day_opus: "weekly Opus",
76
+ seven_day_sonnet: "weekly Sonnet",
77
+ seven_day_overage_included: "weekly",
78
+ overage: "extra usage"
79
+ };
80
+ var DENIAL_TEXT = {
81
+ rule: "by a permission rule",
82
+ mode: "by the permission mode",
83
+ classifier: "by the safety check",
84
+ asyncAgent: "for a background agent"
85
+ };
86
+ function modelLabel(id) {
87
+ const match = /^claude-([a-z]+)-(\d+)-(\d+)/.exec(id);
88
+ if (!match)
89
+ return id;
90
+ const [, family = "", major, minor] = match;
91
+ return `${family.charAt(0).toUpperCase()}${family.slice(1)} ${major}.${minor}`;
92
+ }
93
+ var SYSTEM_NOTICES = {
94
+ api_retry: (m) => {
95
+ const reason = m.error_status === null ? "Lost connection to Claude" : API_ERROR_TEXT[m.error] ?? "Claude request failed";
96
+ const delay = Math.round(m.retry_delay_ms / 1000);
97
+ const when = delay > 0 ? `in ${delay}s` : "now";
98
+ return `${reason} \xB7 retrying ${when} (${m.attempt}/${m.max_retries})`;
99
+ },
100
+ model_refusal_fallback: (m) => m.direction === "retry" ? `${modelLabel(m.original_model)} declined \xB7 ${modelLabel(m.fallback_model)} is answering instead` : m.content || undefined,
101
+ model_refusal_no_fallback: (m) => `${modelLabel(m.original_model)} declined this request`,
102
+ permission_denied: (m) => {
103
+ const tool = m.tool_name.split("__").at(-1) || m.tool_name;
104
+ const why = m.decision_reason ? `: ${m.decision_reason}` : ` ${DENIAL_TEXT[m.decision_reason_type ?? ""] ?? ""}`.trimEnd();
105
+ return `${tool} was blocked${why}`;
106
+ },
107
+ informational: (m) => m.prevent_continuation || m.level === "warning" || m.level === "suggestion" ? m.content : undefined,
108
+ mirror_error: (m) => {
109
+ logger.warn({ error: m.error }, "claudeProvider: transcript mirror batch dropped");
110
+ return;
111
+ }
112
+ };
113
+ function rateLimitNotice(m) {
114
+ const { status, rateLimitType } = m.rate_limit_info;
115
+ const limit = rateLimitType ? `${RATE_LIMIT_TEXT[rateLimitType] ?? ""} `.trimStart() : "";
116
+ if (status === "allowed_warning")
117
+ return `Nearing your ${limit}Claude usage limit`;
118
+ if (status === "rejected")
119
+ return `Reached your ${limit}Claude usage limit`;
120
+ return;
121
+ }
122
+ function claudeNoticeStatus(message) {
123
+ try {
124
+ if (message.type === "rate_limit_event")
125
+ return rateLimitNotice(message);
126
+ if (message.type !== "system")
127
+ return;
128
+ const handler = SYSTEM_NOTICES[message.subtype];
129
+ if (!handler) {
130
+ logger.debug({ subtype: message.subtype, msg: message }, "claudeProvider: system message (unhandled subtype)");
131
+ return;
132
+ }
133
+ const status = handler(message);
134
+ if (status)
135
+ logger.warn({ subtype: message.subtype, status }, "claudeProvider: notice");
136
+ return status;
137
+ } catch (err) {
138
+ logger.debug({ err, msg: message }, "claudeProvider: notice mapping failed");
139
+ return;
140
+ }
141
+ }
142
+
55
143
  // ../../packages/core/src/agents/rollout/shared.ts
56
144
  import { resolve as resolve2 } from "path";
57
145
 
@@ -876,7 +964,8 @@ var COMMON_RUNTIME_MCP_POLICY = {
876
964
  "background-bash": { scopes: ["forum"], forumRequired: true },
877
965
  "agent-health": { scopes: ["forum", "manager", "cron"], forumRequired: true },
878
966
  vault: { scopes: ["dm", "forum", "manager", "cron"], forumRequired: true },
879
- "cua-rs": { scopes: ["dm", "forum", "fork"], forumRequired: false }
967
+ "cua-rs": { scopes: ["dm", "forum", "fork"], forumRequired: false },
968
+ "session-history": { scopes: ["dm", "forum", "manager"], forumRequired: false }
880
969
  };
881
970
  function classifyForumMcpServers(catalog) {
882
971
  const all = Object.entries(catalog).filter(([, entry]) => entry.scopes.includes("forum")).map(([name]) => name);
@@ -2331,6 +2420,28 @@ var MCP_CATALOG = {
2331
2420
  return buildBuiltinMcpServer("decision", ctx, () => buildStdioMcpServer(agent, DECISION_SERVER, args));
2332
2421
  }
2333
2422
  },
2423
+ "session-history": {
2424
+ ...commonRuntimeMcpPolicy("session-history"),
2425
+ build(ctx) {
2426
+ const { userId, session, topicId, queryId, agent, peerBridge } = ctx;
2427
+ if (peerBridge) {
2428
+ if (!topicId || !queryId)
2429
+ return null;
2430
+ const env = canonicalMcpBridgeEnv({
2431
+ surface: "session-history",
2432
+ userId,
2433
+ topicId,
2434
+ queryId,
2435
+ peerBridge
2436
+ });
2437
+ return env ? buildStdioMcpServer(agent, CANONICAL_MCP_PROXY_SERVER, ["--surface=session-history"], env) : null;
2438
+ }
2439
+ const args = [`--user-id=${userId}`, `--topic=${session}`];
2440
+ if (topicId)
2441
+ args.push(`--topic-id=${topicId}`);
2442
+ return buildBuiltinMcpServer("session-history", ctx, () => buildStdioMcpServer(agent, SESSION_HISTORY_SERVER, args));
2443
+ }
2444
+ },
2334
2445
  "session-comm": {
2335
2446
  ...commonRuntimeMcpPolicy("session-comm"),
2336
2447
  build(ctx) {
@@ -3459,12 +3570,13 @@ async function* claudeProvider(opts) {
3459
3570
  yield { type: "tool_use_summary", summary: m.summary };
3460
3571
  continue;
3461
3572
  }
3462
- if (message.type === "system") {
3463
- const m = message;
3464
- if (m.subtype === "init") {
3465
- yield { type: "session", sessionId: m.session_id };
3573
+ if (message.type === "system" || message.type === "rate_limit_event") {
3574
+ if (message.type === "system" && message.subtype === "init") {
3575
+ yield { type: "session", sessionId: message.session_id };
3466
3576
  } else {
3467
- logger.debug({ subtype: m.subtype, msg: m }, "claudeProvider: system message (unhandled subtype)");
3577
+ const status = claudeNoticeStatus(message);
3578
+ if (status)
3579
+ yield { type: "status", content: status };
3468
3580
  }
3469
3581
  continue;
3470
3582
  }
@@ -3600,7 +3712,7 @@ import { dirname as dirname5, join as join3 } from "path";
3600
3712
  import { fileURLToPath } from "url";
3601
3713
 
3602
3714
  // ../../packages/core/src/version.ts
3603
- var NEGOTIUM_VERSION = "0.23.3";
3715
+ var NEGOTIUM_VERSION = "0.23.5";
3604
3716
 
3605
3717
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
3606
3718
  function findPackageJson(specifier, searchFromDir) {
@@ -4405,7 +4517,7 @@ async function createCodexVaultHookBridge(userId) {
4405
4517
  });
4406
4518
  restrictIpcEndpoint(socketPath);
4407
4519
  if (IS_WINDOWS2) {
4408
- const { BINARIES_DIR } = await import("./chunk-q5djsg78.js");
4520
+ const { BINARIES_DIR } = await import("./chunk-ad7kxsaq.js");
4409
4521
  const cached = await ensureCodexWindowsWrapperExe(join5(BINARIES_DIR, "codex-hook-wrapper"));
4410
4522
  await copyFile(cached, wrapperPath);
4411
4523
  await writeFile2(join5(root, "codex-with-hooks.cfg"), [process.execPath, codexCliScriptPath(), socketPath, token].join(`
@@ -4657,6 +4769,49 @@ function extractCodexForkedFromId(jsonl) {
4657
4769
  return;
4658
4770
  }
4659
4771
  }
4772
+ function extractLatestCodexSystemInstructionsTurn(jsonl) {
4773
+ const lines = jsonl.trimEnd().split(`
4774
+ `);
4775
+ for (let index = lines.length - 1;index >= 0; index -= 1) {
4776
+ const line = lines[index] ?? "";
4777
+ if (!line.includes("[System Instructions]"))
4778
+ continue;
4779
+ try {
4780
+ const entry = JSON.parse(line);
4781
+ if (entry.type !== "response_item")
4782
+ continue;
4783
+ if (entry.payload?.type !== "message" || entry.payload.role !== "user")
4784
+ continue;
4785
+ const text = (entry.payload.content ?? []).map((part) => typeof part.text === "string" ? part.text : "").join("");
4786
+ if (text.startsWith(`[System Instructions]
4787
+ `))
4788
+ return text;
4789
+ } catch {}
4790
+ }
4791
+ return;
4792
+ }
4793
+ function codexThreadHasSystemPrompt(threadId, systemPrompt, depth = 0) {
4794
+ const path = latestCodexRolloutPath(threadId);
4795
+ if (!path)
4796
+ return false;
4797
+ try {
4798
+ const jsonl = readFileSync4(path, "utf8");
4799
+ const latest = extractLatestCodexSystemInstructionsTurn(jsonl);
4800
+ if (latest !== undefined) {
4801
+ return latest.startsWith(`[System Instructions]
4802
+ ${systemPrompt}
4803
+
4804
+ `);
4805
+ }
4806
+ if (depth >= 8)
4807
+ return false;
4808
+ const parentId = extractCodexForkedFromId(jsonl);
4809
+ return parentId && parentId !== threadId ? codexThreadHasSystemPrompt(parentId, systemPrompt, depth + 1) : false;
4810
+ } catch (error) {
4811
+ logger.debug({ error, threadId }, "codex system prompt: rollout read failed");
4812
+ return false;
4813
+ }
4814
+ }
4660
4815
  function readLatestCodexTokenTotals(threadId, depth = 0) {
4661
4816
  const path = latestCodexRolloutPath(threadId);
4662
4817
  if (!path)
@@ -4843,6 +4998,14 @@ function buildNumberedDiffSummary(before, after, startLine = 1) {
4843
4998
 
4844
4999
  // ../../packages/core/src/agents/codex-provider.ts
4845
5000
  var CODEX_HOOK_TRUST_BYPASS_NOTICE = "`--dangerously-bypass-hook-trust` is enabled. Enabled hooks may run without review for this invocation.";
5001
+ function codexNoticeStatus(message) {
5002
+ const firstLine = message.trim().split(`
5003
+ `)[0]?.trim() ?? "";
5004
+ const sentence = /^.*?[.!?](?=\s|$)/.exec(firstLine)?.[0] ?? firstLine;
5005
+ if (!sentence)
5006
+ return "Codex notice";
5007
+ return /^codex\b/i.test(sentence) ? sentence : `Codex: ${sentence}`;
5008
+ }
4846
5009
  function sameCodexUsage(usage, total) {
4847
5010
  return usage.input_tokens === total.inputTokens && usage.output_tokens === total.outputTokens && (usage.cached_input_tokens ?? 0) === total.cachedInputTokens && (usage.cache_write_input_tokens ?? 0) === total.cacheWriteInputTokens;
4848
5011
  }
@@ -5268,8 +5431,7 @@ async function* codexProvider(opts) {
5268
5431
  },
5269
5432
  hooks: vaultHook.hooks,
5270
5433
  model_catalog_json: codexModelCatalogPath,
5271
- mcp_servers: codexMcpServers,
5272
- ...opts.toolPolicy ? { sandbox_permissions: [] } : {}
5434
+ mcp_servers: codexMcpServers
5273
5435
  }
5274
5436
  });
5275
5437
  const threadOptions = {
@@ -5290,7 +5452,7 @@ async function* codexProvider(opts) {
5290
5452
  let currentSessionId = opts.sessionId;
5291
5453
  let usageBaseline = currentSessionId ? readLatestCodexTokenTotals(currentSessionId) : undefined;
5292
5454
  let thread = currentSessionId ? codex.resumeThread(currentSessionId, threadOptions) : codex.startThread(threadOptions);
5293
- let prompt = promptForThread(opts, true);
5455
+ let prompt = promptForThread(opts, !currentSessionId || !opts.systemPrompt || !codexThreadHasSystemPrompt(currentSessionId, opts.systemPrompt));
5294
5456
  let agentTextSoFar = "";
5295
5457
  let currentAgentMessageId;
5296
5458
  let finalText = "";
@@ -5318,6 +5480,8 @@ async function* codexProvider(opts) {
5318
5480
  trackedPids.pids = [];
5319
5481
  let heartbeatTriggered = false;
5320
5482
  let attemptCompleted = false;
5483
+ let turnFailed = false;
5484
+ let streamError;
5321
5485
  let heartbeatTimer = null;
5322
5486
  const scheduleHeartbeat = () => {
5323
5487
  if (heartbeatTimer !== null)
@@ -5446,7 +5610,8 @@ async function* codexProvider(opts) {
5446
5610
  } else if (item.type === "error") {
5447
5611
  const message = String(item.message ?? "");
5448
5612
  if (message !== CODEX_HOOK_TRUST_BYPASS_NOTICE) {
5449
- yield { type: "error", content: message };
5613
+ logger.warn({ message }, "codexProvider: codex non-fatal error item");
5614
+ yield { type: "status", content: codexNoticeStatus(message) };
5450
5615
  }
5451
5616
  }
5452
5617
  break;
@@ -5474,7 +5639,15 @@ async function* codexProvider(opts) {
5474
5639
  yield* extractFileEvents(finalText, "result");
5475
5640
  break;
5476
5641
  }
5642
+ case "error": {
5643
+ const message = event.message || "Codex stream error";
5644
+ logger.warn({ message }, "codexProvider: codex stream error event");
5645
+ streamError = message;
5646
+ yield { type: "status", content: codexNoticeStatus(message) };
5647
+ break;
5648
+ }
5477
5649
  case "turn.failed": {
5650
+ turnFailed = true;
5478
5651
  stopReason = "error";
5479
5652
  yield {
5480
5653
  type: "error",
@@ -5486,6 +5659,10 @@ async function* codexProvider(opts) {
5486
5659
  break;
5487
5660
  }
5488
5661
  }
5662
+ if (!attemptCompleted && !turnFailed && streamError) {
5663
+ stopReason = "error";
5664
+ yield { type: "error", content: streamError };
5665
+ }
5489
5666
  } catch (err) {
5490
5667
  if (abortSignal?.aborted)
5491
5668
  return;
@@ -5738,4 +5915,4 @@ export {
5738
5915
  buildClaudeDisallowedTools
5739
5916
  };
5740
5917
 
5741
- //# debugId=E09EB735E1E552E264756E2164756E21
5918
+ //# debugId=D6F835535EA14E1564756E2164756E21