-
Notifications
You must be signed in to change notification settings - Fork 860
fix(xai): restore Grok Responses on the native passthrough route #2254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d6c6a31
e4508d0
add8a55
3d11f6f
bf84d17
d8426a6
6e86b18
6bede37
abc2b9f
10b68d2
c3d62b0
2dd6685
847cd8a
fbce515
4f9f728
26ed833
248a75c
3b328ef
3927a43
1bbb63b
6c2e04d
c43dc8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,6 +54,32 @@ export function supportsNativeResponsesCompactEndpoint( | |
| && normalizedBaseUrl(provider.baseUrl) === OPENAI_API_BASE_URL; | ||
| } | ||
|
|
||
| /** | ||
| /** | ||
| * Whether this destination is an OpenAI-operated Responses backend — the canonical ChatGPT Codex | ||
| * surface or the official OpenAI API. | ||
| * | ||
| * Deliberately not keyed on `authMode === "forward"`: a noncanonical forward provider does not | ||
| * receive the caller's credentials (see the forward-header gate in the Responses adapter), so | ||
| * forward auth says nothing about which backend is on the other end. | ||
| */ | ||
| export function isOpenAiOperatedResponsesDestination(provider: OcxProviderConfig): boolean { | ||
| if (isCanonicalOpenAiForwardProvider(provider)) return true; | ||
| return provider.adapter === "openai-responses" | ||
| && normalizedBaseUrl(provider.baseUrl) === OPENAI_API_BASE_URL; | ||
| } | ||
|
Comment on lines
+66
to
+70
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Find how OpenAI Responses base URLs are expressed in the registry and defaults.
set -euo pipefail
# Registry/default provider rows pointing at the OpenAI API host.
rg -n -C 4 'api\.openai\.com' --type=ts src
# Does any row combine that host with responsesPath?
rg -n -C 6 'responsesPath' --type=ts src | rg -n -C 6 'openai' || trueRepository: lidge-jun/opencodex Length of output: 16452 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- src/providers/openai-tiers.ts ---'
cat -n src/providers/openai-tiers.ts | sed -n '1,110p'
printf '%s\n' '--- destination classification and related adapter branches ---'
rg -n -C 12 'isOpenAiOperatedResponsesDestination|dropNullContentChannel|destinationDecodesNativeCompactionBlob|OPAQUE_COMPACTION_NOTE' src/providers src/adapters
printf '%s\n' '--- URL normalization and responsesPath validation ---'
rg -n -C 10 'function normalizedBaseUrl|normalizedBaseUrl|responsesPath' src/providers src/adapters src/types src/config src/server 2>/dev/null | head -n 260Repository: lidge-jun/opencodex Length of output: 39597 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from urllib.parse import urlsplit
def normalized_base_url(value):
# Probe the likely semantics from the source expression if available below.
return value.strip().rstrip("/")
for value in [
"https://api.openai.com/v1",
"https://api.openai.com/v1/",
"https://api.openai.com",
"https://api.openai.com/",
]:
print(value, "=>", normalized_base_url(value))
PY
printf '%s\n' '--- exact call sites ---'
rg -n -C 18 'isOpenAiOperatedResponsesDestination' srcRepository: lidge-jun/opencodex Length of output: 10175 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- response URL construction ---'
cat -n src/adapters/openai-responses-url.ts | sed -n '1,90p'
cat -n src/adapters/openai-responses.ts | sed -n '40,115p'
cat -n src/adapters/openai-responses.ts | sed -n '1565,1620p'
printf '%s\n' '--- compaction handling ---'
rg -n -C 18 'function scrubOcxCompactionItems|scrubOcxCompactionItems|destinationDecodesNativeCompactionBlob|decodeCompactionSummary|OPAQUE_COMPACTION_NOTE' src/adapters/openai-responses.ts src/responsesRepository: lidge-jun/opencodex Length of output: 25793 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- responsesPath validation and config materialization ---'
rg -n -C 16 'responsesPath.*(valid|schema|starts|URL)|startsWith\\(["'\"']/' src
rg -n -C 12 'responsesPath' src/config* src/providers src/server | rg -v 'types/provider.ts|registry.ts|derive.ts' | head -n 260
printf '%s\n' '--- compact endpoint call sites ---'
rg -n -C 12 'supportsNativeResponsesCompactEndpoint' srcRepository: lidge-jun/opencodex Length of output: 336 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from urllib.parse import urlsplit
def normalized_base_url(value):
u = urlsplit(value.strip())
if u.username or u.password or u.query or u.fragment:
return None
path = u.path.rstrip("/")
return f"{u.scheme}://{u.netloc}{path}"
def legacy_response_url(base):
u = urlsplit(base)
path = u.path.rstrip("/")
if path.endswith("/responses"):
path = path[:-len("/responses")]
if path.endswith("/v1"):
path = path[:-len("/v1")]
return f"{u.scheme}://{u.netloc}{path}/v1/responses"
for base, responses_path in [
("https://api.openai.com/v1", None),
("https://api.openai.com", "/v1/responses"),
("https://api.openai.com/", "/v1/responses"),
]:
actual = legacy_response_url(base) if responses_path is None else base.rstrip("/") + responses_path
print(f"{base!r}, responsesPath={responses_path!r} -> {actual}")
print("normalized:", normalized_base_url(base))
PYRepository: lidge-jun/opencodex Length of output: 543 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- responsesPath checks ---'
rg -n -C 12 'responsesPath' src | head -n 320
printf '%s\n' '--- tests for OpenAI destination classification ---'
rg -n -C 12 'isOpenAiOperatedResponsesDestination|destinationDecodesNativeCompactionBlob|supportsNativeResponsesCompactEndpoint|api.openai.com/v1' --glob '*test*' --glob '*spec*' .
printf '%s\n' '--- provider URL assumptions in documentation ---'
rg -n -C 8 'baseUrl|responsesPath|openai-responses' README.md docs src/types src/providers | head -n 320Repository: lidge-jun/opencodex Length of output: 50376 🏁 Script executed: #!/bin/bash
set -euo pipefail
python3 - <<'PY'
from urllib.parse import urlsplit
def normalized(value):
u = urlsplit(value.strip())
if u.username or u.password or u.query or u.fragment:
return None
return f"{u.scheme}://{u.netloc}{u.path.rstrip('/')}"
def is_current(adapter, base):
return adapter == "openai-responses" and normalized(base) == "https://api.openai.com/v1"
def is_origin_proposal(adapter, base):
return adapter == "openai-responses" and normalized(base) in {
"https://api.openai.com",
"https://api.openai.com/v1",
}
cases = [
("openai-responses", "https://api.openai.com/v1"),
("openai-responses", "https://api.openai.com/v1/"),
("openai-responses", "https://api.openai.com"),
("openai-responses", "https://api.openai.com/"),
("openai-responses", "https://api.openai.com/custom"),
("openai-responses", "https://gateway.example/v1"),
("openai-chat", "https://api.openai.com"),
]
for adapter, base in cases:
print(base, adapter, "current=", is_current(adapter, base), "origin-proposal=", is_origin_proposal(adapter, base))
PYRepository: lidge-jun/opencodex Length of output: 711 Match the OpenAI API origin for custom
At Accept both 🤖 Prompt for AI Agents |
||
|
|
||
| /** | ||
| * Whether this destination can decode a native (non-`ocx1:`) compaction blob. | ||
| * | ||
| * Only the backend that minted a blob can decode it, so this is the OpenAI-operated set above plus | ||
| * any destination whose operator explicitly opts in for a relay that genuinely fronts OpenAI. | ||
| */ | ||
| export function destinationDecodesNativeCompactionBlob(provider: OcxProviderConfig): boolean { | ||
| return isOpenAiOperatedResponsesDestination(provider) | ||
| || provider.decodesNativeCompactionBlobs === true; | ||
| } | ||
|
|
||
| export interface OpenAiTierMigrationProjection { | ||
| config: OcxConfig; | ||
| changed: boolean; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: lidge-jun/opencodex
Length of output: 2649
🏁 Script executed:
Repository: lidge-jun/opencodex
Length of output: 50376
🏁 Script executed:
Repository: lidge-jun/opencodex
Length of output: 50375
🏁 Script executed:
Repository: lidge-jun/opencodex
Length of output: 24541
🏁 Script executed:
Repository: lidge-jun/opencodex
Length of output: 50375
🏁 Script executed:
Repository: lidge-jun/opencodex
Length of output: 397
Use the routed-provider predicate for both custom-tool gates.
At
src/adapters/openai-responses.ts:1670, a noncanonical forward provider skips custom-tool lowering but reaches namespace lowering at line 1682. A promoted namespace child can therefore retaintype: "custom".Change both this gate and
src/server/responses/core.ts:2693to!isCanonicalOpenAiForwardProvider(...). This also enables response restoration for the converted names.🤖 Prompt for AI Agents