chore(ai-chat): add stream timing logs + env-gated aiFetch bypass (diagnostics)

The streaming chat turn hangs in all browsers while the non-streaming test
endpoint works — both use the same model/transport (createOpenAI + aiFetch),
so the suspect is the streaming path / custom undici RetryAgent transport.

- ai-http.ts: wrap aiFetch with per-request timing logs (start, ms-to-headers
  on success, elapsed ms + cause on failure). Chat at info, embeddings at
  debug. Only host+path logged.
- ai-chat.controller.ts / ai-chat.service.ts: log turn START, first-chunk
  latency, FINISHED duration, and elapsed ms on disconnect/error/abort.
- ai.service.ts: AI_BYPASS_RESILIENT_FETCH=true makes the CHAT model omit
  fetch:aiFetch and use the default global fetch — isolates transport vs
  request-shape. Chat-only; embeddings/STT untouched; reversible via env.
- .env.example: document the flag.

No timeout/retry change. tsc clean; ai-chat + ai suites pass (292).
This commit is contained in:
claude_code
2026-06-23 02:13:54 +03:00
parent da058bb6a0
commit 7c308728de
5 changed files with 103 additions and 9 deletions

View File

@@ -128,6 +128,11 @@ MCP_DOCMOST_PASSWORD=
# A slow/hung embeddings endpoint fails after this and the batch continues.
# AI_EMBEDDING_TIMEOUT_MS=120000
# Diagnostic: bypass the resilient outbound HTTP layer (custom undici RetryAgent)
# for the CHAT model, using the default global fetch instead. Use only to isolate
# a streaming/transport issue; leave unset in normal operation.
# AI_BYPASS_RESILIENT_FETCH=true
# --- Anonymous public-share AI assistant ---
# Opt-in per workspace (AI settings -> "public share assistant"; off by default).
# When enabled, anonymous visitors of a published share can ask an AI about that