feat(runner): DeepSeek and MiniMax gateway lanes - #1
Merged
Merged
Conversation
Fork of ericlitman/open-pstack at v1.4.1 (de67e6b). UPSTREAM-FLEX.md adds the second sync layer (cursor -> open-pstack -> flex) with the merge rehearsal procedure and the expected conflict surface for upstream 1.5.0. NOTICE.md records the provenance chain, LICENSE adds the fork copyright line without removing existing holders, and the README gains a fork section stating what flex adds and that a stock install behaves exactly like upstream.
New gateway lanes run the stock claude binary against each lab's Anthropic-compatible endpoint, reusing the exact claude argv and the existing spawn path. flex-providers.ts owns the per-provider env maps: endpoint (overridable), ANTHROPIC_AUTH_TOKEN from DEEPSEEK_API_KEY or MINIMAX_API_KEY, model pins, nonessential-traffic and attribution-header hygiene, and an isolated CLAUDE_CONFIG_DIR under ~/.pstack-flex. childEnvironment deletes inherited ANTHROPIC_* values before injection so a parent session's credentials or endpoint never bleed into a gateway child. - Preflight is claude --version: auth-status semantics under token auth are undocumented, credentials are checked in-process, and the one-shot invocation is the real auth test. - Gateway receipts force costUsd to null (the CLI prices total_cost_usd at Anthropic rates, fiction for third-party traffic); token usage stays. - Served models match case-insensitively (MiniMax-M3 vs minimax-m3) and otherwise fall back to modelEvidence pinned-argv like Codex. - provider==parent stays rejected; gateway providers are distinct, so they run under both parents through the external runner.
A gateway lane refuses to start, in-process and before any subprocess, when its API key variable is missing or its isolated config dir carries a claude.ai OAuth credentials file (or one that cannot be parsed). The refusal is an unauthenticated receipt (exit 77) whose evidence names the path and never the contents. This guarantees a claude.ai login can never be pointed at a third-party endpoint through the runner. Endpoint authentication errors from the one-shot invocation classify as unauthenticated through the existing stderr matching. Tests cover the key-missing, OAuth-refusal, garbage-file, env-injection, happy-path, case-shifted-model, pinned-argv, and endpoint-401 paths, plus the zero-subscription scenario with mocked binaries; nothing performs network I/O.
PROVIDERS now spreads GATEWAY_PROVIDERS, and the preflight, invocation, parse, and preflight-pass paths branch on isGatewayProvider instead of naming deepseek and minimax in each switch. Adding an Anthropic-compatible gateway is one GATEWAY_PROVIDERS entry plus one GATEWAY_SPECS row; the Record type makes a missing spec a compile error.
This was referenced Sep 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #4
What changed
Ports the gateway runner from the legacy flex work onto Open Pstack 1.4.1.
deepseekandminimaxrun the stockclaudebinary against their Anthropic-compatible endpoints with provider keys and isolated Claude config directories.The runner refuses a missing key or OAuth credentials in the gateway config directory before spawning a child. It removes inherited
ANTHROPIC_*variables and Claude cloud-provider selectors, including custom headers and Bedrock routing. A reported model mismatch now fails the lane; a missing report stays unverified withpinned-argv. Gateway receipts keep usage and setcostUsdto null.This PR also records fork provenance. Setup routes and the lane guide are in the stacked PR #2.
Verification
Local gate on
53930c8: 186 Bun tests pass; strict typecheck, manifest parsing, static invariants, andclaude plugin validate plugins/pstackpass. With synthetic values, the installed Claude CLI reported its normal API provider after the runner stripped an inherited Bedrock flag and custom Authorization header. This is a local routing check, not a keyed gateway live test.Live evidence:
costUsd: null, and record the installed version, action, and observed result here.A pull request without live evidence remains a draft. Do not merge, tag, release, or roll it out.