Improve browser research reliability and bound context growth - #152
Improve browser research reliability and bound context growth#152gregpr07 wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
2 issues found across 7 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/opencode/src/session/prompt/gpt.txt">
<violation number="1" location="packages/opencode/src/session/prompt/gpt.txt:1">
P2: This file is wired to every generic GPT session (system.ts returns it as `PROMPT_GPT` for any non-codex/gpt-4/o1/o3 model), but it is now 100% browser-research-specific — it defines the agent as a browser research agent, references only `browser_execute`/CDP, and drops the prior general-purpose guidance (editing approach, git worktree safety, formatting rules, generic tool usage, "generic OpenCode features still apply"). A GPT session run for a non-browser task (edit/apply_patch, shell, plain Q&A, code review) still receives this browser-only prompt, so it loses all general engineering constraints and is told it is a browser agent. If the intent is to bound this prompt to browser-research workloads only, keep the general-purpose guidance (or gate the browser prompt behind a browser-specific path) rather than replacing `gpt.txt` wholesale, which is the shared default for all GPT models.</violation>
</file>
<file name="packages/opencode/src/tool/browser-execute.ts">
<violation number="1" location="packages/opencode/src/tool/browser-execute.ts:82">
P2: When a browser snippet emits more than 400 lines or 8 KiB of output, truncate.output keeps only the head of `fullOutput` (its `direction` defaults to "head"). Because the `=> ${result.result}` line and the screenshot count are appended at the very end of `fullOutput`, they are cut out of the model-visible content for large outputs. The `=> result` value is usually the key outcome of a browser snippet, and metadata ({ result, output, outputPath }) is not forwarded to the model — toModelMessagesEffect only passes `part.state.output`, so the result survives only if the agent follows the hint and reads the saved file. Preserve the trailing result by truncating from the tail so the final outcome stays in primary model context.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| @@ -1,107 +1,22 @@ | |||
| You are BrowserCode (a fork of OpenCode at https://github.com/anomalyco/opencode that adds browser-use integration). You and the user share the same workspace and collaborate to achieve the user's goals. For BrowserCode-specific features (`browser_execute`, the harness, cloud integrations) point users at https://github.com/browser-use/browsercode; generic OpenCode features still apply. | |||
| You are BrowserCode's browser research agent. Complete the user's task; do not merely describe a plan. | |||
There was a problem hiding this comment.
P2: This file is wired to every generic GPT session (system.ts returns it as PROMPT_GPT for any non-codex/gpt-4/o1/o3 model), but it is now 100% browser-research-specific — it defines the agent as a browser research agent, references only browser_execute/CDP, and drops the prior general-purpose guidance (editing approach, git worktree safety, formatting rules, generic tool usage, "generic OpenCode features still apply"). A GPT session run for a non-browser task (edit/apply_patch, shell, plain Q&A, code review) still receives this browser-only prompt, so it loses all general engineering constraints and is told it is a browser agent. If the intent is to bound this prompt to browser-research workloads only, keep the general-purpose guidance (or gate the browser prompt behind a browser-specific path) rather than replacing gpt.txt wholesale, which is the shared default for all GPT models.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/src/session/prompt/gpt.txt, line 1:
<comment>This file is wired to every generic GPT session (system.ts returns it as `PROMPT_GPT` for any non-codex/gpt-4/o1/o3 model), but it is now 100% browser-research-specific — it defines the agent as a browser research agent, references only `browser_execute`/CDP, and drops the prior general-purpose guidance (editing approach, git worktree safety, formatting rules, generic tool usage, "generic OpenCode features still apply"). A GPT session run for a non-browser task (edit/apply_patch, shell, plain Q&A, code review) still receives this browser-only prompt, so it loses all general engineering constraints and is told it is a browser agent. If the intent is to bound this prompt to browser-research workloads only, keep the general-purpose guidance (or gate the browser prompt behind a browser-specific path) rather than replacing `gpt.txt` wholesale, which is the shared default for all GPT models.</comment>
<file context>
@@ -1,107 +1,22 @@
-You are BrowserCode (a fork of OpenCode at https://github.com/anomalyco/opencode that adds browser-use integration). You and the user share the same workspace and collaborate to achieve the user's goals. For BrowserCode-specific features (`browser_execute`, the harness, cloud integrations) point users at https://github.com/browser-use/browsercode; generic OpenCode features still apply.
+You are BrowserCode's browser research agent. Complete the user's task; do not merely describe a plan.
-You are a deeply pragmatic, effective software engineer. You take engineering quality seriously, and collaboration comes through as direct, factual statements. You communicate efficiently, keeping the user clearly informed about ongoing actions without unnecessary detail. You build context by examining the codebase first without making assumptions or jumping to conclusions. You think through the nuances of the code you encounter, and embody the mentality of a skilled senior software engineer.
</file context>
| const contextualOutput = yield* truncate.output(fullOutput, { | ||
| maxBytes: MAX_CONTEXT_BYTES, | ||
| maxLines: MAX_CONTEXT_LINES, | ||
| }) |
There was a problem hiding this comment.
P2: When a browser snippet emits more than 400 lines or 8 KiB of output, truncate.output keeps only the head of fullOutput (its direction defaults to "head"). Because the => ${result.result} line and the screenshot count are appended at the very end of fullOutput, they are cut out of the model-visible content for large outputs. The => result value is usually the key outcome of a browser snippet, and metadata ({ result, output, outputPath }) is not forwarded to the model — toModelMessagesEffect only passes part.state.output, so the result survives only if the agent follows the hint and reads the saved file. Preserve the trailing result by truncating from the tail so the final outcome stays in primary model context.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/src/tool/browser-execute.ts, line 82:
<comment>When a browser snippet emits more than 400 lines or 8 KiB of output, truncate.output keeps only the head of `fullOutput` (its `direction` defaults to "head"). Because the `=> ${result.result}` line and the screenshot count are appended at the very end of `fullOutput`, they are cut out of the model-visible content for large outputs. The `=> result` value is usually the key outcome of a browser snippet, and metadata ({ result, output, outputPath }) is not forwarded to the model — toModelMessagesEffect only passes `part.state.output`, so the result survives only if the agent follows the hint and reads the saved file. Preserve the trailing result by truncating from the tail so the final outcome stays in primary model context.</comment>
<file context>
@@ -66,18 +70,28 @@ export const BrowserExecuteTool = Tool.define(
+ ]
+ .filter(Boolean)
+ .join("\n\n")
+ const contextualOutput = yield* truncate.output(fullOutput, {
+ maxBytes: MAX_CONTEXT_BYTES,
+ maxLines: MAX_CONTEXT_LINES,
</file context>
| const contextualOutput = yield* truncate.output(fullOutput, { | |
| maxBytes: MAX_CONTEXT_BYTES, | |
| maxLines: MAX_CONTEXT_LINES, | |
| }) | |
| const contextualOutput = yield* truncate.output(fullOutput, { | |
| maxBytes: MAX_CONTEXT_BYTES, | |
| maxLines: MAX_CONTEXT_LINES, | |
| direction: "tail", | |
| }) |
There was a problem hiding this comment.
I dont think should truncate responses.... not sure about this part
Summary
This stays pure TypeScript/JavaScript. It does not add Python, a notebook runtime, a new browser API, or task-specific benchmark logic.
Evaluation
Internal Bench Hard, all 106 tasks, GPT-5.5, medium reasoning:
Against the immediate predecessor, this is +1 pass with 13.4% lower agent cost, 18.6% fewer cached input tokens, 7.9% fewer uncached input tokens, and 6.2% fewer output tokens. Browser calls increased 9.9%, so the saving comes from leaner model context rather than less browsing.
The 81/106 comparison spans a larger target evolution and should be read as a product-level comparison, not an isolated causal A/B. The 86 -> 87 comparison used the same eval-platform commit and isolates the final evidence-budget commit.
Verification
Summary by cubic
Bounds browser research behavior and model context to improve reliability and cost. Previously we used a generic prompt and surfaced full tool output; now we use a compact browser-research contract, persist the CDP session, cap per-call time at 2 minutes, and limit model-visible tool output to 8 KiB/400 lines while saving the full output to disk.
browser_executenow returns compact context with full output saved. Tool metadata includestruncatedandoutputPathwhen truncation occurs. Screenshots still auto-attach.await import(...?t=...), and switching strategy after three no-evidence calls.gpt-5.5models use mediumtextVerbosity; tests cover the new default.Review/Rollout
metadata.outputPathor use focused Grep/Read instead.gpt-5.5verbosity if tests assertedlow.Written for commit 806a396. Summary will update on new commits.