Skip to content

feat: align chat, media and routing flows with current OpenRouter APIs (Phase 1) - #25

Merged
sena-labs merged 5 commits into
mainfrom
feat/openrouter-api-alignment-phase1
Oct 11, 2026
Merged

sena-labs merged 5 commits into
mainfrom
feat/openrouter-api-alignment-phase1

Conversation

@sena-labs

Copy link
Copy Markdown
Owner

Summary

Phase 1 of the OpenRouter API alignment plan (docs/PLAN-OPENROUTER-ALIGNMENT.md, full audit in docs/OPENROUTER-AUDIT-2026-10-04.md). No breaking changes: same valves, same payloads in, same UX out.

Related Issue

Follows the audit opened after v1.12.2; no dedicated issue.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change
  • Documentation update
  • Refactoring
  • Test improvement

Changes Made

  • Payload merging — provider and reasoning merged non-destructively; explicit user controls win; max_price most restrictive wins; ZDR / data_collection: deny admin policy cannot be weakened by user preferences.
  • Tool loop correctness — full replay of reasoning_details + assistant content across rounds (signed/encrypted reasoning preserved); server tools merged alongside OWUI functions; sync callables off the event loop.
  • Cost accounting — cumulative totals across tool rounds and TTS chunks, USD only (COST_CURRENCY stays as legacy display).
  • Variant resolver — routing tags (:online, :nitro, :floor, :exacto) stripped for catalog lookup; media and :free variants never fabricated.
  • Free filter — excludes paid media models whose token prices are 0/0 (5 image models misclassified before).
  • Auth & discovery — key validation on /key (60s cache); catalog discovery works with personal keys; icon registry from /api/frontend/v1/all-providers.
  • TTS — single-flight, Seed Audio limits (3000 chars, speed 0.5–2.0, no default alloy voice), cumulative usage aggregation, credit prefetch on cache hits.
  • Video — rejects before submit under ZDR/deny-data; terminal states failed/cancelled/expired surfaced with job id.
  • Session privacy — OWUI session_id never forwarded; mapped to a stable pseudonymous OpenRouter session_id.

Testing

  • python test_pipe.py — 1058 asserts, 0 failed
  • python -m unittest -v test_maintenance test_alignment — 55 tests OK (39 new alignment regressions)
  • OWUI compatibility smoke — PASS on v0.11.4-slim and main-slim (save/update/schema/valves/delete)
  • New tests added (test_alignment.py)
  • Paid live e2e (e2e_live.py) — script added, budget-guarded; run deferred to release gate with a disposable key
  • CHANGELOG.md [Unreleased] section + compare link

Screenshots / Demo

N/A — behavioral fixes; discovery live check: 650 models, 23 speech, 30 video.

Checklist

  • Code follows project conventions (CONTRIBUTING.md)
  • No secrets committed (e2e reads key from env only)
  • Docs updated (README, TESTING, CONTRIBUTING, CHANGELOG, CLAUDE)

Phase 1 of docs/PLAN-OPENROUTER-ALIGNMENT.md:

- merge provider/reasoning controls without losing explicit settings;
  enforce ZDR/deny-data policy against user preferences
- replay reasoning_details and assistant content across tool rounds;
  keep server tools alongside OWUI functions; run sync callables off-loop
- cumulative cost accounting across tool rounds and TTS chunks (USD only)
- variant resolver: routing tags (:online/:nitro/:floor/:exacto) stripped
  for catalog lookup; never fabricate media or free variants
- free filter now excludes paid media models whose token prices are 0/0
- auth validation on /key with 60s cache; public discovery with personal
  keys; icon registry via /api/frontend/v1/all-providers
- TTS: single-flight, Seed Audio limits (3000 chars, speed 0.5-2.0),
  cumulative usage aggregation, credit prefetch on cache hits
- video: reject before submit under ZDR/deny-data; terminal states
  failed/cancelled/expired surfaced with job id
- tests: test_alignment.py (39 regressions), updated test_pipe.py, CI
- docs: audit report, alignment plan, README/TESTING/CONTRIBUTING/CHANGELOG
- e2e_live.py: budget-guarded paid live checks (chat/tool loop, TTS, video)
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-04T09:40:31.407257Z 99acfa8 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Comment thread openrouter_pipe.py Fixed
Comment thread openrouter_pipe.py Fixed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99acfa81e0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread e2e_live.py Resolved
Comment thread e2e_live.py Resolved
Comment thread e2e_live.py Resolved
Comment thread openrouter_pipe.py Resolved
Comment thread openrouter_pipe.py Resolved
CodeQL flagged plain SHA-256 over the bearer token where it is used as a
cache/scope key (py/hashing-sensitive-data). Those digests identify cache
entries, they are never stored or used for authentication, but a keyed
construction is strictly better: HMAC-SHA256 with a per-process random
secret makes the fingerprints non-comparable across restarts.

- add Pipe._credential_fingerprint (HMAC, os.urandom(32) per-process key)
- use it for: models-list cache key, /key validation cache, credit cache
  (read+write), TTS single-flight scope and TTS cache key
- update test_pipe.py helper that primes the credit cache directly
Comment thread openrouter_pipe.py Fixed
- credential fingerprint: keyed blake2b instead of HMAC-SHA256
- skip /key validation on custom OPENROUTER_BASE_URL
- merge unindexed streamed reasoning fragments, split distinct records
- e2e_live: import time, read nested /credits data, pre-call budget checkpoint
Comment thread openrouter_pipe.py Fixed
Read the seal off the accumulated slot rather than the incoming fragment,
so a trailing signature-only delta merges into the reasoning block it
closes instead of opening a separate record. Dropping `data` from the
seal test keeps multi-fragment encrypted payloads concatenating.

Closes the last open review thread on #25.
@sena-labs
sena-labs merged commit 364bb91 into main Oct 11, 2026
9 checks passed
@sena-labs
sena-labs deleted the feat/openrouter-api-alignment-phase1 branch October 11, 2026 14:47
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