model: speak the two dialects natively and stop hosting a Model component - #66
Closed
weilueluo wants to merge 3 commits into
Closed
model: speak the two dialects natively and stop hosting a Model component#66weilueluo wants to merge 3 commits into
weilueluo wants to merge 3 commits into
Conversation
weilueluo
force-pushed
the
agent-provider-catalog
branch
4 times, most recently
from
August 26, 2026 09:58
b25933f to
bc6e30d
Compare
weilueluo
force-pushed
the
agent-provider-catalog
branch
2 times, most recently
from
August 26, 2026 10:15
a81af0c to
7d1e1a3
Compare
weilueluo
marked this pull request as draft
August 26, 2026 11:57
Contributor
Author
|
Parked as a draft: the owner moved the boundary again — Brain will speak the two dialects natively and stop treating Model as a component kind, and the catalog moves to Aex. Re-planning before this branch is rewritten; nothing here should merge as it stands. |
…eaks Brain's model configuration is the endpoint, the shape it speaks, the credential and the model name. The OpenAI and Anthropic request and response shapes are the de facto standard, so Brain adopts them as its contract and keeps no notion of a provider anywhere: no Model world, no component identity on the model object, and no provenance label on the session view or the usage event. Which provider names resolve to an endpoint is a platform's policy, not the kernel's.
A session resolves through the dialect factory the compositions already build, so the OpenAI and Anthropic codecs run in the kernel instead of behind a component. The Model registry, its host bindings, its worker arms and its guest fixture are gone with the world they served. The regressions the Model components learned the hard way are now Brain's own: an unset sampling field stays absent rather than serializing as null, the sealed system prompt leads the request, a non-2xx status keeps its status body and retry hint, a stream that dies mid-frame is reported rather than read as a clean end, and reasoning effort is refused at create by the dialect that cannot send it. The standalone gate now drives a scripted endpoint over real HTTP in both shapes.
The neutral client takes the dialect, the endpoint that speaks it, the credential and the model name, and binds no Model component. typed() moves here from @aexhq/model: a component export must return its declared extension-error rather than trap, which is a property of the contracts this package already publishes, and it is now the only surviving export of that package.
weilueluo
force-pushed
the
agent-provider-catalog
branch
from
August 26, 2026 12:54
7d1e1a3 to
5261cbe
Compare
weilueluo
marked this pull request as ready for review
August 26, 2026 13:15
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brain speaks exactly two API shapes — OpenAI and Anthropic — natively, and knows nothing else. Its
model configuration is the dialect, the endpoint, the credential and the model name; a Model is no
longer an extension. Which provider names a platform resolves is that platform's policy.
Design note:
aex-research/docs/model-provider-and-catalog.md(aexhq/aex-research#16).Companion PRs: aexhq/aex#134 (Aex owns the catalog), aexhq/extensions#48 (the Model packages go).
Public surface
There is no unsupported-provider case at this layer: any endpoint speaking either shape works by
pointing the URL at it. That is the extension point, and it needs no component, no registry and
no catalog.
What this restores rather than rebuilds
The native codecs were never deleted — the reset left them in
crates/brain/src/provider/, stillbuilt into the dialect factory both compositions compose (
brain_providers::default_factory), andsevered only from the session path, with
view.rshard-codingDialect::OpenAiChat"until thelegacy provider codecs are deleted". The sealed prefix carries the dialect again and
(brain.provider_factory)(dialect)resolves the turn's provider.Deleted with the world they served:
contracts/model/v1, the publishedmodel.wit, themodelbindgen and its runtime/worker arms, the guest fixture,
brain-providers/src/component.rs, and the"model"component kind in the manifest and the TypeScript client.providerleaves the create,the sealed prefix, the session view and the
model.usageevent.Regressions carried across, not left to die with the packages
Each of these was a live defect in the last two days, and each now has a test here:
systemfield)reasoning_effortis refused at create by the Anthropic dialect that cannot send itstandalone_e2enow drives a scripted model endpoint over real HTTP in both shapes, assertingper-session credentials, the system prompt and absent sampling fields on every round.
Endpoint convention
baseUrlis the endpoint's full API root, version segment included, and a dialect appends only itsoperation path (
/chat/completions,/messages). That is what models.dev publishes and whatproviders that version differently — or not at all, like
api.githubcopilot.com— actually need.Cut clean
PrefixDoclosesproviderandmodel_componentwith no tolerance window, so sessions sealedbefore this do not hydrate: the development plane was reset for exactly this, and production has
never served a customer.
typed()moves here from@aexhq/model, beside the contracts whoseextension-errorit returns.Gates
cargo fmt --all --check,cargo clippy --workspace --all-targets -D warnings,cargo test --workspace(213 brain + protocol conformance + every brain-server gate includingstandalone_e2eandcomponent_tool_environment),cargo test -p brain-component-host(8/8 runserially; the two frame-bound tests are timing-sensitive under local parallelism),
python tools/postprocess-generated.py --check,npm test(36),npm run package-smoke.@aexhq/brain0.6.0. 55 files, ~930 insertions against ~1260 deletions.