Skip to content

fix(stream) + feat(api): emit Usage before Done; expose model capabilities in /v1/models#99

Open
shivam2014 wants to merge 2 commits into
nyroway:masterfrom
shivam2014:fix/stream-usage-and-model-capabilities
Open

fix(stream) + feat(api): emit Usage before Done; expose model capabilities in /v1/models#99
shivam2014 wants to merge 2 commits into
nyroway:masterfrom
shivam2014:fix/stream-usage-and-model-capabilities

Conversation

@shivam2014

Copy link
Copy Markdown
Contributor

Two independent fixes:

1. Stream: emit Usage delta before Done

parse_openai_chunk currently pushes Done before Usage. This means format_deltas emits usage={0,0,0} in the chunk before [DONE], and the OpenAI SDK stops at that first [DONE] — the real token counts in the subsequent Usage chunk are never seen by the client.

Fix: reorder so Usage delta precedes Done. Includes a regression test.

2. API: expose model capabilities in /v1/models

The /v1/models endpoint currently returns bare {id, object, created, owned_by}. This adds max_context_length and max_output_tokens by pre-fetching ModelCapabilities from the admin for each route's target model.

{
  "id": "deepseek-v3",
  "object": "model",
  "owned_by": "Nyro",
  "max_context_length": 131072,
  "max_output_tokens": 8192
}

Files: stream.rs (+64, -5, 1 test), handler.rs (+41, -9)
Tests: cargo test --workspace --exclude nyro-desktop --exclude nyro-server — 153 passed, 0 failed

shivam94 added 2 commits April 30, 2026 09:40
When the upstream sends finish_reason and usage in the same SSE chunk,
parse_openai_chunk was pushing Done before Usage. This caused
format_deltas to emit usage={0,0,0} in the chunk before [DONE],
and the OpenAI SDK stops at that first [DONE] — the real token
counts in the subsequent Usage chunk were never seen by clients.

Fix: reorder so Usage delta precedes Done. Includes regression test.
The OpenAI-compatible /v1/models endpoint now includes
max_context_length and max_output_tokens for each model,
enriched from models.dev.json capabilities source.

This allows downstream clients (Hermes, etc.) to auto-detect
the correct context window from the proxy, rather than relying
on static config.
@shuaijinchao

Copy link
Copy Markdown
Collaborator

fetch nyro model context is virtual model, it include 1 to many providers real model, theri context length difference, so context length should not in /v1/models api.
what do you think ?

@shivam2014

Copy link
Copy Markdown
Contributor Author

fetch nyro model context is virtual model, it include 1 to many providers real model, theri context length difference, so context length should not in /v1/models api. what do you think ?

Fair point. Instead of dropping the field entirely, what about reporting the minimum context_window across all routes for that virtual model? Deterministic, safe for every route, and still useful to clients.

@shuaijinchao

Copy link
Copy Markdown
Collaborator

good idea.
bro, you can add me wechat: xincps

@shivam2014

Copy link
Copy Markdown
Contributor Author

good idea. bro, you can add me wechat: xincps

Appreciate the gesture. Unfortunately I don't have WeChat. Happy to connect on X if you prefer. Link on my GitHub bio. Also very happy with your router. Great job !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants