45646f4d09
Portal will serve anthropic/* from more than one upstream (OpenRouter passthrough today; GMI/Vertex once it is back online). The native Messages wire is the better transport but is only safe where the upstream keeps prompt-cache routing sticky: measured false on the OpenRouter path (14-20% of consecutive calls re-write the previous turn; #104284 moved the default to chat), untested on GMI. Hermes cannot see the upstream in the request, only in the response: OpenRouter stamps `provider` (chat wire) and mints `gen-<unix>-<rand>` ids; GMI/Vertex returns Anthropic-native `msg_...` ids and no provider. `auto` therefore starts every session on chat (correct on both upstreams), classifies the first response, and switches that session to native only when the upstream is GMI AND `agent/nous_wire.py::GMI_NATIVE_WIRE_CLEARED` is True. The switch is scheduled at response time and applied at the start of the next iteration (turn_iteration_prep), so nothing is rebuilt while a response is being consumed; it goes through switch_model so the client, cache policy and _primary_runtime stay consistent. One decision per session, call 1 only; unknown upstream never switches; a failed switch logs and stays. GMI_NATIVE_WIRE_CLEARED is False: until the 20x6 concurrency probe (evals/postmortem/live_ab) is clean on a GMI-served anthropic/* id on the native wire, `auto` behaves exactly like `chat`. Flipping it is the whole rollout once GMI is measured. Default stays `chat`. Tests (17): classifier on real Portal response shapes from both wires and both upstreams; chat for openrouter/unknown, GMI gated on the flag; one decision per session, call 1 only, explicit chat/native never auto-switch, other providers/models untouched, switch failure swallowed and final; record_response_usage on a real AIAgent invokes the hook once. Live (auto, real Portal, Fable 5.1): arm A, real classification (OpenRouter today) - stays on chat through a tool loop and a second turn, cache 97-99%. Arm B, classifier forced to gmi with the flag on - call 1 on chat, switch applied before call 2, calls 2-3 on the native wire in the same session, tool result and both turns correct, cache 97-99%. An earlier shape that switched inside the response path broke call 1 (SimpleNamespace has no .content); the scheduled apply is why.
Website
This website is built using Docusaurus, a modern static website generator.
Installation
yarn
Local Development
yarn start
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
Build
yarn build
This command generates static content into the build directory and can be served using any static contents hosting service.
Deployment
Using SSH:
USE_SSH=true yarn deploy
Not using SSH:
GIT_USER=<Your GitHub username> yarn deploy
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the gh-pages branch.
Diagram Linting
CI runs ascii-guard to lint docs for ASCII box diagrams. Use Mermaid (````mermaid`) or plain lists/tables instead of ASCII boxes to avoid CI failures.