Skip to content

Route session auto-naming through the provider adapter - #1137

Merged
Open-Squilla merged 6 commits into
TokenRhythm:mainfrom
QinLuza:fix/session-naming-provider-adapter
Sep 18, 2026
Merged

Open-Squilla merged 6 commits into
TokenRhythm:mainfrom
QinLuza:fix/session-naming-provider-adapter

Conversation

@QinLuza

@QinLuza QinLuza commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Scope

Session auto-naming previously sent OpenAI chat-completions requests even when the selected provider used Anthropic's native protocol. Route production naming through the selected provider adapter so its protocol, credentials, request constraints, and usage accounting match normal provider calls.

Scope boundary: preserve explicit naming model/tier selection and session overrides using an isolated selector; keep the physical request model and usage ledger consistent. Preserve resolved output limits (normally 512 tokens, TokenRhythm 1024, subject to lower configured limits), reasoning controls, correlation, title sanitization, manual rename precedence, and bounded stream cleanup. Structured refusal/content-filter responses retain the fallback title while completed usage remains accounted.

Non-goals: change routing policy, ordinary chat behavior, the public gateway event schema, or remove the legacy direct-HTTP naming helper.

Branch

Base branch: main

Target exception: N/A

Issue

Linked issue: None

If None, reason: this original PR tracks the native-provider naming defect and its regression coverage.

Release Note

Release note: Fix session auto-naming for native provider protocols while preserving configured naming models, usage accounting, and fallback titles.

Tests

Ruff: ruff check src tests passed.

Mypy: mypy src/opensquilla --show-error-codes passed (1608 source files).

Pytest: 658 focused cases passed: 48 terminal-cleanup cases plus 133 naming/real-adapter/refusal/target-selection cases and 477 provider, accounting, request-golden, and stream-golden cases. HTTP integration fixtures use real selectors/adapters with offline MockTransport and check the resulting usage ledger. Coverage includes native Anthropic messages, explicit model/tier and session overrides, registry aliases, resolved token caps, timeout/cancellation/cleanup, refusal evidence, sanitization, and concurrent manual rename.

Build: the previous updated PR passed its full CI. The merge queue exposed a 2-second timeout in an unchanged Gateway test while formatting an intentionally raised exception. A controlled baseline/candidate comparison reproduced the same failure by delaying only the renderer. The test now captures and asserts its expected warning while preserving the timeout and all durable-ack assertions. Current main is integrated; required CI runs again on this final update, and final merge-queue checks remain authoritative.

Regression tests: added

Notes: the 15 stream-golden changes each add only the default internal Provider DoneEvent refusal: false field; a value-level comparison verified no other snapshot changes, and the normal non-regenerating suite passed. Local focused validation ran on macOS/Python 3.12 with explicit source imports. These provider changes are platform-neutral; local results do not claim native Linux/Windows or full-suite acceptance.

The default test path remains offline, deterministic, credential-free, and safe for forks.

Maintainer Live Check

Maintainer live check: no

Surface: provider

Maintainer-only note: protocol and accounting regression checks use synthetic offline responses; contributors do not need credentials.

Safety

All fixtures use synthetic requests, dummy credentials, and isolated local storage. No real prompts, transcripts, secrets, machine-specific paths, runtime data, or assistant scratch artifacts are committed. Refusal metadata is an internal boolean without retaining refusal content; the separate public gateway Done event is unchanged.

Third-Party Origin

Third-party origin: none

Original contribution by @QinLuza remains in this PR's history. Maintainer follow-up commits integrate current main and repair regression gaps without replacing the contributor's PR.

Documentation Changes

  • Links point to existing repository files or stable external pages.
  • Code fences and Markdown tables render correctly on GitHub.
  • Examples avoid real secrets, local private paths, and private transcripts.

Session auto-naming was the last auxiliary request still issuing a bare
`/chat/completions` POST with URL-sniffed provider selection, duplicating
credential, wire-dialect, and failure-classification logic that the provider
adapters already own.

Add `call_naming_provider()`, mirroring the compaction summarizer's adapter
path: it streams one non-tool turn through `provider.chat`, inheriting the
adapter's wire dialect, credential handling, failure classification, and
usage accounting (via the same `account_provider_stream` wrapper). The
orchestrator (`generate_session_title`) now routes through it.

`call_naming_llm()` is retained as a legacy direct-POST helper for callers
that still construct a target from a raw URL + API key; its wire contract is
unchanged and covered by the existing mocked-httpx tests.

Verification: 62 naming tests pass (9 new for `call_naming_provider`,
including a real-adapter integration test); full `tests/test_session/` plus
`tests/test_engine/test_usage_http.py` = 624 passed, 1 skipped; ruff clean.
@QinLuza QinLuza closed this Aug 21, 2026
@QinLuza
QinLuza deleted the fix/session-naming-provider-adapter branch August 21, 2026 11:18
@QinLuza
QinLuza restored the fix/session-naming-provider-adapter branch August 21, 2026 12:06
@QinLuza QinLuza reopened this Aug 21, 2026
@Open-Squilla

Copy link
Copy Markdown
Contributor

Thanks for addressing this. I validated the change against the origin/main snapshot fetched for this review (00071e166), integrating PR head a185bc281 using real provider adapters, synthetic HTTP responses, and the session/usage SQLite path. The Anthropic case is fixed: naming now calls /v1/messages with the proper authentication, persists the title, and records one finalized usage event.

I recommend keeping this PR open and updating it before merge. The local integration needed one import-conflict resolution, and the adapter path currently introduces these regressions:

  1. The selected naming model does not reach the request. With naming.model or naming.tier selecting a different model, the HTTP payload still uses the active chat model, while the usage-event envelope records the requested naming model. The baseline sends and records the selected naming model consistently. Please build/resolve the adapter for the selected target and cover the actual HTTP payload, not just the helper arguments.
  2. The current TokenRhythm naming budget is lost. Main allows 1,024 output tokens; the new helper hard-codes 512 in request fitting, ChatConfig, and output validation. Please carry forward the current resolved/provider-specific budget.
  3. Current refusal handling is lost. A streamed structured refusal or finish_reason=content_filter with visible text now persists a title and emits sessions.changed; main leaves the fallback title intact. Please retain that behavior and exercise it through real SSE decoding.

Validation: the two naming test files pass 102 tests on the baseline. The local integration has 105 passing and 6 failing tests: two new tests conflict with main's updated prompt/title filtering, and four existing HTTP tests need SSE fixtures after the transport migration. The 23 focused usage-accounting tests and Ruff pass. The synthetic end-to-end probes above independently demonstrate the production regressions; they are not conclusions drawn only from those outdated test fixtures. This was targeted offline validation on macOS, not full CI or live-provider acceptance.

The adapter-based approach is useful; a rebase preserving the current naming behavior, these regression tests, and fresh required CI should make this ready for another review.

After validation, main advanced to ebe091d20 via #1565 (CLI/list-limit validation). I checked that diff; the naming/provider/accounting code, tested files and dependency lock are unchanged. The refreshed PR still needs the required CI result and Validate target branch checks before entering the merge queue.

@Open-Squilla
Open-Squilla added this pull request to the merge queue Sep 17, 2026
@Open-Squilla
Open-Squilla removed this pull request from the merge queue due to a manual request Sep 17, 2026
@Open-Squilla
Open-Squilla added this pull request to the merge queue Sep 17, 2026
@github-actions

Copy link
Copy Markdown

Merge queue CI: failurerun 35286935546, attempt 1.
Tested queue candidate: 8552711474839605cf623b77b18c3936509212f1. This result belongs to that combined tree, not necessarily the PR's current head.

The run summary lists reused suites and executed checks. A green PR check alone does not mean queue validation has passed.

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 17, 2026
@Open-Squilla
Open-Squilla added this pull request to the merge queue Sep 18, 2026
@github-actions

Copy link
Copy Markdown

Merge queue CI: successrun 35292862877, attempt 1.
Tested queue candidate: 6a6c7634e8340ddc43edb11b897167e5211c3389. This result belongs to that combined tree, not necessarily the PR's current head.

The run summary lists reused suites and executed checks. A green PR check alone does not mean queue validation has passed.

@github-actions

Copy link
Copy Markdown

Merge queue CI: successrun 35293033811, attempt 1.
Tested queue candidate: 996cfe2982e5b06d66b9a63b8f700af474397c59. This result belongs to that combined tree, not necessarily the PR's current head.

The run summary lists reused suites and executed checks. A green PR check alone does not mean queue validation has passed.

Merged via the queue into TokenRhythm:main with commit 996cfe2 Sep 18, 2026
64 checks passed
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