fix(auth): recognize Interactions finish events in empty-completion detector - #210
Open
warelik wants to merge 2 commits into
Open
fix(auth): recognize Interactions finish events in empty-completion detector#210warelik wants to merge 2 commits into
warelik wants to merge 2 commits into
Conversation
…etector The Interactions protocol ends a turn with a bare "finish" event whose usage lives under metadata.total_usage. The empty-completion detector had no Interactions branch, so every Interactions stream fell through to unknown data and was committed as a valid response. Port the event set, chunk shapes, evalInteractions, and the finish handling from the upstream review on router-for-me/CLIProxyAPI#4881 (commit baf43ba5). A bare finish with zero output tokens is now treated as an empty completion; one with positive tokens is not. Relates to kaitranntt#202.
warelik
commented
Aug 21, 2026
warelik
left a comment
Contributor
Author
There was a problem hiding this comment.
Ready — approving.
Verified the port against upstream router-for-me/CLIProxyAPI@baf43ba5 (PR #4881):
- Port fidelity — the added types block (
interactionsEventTypes,interactionsChunk/Meta/Usage/Step/Content/Delta, helpers) andevalInteractions/evalInteractionsUsage/evalInteractionsStepsare byte-identical to upstream (diffed the extracted sections against the upstream blob). The base had no Interactions branch at all, so this is the full port plus thefinishdelta. - Wiring —
evalJSONtriesevalInteractionslast, same order as upstream; all referenced helpers (hasJSONKey,hasMeaningfulJSONArguments,nonEmptyJSONPayload,tokenCount) exist in the fork;isTerminalEmptynow includesinteractionsTerminal; no duplicate declarations; gofmt clean; CI build green. - No recognition shadowing — earlier evaluators cannot swallow Interactions events:
evalOpenAIneedschoices,evalClaudeneeds its own type set,evalOpenAIResponsehas no overlap with the interactions event types (including barefinish),evalGeminineedscandidates/usageMetadata/promptFeedback. - Translator parity claim checks out —
interactions_gemini_response.gohandlesfinishalongsideinteraction.completed, andtranslatorcommon.InteractionsUsageresolvesmetadata.total_usagebeforemetadata.usage, which the detector mirrors. - New tests traced by hand — both cases walk
isEmptyCompletionPayload→evalSSE→evalInteractionsto the expected verdicts (zero-outputfinish→ empty; 7 output tokens → not empty).
One non-blocking test-coverage suggestion inline. Fixes the #202 scenario as described.
Adds the broader predicate, streaming detector, and execute rotation scaffolding tests that cover the upstream Interactions evaluator branch: - JSON-shape predicate cases (empty steps, function_call, media, file_uri) - interaction.completed SSE scaffolds - TestStreamBootstrapDetectorInteractionsScaffoldAllowsFailover - TestExecuteInteractionsMeaningfulOutputNotRotated Also adds emptyPayload/contentPayload fields to emptyCompletionTestExecutor so non-OpenAI first-auth empty/content responses can be overridden. Closes kaitranntt#202
warelik
force-pushed
the
ao/airouters-15-fix-empty-completion-interactions
branch
from
August 22, 2026 05:07
4be4c2c to
1302eae
Compare
warelik
added a commit
to warelik/CLIProxyAPIPlus
that referenced
this pull request
Aug 22, 2026
…nts in empty-completion detector
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.
Summary
sdk/cliproxy/auth/empty_completion.gohad no Interactions branch, so an Interactions turn ending in a barefinishevent with zero output was treated as unknown data and committed as a valid response. The detector now recognizes the Interactions protocol and thefinishevent, reading usage frommetadata.total_usage(falling back tometadata.usage) exactly as the translator does.Ported from the upstream review on router-for-me/CLIProxyAPI#4881, commit
baf43ba5.Changes
interactionsEventTypes,interactionsChunk,interactionsMeta,interactionsUsage,interactionsStep,interactionsContent,interactionsDelta, and helper methods.evalInteractions,evalInteractionsUsage, andevalInteractionsSteps.evalInteractionsintoevalJSON.interactionsTerminaltoemptyCompletionAccumandisTerminalEmpty.Test plan
go build ./...go vet ./sdk/cliproxy/auth/...go test ./sdk/cliproxy/auth/...TestEmptyCompletionPredicateInteractionscases:finishwithmetadata.total_usage.total_output_tokens: 0is emptyfinishwithmetadata.total_usage.total_output_tokens: 7is not emptyCross-references
empty_completion.go(GeminithoughtSignatureboundary); this branch is intentionally based onmainand its diff is disjoint from fix(signature): harden cross-provider signature boundaries #209's hunk, so the two can be merged in either order.