Repository navigation
Conversation
|
I'd like to use the actual OpenDots application with an existing ChatGPT subscription, so this addresses an important use case. Adding the request here to keep the discussion with the existing implementation. My intended workflow is to self-host OpenDots on a private VPS, open its normal UI from a laptop or phone, and sign in to the selected ChatGPT account without supplying an OpenAI API key or enabling separate model API billing. I want to keep the upstream UI and workflows and avoid maintaining a replacement application. Could you and the maintainers clarify the supported path and acceptance criteria?
The official Sign in with ChatGPT registration guide, self-hosted VM guide, and preview limitations seem relevant. I have not live-tested this PR and am not claiming feature parity. Is this PR the intended upstream direction for that workflow, and what still needs validation before it can be recommended? |
|
Thanks — this is a very useful framing of the intended use case. A couple of clarifications on the current state of this PR: First, this has not been live-tested yet. The PR is intentionally still in Draft. The automated tests cover OAuth state/PKCE/ID-token validation, token refresh/rotation, Responses API request shaping, model discovery, local OpenDots tool execution, and ensuring ChatGPT-plan failures never fall back to The current implementation is primarily aimed at the local/self-hosted flow where the browser and OpenDots process share the same machine. Your VPS workflow needs one additional piece. OpenAI’s documented VM flow requires completing OAuth locally because the On the other points:
The current acceptance criteria I’d use before moving this out of Draft are:
So I see this PR as a candidate implementation of that direction, but not something I’d recommend yet. The next step is real-account validation, and the remote-VPS workflow needs explicit validation/UX before we can claim support for it. I’d also welcome maintainer guidance on whether this provider boundary and VM workflow match the direction you’d want upstream. |
| const issuer = 'https://auth.openai.com'; | ||
| const resource = 'https://api.openai.com/v1'; |
There was a problem hiding this comment.
Doesn't make sense to keep this as env variables?
There was a problem hiding this comment.
Good question. I actually considered making these configurable, but kept them fixed for now because this provider is specifically implementing OpenAI’s Sign in with ChatGPT flow, and those two values are part of that protocol rather than normal deployment configuration.
The separate OpenAI-compatible/API-key path is still configurable through OPENAI_BASE_URL, so custom providers remain supported there.
My thinking was that keeping the OAuth issuer/resource fixed reduces the chance of accidentally sending auth/token traffic to the wrong endpoint. For tests, we can still mock the network layer without exposing them as runtime env vars.
That said, if you have a deployment case where making them env-configurable would be useful, happy to adjust it.
jerelvelarde
left a comment
There was a problem hiding this comment.
This offers useful opt-in template value: server-side ChatGPT authorization and plan inference while retaining explicit API-key/provider choice, with no automatic billing fallback. The implementation validates PKCE/state/nonce and signed identity tokens, serializes refreshes in one process, persists rotating credentials atomically, protects token files, and sanitizes provider failures. The description accurately calls out unencrypted token storage, the single-process constraint and unverified remote callback/live account behavior.
Keep this as a draft. Credential-free focused tests pass all 41 cases across auth flow/refresh/store, plan request, research and TanStack integration. A further signed-token checkpoint/restart fixture reproduces the scope-check omission described inline; its consequence is one locally dispatched request after direct-use permission disappears, not demonstrated successful unauthorized inference. Original tests passed with canonical TMPDIR=/private/tmp; /tmp itself is a macOS symlink rejected by the intended credential-directory protection.
The request shape follows the documented preview: stream:true/store:false, public Responses endpoint, model visibility filtering, and local function tools through additional_tools are supported. See official sign-in requirements, models and inference, and preview limitations. Mocks do not establish actual Plus/Pro eligibility or deployment enablement. Before readying, fix the recovery consent gate, complete live authorization/plan inference and supported deployment validation, and resolve substantial production conflicts with current main 210a687 (configuration, dialog, agent setup and research) before rerunning the repository gates. Full repository gate results are recorded separately by the coordinating reviewer; encrypted reasoning/HITL continuation and live UI/provider behavior were not independently established by this focused review.
| Object.assign(p, p.pendingRefresh); | ||
| delete p.pendingRefresh; | ||
| await this.save(); | ||
| if (p.accessToken && p.expiresAt > Date.now()) return p.accessToken; |
There was a problem hiding this comment.
[P2] Recheck direct-use scope after recovering a refresh checkpoint
The checkpoint recovery path returns the newly installed token without checking its newly installed scopes. This is reachable when a legitimate refresh returns identity-only scopes plus a rotating token/ID token, ID-token verification temporarily fails because JWKS is unavailable, and the process retries or restarts. getValidAccessToken checks the old profile scopes before recovery; after Object.assign the return here bypasses the direct-use check in the normal refresh path. With the actual auth class, signed ID token, persisted file/restart and plan-fetch adapter, the diagnostic sends one Responses POST with the identity-only successor token while status already reports needsReconsent. This is a local consent/error-contract defect, not evidence of bypassing OpenAI server authorization. Preserve the rotated credentials, then require chatgpt.tokens.use.direct before returning any recovered token, and add the reduced-scope checkpoint regression.
What
Allow OpenDots users to authenticate with ChatGPT and use eligible Plus/Pro plan usage for text inference without an OpenAI API key. Existing API-key deployments remain supported.
Architecture
ChatGPT OAuth → protected server credential store → rotating-token refresh → TanStack AI Responses adapter → CopilotKit BuiltInAgent. The current OpenAI-compatible Chat Completions adapter remains available.
Safety and compatibility
store:false, stream through the public/v1/responsesendpoint, preserve local tools across continuations, and never fall back to API-key billing automatically.Validation
npm ci(Node 24): passed; 0 reported vulnerabilities.npm test: 38 files; 188 passed, 1 skipped (Windows-only symlink test).npm run typecheck: passed.npm run lint: passed.npm run build: passed; Vite reports the existing large-chunk warning.git diff --check: passed. Repository-widenpm run check-formatstill reports 112 warnings in unchanged files.Known limitations before broader deployment
Automated coverage complete; live ChatGPT OAuth authorization still requires manual validation.