feat(providers): add Upstage Open2 beta bridge - #400
Conversation
Add a keyless provider preset and WebSocket adapter for Upstage's public Open2 beta. Bootstrap and rotate anonymous web sessions in memory, map text/reasoning/usage events, and document the beta compatibility boundary.
📝 WalkthroughWalkthroughAdds an unofficial Upstage Open2 Beta provider using anonymous session cookies and WebSockets, with message/event conversion, reasoning controls, registry wiring, CLI handling, tests, runtime dependencies, and documentation updates. ChangesOpen2 Beta provider
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant OpenCodex
participant requestOpen2Session
participant createOpen2BetaAdapter
participant Open2WebSocket
participant mapOpen2Event
OpenCodex->>requestOpen2Session: Request anonymous session
requestOpen2Session->>Open2WebSocket: Connect with solar_session cookie
Open2WebSocket-->>createOpen2BetaAdapter: Return ready frame
createOpen2BetaAdapter->>Open2WebSocket: Send converted start request
Open2WebSocket-->>mapOpen2Event: Stream protocol events
mapOpen2Event-->>OpenCodex: Emit adapter events
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tests/open2-beta-adapter.test.ts (1)
1-79: 🩺 Stability & Availability | 🔵 Trivial | 🏗️ Heavy liftMissing regression coverage for
requestSessionandrunTurn's WebSocket lifecycle.The added tests exercise only the pure mapping helpers (
open2Messages,mapOpen2Event,open2ReasoningEffort). The stateful, protocol-sensitive logic — session cache/candidate fallback inrequestSession, theready/protocol check, sequence-gap detection, abort handling, and the ready-timeout — has no test coverage at all. This is the part of the adapter most likely to regress silently (e.g., the hang risk flagged insrc/adapters/open2-beta.ts), and it's exactly the kind of adapter behavior change this test suite should protect.Consider adding tests with a mock
ws/WebSocket (e.g. injecting a fake socket or stubbingfetch) to cover: session refresh viaSet-Cookie, sequence-gapfail(), and abort-triggered cancellation. Want me to draft these?As per path instructions, "A behavior change in src/ should come with a focused regression test near the existing tests for that subsystem. Flag PRs that change shared routing, adapters, config, or server behavior without touching tests."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/open2-beta-adapter.test.ts` around lines 1 - 79, Add focused regression tests for the stateful WebSocket behavior in requestSession and runTurn, using a mock WebSocket or stubbed fetch. Cover session refresh from Set-Cookie, ready/protocol validation, sequence-gap failure, abort-triggered cancellation, and the ready-timeout path while preserving the existing pure-helper tests.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs-site/src/content/docs/ja/reference/adapters.md`:
- Line 3: Update the adapter reference pages in
docs-site/src/content/docs/ja/reference/adapters.md (line 3),
docs-site/src/content/docs/ko/reference/adapters.md (line 3),
docs-site/src/content/docs/ru/reference/adapters.md (line 3), and
docs-site/src/content/docs/zh-cn/reference/adapters.md (line 3) to add
translated Open2 Beta sections covering the WebSocket target, anonymous
solar_session authentication, runTurn, in-memory cookies, reasoning choices, and
beta limitations, or link each locale to the corresponding English section until
translations are available; keep all localized behavior consistent with the
English adapter reference.
In `@docs-site/src/content/docs/reference/adapters.md`:
- Around line 159-161: Update the adapter documentation to accurately describe
usage events: standalone usage frames in open2-beta are mapped to heartbeat
events and do not emit token counts, while usage is included only when present
in the complete event. Narrow the existing AdapterEvent description rather than
promising standalone usage data that is discarded.
- Around line 162-163: Synchronize the reasoning-choice documentation with the
provider metadata: inspect the relevant provider entry in the registry’s
reasoningEfforts and modelReasoningEfforts definitions, then either add none to
both when it is supported by CLI/API behavior or remove none from the adapter
documentation. Ensure the documented choices and user-facing metadata expose the
same contract.
In `@src/adapters/open2-beta.ts`:
- Around line 41-57: Verify the upstream wire format for the usage event and
resolve the unused top-level fields in Open2Event. If usage events carry
input_tokens, output_tokens, total_tokens, cached_input_tokens, or
reasoning_tokens, update mapOpen2Event and the related usage handling to emit or
fold that telemetry into the appropriate event; otherwise remove those fields
from Open2Event. Keep nested data.usage handling in open2Usage unchanged.
- Around line 300-313: In the socket start-request construction, compute
open2Messages(parsed) once and store the result in a local variable before
building the payload. Reuse that variable for both the messages field and the
user-message count used by turn_index.
- Around line 264-345: Replace the one-shot ready timeout in runTurn with a
resettable idle timeout covering the entire post-handshake turn. After receiving
ready, start or reset idleTimer; reset it whenever valid activity is received,
including event and ack frames, and have it call fail with a retryable timeout
error and terminate the socket when exceeded. Clear idleTimer in finish()
alongside readyTimeout, preserving existing completion and abort behavior.
In `@src/cli/provider.ts`:
- Line 226: Add a focused CLI regression test covering the provider
authentication guidance around the registryEntry keyOptional condition in
provider handling: optional-key providers must not print API-key instructions,
required-key providers must print them, and supplying --api-key must suppress
the prompt for both. Place it near the existing CLI/provider subsystem tests and
reuse the established test setup and output assertions.
In `@tests/provider-registry-parity.test.ts`:
- Line 32: Add a resolveAdapter parity assertion for adapter "open2-beta" in
tests/provider-registry-parity.test.ts, alongside the existing cursor and azure
resolveAdapter cases. Verify it resolves consistently with the registry entry
and exercises the open2-beta branch in adapter-resolve.ts.
---
Outside diff comments:
In `@tests/open2-beta-adapter.test.ts`:
- Around line 1-79: Add focused regression tests for the stateful WebSocket
behavior in requestSession and runTurn, using a mock WebSocket or stubbed fetch.
Cover session refresh from Set-Cookie, ready/protocol validation, sequence-gap
failure, abort-triggered cancellation, and the ready-timeout path while
preserving the existing pure-helper tests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 7ee7cfac-1379-47ad-9b85-bbd7b453b0d8
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (15)
README.mddocs-site/src/content/docs/guides/providers.mddocs-site/src/content/docs/ja/reference/adapters.mddocs-site/src/content/docs/ko/reference/adapters.mddocs-site/src/content/docs/reference/adapters.mddocs-site/src/content/docs/ru/reference/adapters.mddocs-site/src/content/docs/zh-cn/reference/adapters.mdpackage.jsonsrc/adapters/open2-beta.tssrc/cli/provider.tssrc/index.tssrc/providers/registry.tssrc/server/adapter-resolve.tstests/open2-beta-adapter.test.tstests/provider-registry-parity.test.ts
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs-site/src/content/docs/guides/providers.md (2)
149-155: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick winDocument that refreshed session cookies are memory-only.
The caution explains automatic anonymous-session creation and refresh, but does not state that the
solar_sessioncookie is not persisted or a durable credential. Add that storage boundary explicitly so users understand the privacy and restart behavior of this keyless flow.Proposed wording
The `open2-beta` preset is an unofficial bridge to Upstage's private beta web protocol, not a stable public API. OpenCodex creates and refreshes its anonymous session automatically, so it is currently free and needs no API key while the public beta remains open. +The refreshed `solar_session` cookie is kept only in memory and is not a durable or stored credential. Upstage may change, restrict, authenticate, or remove the protocol without notice, which can break the adapter.As per path instructions, the Open2 Beta documentation must state that cookies are not a durable/stored credential.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs-site/src/content/docs/guides/providers.md` around lines 149 - 155, Update the “Open2 Beta compatibility” caution to explicitly state that the automatically refreshed solar_session cookie is kept only in memory, is not persisted as a durable credential, and is lost on restart. Preserve the existing explanation of anonymous session creation and keyless usage.Source: Path instructions
113-121: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winQualify the API-key catalog wording for the keyless Open2 preset.
The table correctly labels
open2-betaas keyless, but the surrounding text says the dashboard opens “a key provider’s dashboard,” validates a key, and stores it. That contradicts Open2’s anonymous-session flow and may send users looking for a nonexistent API-key configuration. Reword this to apply only to key-based entries and explicitly describe Open2 as a keyless/session-backed preset.Proposed wording
-opencodex ships 54 built-in presets: 43 key-based, seven OAuth, three local, and the default -ChatGPT-forward preset. The dashboard's **Add provider** picker opens a key provider's dashboard, -validates the key, and stores it. Notable entries: +opencodex ships 54 built-in presets: 43 key-based, seven OAuth, three local, and the default +ChatGPT-forward preset. For key-based entries, the dashboard's **Add provider** picker opens the +provider's dashboard, validates the key, and stores it. Notable entries include keyless presets +such as `open2-beta`:As per path instructions, user-facing docs must stay in sync with actual CLI/API behavior.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs-site/src/content/docs/guides/providers.md` around lines 113 - 121, Revise the provider catalog description around the built-in preset counts and “Add provider” flow to apply key validation and storage only to key-based entries. Explicitly describe the Upstage Open2 Beta preset as keyless and using an anonymous session-backed flow, while preserving the existing provider table and counts.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@docs-site/src/content/docs/guides/providers.md`:
- Around line 149-155: Update the “Open2 Beta compatibility” caution to
explicitly state that the automatically refreshed solar_session cookie is kept
only in memory, is not persisted as a durable credential, and is lost on
restart. Preserve the existing explanation of anonymous session creation and
keyless usage.
- Around line 113-121: Revise the provider catalog description around the
built-in preset counts and “Add provider” flow to apply key validation and
storage only to key-based entries. Explicitly describe the Upstage Open2 Beta
preset as keyless and using an anonymous session-backed flow, while preserving
the existing provider table and counts.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: b795e37e-4e56-489e-85a8-c75a1a3a7702
📒 Files selected for processing (1)
docs-site/src/content/docs/guides/providers.md
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7e76094e57
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| "@bufbuild/protobuf": "^2.12.0", | ||
| "@modelcontextprotocol/sdk": "^1", | ||
| "bun": "1.3.14", | ||
| "ws": "^8.18.3", |
There was a problem hiding this comment.
Require security review for the new dependency
This adds a new runtime package to the dependency-installation surface, so the PR needs an explicit security-review sign-off before merge; otherwise a dependency change can ship without the review gate required for this repository.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The new runtime dependency and cookie boundary are documented, the privacy scan and complete pre-push gate are green, and both maintainers are requested on the PR. This thread remains open pending explicit maintainer security-review sign-off, as required by MAINTAINERS.md.
|
Addressed all actionable automated feedback in d2760c8. Additional review-body items that did not have inline threads are also covered:
Validation:
The dependency security-review thread is intentionally left unresolved until a maintainer explicitly signs off. |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs-site/src/content/docs/guides/providers.md (1)
150-158: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winDocument the Open2 proxy fail-closed behavior.
The adapter rejects outbound HTTP(S) proxy configurations unless
open2-beta.upstage.aiis covered byNO_PROXY, but this compatibility callout omits that operational requirement. Users can therefore encounter expected adapter failures without the documented remedy.Add the same proxy guidance used in the adapter reference:
Suggested documentation update
Refreshed `solar_session` values remain in process memory only, are never persisted, and are lost when OpenCodex restarts. +When an outbound HTTP(S) proxy is configured, the adapter fails closed unless the +Open2 host is explicitly covered by `NO_PROXY`; add it only when direct connections +are intended.As per path instructions, the Open2 Beta compatibility callout must stay consistent with the adapter’s fail-closed proxy behavior.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs-site/src/content/docs/guides/providers.md` around lines 150 - 158, Update the “Open2 Beta compatibility” caution callout to document the adapter’s fail-closed proxy behavior: outbound HTTP(S) proxies are rejected unless open2-beta.upstage.ai is included in NO_PROXY. Include the operational remedy and keep the wording consistent with the existing adapter reference.Source: Path instructions
src/adapters/open2-beta.ts (1)
136-163: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winAdd a timeout to the anonymous session fetch
src/adapters/open2-beta.ts:136-163(called fromrunTurnat line 391).requestOpen2Session()passes onlyincoming.abortSignal, butIncomingMeta.abortSignalis optional, so a stalled/api/sessionresponse can hang the turn before the WebSocket ready/idle timeouts ever start. Thread a timeout signal into this fetch (or add a dedicatedsessionTimeoutMs) and compose it withincoming.abortSignalviaAbortSignal.any(...).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/adapters/open2-beta.ts` around lines 136 - 163, Add a dedicated timeout to requestOpen2Session and compose it with the optional abort signal using AbortSignal.any, then pass the combined signal to fetchImpl for the /api/session request. Preserve caller cancellation while ensuring stalled session requests terminate independently before runTurn’s WebSocket timeouts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/adapters/open2-beta.ts`:
- Around line 382-388: Update the outbound-proxy error emitted in the
hasOutboundProxy(target) branch to derive the NO_PROXY guidance from the
configured target/baseUrl rather than hardcoding open2-beta.upstage.ai. Preserve
the existing error type and control flow while ensuring custom or self-hosted
origins receive the correct host guidance.
- Around line 120-125: Update the response handling around
refreshedSessionFromHeader to iterate over response.headers.getSetCookie()
rather than parsing response.headers.get("set-cookie"). Extract solar_session
from each separate Set-Cookie value and use the matching cookie, preserving
undefined when no refresh cookie is present; remove or bypass the
comma-joined-header parsing helper.
In `@tests/cli-provider.test.ts`:
- Around line 100-120: Add a focused test in the Open2 adapter tests covering
configured API keys: verify that the adapter ignores any supplied key and
authenticates exclusively with the anonymous solar_session credential. Keep the
existing CLI hint-text coverage unchanged and assert the actual authentication
behavior at the Open2 adapter boundary.
---
Outside diff comments:
In `@docs-site/src/content/docs/guides/providers.md`:
- Around line 150-158: Update the “Open2 Beta compatibility” caution callout to
document the adapter’s fail-closed proxy behavior: outbound HTTP(S) proxies are
rejected unless open2-beta.upstage.ai is included in NO_PROXY. Include the
operational remedy and keep the wording consistent with the existing adapter
reference.
In `@src/adapters/open2-beta.ts`:
- Around line 136-163: Add a dedicated timeout to requestOpen2Session and
compose it with the optional abort signal using AbortSignal.any, then pass the
combined signal to fetchImpl for the /api/session request. Preserve caller
cancellation while ensuring stalled session requests terminate independently
before runTurn’s WebSocket timeouts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0901fce4-55d2-40db-b2ba-4ce0c61d8830
📒 Files selected for processing (13)
README.mddocs-site/src/content/docs/guides/providers.mddocs-site/src/content/docs/ja/reference/adapters.mddocs-site/src/content/docs/ko/reference/adapters.mddocs-site/src/content/docs/reference/adapters.mddocs-site/src/content/docs/ru/reference/adapters.mddocs-site/src/content/docs/zh-cn/reference/adapters.mdsrc/adapters/open2-beta.tssrc/codex/catalog/parsing.tstests/catalog-cursor-search.test.tstests/cli-provider.test.tstests/open2-beta-adapter.test.tstests/provider-registry-parity.test.ts
| /** Extract only the Open2 session cookie value from a Set-Cookie response header. */ | ||
| function refreshedSessionFromHeader(header: string | null): string | undefined { | ||
| if (!header) return undefined; | ||
| const match = /(?:^|[,;]\s*)solar_session=([^;]+)/.exec(header); | ||
| return match?.[1]; | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Does Bun's fetch Response support headers.getSetCookie()?
💡 Result:
Yes, Bun's Fetch API supports the Headers.getSetCookie method [1][2][3]. This method returns an array of strings containing the values of all Set-Cookie headers associated with a response, adhering to the standard Web API functionality [1][3]. It was implemented in Bun to better support the handling of multiple Set-Cookie headers, providing compatibility with server-side environments [4][3].
Citations:
- 1: https://bun.com/reference/globals/Headers/getSetCookie
- 2: https://bun.sh/reference/globals/Headers/getSetCookie
- 3: https://developer.mozilla.org/en-US/docs/Web/API/Headers/getSetCookie
- 4: oven-sh/bun@d84f79b
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="src/adapters/open2-beta.ts"
echo "== outline =="
ast-grep outline "$file" --view expanded || true
echo
echo "== relevant lines =="
nl -ba "$file" | sed -n '100,190p'
echo
echo "== set-cookie usages =="
rg -n 'getSetCookie|get\("set-cookie"\)|set-cookie' "$file"Repository: lidge-jun/opencodex
Length of output: 3617
🏁 Script executed:
#!/bin/bash
set -euo pipefail
node - <<'JS'
const h = new Headers();
h.append('Set-Cookie', 'a=1; Expires=Wed, 21 Oct 2015 07:28:00 GMT');
h.append('Set-Cookie', 'b=2');
console.log('get:', h.get('set-cookie'));
console.log('getSetCookie' in h ? h.getSetCookie() : 'no getSetCookie');
JSRepository: lidge-jun/opencodex
Length of output: 266
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Lightweight semantic probe: inspect whether the adapter is already handling
# multiple cookies or only a single session cookie.
rg -n 'refreshedSessionFromHeader|solar_session|get\("set-cookie"\)|cookie' src/adapters/open2-beta.tsRepository: lidge-jun/opencodex
Length of output: 1034
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p = Path("src/adapters/open2-beta.ts")
text = p.read_text()
for needle in ['get("set-cookie")', 'getSetCookie()', 'solar_session', 'refreshedSessionFromHeader']:
print(needle, text.find(needle))
PYRepository: lidge-jun/opencodex
Length of output: 248
Use response.headers.getSetCookie() here
src/adapters/open2-beta.ts:148-156 should iterate over response.headers.getSetCookie() instead of parsing get("set-cookie"). get() comma-joins duplicate Set-Cookie headers, so a second cookie or an Expires= attribute with commas can make solar_session extraction ambiguous. getSetCookie() keeps each header separate and makes the refresh cookie unambiguous.
🧰 Tools
🪛 OpenGrep (1.25.0)
[ERROR] 123-123: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.
(coderabbit.command-injection.exec-js)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/adapters/open2-beta.ts` around lines 120 - 125, Update the response
handling around refreshedSessionFromHeader to iterate over
response.headers.getSetCookie() rather than parsing
response.headers.get("set-cookie"). Extract solar_session from each separate
Set-Cookie value and use the matching cookie, preserving undefined when no
refresh cookie is present; remove or bypass the comma-joined-header parsing
helper.
| if (hasOutboundProxy(target)) { | ||
| emit({ | ||
| type: "error", | ||
| message: "Open2 Beta WebSockets cannot safely use the configured outbound proxy. Add open2-beta.upstage.ai to NO_PROXY or disable this provider.", | ||
| }); | ||
| return; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Proxy-bypass error hardcodes the default host, ignoring a custom baseUrl.
The message unconditionally says "Add open2-beta.upstage.ai to NO_PROXY...", but target (line 381) is derived from the actually-configured provider.baseUrl (which could be a self-hosted mirror). If an operator points this adapter at a different origin, the guidance is factually wrong and will misdirect troubleshooting.
🐛 Proposed fix: use the real target host
if (hasOutboundProxy(target)) {
emit({
type: "error",
- message: "Open2 Beta WebSockets cannot safely use the configured outbound proxy. Add open2-beta.upstage.ai to NO_PROXY or disable this provider.",
+ message: `Open2 Beta WebSockets cannot safely use the configured outbound proxy. Add ${target.hostname} to NO_PROXY or disable this provider.`,
});
return;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (hasOutboundProxy(target)) { | |
| emit({ | |
| type: "error", | |
| message: "Open2 Beta WebSockets cannot safely use the configured outbound proxy. Add open2-beta.upstage.ai to NO_PROXY or disable this provider.", | |
| }); | |
| return; | |
| } | |
| if (hasOutboundProxy(target)) { | |
| emit({ | |
| type: "error", | |
| message: `Open2 Beta WebSockets cannot safely use the configured outbound proxy. Add ${target.hostname} to NO_PROXY or disable this provider.`, | |
| }); | |
| return; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/adapters/open2-beta.ts` around lines 382 - 388, Update the outbound-proxy
error emitted in the hasOutboundProxy(target) branch to derive the NO_PROXY
guidance from the configured target/baseUrl rather than hardcoding
open2-beta.upstage.ai. Preserve the existing error type and control flow while
ensuring custom or self-hosted origins receive the correct host guidance.
| test("provider add prints API-key guidance only when a required key is missing", () => { | ||
| for (const testCase of [ | ||
| { provider: "deepseek", args: [] as string[], expectsGuidance: true }, | ||
| { provider: "deepseek", args: ["--api-key", "configured"], expectsGuidance: false }, | ||
| { provider: "open2-beta", args: [] as string[], expectsGuidance: false }, | ||
| { provider: "open2-beta", args: ["--api-key", "configured"], expectsGuidance: false }, | ||
| ]) { | ||
| const { dir } = freshConfig(); | ||
| try { | ||
| const result = runCli(["provider", "add", testCase.provider, ...testCase.args], { OPENCODEX_HOME: dir }); | ||
| expect(result.status).toBe(0); | ||
| if (testCase.expectsGuidance) { | ||
| expect(result.stdout).toContain("Set API key with:"); | ||
| } else { | ||
| expect(result.stdout).not.toContain("Set API key with:"); | ||
| } | ||
| } finally { | ||
| rmSync(dir, { recursive: true, force: true }); | ||
| } | ||
| } | ||
| }); |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win
Exercise the Open2 authentication contract, not only the hint text.
Lines 104-105 would still pass if --api-key configured were later forwarded as an HTTP/WS credential. Add a focused assertion in tests/open2-beta-adapter.test.ts that configured keys are ignored and only the anonymous solar_session is used.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/cli-provider.test.ts` around lines 100 - 120, Add a focused test in the
Open2 adapter tests covering configured API keys: verify that the adapter
ignores any supplied key and authenticates exclusively with the anonymous
solar_session credential. Keep the existing CLI hint-text coverage unchanged and
assert the actual authentication behavior at the Open2 adapter boundary.
Source: Path instructions
|
Appreciate the effort you put into this, but we are going to close this one for now rather than leave it open-ended. Main reasons:
We would be happy to revisit if Open2 ships an official API surface (at which point a preset-style integration like the existing OpenAI-compatible providers would be very welcome), or as a documented external/custom-provider recipe in the meantime. Thanks again for the contribution. |
|
제가 링크드인으로 업스테이지에 문의한번 남겨 보겠습니다! |
Summary
open2-beta, an unofficial Upstage Open2 public-beta provider preset andrunTurnWebSocket adapter.GET /api/session, keeps rotatedsolar_sessioncookies in memory only, and reconnects with thesolar-chat.v1subprotocol.solar-open2with the beta UI reasoning choices (none,medium,high,max) and fixes the CLI hint so key-optional providers do not ask for an API key.wsbecause the beta handshake requires browser-style Cookie, Origin, and User-Agent headers that the Bun-native WebSocket path did not successfully negotiate.Beta / compatibility notice
Live verification (2026-07-24)
GET /api/sessionreturned 200 and issued a rotating session cookie; no cookie or token value is stored in the repository or printed by the smoke check.solar-chat.v1ready frame.OPEN2_PR_OK, completed normally, and included usage.Verification
bun run typecheckbun test tests/open2-beta-adapter.test.ts tests/provider-registry-parity.test.ts: 29 pass / 0 failbun run test: 4031 pass / 0 failbun run lint:guibun run privacy:scanbun run doctor:gui:if-changed(skipped: no GUI source changes)cd docs-site && bun install --frozen-lockfile && bun run buildgit diff --checkopen2-beta.upstage.aiChecklist
This PR changes dependency installation and anonymous session-cookie handling, so it requires explicit maintainer security review under
MAINTAINERS.mdbefore merge. The cookie is held in process memory only, never logged, and the privacy scan is green.Summary by CodeRabbit
provider addguidance so API-key instructions show only when a provider truly requires a key.