You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You cannot improve what you cannot see. The maintainer says the AI "isn't good," but the service emits no per-request signal about why it is slow, expensive, or failing: no token counts, no cost, no latency breakdown, no trace of what the model actually did. Every answer-quality issue in this campaign — sampling (#ai-18), RAG (#24), tafsir (#17), caching (#27) — adds LLM calls whose cost and latency will silently balloon with nothing watching. This issue instruments the LLM layer: capture per-request input/output token usage, estimated cost, and end-to-end + model latency, tie it to a request/trace ID, and expose it so regressions and runaway spend are visible. This is the ops backbone that keeps the quality push from bankrupting the Gemini quota.
Current state
The /chat handler logs three human strings — the truncated prompt, "Sending message to chat...", and "Chat response generated successfully" (main.py, lines 121, 142, 174) — via logging.basicConfig(level=logging.INFO) (line 14). No token counts, no timings, no cost, no correlation ID.
The Gemini response object carries usage_metadata (prompt/candidates token counts), but the code only reads response.text (lines 153, 176) and throws the usage data away.
A metrics surface — expose aggregates (request count, token/cost totals and per-request percentiles, p50/p95 latency, error rate, cache hit rate if [Enhancement] Semantic response cache with embedding-similarity matching for repeated questions #27 lands) via a metrics endpoint (Prometheus-style text or a JSON summary) or structured metric log lines a collector can scrape. Keep it lightweight — this is a small Render service (render.yaml).
Tracing spans — emit spans for the meaningful stages of a request (intent → retrieval → generation → verification → post-processing) so a slow request can be attributed to a stage. OpenTelemetry-compatible if the dep footprint is justified; otherwise a minimal internal span logger. Don't require a heavy external backend to be useful.
Tests — offline tests with a mocked client returning known usage_metadata, asserting token/cost/latency are captured correctly, the cost table math is right, spans are emitted per stage, and no content leaks into metric labels. No live API calls in CI.
CI (.github/workflows/ci.yml) has no pytest step — add one; extend flake8 to new modules.
PRs target the dev branch (see CONTRIBUTING.md).
Difficulty
Medium — the measurements themselves are tractable (the SDK already returns usage metadata), but doing it cleanly means threading a correlation ID through the request, building on the async refactor for honest latency, keeping the metrics surface light on a tiny host, and carefully not duplicating token counting (#13) or logging (#11) that neighboring issues own.
🏆 GrantFox OSS — Official Campaign | FWC26. Apply for this issue through the GrantFox campaign page. The maintainer assigns one contributor before work starts; unassigned PRs may not be reviewed. PRs target the dev branch. Quality bar: CI must stay green.
💬 Questions or need help? Reach the maintainers and other contributors on the DeenBridge Telegram: https://t.me/+nst9lXNj1wc4ZDE0
Summary
You cannot improve what you cannot see. The maintainer says the AI "isn't good," but the service emits no per-request signal about why it is slow, expensive, or failing: no token counts, no cost, no latency breakdown, no trace of what the model actually did. Every answer-quality issue in this campaign — sampling (#ai-18), RAG (#24), tafsir (#17), caching (#27) — adds LLM calls whose cost and latency will silently balloon with nothing watching. This issue instruments the LLM layer: capture per-request input/output token usage, estimated cost, and end-to-end + model latency, tie it to a request/trace ID, and expose it so regressions and runaway spend are visible. This is the ops backbone that keeps the quality push from bankrupting the Gemini quota.
Current state
/chathandler logs three human strings — the truncated prompt, "Sending message to chat...", and "Chat response generated successfully" (main.py, lines 121, 142, 174) — vialogging.basicConfig(level=logging.INFO)(line 14). No token counts, no timings, no cost, no correlation ID.usage_metadata(prompt/candidates token counts), but the code only readsresponse.text(lines 153, 176) and throws the usage data away.send_messagecall (lines 143–151) is not even wrapped in a timer, and (per [Bug] /chat blocks the event loop and turns every Gemini failure into a leaky 500 #7) it blocks the event loop, so latency is currently invisible and bad.stellar.pysimilarly logs only a truncated public key (line 127). There is no metrics endpoint and nothing aggregates anything.What to build
usage_metadata), model name, estimated cost (a configurable per-model price table), model latency, and end-to-end handler latency. Attach the request/trace ID from [Enhancement] Structured JSON logging with request IDs and prompt redaction #11 so telemetry joins logs. Build on the async fix ([Bug] /chat blocks the event loop and turns every Gemini failure into a leaky 500 #7) so timing is meaningful.render.yaml).usage_metadata, asserting token/cost/latency are captured correctly, the cost table math is right, spans are emitted per stage, and no content leaks into metric labels. No live API calls in CI.Acceptance criteria
Pointers
main.py— logging setup (lines 13–15), the three log lines (121, 142, 174), thesend_messagecall and discarded response metadata (lines 143–176).stellar.py— logging (line 127) if telemetry is extended to non-LLM endpoints.render.yaml/requirements.txt— keep added deps light; justify OpenTelemetry if used..github/workflows/ci.yml) has no pytest step — add one; extend flake8 to new modules.devbranch (seeCONTRIBUTING.md).Difficulty
Medium — the measurements themselves are tractable (the SDK already returns usage metadata), but doing it cleanly means threading a correlation ID through the request, building on the async refactor for honest latency, keeping the metrics surface light on a tiny host, and carefully not duplicating token counting (#13) or logging (#11) that neighboring issues own.
🏆 GrantFox OSS — Official Campaign | FWC26. Apply for this issue through the GrantFox campaign page. The maintainer assigns one contributor before work starts; unassigned PRs may not be reviewed. PRs target the
devbranch. Quality bar: CI must stay green.💬 Questions or need help? Reach the maintainers and other contributors on the DeenBridge Telegram: https://t.me/+nst9lXNj1wc4ZDE0