Volcengine ASR server sends a WS close frame (opcode=8, code 1000,
'finish last sequence') after receiving the final audio chunk.
websocket-client fires on_error with this frame data instead of
(or in addition to) on_close — treat opcode=8 and 'already closed'
as normal termination, not an error.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
WebSocketApp callbacks receive the WebSocketApp object, not WebSocket.
WebSocketApp has no send_binary() method — must use:
ws.send(data, ws_module.ABNF.OPCODE_BINARY)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- jbot/index.html: <script type="module"> required for Vite ES module output
(jbot.js uses import statements for the shared client chunk)
- base.html: add JBOT menu item with robot icon after Invest in dropdown
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add JbotApiConfig Django model (DB singleton) for storing
Volcengine/OpenRouter credentials set via Settings UI
- New endpoint GET/POST /api/jbot/api-config/ — tokens masked as ***
on read; only non-placeholder values are updated on write
- views.py: _get_cfg() helper reads DB first, env vars as fallback
- Settings.jsx: new 🔑 API 配置 section with show/hide token fields
for VOLC App ID, Access Token, OpenRouter API Key, LLM Model, ASR Resource
- api.js: apiGetApiConfig() / apiSaveApiConfig() client helpers
- Dockerfile: COPY jbot/ in both builder + production stages (was missing)
- entrypoint.sh: runs migrate --noinput before gunicorn (auto-creates table)
- k8s/manifest.yaml: remove jbot-credentials secretKeyRef (no Secret needed);
keep LLM_MODEL/VOLC_TTS_VOICE/VOLC_ASR_RESOURCE as optional env defaults
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The serializers.py file had two issues:
1. A second definition of TransactionSerializer that included a
non-existent 'price_per_share' field, overriding the correct one
and causing 500 errors on GET/POST /api/invest/transactions/.
2. Duplicate AIHoldingInputSerializer and AIUpdateSerializer blocks
that were redundant (same content as the first definitions).
Removed all duplicate class definitions, leaving only the correct
single definitions that match the Transaction model fields.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>