Repository navigation
Conversation
Providers can declare experimental_modelOptions: picker choices with values, a default and a per-value reason shown on models that reject it. Model catalog entries narrow the values they accept through experimental_supportedModelOptions. The server resolves each declared option from the request, the thread's last turn, then the project defaults, falling back to the declared default. Explicit unknown ids or values are rejected with a 400. The resolved values are stored with turn requests, queued messages and project defaults, and reach deriveProviderOptions as experimental_modelOptions. Codex declares a daybreak option. Its catalog maps each model's availableAccessPrograms to off/on, and the Daybreak alias models move to selected-only once another model offers the switch. With Daybreak on, the bridge sends the model's cyberAccessProgram on turn/start (Daybreak Blue before Red) and refuses the turn before reaching Codex when the model has no Daybreak program. The CLI accepts --model-option id=value on thread spawn and tell, and the SDK forwards experimental_modelOptions on send.
The model picker renders each provider-declared option the selected provider's models can use: two values as a switch, more as a segmented control. Models that reject the selected value are greyed out with the value's reason and ignore clicks and Enter, changing a value moves the selection to a compatible model (current, then default, then first), and the trigger names active options. New-thread composers remember the choice per provider and send it as a client preference. Thread composers show the thread's resolved values and send them explicitly only after the user changes them, so ordinary follow-ups inherit the previous turn's values on the server. Queued-row editing keeps its options read-only. NewThreadRequest carries the values as experimental_modelOptions. bb provider models gains a Model options column, and the provider plugin API doc, Plugin Guide, CLI guide, JSON shapes, Codex skill and api_to_audit.md describe the option, the Daybreak consumer and --model-option. The plugin SDK moves to 0.6.27 and the host-daemon protocol to 230 for the model catalog field; the Codex plugin now requires SDK 0.6.27.
Codex lists gpt-daybreak-blue-latest and gpt-daybreak-red-latest as their own models. With the Daybreak switch they only duplicate it, and as selected-only entries they still showed under More models, greyed out while Daybreak was off. Drop them from the catalog when another model offers Daybreak, as Codex Desktop does. Codex accepts unlisted model ids, so a thread already on an alias keeps running.
iipanda
marked this pull request as ready for review
October 8, 2026 13:58
This branch has not been deployed
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.
Human comments
What was wrong
Codex's Daybreak, OpenAI's cyber access program, could only be used in bb by picking the opaque "Daybreak Blue" alias model. It was impossible to use Daybreak with a chosen model such as 6-Sol, because bb never sent
cyberAccessProgram. More generally, a provider had no way to add its own choice to bb's model picker; Fast mode is the only such control, and it is hard-coded as service tiers. Per the maintainer's suggestion on #4802, this adds a generic, provider-declared picker option API and uses it for Daybreak.What changed
experimental_modelOptions: [{ id, label, description?, values, defaultValue }]. Each value carries an optionalmodelUnavailableReason.model/listentry narrows the values it accepts withexperimental_supportedModelOptions; an entry without the option id accepts every value. The design mirrorsserviceTiers/supportedServiceTiers.0142addsmodel_options_json) and project defaults.deriveProviderOptionsasctx.experimental_modelOptions. They cross the daemon wire only as the provider's derivedproviderOptions.NewThreadRequest.experimental_modelOptionscarries the values for plugins.daybreakoff/on option, mapped from each model'savailableAccessPrograms.cyber(missing metadata meansoffonly).turn/startsends the model's program (Daybreak Blue before Red). A model without one is refused before reaching Codex: "Daybreak isn't available for . Turn off Daybreak or choose another model."gpt-daybreak-*-latestaliases are hidden once another model offers the switch, as Codex Desktop does.bb thread spawnandbb thread telltake a repeatable--model-option id=value.bb provider modelsgains a Model options column, and the SDK forwardsexperimental_modelOptions.docs/api_to_audit.md,docs/provider-plugin-api.md, the Plugin Guide card, the CLI guide, the JSON shapes, and the Codex skill.HOST_DAEMON_PROTOCOL_VERSION231 (model catalog field), and the Codex plugin now requires SDK >= 0.6.32.modelOptions, per the no-meaningless-optional rule, so about 150 test fixtures gain amodelOptions: {}line.How you verified
turn/start.pnpm exec turbo run typecheckpasses for every package. The test suites of all touched packages pass (domain, plugin-sdk, server-contract, db, server, cli, sdk, client-core, app, provider-codex, host-daemon-contract, plugin-api-docs, templates). One unrelatedFilePreviewtest failed under load and passes alone.--model-option daybreak=onon 6-Sol completed, and Codex's own log showscyber_access_program: Some(DaybreakBlue).daybreak=maybereturned 400.Out of scope, listed in
docs/api_to_audit.md:experimental_ProviderModelPickersupport.Fixes #4802