negotium 0.23.3 → 0.23.4

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 (30) hide show
  1. package/dist/agent-helpers.js +171 -12
  2. package/dist/agent-helpers.js.map +8 -7
  3. package/dist/{chunk-6gt62j1j.js → chunk-ggdwn8d5.js} +3 -3
  4. package/dist/{chunk-6gt62j1j.js.map → chunk-ggdwn8d5.js.map} +2 -2
  5. package/dist/{chunk-9zn0bkc9.js → chunk-jarf6nb2.js} +2 -2
  6. package/dist/{chunk-9zn0bkc9.js.map → chunk-jarf6nb2.js.map} +1 -1
  7. package/dist/{chunk-cez5m5hm.js → chunk-pwafy9bb.js} +1 -1
  8. package/dist/{chunk-q5djsg78.js → chunk-qekt5bnd.js} +1 -1
  9. package/dist/{chunk-6cnpkzkb.js → chunk-vtd5kn4n.js} +1 -1
  10. package/dist/{chunk-6cnpkzkb.js.map → chunk-vtd5kn4n.js.map} +3 -3
  11. package/dist/hosted-agent.js +166 -13
  12. package/dist/hosted-agent.js.map +8 -7
  13. package/dist/main.js +190 -12
  14. package/dist/main.js.map +9 -8
  15. package/dist/mcp-factories.js +171 -12
  16. package/dist/mcp-factories.js.map +8 -7
  17. package/dist/registry.js +3 -3
  18. package/dist/rollout.js +2 -2
  19. package/dist/runtime/src/agents/claude-notices.ts +130 -0
  20. package/dist/runtime/src/agents/claude-provider.ts +9 -11
  21. package/dist/runtime/src/agents/codex-provider.ts +51 -6
  22. package/dist/runtime/src/agents/rollout/codex.ts +58 -0
  23. package/dist/runtime/src/version.ts +1 -1
  24. package/dist/types/packages/core/src/agents/claude-notices.d.ts +15 -0
  25. package/dist/types/packages/core/src/agents/codex-provider.d.ts +6 -0
  26. package/dist/types/packages/core/src/agents/rollout/codex.d.ts +12 -0
  27. package/dist/types/packages/core/src/version.d.ts +1 -1
  28. package/package.json +1 -1
  29. /package/dist/{chunk-cez5m5hm.js.map → chunk-pwafy9bb.js.map} +0 -0
  30. /package/dist/{chunk-q5djsg78.js.map → chunk-qekt5bnd.js.map} +0 -0
package/dist/main.js CHANGED
@@ -6291,6 +6291,49 @@ function extractCodexForkedFromId(jsonl) {
6291
6291
  return;
6292
6292
  }
6293
6293
  }
6294
+ function extractLatestCodexSystemInstructionsTurn(jsonl) {
6295
+ const lines = jsonl.trimEnd().split(`
6296
+ `);
6297
+ for (let index = lines.length - 1;index >= 0; index -= 1) {
6298
+ const line = lines[index] ?? "";
6299
+ if (!line.includes("[System Instructions]"))
6300
+ continue;
6301
+ try {
6302
+ const entry = JSON.parse(line);
6303
+ if (entry.type !== "response_item")
6304
+ continue;
6305
+ if (entry.payload?.type !== "message" || entry.payload.role !== "user")
6306
+ continue;
6307
+ const text = (entry.payload.content ?? []).map((part) => typeof part.text === "string" ? part.text : "").join("");
6308
+ if (text.startsWith(`[System Instructions]
6309
+ `))
6310
+ return text;
6311
+ } catch {}
6312
+ }
6313
+ return;
6314
+ }
6315
+ function codexThreadHasSystemPrompt(threadId, systemPrompt, depth = 0) {
6316
+ const path = latestCodexRolloutPath(threadId);
6317
+ if (!path)
6318
+ return false;
6319
+ try {
6320
+ const jsonl = readFileSync4(path, "utf8");
6321
+ const latest = extractLatestCodexSystemInstructionsTurn(jsonl);
6322
+ if (latest !== undefined) {
6323
+ return latest.startsWith(`[System Instructions]
6324
+ ${systemPrompt}
6325
+
6326
+ `);
6327
+ }
6328
+ if (depth >= 8)
6329
+ return false;
6330
+ const parentId = extractCodexForkedFromId(jsonl);
6331
+ return parentId && parentId !== threadId ? codexThreadHasSystemPrompt(parentId, systemPrompt, depth + 1) : false;
6332
+ } catch (error) {
6333
+ logger.debug({ error, threadId }, "codex system prompt: rollout read failed");
6334
+ return false;
6335
+ }
6336
+ }
6294
6337
  function readLatestCodexTokenTotals(threadId, depth = 0) {
6295
6338
  const path = latestCodexRolloutPath(threadId);
6296
6339
  if (!path)
@@ -6564,7 +6607,7 @@ var exports_version = {};
6564
6607
  __export(exports_version, {
6565
6608
  NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
6566
6609
  });
6567
- var NEGOTIUM_VERSION = "0.23.3";
6610
+ var NEGOTIUM_VERSION = "0.23.4";
6568
6611
 
6569
6612
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
6570
6613
  import { spawn as spawn2 } from "child_process";
@@ -7653,6 +7696,97 @@ var init_conversations = __esm(async () => {
7653
7696
  };
7654
7697
  });
7655
7698
 
7699
+ // ../../packages/core/src/agents/claude-notices.ts
7700
+ function modelLabel(id) {
7701
+ const match = /^claude-([a-z]+)-(\d+)-(\d+)/.exec(id);
7702
+ if (!match)
7703
+ return id;
7704
+ const [, family = "", major, minor] = match;
7705
+ return `${family.charAt(0).toUpperCase()}${family.slice(1)} ${major}.${minor}`;
7706
+ }
7707
+ function rateLimitNotice(m) {
7708
+ const { status, rateLimitType } = m.rate_limit_info;
7709
+ const limit = rateLimitType ? `${RATE_LIMIT_TEXT[rateLimitType] ?? ""} `.trimStart() : "";
7710
+ if (status === "allowed_warning")
7711
+ return `Nearing your ${limit}Claude usage limit`;
7712
+ if (status === "rejected")
7713
+ return `Reached your ${limit}Claude usage limit`;
7714
+ return;
7715
+ }
7716
+ function claudeNoticeStatus(message) {
7717
+ try {
7718
+ if (message.type === "rate_limit_event")
7719
+ return rateLimitNotice(message);
7720
+ if (message.type !== "system")
7721
+ return;
7722
+ const handler = SYSTEM_NOTICES[message.subtype];
7723
+ if (!handler) {
7724
+ logger.debug({ subtype: message.subtype, msg: message }, "claudeProvider: system message (unhandled subtype)");
7725
+ return;
7726
+ }
7727
+ const status = handler(message);
7728
+ if (status)
7729
+ logger.warn({ subtype: message.subtype, status }, "claudeProvider: notice");
7730
+ return status;
7731
+ } catch (err) {
7732
+ logger.debug({ err, msg: message }, "claudeProvider: notice mapping failed");
7733
+ return;
7734
+ }
7735
+ }
7736
+ var API_ERROR_TEXT, RATE_LIMIT_TEXT, DENIAL_TEXT, SYSTEM_NOTICES;
7737
+ var init_claude_notices = __esm(() => {
7738
+ init_logger();
7739
+ API_ERROR_TEXT = {
7740
+ overloaded: "Claude is overloaded",
7741
+ rate_limit: "Claude rate limit hit",
7742
+ server_error: "Claude API error",
7743
+ unknown: "Claude request failed",
7744
+ authentication_failed: "Claude sign-in failed",
7745
+ oauth_org_not_allowed: "Organization not allowed for Claude",
7746
+ account_on_hold: "Claude account is on hold",
7747
+ verification_required: "Claude account needs verification",
7748
+ billing_error: "Claude billing issue",
7749
+ invalid_request: "Claude rejected the request",
7750
+ model_not_found: "Claude model not found",
7751
+ max_output_tokens: "Claude reply hit the length limit",
7752
+ cloud_credential_error: "Cloud credentials failed"
7753
+ };
7754
+ RATE_LIMIT_TEXT = {
7755
+ five_hour: "5-hour",
7756
+ seven_day: "weekly",
7757
+ seven_day_opus: "weekly Opus",
7758
+ seven_day_sonnet: "weekly Sonnet",
7759
+ seven_day_overage_included: "weekly",
7760
+ overage: "extra usage"
7761
+ };
7762
+ DENIAL_TEXT = {
7763
+ rule: "by a permission rule",
7764
+ mode: "by the permission mode",
7765
+ classifier: "by the safety check",
7766
+ asyncAgent: "for a background agent"
7767
+ };
7768
+ SYSTEM_NOTICES = {
7769
+ api_retry: (m) => {
7770
+ const reason = m.error_status === null ? "Lost connection to Claude" : API_ERROR_TEXT[m.error] ?? "Claude request failed";
7771
+ const delay2 = Math.round(m.retry_delay_ms / 1000);
7772
+ const when = delay2 > 0 ? `in ${delay2}s` : "now";
7773
+ return `${reason} \xB7 retrying ${when} (${m.attempt}/${m.max_retries})`;
7774
+ },
7775
+ model_refusal_fallback: (m) => m.direction === "retry" ? `${modelLabel(m.original_model)} declined \xB7 ${modelLabel(m.fallback_model)} is answering instead` : m.content || undefined,
7776
+ model_refusal_no_fallback: (m) => `${modelLabel(m.original_model)} declined this request`,
7777
+ permission_denied: (m) => {
7778
+ const tool = m.tool_name.split("__").at(-1) || m.tool_name;
7779
+ const why = m.decision_reason ? `: ${m.decision_reason}` : ` ${DENIAL_TEXT[m.decision_reason_type ?? ""] ?? ""}`.trimEnd();
7780
+ return `${tool} was blocked${why}`;
7781
+ },
7782
+ informational: (m) => m.prevent_continuation || m.level === "warning" || m.level === "suggestion" ? m.content : undefined,
7783
+ mirror_error: (m) => {
7784
+ logger.warn({ error: m.error }, "claudeProvider: transcript mirror batch dropped");
7785
+ return;
7786
+ }
7787
+ };
7788
+ });
7789
+
7656
7790
  // ../../packages/core/src/agents/deep-map.ts
7657
7791
  function deepMapStrings(value, fn) {
7658
7792
  if (typeof value === "string")
@@ -8169,12 +8303,13 @@ async function* claudeProvider(opts) {
8169
8303
  yield { type: "tool_use_summary", summary: m.summary };
8170
8304
  continue;
8171
8305
  }
8172
- if (message.type === "system") {
8173
- const m = message;
8174
- if (m.subtype === "init") {
8175
- yield { type: "session", sessionId: m.session_id };
8306
+ if (message.type === "system" || message.type === "rate_limit_event") {
8307
+ if (message.type === "system" && message.subtype === "init") {
8308
+ yield { type: "session", sessionId: message.session_id };
8176
8309
  } else {
8177
- logger.debug({ subtype: m.subtype, msg: m }, "claudeProvider: system message (unhandled subtype)");
8310
+ const status = claudeNoticeStatus(message);
8311
+ if (status)
8312
+ yield { type: "status", content: status };
8178
8313
  }
8179
8314
  continue;
8180
8315
  }
@@ -8285,6 +8420,7 @@ async function* claudeProvider(opts) {
8285
8420
  }
8286
8421
  var CLAUDE_DEFAULT_DISALLOWED_TOOLS, CLAUDE_NATIVE_AGENT_TOOLS, CLAUDE_IMAGE_MAX_BYTES, CLAUDE_IMAGE_MIME_TYPES, CLAUDE_ABORT_SIGKILL_DELAY_MS = 2500, claudeProcessExitListeners;
8287
8422
  var init_claude_provider = __esm(async () => {
8423
+ init_claude_notices();
8288
8424
  init_claude_registry();
8289
8425
  init_vault_tool_policy();
8290
8426
  init_file_events();
@@ -9241,13 +9377,22 @@ var exports_codex_provider = {};
9241
9377
  __export(exports_codex_provider, {
9242
9378
  toCodexMcpServers: () => toCodexMcpServers,
9243
9379
  normalizeCodexTurnUsage: () => normalizeCodexTurnUsage,
9244
- codexProvider: () => codexProvider
9380
+ codexProvider: () => codexProvider,
9381
+ codexNoticeStatus: () => codexNoticeStatus
9245
9382
  });
9246
9383
  import { execFileSync as execFileSync5 } from "child_process";
9247
9384
  import { existsSync as existsSync16, readFileSync as readFileSync11, realpathSync as realpathSync4, statSync as statSync5 } from "fs";
9248
9385
  import { homedir as homedir8 } from "os";
9249
9386
  import { dirname as dirname11, isAbsolute as isAbsolute3, join as join16, relative as relative2, resolve as resolve10 } from "path";
9250
9387
  import { Codex } from "@openai/codex-sdk";
9388
+ function codexNoticeStatus(message) {
9389
+ const firstLine = message.trim().split(`
9390
+ `)[0]?.trim() ?? "";
9391
+ const sentence = /^.*?[.!?](?=\s|$)/.exec(firstLine)?.[0] ?? firstLine;
9392
+ if (!sentence)
9393
+ return "Codex notice";
9394
+ return /^codex\b/i.test(sentence) ? sentence : `Codex: ${sentence}`;
9395
+ }
9251
9396
  function sameCodexUsage(usage, total) {
9252
9397
  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;
9253
9398
  }
@@ -9665,8 +9810,7 @@ async function* codexProvider(opts) {
9665
9810
  },
9666
9811
  hooks: vaultHook.hooks,
9667
9812
  model_catalog_json: codexModelCatalogPath,
9668
- mcp_servers: codexMcpServers,
9669
- ...opts.toolPolicy ? { sandbox_permissions: [] } : {}
9813
+ mcp_servers: codexMcpServers
9670
9814
  }
9671
9815
  });
9672
9816
  const threadOptions = {
@@ -9687,7 +9831,7 @@ async function* codexProvider(opts) {
9687
9831
  let currentSessionId = opts.sessionId;
9688
9832
  let usageBaseline = currentSessionId ? readLatestCodexTokenTotals(currentSessionId) : undefined;
9689
9833
  let thread = currentSessionId ? codex.resumeThread(currentSessionId, threadOptions) : codex.startThread(threadOptions);
9690
- let prompt = promptForThread(opts, true);
9834
+ let prompt = promptForThread(opts, !currentSessionId || !opts.systemPrompt || !codexThreadHasSystemPrompt(currentSessionId, opts.systemPrompt));
9691
9835
  let agentTextSoFar = "";
9692
9836
  let currentAgentMessageId;
9693
9837
  let finalText = "";
@@ -9715,6 +9859,8 @@ async function* codexProvider(opts) {
9715
9859
  trackedPids.pids = [];
9716
9860
  let heartbeatTriggered = false;
9717
9861
  let attemptCompleted = false;
9862
+ let turnFailed = false;
9863
+ let streamError;
9718
9864
  let heartbeatTimer = null;
9719
9865
  const scheduleHeartbeat = () => {
9720
9866
  if (heartbeatTimer !== null)
@@ -9843,7 +9989,8 @@ async function* codexProvider(opts) {
9843
9989
  } else if (item.type === "error") {
9844
9990
  const message = String(item.message ?? "");
9845
9991
  if (message !== CODEX_HOOK_TRUST_BYPASS_NOTICE) {
9846
- yield { type: "error", content: message };
9992
+ logger.warn({ message }, "codexProvider: codex non-fatal error item");
9993
+ yield { type: "status", content: codexNoticeStatus(message) };
9847
9994
  }
9848
9995
  }
9849
9996
  break;
@@ -9871,7 +10018,15 @@ async function* codexProvider(opts) {
9871
10018
  yield* extractFileEvents(finalText, "result");
9872
10019
  break;
9873
10020
  }
10021
+ case "error": {
10022
+ const message = event.message || "Codex stream error";
10023
+ logger.warn({ message }, "codexProvider: codex stream error event");
10024
+ streamError = message;
10025
+ yield { type: "status", content: codexNoticeStatus(message) };
10026
+ break;
10027
+ }
9874
10028
  case "turn.failed": {
10029
+ turnFailed = true;
9875
10030
  stopReason = "error";
9876
10031
  yield {
9877
10032
  type: "error",
@@ -9883,6 +10038,10 @@ async function* codexProvider(opts) {
9883
10038
  break;
9884
10039
  }
9885
10040
  }
10041
+ if (!attemptCompleted && !turnFailed && streamError) {
10042
+ stopReason = "error";
10043
+ yield { type: "error", content: streamError };
10044
+ }
9886
10045
  } catch (err) {
9887
10046
  if (abortSignal?.aborted)
9888
10047
  return;
@@ -48942,6 +49101,17 @@ class TerminalApp {
48942
49101
  return;
48943
49102
  }
48944
49103
  if (chunk === "\r") {
49104
+ const commands = this.#shownCommands();
49105
+ if (commands.length > 0) {
49106
+ const selected = commands[Math.min(this.#state.suggestionIndex, commands.length - 1)];
49107
+ if (selected) {
49108
+ if (selected.usage.includes("<")) {
49109
+ this.#replaceInput(`/${selected.name} `);
49110
+ return;
49111
+ }
49112
+ this.#replaceInput(`/${selected.name}`);
49113
+ }
49114
+ }
48945
49115
  if (this.#state.overlay !== "vault" && !activeQuestion(this.#state) && commandSuggestions(this.#input.text).length === 0 && this.#pathItems().length > 0 && this.#applyPathCompletion(true)) {
48946
49116
  return;
48947
49117
  }
@@ -49658,6 +49828,14 @@ class TerminalApp {
49658
49828
  `)[cursor.row] ?? "";
49659
49829
  return pathSuggestions(lineText, cursor.col)?.items ?? [];
49660
49830
  }
49831
+ #shownCommands() {
49832
+ const state2 = this.#state;
49833
+ if (state2.creatingTopic || state2.overlay === "vault" || composerHoldsSecret(state2))
49834
+ return [];
49835
+ if (activeQuestion(state2))
49836
+ return [];
49837
+ return commandSuggestions(this.#input.text);
49838
+ }
49661
49839
  #suggestionCount() {
49662
49840
  const commands = commandSuggestions(this.#input.text).length;
49663
49841
  return commands > 0 ? commands : this.#pathItems().length;
@@ -60396,4 +60574,4 @@ switch (command) {
60396
60574
  }
60397
60575
  }
60398
60576
 
60399
- //# debugId=202F5FA265766A0464756E2164756E21
60577
+ //# debugId=7009B5CBB966BCAA64756E2164756E21