Conversation
Agent-Logs-Url: https://github.com/copsys/codex-app-proxy/sessions/41e79ae7-148a-4f6d-970c-4f5ad05386fd Co-authored-by: copsys <31281180+copsys@users.noreply.github.com>
Agent-Logs-Url: https://github.com/copsys/codex-app-proxy/sessions/41e79ae7-148a-4f6d-970c-4f5ad05386fd Co-authored-by: copsys <31281180+copsys@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a per-request “BrowserOS mode” to bias the proxy/Codex prompt toward tool orchestration (avoiding environment-refusal text) when BrowserOS is the executor, and documents the new request contract.
Changes:
- Add
browseros_modehandling in/v1/chat/completions, defaulting to enabled whentoolsare provided (unless explicitly disabled), and thread it through the Codex execution path. - Expand tool-instruction injection and broaden tool-call parsing to recognize multiple response formats.
- Document
tools/tool_choicesupport andbrowseros_modesemantics in the README.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/index.ts | Parses tools, computes browseros_mode, defaults tool_choice, and passes the flag through streaming/non-streaming paths. |
| src/codex.ts | Adds browseros_mode to options, expands tool-call parsing formats, and updates tool-instruction text/schema support. |
| src/codex-client.ts | Injects BrowserOS-specific tool-mode instructions and adds a warning when tools are present but no tool calls are parsed. |
| README.md | Documents tools / tool_choice and browseros_mode default/usage for BrowserOS integrations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const name = raw?.name || raw?.toolName || raw?.function?.name || ""; | ||
| const argsRaw = | ||
| raw?.arguments ?? raw?.input ?? raw?.parameters ?? raw?.function?.arguments; | ||
| if (!name) return; | ||
| const args = | ||
| typeof argsRaw === "string" | ||
| ? argsRaw | ||
| : JSON.stringify(argsRaw ?? {}); |
There was a problem hiding this comment.
parseToolCalls will currently treat any JSON object containing a name field (e.g., { "name": "Alice" }), or any JSON code fence containing such an object, as a tool call. With tools enabled, this can lead to false-positive tool executions if the model outputs or echoes arbitrary JSON. Consider tightening detection (e.g., require the canonical tool-call shape like {name, arguments} / {function:{name,arguments}}), and ideally validate that name matches one of the provided tool definitions before emitting a tool call.
| const name = raw?.name || raw?.toolName || raw?.function?.name || ""; | |
| const argsRaw = | |
| raw?.arguments ?? raw?.input ?? raw?.parameters ?? raw?.function?.arguments; | |
| if (!name) return; | |
| const args = | |
| typeof argsRaw === "string" | |
| ? argsRaw | |
| : JSON.stringify(argsRaw ?? {}); | |
| if (!raw || typeof raw !== "object") return; | |
| // Support only canonical tool-call shapes: | |
| // 1) { function: { name, arguments } } | |
| // 2) { name, arguments } | |
| let name: string | undefined; | |
| let argsRaw: any; | |
| if (raw.function && typeof raw.function === "object") { | |
| name = typeof raw.function.name === "string" ? raw.function.name : undefined; | |
| argsRaw = raw.function.arguments; | |
| } else { | |
| name = typeof raw.name === "string" ? raw.name : undefined; | |
| argsRaw = raw.arguments; | |
| } | |
| // Require both a valid name and explicit arguments to treat this as a tool call. | |
| if (!name || argsRaw === undefined) return; | |
| const args = | |
| typeof argsRaw === "string" ? argsRaw : JSON.stringify(argsRaw); |
| eventQueue.push({ type: "tool_calls", calls: toolCalls }); | ||
| } else { | ||
| console.warn( | ||
| `[CodexClient] Tools provided but no tool calls parsed. Assistant preview: ${accumulatedText.slice(0, 300).replace(/\s+/g, " ")}`, |
There was a problem hiding this comment.
This warning logs a preview of the assistant output (accumulatedText) when tools are provided but no tool calls are parsed. That content may include sensitive user data or secrets and will end up in server logs. Consider gating this behind a debug flag and/or redacting content (e.g., log only length / hash / truncated-with-redaction) to reduce accidental data exposure.
| `[CodexClient] Tools provided but no tool calls parsed. Assistant preview: ${accumulatedText.slice(0, 300).replace(/\s+/g, " ")}`, | |
| `[CodexClient] Tools provided but no tool calls parsed. Assistant preview redacted (length=${accumulatedText.length}).`, |
BrowserOS can reach this proxy’s OpenAI-compatible endpoint, but tool-enabled browsing requests were returning provider text refusals (e.g., inability to control browser) instead of function/tool calls. This change adds an explicit proxy mode to bias the model toward tool orchestration when BrowserOS is the runtime executor.
Request contract update
browseros_modeto/v1/chat/completionsrequest handling.index.ts -> codex.ts -> codex-client.tsso behavior is controlled per request, not globally.Tool-orchestration instruction path
browseros_mode: trueandtoolsare present, injects BrowserOS-specific developer instructions intobaseInstructions.Documentation
tools/tool_choicesupport for agentic clients.browseros_modesemantics and when to enable it for BrowserOS integrations.