Commit Graph

37 Commits

Author SHA1 Message Date
Dylan Hurd
e3ab0bd973 chore(personality) new schema with fallbacks (#10147)
## Summary
Let's dial in this api contract in a bit more with more robust fallback
behavior when model_instructions_template is false.

Switches to a more explicit template / variables structure, with more
fallbacks.

## Testing
- [x] Adding unit tests
- [x] Tested locally
2026-01-30 00:10:12 -07:00
Owen Lin
81a17bb2c1 feat(app-server): support external auth mode (#10012)
This enables a new use case where `codex app-server` is embedded into a
parent application that will directly own the user's ChatGPT auth
lifecycle, which means it owns the user’s auth tokens and refreshes it
when necessary. The parent application would just want a way to pass in
the auth tokens for codex to use directly.

The idea is that we are introducing a new "auth mode" currently only
exposed via app server: **`chatgptAuthTokens`** which consist of the
`id_token` (stores account metadata) and `access_token` (the bearer
token used directly for backend API calls). These auth tokens are only
stored in-memory. This new mode is in addition to the existing `apiKey`
and `chatgpt` auth modes.

This PR reuses the shape of our existing app-server account APIs as much
as possible:
- Update `account/login/start` with a new `chatgptAuthTokens` variant,
which will allow the client to pass in the tokens and have codex
app-server use them directly. Upon success, the server emits
`account/login/completed` and `account/updated` notifications.
- A new server->client request called
`account/chatgptAuthTokens/refresh` which the server can use whenever
the access token previously passed in has expired and it needs a new one
from the parent application.

I leveraged the core 401 retry loop which typically triggers auth token
refreshes automatically, but made it pluggable:
- **chatgpt** mode refreshes internally, as usual.
- **chatgptAuthTokens** mode calls the client via
`account/chatgptAuthTokens/refresh`, the client responds with updated
tokens, codex updates its in-memory auth, then retries. This RPC has a
10s timeout and handles JSON-RPC errors from the client.

Also some additional things:
- chatgpt logins are blocked while external auth is active (have to log
out first. typically clients will pick one OR the other, not support
both)
- `account/logout` clears external auth in memory
- Ensures that if `forced_chatgpt_workspace_id` is set via the user's
config, we respect it in both:
- `account/login/start` with `chatgptAuthTokens` (returns a JSON-RPC
error back to the client)
- `account/chatgptAuthTokens/refresh` (fails the turn, and on next
request app-server will send another `account/chatgptAuthTokens/refresh`
request to the client).
2026-01-29 23:46:04 +00:00
pakrym-oai
fbb3a30953 Remove WebSocket wire format (#10179)
I'd like WireApi to go away (when chat is removed) and WebSockets is
still responses API just over a different transport.
2026-01-29 13:50:53 -08:00
Dylan Hurd
ce3d764ae1 chore(config) personality as a feature (#10116)
## Summary
Sets up an explicit Feature flag for `/personality`, so users can now
opt in to it via `/experimental`. #10114 also updates the config

## Testing
- [x] Tested locally
2026-01-28 17:58:28 -07:00
Dylan Hurd
fef3e36f67 fix(core) info cleanup (#9986)
## Summary
Simplify this logic a bit.
2026-01-27 21:15:15 -07:00
Ahmed Ibrahim
509ff1c643 Fixing main and make plan mode reasoning effort medium (#9980)
It's overthinking so much on high and going over the context window.
2026-01-26 22:30:24 -08:00
Dylan Hurd
25fccc3d4d chore(core) move model_instructions_template config (#9871)
## Summary
Move `model_instructions_template` config to the experimental slug while
we iterate on this feature

## Testing
- [x] Tested locally, unit tests still pass
2026-01-26 07:02:11 +00:00
Dylan Hurd
031bafd1fb feat(tui) /personality (#9718)
## Summary
Adds /personality selector in the TUI, which leverages the new core
interface in #9644

Notes:
- We are doing some of our own state management for model_info loading
here, but not sure if that's ideal. open to opinions on simpler
approach, but would like to avoid blocking on a larger refactor
- Right now, the `/personality` selector just hides when the model
doesn't support it. we can update this behavior down the line

## Testing
- [x] Tested locally
- [x] Added snapshot tests
2026-01-25 21:59:42 -08:00
Ahmed Ibrahim
cb2bbe5cba Adjust modes masks (#9868) 2026-01-25 12:44:17 -08:00
Ahmed Ibrahim
58450ba2a1 Use collaboration mode masks without mutating base settings (#9806)
Keep an unmasked base collaboration mode and apply the active mask on
demand. Simplify the TUI mask helpers and update tests/docs to match the
mask contract.
2026-01-25 07:35:31 +00:00
Ahmed Ibrahim
b3127e2eeb Have a coding mode and only show coding and plan (#9802) 2026-01-23 19:28:49 -08:00
Ahmed Ibrahim
69cfc73dc6 change collaboration mode to struct (#9793)
Shouldn't cause behavioral change
2026-01-23 17:00:23 -08:00
Ahmed Ibrahim
45fe58159e Select default model from filtered presets (#9782)
Pick the first available preset after auth filtering for default
selection.
2026-01-23 12:18:36 -08:00
Ahmed Ibrahim
d86bd20411 Change the prompt for planning and reasoning effort (#9733)
Change the prompt for planning and reasoning effort preset for better
experience
2026-01-22 18:22:12 -08:00
Dylan Hurd
96a72828be feat(core) ModelInfo.model_instructions_template (#9597)
## Summary
#9555 is the start of a rename, so I'm starting to standardize here.
Sets up `model_instructions` templating with a strongly-typed object for
injecting a personality block into the model instructions.

## Testing
- [x] Added tests
- [x] Ran locally
2026-01-21 18:11:18 -08:00
Ahmed Ibrahim
56fe5e7bea merge remote models (#9547)
We have `models.json` and `/models` response
Behavior:
1. New models from models endpoint gets added
2. Shared models get replaced by remote ones
3. Existing models in `models.json` but not `/models` are kept
4. Mark highest priority as default
2026-01-20 14:02:07 -08:00
Dylan Hurd
714151eb4e feat(personality) introduce model_personality config (#9459)
## Summary
Introduces the concept of a config model_personality. I would consider
this an MVP for testing out the feature. There are a number of
follow-ups to this PR:

- More sophisticated templating with validation
- In-product experience to manage this

## Testing
- [x] Testing locally
2026-01-20 11:06:14 -08:00
jif-oai
6bbf506120 feat: metrics on remote models (#9528) 2026-01-20 13:02:55 +00:00
Dylan Hurd
675f165c56 fix(core) Preserve base_instructions in SessionMeta (#9427)
## Summary
This PR consolidates base_instructions onto SessionMeta /
SessionConfiguration, so we ensure `base_instructions` is set once per
session and should be (mostly) immutable, unless:
- overridden by config on resume / fork
- sub-agent tasks, like review or collab


In a future PR, we should convert all references to `base_instructions`
to consistently used the typed struct, so it's less likely that we put
other strings there. See #9423. However, this PR is already quite
complex, so I'm deferring that to a follow-up.

## Testing
- [x] Added a resume test to assert that instructions are preserved. In
particular, `resume_switches_models_preserves_base_instructions` fails
against main.

Existing test coverage thats assert base instructions are preserved
across multiple requests in a session:
- Manual compact keeps baseline instructions:
core/tests/suite/compact.rs:199
- Auto-compact keeps baseline instructions:
core/tests/suite/compact.rs:1142
- Prompt caching reuses the same instructions across two requests:
core/tests/suite/prompt_caching.rs:150 and
core/tests/suite/prompt_caching.rs:157
- Prompt caching with explicit expected string across two requests:
core/tests/suite/prompt_caching.rs:213 and
core/tests/suite/prompt_caching.rs:222
- Resume with model switch keeps original instructions:
core/tests/suite/resume.rs:136
- Compact/resume/fork uses request 0 instructions for later expected
payloads: core/tests/suite/compact_resume_fork.rs:215
2026-01-19 21:59:36 -08:00
Ahmed Ibrahim
f72f87fbee Add collaboration modes test prompts (#9443)
# External (non-OpenAI) Pull Request Requirements

Before opening this Pull Request, please read the dedicated
"Contributing" markdown file or your PR may be closed:
https://github.com/openai/codex/blob/main/docs/contributing.md

If your PR conforms to our contribution guidelines, replace this text
with a detailed and high quality description of your changes.

Include a link to a bug report or enhancement request.
2026-01-18 11:39:08 -08:00
Ahmed Ibrahim
8f0e0300d2 Expose collaboration presets (#9421)
Expose collaboration presets for clients

---------

Co-authored-by: Josh McKinney <joshka@openai.com>
2026-01-17 12:32:50 -08:00
Ahmed Ibrahim
b9ff4ec830 change api default model (#9188) 2026-01-13 22:33:34 -08:00
Ahmed Ibrahim
4d787a2cc2 Renew cache ttl on etag match (#9174)
so we don't do unnecessary fetches
2026-01-14 01:21:41 +00:00
Ahmed Ibrahim
7e33ac7eb6 clean models manager (#9168)
Have only the following Methods:
- `list_models`: getting current available models
- `try_list_models`: sync version no refresh for tui use
- `get_default_model`: get the default model (should be tightened to
core and received on session configuration)
- `get_model_info`: get `ModelInfo` for a specific model (should be
tightened to core but used in tests)
- `refresh_if_new_etag`: trigger refresh on different etags

Also move the cache to its own struct
2026-01-13 16:55:33 -08:00
Ahmed Ibrahim
325ce985f1 Use markdown for migration screen (#8952)
Next steps will be routing this to model info
2026-01-13 07:41:42 +00:00
Ahmed Ibrahim
81caee3400 Add 5s timeout to models list call + integration test (#8942)
- Enforce a 5s timeout around the remote models refresh to avoid hanging
/models calls.
2026-01-08 18:06:10 -08:00
pakrym-oai
634764ece9 Immutable CodexAuth (#8857)
Historically we started with a CodexAuth that knew how to refresh it's
own tokens and then added AuthManager that did a different kind of
refresh (re-reading from disk).

I don't think it makes sense for both `CodexAuth` and `AuthManager` to
be mutable and contain behaviors.

Move all refresh logic into `AuthManager` and keep `CodexAuth` as a data
object.
2026-01-08 11:43:56 -08:00
Michael Bolin
59d6937550 fix: reduce duplicate include_str!() calls (#8914) 2026-01-08 17:20:41 +00:00
Ahmed Ibrahim
187924d761 Override truncation policy at model info level (#8856)
We used to override truncation policy by comparing model info vs config
value in context manager. A better way to do it is to construct model
info using the config value
2026-01-07 13:06:20 -08:00
pakrym-oai
018de994b0 Stop using AuthManager as the source of codex_home (#8846) 2026-01-07 18:56:20 +00:00
Ahmed Ibrahim
9179c9deac Merge Modelfamily into modelinfo (#8763)
- Merge ModelFamily into ModelInfo
- Remove logic for adding instructions to apply patch
- Add compaction limit and visible context window to `ModelInfo`
2026-01-07 10:35:09 -08:00
charley-oai
3389465c8d Enable model upgrade popup even when selected model is no longer in picker (#8802)
With `config.toml`:
```
model = "gpt-5.1-codex"
```
(where `gpt-5.1-codex` has `show_in_picker: false` in
[`model_presets.rs`](https://github.com/openai/codex/blob/main/codex-rs/core/src/models_manager/model_presets.rs);
this happens if the user hasn't used codex in a while so they didn't see
the popup before their model was changed to `show_in_picker: false`)

The upgrade picker used to not show (because `gpt-5.1-codex` was
filtered out of the model list in code). Now, the filtering is done
downstream in tui and app-server, so the model upgrade popup shows:

<img width="1503" height="227" alt="Screenshot 2026-01-06 at 5 04 37 PM"
src="https://github.com/user-attachments/assets/26144cc2-0b3f-4674-ac17-e476781ec548"
/>
2026-01-06 19:32:27 -08:00
Ahmed Ibrahim
6846bc1115 hard disable remote models refresh when feature is disabled (#8687)
We were refreshing on tag mismatch even with feature is disabled
2026-01-02 15:22:51 -08:00
Ahmed Ibrahim
66b7c673e9 Refresh on models etag mismatch (#8491)
- Send models etag
- Refresh models on 412
- This wires `ModelsManager` to `ModelFamily` so we don't mutate it
mid-turn
2026-01-01 11:41:16 -08:00
Ahmed Ibrahim
40de81e7af Remove reasoning format (#8484)
This isn't very useful parameter. 

logic:
```
if model puts `**` in their reasoning, trim it and visualize the header.
if couldn't trim: don't render
if model doesn't support: don't render
```

We can simplify to:
```
if could trim, visualize header.
if not, don't render
```
2025-12-23 16:01:46 -08:00
Ahmed Ibrahim
6b2ef216f1 remove minimal client version (#8447)
This isn't needed value by client
2025-12-22 12:52:24 -08:00
Ahmed Ibrahim
f0dc6fd3c7 Rename OpenAI models to models manager (#8346)
# External (non-OpenAI) Pull Request Requirements

Before opening this Pull Request, please read the dedicated
"Contributing" markdown file or your PR may be closed:
https://github.com/openai/codex/blob/main/docs/contributing.md

If your PR conforms to our contribution guidelines, replace this text
with a detailed and high quality description of your changes.

Include a link to a bug report or enhancement request.
2025-12-19 16:20:05 -08:00