Commit Graph

9 Commits

Author SHA1 Message Date
ericmaddox
6ca41cbe8b fix(opencode): send ephemeral x-opencode-session header on one-shot requests
OpenCode Go strictly requires an x-opencode-session header on all requests to route requests efficiently and avoid HTTP 400 MissingSessionID. In turn chats and parented auxiliary calls, the header is derived from the conversation context or session ID. For stateless one-shot requests (commit messages, summaries, unparented auxiliary tasks), opencode_session_headers now falls back to generating an ephemeral session ID so one-shot requests to OpenCode succeed.

Closes #105841
2026-09-19 10:06:00 -07:00
Ritesh Patel
998f614c7f feat(providers): remove the keyless opencode-free tier
OpenCode's free tier now returns HTTP 403 for anonymous traffic outside
the OpenCode client, so the built-in keyless provider is dead weight:

- drop the opencode-free provider row, aliases (free/opencode_free), model
  catalog, keyless runtime ladder rung, header wiring, and cached slugs
- delete the model-providers/opencode-free plugin
- update tests and the compat manifest for the removed symbols
- keep a migration hint in auth.py so users who had it configured see a
  clear error naming the removal

Existing opencode-free configs can move to opencode-zen (pay-as-you-go)
or opencode-go (flat subscription).
2026-09-18 15:40:37 +05:30
teknium1
4f0eea5e94 fix(tui-gateway): carry session_id in the llm.oneshot runtime snapshot; align feasibility test
Review follow-up on #113189. `_main_runtime_from_agent` (the Desktop/TUI-gateway
`llm.oneshot` session-bound path, task defaults to title_generation) built its explicit
main_runtime without `session_id`, so on an OpenCode route the title request still sent
no `x-opencode-session` (MissingSessionID -> paid main-model fallback) — the exact symptom
this PR fixes on /btw, the turn_context titler and `_current_main_runtime`. Add the field;
it is str-valued so the existing strip() branch keeps it.

Also fixes the red CI run 35127963318: `test_feasibility_check_passes_live_main_runtime`
asserts the exact `_current_main_runtime` dict, which this PR extended with `session_id`.
2026-09-16 17:22:17 -07:00
teknium1
6f8389d67b fix(aux): keep the /btw and title snapshots duck-typed; make the out-of-turn header tests discriminating
Follow-up on the salvaged #112721 commits (@fangliquanflq):

- agent/turn_context.py, tui_gateway/methods_prompt.py: add ``session_id`` to the explicit
  snapshot dicts instead of switching them to ``agent._current_main_runtime()``. The titling
  prologue is duck-typed (its tests drive a minimal stub) and the snapshot values feed the
  ``runtime_validator`` equality checks, where ``_current_main_runtime()``'s ``"" `` for a
  missing attribute would no longer match the live ``None``. Same outcome — the background
  request inherits the conversation's ``x-opencode-session`` — without changing what the
  callers read.
- tests/agent/test_opencode_session_affinity.py: the salvaged title test passed on an
  unfixed tree because the titler thread republishes the conversation contextvar
  (``set_conversation_context``) and the affinity header falls back to it. Replace it with
  two invariant tests (sync + async ``call_llm(main_runtime=...)`` with EVERY ambient source
  unset via the ``out_of_turn`` fixture): red on origin/main, green here; both also pin
  that the explicit binding does not leak past the call.
- website/docs/integrations/providers.md: name the background/out-of-turn auxiliary calls
  the header now covers.

Fixes #112717
2026-09-16 17:22:17 -07:00
fangliquan
de03c34233 fix(auxiliary): preserve session in out-of-turn snapshots 2026-09-16 17:22:17 -07:00
fangliquan
03451ea9b3 test(agent): cover explicit auxiliary session snapshot 2026-09-16 17:22:17 -07:00
fangliquan
20ade400ab fix(auxiliary): propagate OpenCode session header 2026-09-16 17:22:17 -07:00
Teknium
cc81e436ce fix(models): delist hy3-free and laguna-s-2.1-free — OpenCode relay dropped them (anon 401)
The OpenCode Zen relay no longer serves hy3-free (since ~2026-08-31) or
laguna-s-2.1-free (new, verified 2026-09-09): both are gone from the live
GET /zen/v1/models catalog and anonymous chat completions return
401 {"type":"ModelError","message":"Model <id> is not supported"}
(2 probes >=60s apart, x-opencode-session header present).

- hermes_cli/models_catalog_static.py: remove both slugs from the
  opencode-free offline floor and the opencode-zen discovery floor;
  document the delist dates in the catalog comment.
- plugins/model-providers/opencode-free: default_aux_model moves from the
  dead laguna-s-2.1-free to nemotron-3.5-lightning-free (fastest surviving
  anonymous model).
- tests: swap fixtures off the dead slugs; extend the floor-exclusion
  invariant to cover both.

The live revalidation path already hides them when the relay is reachable;
this fixes the OFFLINE floor and the aux default, which would otherwise
offer/route to models that 401.
2026-09-13 21:06:39 -07:00
Teknium
139396995a feat(opencode): send x-opencode-session on every OpenCode request for backend affinity
OpenCode pins requests sharing an x-opencode-session value to one upstream
backend, which is what keeps its prompt cache warm across a conversation.
Hermes never sent it, so cache ratios on OpenCode traffic were poor.

- agent/opencode_affinity.py: single owner of the header — target detection
  (built-in zen/go/free, custom opencode-* providers, any opencode.ai URL)
  and the key (affinity scope → conversation root → session id, cron
  timestamp stripped), same resolution as OpenRouter/xAI affinity hints.
- build_api_kwargs: merged once after the per-mode builder, so
  chat_completions, codex_responses and anthropic_messages all carry it.
- auxiliary _build_call_kwargs: same key from the runtime-main session so
  compression/title/vision calls stay on the conversation's backend; the
  aux Codex and Anthropic adapters now forward extra_headers.

Closes #81584, #81832 (deepseek-v4-flash 400 without the header).
2026-09-02 21:46:36 -07:00