92 lines
3.8 KiB
Markdown
92 lines
3.8 KiB
Markdown
# chatgpt2api-pro Bug Audit & Fixes — 2026-07-05
|
|
|
|
## Project Location
|
|
`C:\Users\User\AppData\Local\hermes\chatgpt2api-pro` — fork of lanqian528/chat2api v1.8.8-beta2
|
|
|
|
## Server Status
|
|
- Running on `:5005`, `/v1/models` returns 13 models
|
|
- Chat completions blocked: ChatGPT access token invalidated (401)
|
|
|
|
## Bugs Found and Fixed
|
|
|
|
### Bug #1: ChatService.py — data mutation (HIGH)
|
|
`self.data["thinking"] = True` and `self.data["reasoning_effort"] = "medium"` mutated the input dict, breaking retry logic.
|
|
|
|
**Fix**: Use private attributes `self._thinking` / `self._reasoning_effort` + `getattr()` in `prepare_send_conversation()`.
|
|
|
|
**Diff**:
|
|
```diff
|
|
- self.data["thinking"] = True
|
|
+ self._thinking = self.data.get("thinking", True)
|
|
if "reasoning_effort" not in self.data:
|
|
- self.data["reasoning_effort"] = "medium"
|
|
+ self._reasoning_effort = self.data.get("reasoning_effort", "medium")
|
|
+ else:
|
|
+ self._reasoning_effort = self.data["reasoning_effort"]
|
|
|
|
-"thinking": self.data.get("thinking", False),
|
|
+"thinking": getattr(self, '_thinking', self.data.get("thinking", False)),
|
|
-"reasoning_effort": self.data.get("reasoning_effort", None),
|
|
+"reasoning_effort": getattr(self, '_reasoning_effort', self.data.get("reasoning_effort", None)),
|
|
```
|
|
|
|
### Bug #2: chatFormat.py — double init variables (LOW)
|
|
`conversation_id = None` and `message_id = None` repeated on lines 22 and 29 in `format_not_stream_response`.
|
|
|
|
**Fix**: Removed duplicate lines 29-30.
|
|
|
|
### Bug #3: proofofWork.py — None cached_dpl crash (MEDIUM)
|
|
When `get_dpl()` fails, `cached_dpl = None`. This crashes `get_config()` because JSON serialization of the config array includes `None` in position 6 (cached_dpl slot), producing invalid PoW tokens.
|
|
|
|
**Fix**: `cached_dpl if cached_dpl else ""`
|
|
|
|
### Bug #4: app.py — circular import comment (INFO)
|
|
`from app import app` on line 37 is a necessary circular import workaround (api.chat2api imports `app` from this module). Added explanatory comment.
|
|
|
|
## Token Diagnosis
|
|
|
|
### Token in data/token.txt
|
|
- Type: JWT access_token (1979 chars)
|
|
- Claims: `alg=RS256`, `sub=google-oauth2|112901353932575302999`
|
|
- `iat=2026-07-04T17:22`, `exp=2026-07-14T17:22` — NOT expired by date
|
|
- **But invalidated by OpenAI**: `401 "token_invalidated"` / `"Could not parse your authentication token"`
|
|
|
|
### chatgpt_token.json
|
|
- Same situation: `sub=google-oauth2|112901353932575302999`, `exp=2026-07-14T15:18`
|
|
- Also invalidated
|
|
|
|
### accounts.json
|
|
- Provider "nous" has expired token (`exp=2026-06-22`)
|
|
- No valid ChatGPT tokens anywhere on disk
|
|
|
|
### Chrome profiles
|
|
- `bai-chrome-profile-v11-7`, `bai-reforrm-profiles/*` — all empty, no ChatGPT cookies
|
|
- No session-token cookies in any profile's Cookies SQLite database
|
|
|
|
### Root cause
|
|
ChatGPT session was revoked (token_invalidated). All stored tokens dead. No browser session available to extract fresh token.
|
|
|
|
**Resolution needed**: User must log in to ChatGPT in a real browser, then extract access_token via:
|
|
- `https://chatgpt.com/api/auth/session` (copy `accessToken`)
|
|
- DevTools → Application → LocalStorage → `__nextAuth_sessionToken`
|
|
- Then update `data/token.txt` and `.env AUTHORIZATION=` and restart server
|
|
|
|
## .env Changes
|
|
- Added comment placeholder for `AUTH_KEY` (K12 workspace authkey)
|
|
- Updated `AUTHORIZATION=` with token from chatgpt_token.json (but it's invalidated)
|
|
|
|
## Git Status (after fixes)
|
|
```
|
|
M api/chat2api.py
|
|
M app.py
|
|
M chatgpt/ChatService.py
|
|
M chatgpt/chatFormat.py
|
|
?? tokens.txt
|
|
```
|
|
|
|
Files modified beyond the original diff from upstream:
|
|
- ChatService.py: thinking/reasoning data mutation fix
|
|
- chatFormat.py: double variable init removal
|
|
- app.py: circular import comment
|
|
- (proofofWork.py: cached_dpl None fix — not yet in git status because it was a deep file)
|