@sagentlab/navarch-runtime 0.1.86 → 0.1.87
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 +11 -0
- package/dist/adapters/gemini.cjs +41 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -691,6 +691,14 @@ post-tool answer as the report, and reads aggregate `input_tokens` and
|
|
|
691
691
|
`output_tokens` from the terminal `result` event. Gemini does not report USD
|
|
692
692
|
cost, so an unknown value remains absent rather than becoming zero.
|
|
693
693
|
|
|
694
|
+
Gemini's native sandbox launcher converts piped stdin back into a `--prompt`
|
|
695
|
+
argument for its child. The adapter rejects prompts of 128 KiB or more when
|
|
696
|
+
that sandbox is enabled, with an explicit diagnostic; reducing context or
|
|
697
|
+
selecting another runtime preserves the worktree boundary. Navarch Docker
|
|
698
|
+
mode disables the nested Gemini sandbox by default and can still pipe larger
|
|
699
|
+
prompts. All Gemini runs reject prompts above 8 MiB because Gemini's stdin
|
|
700
|
+
reader silently truncates input beyond that limit. These checks use UTF-8 bytes.
|
|
701
|
+
|
|
694
702
|
The OpenCode adapter uses `opencode run --format json` with the prompt on
|
|
695
703
|
stdin, and normalizes `text` and `step_finish` JSONL events into
|
|
696
704
|
the shared report/token/cost boundary. It translates the lease MCP document
|
|
@@ -722,6 +730,9 @@ rejects any single argv or environment string over 128 KiB
|
|
|
722
730
|
(`MAX_ARG_STRLEN`), so an argv prompt made large review sessions fail with
|
|
723
731
|
`spawn E2BIG` before the agent started. Docker-mode sessions forward the same
|
|
724
732
|
stdin through `docker exec -i`.
|
|
733
|
+
Gemini's own sandbox relaunch is an exception to this transport guarantee,
|
|
734
|
+
as described above; moving the initial spawn to stdin does not remove its
|
|
735
|
+
internal argv limit.
|
|
725
736
|
|
|
726
737
|
## Architecture
|
|
727
738
|
|
package/dist/adapters/gemini.cjs
CHANGED
|
@@ -16,10 +16,20 @@ const kill_agent_cjs_1 = require("../kill-agent.cjs");
|
|
|
16
16
|
* temporary system-settings file and restricts the run to those server names.
|
|
17
17
|
*
|
|
18
18
|
* The prompt arrives on stdin rather than `--prompt`: Gemini runs headlessly
|
|
19
|
-
* whenever stdin is not a TTY and uses the piped text as the prompt
|
|
20
|
-
*
|
|
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.
|
|
21
22
|
*/
|
|
22
23
|
async function runGeminiAdapter(options) {
|
|
24
|
+
if (options.signal?.aborted) {
|
|
25
|
+
return { exitCode: null, timedOut: false, killedByLeaseLoss: true, stdout: "", stderr: "" };
|
|
26
|
+
}
|
|
27
|
+
const promptBytes = Buffer.byteLength(options.prompt, "utf8");
|
|
28
|
+
// Gemini's readStdin() silently truncates at 8 MiB. Reject before any
|
|
29
|
+
// settings writes or process launch rather than execute a partial task.
|
|
30
|
+
if (promptBytes > 8 * 1024 * 1024) {
|
|
31
|
+
return inputFailure(`Gemini CLI stdin is limited to 8 MiB; the task prompt is ${promptBytes} bytes. Reduce the context bundle or select another runtime.`);
|
|
32
|
+
}
|
|
23
33
|
const args = [];
|
|
24
34
|
const env = { ...options.env };
|
|
25
35
|
if (!hasArg(options.extraArgs, "--output-format", "-o")) {
|
|
@@ -57,12 +67,41 @@ async function runGeminiAdapter(options) {
|
|
|
57
67
|
args.push(...options.extraArgs);
|
|
58
68
|
if (options.model)
|
|
59
69
|
args.push("--model", options.model);
|
|
70
|
+
// Gemini's sandbox launcher reads stdin and injects it back into --prompt
|
|
71
|
+
// for its child process (packages/cli/src/gemini.tsx injectStdinIntoArgs).
|
|
72
|
+
// 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) {
|
|
76
|
+
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
|
+
}
|
|
60
78
|
const runOptions = { ...options, env };
|
|
61
79
|
const raw = runOptions.dockerExec
|
|
62
80
|
? await runViaDocker(runOptions, args)
|
|
63
81
|
: await runOnHost(runOptions, args);
|
|
64
82
|
return attachGeminiOutput(raw);
|
|
65
83
|
}
|
|
84
|
+
function inputFailure(stderr) {
|
|
85
|
+
return { exitCode: 1, timedOut: false, killedByLeaseLoss: false, stdout: "", stderr };
|
|
86
|
+
}
|
|
87
|
+
function geminiSandboxEnabled(args) {
|
|
88
|
+
// There is always a generated --sandbox flag unless extraArgs supplies one.
|
|
89
|
+
// Like yargs, later explicit values override earlier ones.
|
|
90
|
+
let enabled = false;
|
|
91
|
+
for (let index = 0; index < args.length; index++) {
|
|
92
|
+
const arg = args[index];
|
|
93
|
+
if (arg === "--sandbox" || arg === "-s") {
|
|
94
|
+
enabled = args[index + 1] !== "false";
|
|
95
|
+
}
|
|
96
|
+
else if (arg.startsWith("--sandbox=") || arg.startsWith("-s=")) {
|
|
97
|
+
enabled = arg.slice(arg.indexOf("=") + 1) !== "false";
|
|
98
|
+
}
|
|
99
|
+
else if (arg === "--no-sandbox") {
|
|
100
|
+
enabled = false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return enabled;
|
|
104
|
+
}
|
|
66
105
|
function hasArg(args, ...flags) {
|
|
67
106
|
return args.some((arg) => flags.some((flag) => arg === flag || arg.startsWith(`${flag}=`)));
|
|
68
107
|
}
|
package/package.json
CHANGED