fix(api): record audio transcription/translation/speech requests in call_logs (#13544) - #13803
Merged
diegosouzapw merged 2 commits intoSep 16, 2026
Merged
Conversation
…all_logs (#13544) open-sse/handlers/audioTranscription.ts and src/app/api/v1/audio/transcriptions/route.ts never called saveCallLog(), unlike every other proxied endpoint (embeddings, images, video, rerank, search). Successful and failed /v1/audio/transcriptions requests were therefore invisible in Dashboard -> Request Logs. Threaded the API key metadata from enforceApiKeyPolicy() into the handler and added the missing saveCallLog() call on both the success and error path, plus a best-effort peek at upstream `usage:{type:"duration"}` so it is persisted for future cost-pipeline consumption. Applied the identical fix to the sibling /v1/audio/translations and /v1/audio/speech routes, which had the same gap. Regression test: tests/unit/issue-13544-audio-transcription-call-log.test.ts
…ogged (base-red fix #13747)
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…all_logs (diegosouzapw#13544) (diegosouzapw#13803) Merged in the 2026-09-16 sweep of the maintainer's own open PRs, at the owner's explicit instruction. No push was made to the PR branch: the merge took the head as the owning session left it (verified OPEN, non-draft and MERGEABLE against the release tip immediately before merging).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #13544
Root cause
open-sse/handlers/audioTranscription.tsandsrc/app/api/v1/audio/transcriptions/route.tsnever called
saveCallLog()(@/lib/usageDb), unlike every other proxied API surface(embeddings, images, video, rerank, search). Successful and failed
/v1/audio/transcriptionsrequests were therefore invisible in Dashboard → Request Logs,even though the upstream provider was dispatched correctly and the transcription was
returned to the client. The reporter's secondary point was also confirmed: the response
route hardcodes
costUsd: 0with a comment claiming "no text body available" — stale forthe OpenAI-compatible default handler, which already buffers the full upstream JSON body
(including a provider's
usage:{type:"duration",seconds:N}) before returning it; it wasjust never parsed for logging.
The identical gap exists in the sibling
/v1/audio/translationsand/v1/audio/speechroutes — same code shape, not user-reported, fixed alongside since it's the same class of
defect.
Fix
policy.apiKeyInfo.{id,name}fromenforceApiKeyPolicy()intotranscribeWithModel()/translateWithModel()(and thepostHandlerclosure forspeech), matching how
rerank.tsandembeddings.tsalready do this.saveCallLog()on both the success and error branch of all three routes, withprovider,model,connectionId,duration,apiKeyId,apiKeyName— mirroring thecanonical shape in
open-sse/handlers/embeddings.ts/src/app/api/v1/rerank/route.ts.peekDurationUsage()in the transcriptions route: a best-effort peek (viaresponse.clone().json(), never touching the original stream) at a provider'susage:{type:"duration",seconds:N}body, persisted on the call_logs row'sresponseBodyfor audit ahead of a future per-second cost rule. No cost pricing engineis added here —
costUsdstays0for transcription, matching the existing comment'sactual (if previously mis-explained) behavior.
handleComboChat→transcribeWithModel/translateWithModelper target)now receives the caller's
apiKeyId/apiKeyNametoo, so combo-routed audio requests areattributed correctly as well.
Regression test
tests/unit/issue-13544-audio-transcription-call-log.test.ts— drives a realPOST /v1/audio/transcriptionsthrough the actual route (provider-node resolution,enforceApiKeyPolicy, upstream dispatch) against a mocked OpenAI-compatible provider.RED (on unfixed
release/v3.8.51tip):GREEN (after the fix):
The success-path assertions also confirm the row carries
provider/model/status/apiKeyId, and thatgetCallLogById()returns the persistedusage:{type:"duration", seconds:3}onresponseBody(issue Validation Plan steps 4 and 5).Gates run
npx eslint --suppressions-location config/quality/eslint-suppressions.json <changed files>→ 0 errors/warningsnpm run typecheck:core→ 0 errorsnode scripts/check/check-test-discovery.mjs→ OK, 0 new orphansnode scripts/check/check-cognitive-complexity.mjs→ OK (1276 violations vs baseline 1437 — improved, not regressed)node scripts/check/check-file-size.mjs→ no ✗ on any file this PR touchesnode scripts/check/check-complexity.mjs→ did not finish within the session's availabletime due to heavy concurrent load from several other active sessions on the shared devbox
running the same repo-wide scan in parallel (confirmed via
ps); this PR's diff is asmall, flat threading of a few extra parameters plus straight-line
if/elsesaveCallLogcalls copied from the already-passing
rerank.ts/embeddings.tspattern, so it is veryunlikely to move this ratchet. Flagging for CI to confirm rather than asserting a result
I couldn't observe locally.
tests/unit/issue-13544-audio-transcription-call-log.test.ts,audio-transcriptions-combo-resolution.test.ts,audio-transcription-handler.test.ts,audio-transcription-openrouter.test.ts,audio-transcription-opus-filename.test.ts,audio-translations-combo-resolution.test.ts,audio-translations-route.test.ts,audio-speech-dynamic-node-9096.test.ts,audio-speech-fishaudio.test.ts,audio-speech-handler.test.ts,audio-speech-ogg-alias-10587.test.ts) → 88/88 pass, noregressions.
Existing tests aligned
None — no existing assertion encoded the old buggy contract; all pre-existing audio
test files pass unmodified.
Not covered here
triage plan —
costUsdstays0, unchanged behavior; only the upstream usage value isnow persisted for future consumption).
core
saveCallLogfix but not the duration-usage enrichment, since only the defaultOpenAI-compatible branch exposes a buffered JSON body to peek at.