@sagentlab/navarch-runtime 0.1.103 → 0.1.107

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/README.md CHANGED
@@ -717,8 +717,12 @@ post-tool answer as the report, and reads aggregate `input_tokens` and
717
717
  cost, so an unknown value remains absent rather than becoming zero.
718
718
 
719
719
  Gemini's native sandbox launcher converts piped stdin back into a `--prompt`
720
- argument for its child. The adapter rejects prompts of 128 KiB or more when
721
- that sandbox is enabled, with an explicit diagnostic; reducing context or
720
+ argument for its child. When that sandbox follows Linux argv rules (a Linux
721
+ host, a Docker session, or a `docker`/`podman` sandbox chosen through
722
+ `GEMINI_SANDBOX`), the adapter rejects prompts of 128 KiB or more; macOS
723
+ `sandbox-exec` has no per-string limit, so there the adapter only rejects
724
+ prompts that would approach the 1 MiB total argv limit (about 900 KiB once
725
+ shell-quoted). Both rejections carry an explicit diagnostic; reducing context or
722
726
  selecting another runtime preserves the worktree boundary. Navarch Docker
723
727
  mode disables the nested Gemini sandbox by default and can still pipe larger
724
728
  prompts. All Gemini runs reject prompts above 8 MiB because Gemini's stdin
@@ -17,8 +17,10 @@ const kill_agent_cjs_1 = require("../kill-agent.cjs");
17
17
  *
18
18
  * The prompt arrives on stdin rather than `--prompt`: Gemini runs headlessly
19
19
  * whenever stdin is not a TTY and uses the piped text as the prompt. Its
20
- * native sandbox puts stdin back into argv, so that path still has Linux's
21
- * 128 KiB per-string limit. Gemini also caps stdin at 8 MiB.
20
+ * native sandbox puts stdin back into argv, so that path still has an argv
21
+ * limit: Linux's 128 KiB per-string limit for container sandboxes and Linux
22
+ * hosts, or macOS's 1 MiB total for sandbox-exec. Gemini also caps stdin at
23
+ * 8 MiB.
22
24
  */
23
25
  async function runGeminiAdapter(options) {
24
26
  if (options.signal?.aborted) {
@@ -70,9 +72,21 @@ async function runGeminiAdapter(options) {
70
72
  // Gemini's sandbox launcher reads stdin and injects it back into --prompt
71
73
  // for its child process (packages/cli/src/gemini.tsx injectStdinIntoArgs).
72
74
  // Moving our first spawn's prompt to stdin cannot fix that second spawn.
73
- // Check the effective flag, including operator overrides, without disabling
74
- // the worktree guard. Even on macOS a Docker sandbox may launch on Linux.
75
- if (geminiSandboxEnabled(args) && promptBytes >= 128 * 1024) {
75
+ // Check the effective sandbox, including operator overrides, without
76
+ // disabling the worktree guard. Even on macOS a Docker sandbox may launch on
77
+ // Linux, while macOS sandbox-exec re-quotes the prompt into one `sh -c`
78
+ // string that only the 1 MiB total ARG_MAX bounds.
79
+ const platform = options.dockerExec ? "linux" : process.platform;
80
+ const sandboxCommand = geminiSandboxCommand(args, geminiProcessEnv(options, env), platform);
81
+ if (sandboxCommand === "sandbox-exec" && platform === "darwin") {
82
+ // shell-quote backslash-escapes these inside the double-quoted prompt.
83
+ // Leave the rest of ARG_MAX for the environment and Gemini's own args.
84
+ const quotedBytes = promptBytes + (options.prompt.match(/["\\$`!]/g)?.length ?? 0);
85
+ if (quotedBytes > 900 * 1024) {
86
+ return inputFailure(`Gemini CLI re-encodes stdin as --prompt when launching its macOS sandbox-exec sandbox; the ${promptBytes}-byte task prompt exceeds macOS's 1 MiB argv limit. Reduce the context bundle or select another runtime that supports large prompts in its sandbox.`);
87
+ }
88
+ }
89
+ else if (sandboxCommand && promptBytes >= 128 * 1024) {
76
90
  return inputFailure(`Gemini CLI re-encodes stdin as --prompt when launching its native sandbox; the ${promptBytes}-byte task prompt exceeds Linux's argv limit. Reduce the context bundle or select another runtime that supports large prompts in its sandbox.`);
77
91
  }
78
92
  const runOptions = { ...options, env };
@@ -84,7 +98,30 @@ async function runGeminiAdapter(options) {
84
98
  function inputFailure(stderr) {
85
99
  return { exitCode: 1, timedOut: false, killedByLeaseLoss: false, stdout: "", stderr };
86
100
  }
87
- function geminiSandboxEnabled(args) {
101
+ function geminiProcessEnv(options, env) {
102
+ // Docker exec forwards only the session env names into the container.
103
+ return options.dockerExec ? env : { ...process.env, ...env };
104
+ }
105
+ /**
106
+ * Mirrors Gemini's getSandboxCommand (packages/cli/src/config/sandboxConfig.ts):
107
+ * GEMINI_SANDBOX overrides the --sandbox flag and may name the command;
108
+ * otherwise an enabled sandbox is sandbox-exec on macOS and a container
109
+ * (docker or podman) elsewhere. Returns null when no sandbox relaunch occurs.
110
+ */
111
+ function geminiSandboxCommand(args, env, platform) {
112
+ const configured = env.GEMINI_SANDBOX?.toLowerCase().trim() ?? "";
113
+ let sandbox = configured.length > 0 ? configured : geminiSandboxFlag(args);
114
+ if (sandbox === "1" || sandbox === "true")
115
+ sandbox = true;
116
+ else if (sandbox === "0" || sandbox === "false" || !sandbox)
117
+ sandbox = false;
118
+ if (sandbox === false)
119
+ return null;
120
+ if (typeof sandbox === "string")
121
+ return sandbox;
122
+ return platform === "darwin" ? "sandbox-exec" : "docker";
123
+ }
124
+ function geminiSandboxFlag(args) {
88
125
  // There is always a generated --sandbox flag unless extraArgs supplies one.
89
126
  // Like yargs, later explicit values override earlier ones.
90
127
  let enabled = false;
package/dist/session.cjs CHANGED
@@ -631,6 +631,10 @@ async function runClaimedSession(deps, claimed, sessionId, lifecycle) {
631
631
  ...result,
632
632
  killedByLeaseLoss: leaseLost || result.killedByLeaseLoss,
633
633
  });
634
+ // Correction turns reuse the previous turn's findings. The completion
635
+ // summary is collapsed to one 500-character line, so hand them the final
636
+ // prose instead, including from adapters that only return stdout.
637
+ const previousTurnReport = () => (0, redact_cjs_1.redactText)(result.reportText ?? (0, exit_conditions_cjs_1.parseClaudeJsonResult)(result.stdout)?.result ?? result.stdout, registry.list());
634
638
  let headBranch = gitWorktree.branch;
635
639
  let headSha;
636
640
  try {
@@ -706,11 +710,9 @@ async function runClaimedSession(deps, claimed, sessionId, lifecycle) {
706
710
  log.warn(`session ${leaseId} finished without delivering (${delivery.reason}); ` +
707
711
  `restarting agent turn ${deliveryCorrectionRetries}/${DELIVERY_CORRECTION_RETRIES} in the same worktree.`);
708
712
  nextPrompt = (0, delivery_cjs_1.renderDeliveryCorrectionPrompt)({
709
- originalPrompt: runPrompt,
713
+ originalPrompt: briefPrompt,
710
714
  taskType: task.task_type,
711
- // The completion summary is capped at 500 characters. Preserve
712
- // the final prose from adapters that only return stdout as well.
713
- previousReport: (0, redact_cjs_1.redactText)(result.reportText ?? (0, exit_conditions_cjs_1.parseClaudeJsonResult)(result.stdout)?.result ?? result.stdout, registry.list()),
715
+ previousReport: previousTurnReport(),
714
716
  reason: delivery.reason,
715
717
  attempt: deliveryCorrectionRetries,
716
718
  maxAttempts: DELIVERY_CORRECTION_RETRIES,
@@ -808,7 +810,7 @@ async function runClaimedSession(deps, claimed, sessionId, lifecycle) {
808
810
  nextPrompt = (0, prompt_cjs_1.renderCompletionRemediationPrompt)({
809
811
  originalPrompt: briefPrompt,
810
812
  rejection: redactedRejection,
811
- previousReport: redactedReport,
813
+ previousReport: previousTurnReport(),
812
814
  attempt: completionRemediationRetries,
813
815
  maxAttempts: COMPLETION_REMEDIATION_RETRIES,
814
816
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sagentlab/navarch-runtime",
3
- "version": "0.1.103",
3
+ "version": "0.1.107",
4
4
  "description": "Navarch machine-side session manager: claims delivery tasks and runs them through local coding agents.",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",