detached 029fea4

Merge branch 'main' into perf/swarm-detached-log-tail

commit
029fea4e86edda82dd016a8d9286b34f3d5c7d09
author
Patric Eckhart · · 2026-09-24 11:29 UTC
committer
GitHub · · 2026-09-24 11:29 UTC
merge of
8db8b1e + 9a5c565 · diff against the first parent
signature
GPG UnverifiedB5690EEEBB952194 The key is unknown
10 files · +155 -22
M README.md +3 -1
@@ -749,10 +749,12 @@ Use `/login` and pick **api key** to paste an AI Studio key. zot probes `/v1beta
749749
750750 > **Free-tier rate limits.** AI Studio's free tier has tight per-minute and per-day caps that vary by model: `gemini-2.5-pro` is the strictest (a few requests per minute, ~50 per day), Flash and Flash-Lite are far more generous. If a Pro turn 429s with `"You exceeded your current quota"` while Flash on the same key still works, you've hit the Pro free-tier RPD. Either switch to Flash for agent loops, or [enable billing](https://aistudio.google.com/app/apikey) on your AI Studio project to flip the same key from free to pay-as-you-go pricing (`$1.25/M` input, `$10/M` output for Pro).
751751
752-Reasoning levels (`--reasoning off|minimum|low|medium|high|xhigh|max`, also configurable through `/reasoning` or in `/settings` as **reasoning level**) map differently per generation. `max` is a distinct opt-in tier above `xhigh`. GPT-5.6 and adaptive-thinking Claude models receive native `max`; unsupported providers clamp it to their highest accepted effort. Budget-based providers retain their provider/model caps. Gemini 3.x uses the `thinkingLevel` enum (`MINIMAL`/`LOW`/`MEDIUM`/`HIGH`), with Gemini-3-Pro pinned to `LOW` minimum and `HIGH` for any medium-or-higher request. `off` sends no reasoning config except on always-on thinking models. Gemini 2.0 models have no thinking config.
752+Reasoning levels (`--reasoning off|minimum|low|medium|high|xhigh|max`, also configurable through `/reasoning` or in `/settings` as **reasoning level**) map differently per generation. `max` is a distinct opt-in tier above `xhigh`. GPT-5.6, GPT-6, and adaptive-thinking Claude models receive native `max`; unsupported providers clamp it to their highest accepted effort. Budget-based providers retain their provider/model caps. Gemini 3.x uses the `thinkingLevel` enum (`MINIMAL`/`LOW`/`MEDIUM`/`HIGH`), with Gemini-3-Pro pinned to `LOW` minimum and `HIGH` for any medium-or-higher request. `off` sends no reasoning config except on always-on thinking models. Gemini 2.0 models have no thinking config.
753753
754754 Claude Opus 5.5 is available through Anthropic (`--provider anthropic --model claude-opus-5-5`) and GitHub Copilot (`--provider github-copilot --model claude-opus-5.5`, subject to account availability). Both entries support a 1,000,000-token context window and up to 128,000 output tokens. Adaptive thinking is always on, with `low`, `medium`, `high`, `xhigh`, and `max` effort levels. The default, `off`, and `minimum` requests use `low` instead. The reasoning selector omits unsupported levels. Catalog prices per million tokens are $4 input, $20 output, $0.20 cache reads, and $5 cache writes. Copilot billing remains governed by your plan.
755755
756+GPT-6 Sol and GPT-6 Luna are available through OpenAI API keys, OpenAI Codex subscriptions, and GitHub Copilot. Select `gpt-6-sol` or `gpt-6-luna` with `--provider openai`, `openai-responses`, `openai-codex`, or `github-copilot`. Both use the Responses API, support up to 128,000 output tokens, and expose `low` through `max` reasoning. OpenAI and Codex entries use a 272,000-token context window, while Copilot entries use 1,000,000 tokens. Access through subscription providers depends on account availability and organization policy.
757+
756758 You can add additional Gemini model IDs to `models.json` under the `google` provider.
757759
758760 ### Gemini Enterprise Agent Platform (formerly Google Vertex AI)
@@ -749,10 +749,12 @@ Use `/login` and pick **api key** to paste an AI Studio key. zot probes `/v1beta
749 749
750 > **Free-tier rate limits.** AI Studio's free tier has tight per-minute and per-day caps that vary by model: `gemini-2.5-pro` is the strictest (a few requests per minute, ~50 per day), Flash and Flash-Lite are far more generous. If a Pro turn 429s with `"You exceeded your current quota"` while Flash on the same key still works, you've hit the Pro free-tier RPD. Either switch to Flash for agent loops, or [enable billing](https://aistudio.google.com/app/apikey) on your AI Studio project to flip the same key from free to pay-as-you-go pricing (`$1.25/M` input, `$10/M` output for Pro).750 > **Free-tier rate limits.** AI Studio's free tier has tight per-minute and per-day caps that vary by model: `gemini-2.5-pro` is the strictest (a few requests per minute, ~50 per day), Flash and Flash-Lite are far more generous. If a Pro turn 429s with `"You exceeded your current quota"` while Flash on the same key still works, you've hit the Pro free-tier RPD. Either switch to Flash for agent loops, or [enable billing](https://aistudio.google.com/app/apikey) on your AI Studio project to flip the same key from free to pay-as-you-go pricing (`$1.25/M` input, `$10/M` output for Pro).
751 751
752-Reasoning levels (`--reasoning off|minimum|low|medium|high|xhigh|max`, also configurable through `/reasoning` or in `/settings` as **reasoning level**) map differently per generation. `max` is a distinct opt-in tier above `xhigh`. GPT-5.6 and adaptive-thinking Claude models receive native `max`; unsupported providers clamp it to their highest accepted effort. Budget-based providers retain their provider/model caps. Gemini 3.x uses the `thinkingLevel` enum (`MINIMAL`/`LOW`/`MEDIUM`/`HIGH`), with Gemini-3-Pro pinned to `LOW` minimum and `HIGH` for any medium-or-higher request. `off` sends no reasoning config except on always-on thinking models. Gemini 2.0 models have no thinking config.752+Reasoning levels (`--reasoning off|minimum|low|medium|high|xhigh|max`, also configurable through `/reasoning` or in `/settings` as **reasoning level**) map differently per generation. `max` is a distinct opt-in tier above `xhigh`. GPT-5.6, GPT-6, and adaptive-thinking Claude models receive native `max`; unsupported providers clamp it to their highest accepted effort. Budget-based providers retain their provider/model caps. Gemini 3.x uses the `thinkingLevel` enum (`MINIMAL`/`LOW`/`MEDIUM`/`HIGH`), with Gemini-3-Pro pinned to `LOW` minimum and `HIGH` for any medium-or-higher request. `off` sends no reasoning config except on always-on thinking models. Gemini 2.0 models have no thinking config.
753 753
754 Claude Opus 5.5 is available through Anthropic (`--provider anthropic --model claude-opus-5-5`) and GitHub Copilot (`--provider github-copilot --model claude-opus-5.5`, subject to account availability). Both entries support a 1,000,000-token context window and up to 128,000 output tokens. Adaptive thinking is always on, with `low`, `medium`, `high`, `xhigh`, and `max` effort levels. The default, `off`, and `minimum` requests use `low` instead. The reasoning selector omits unsupported levels. Catalog prices per million tokens are $4 input, $20 output, $0.20 cache reads, and $5 cache writes. Copilot billing remains governed by your plan.754 Claude Opus 5.5 is available through Anthropic (`--provider anthropic --model claude-opus-5-5`) and GitHub Copilot (`--provider github-copilot --model claude-opus-5.5`, subject to account availability). Both entries support a 1,000,000-token context window and up to 128,000 output tokens. Adaptive thinking is always on, with `low`, `medium`, `high`, `xhigh`, and `max` effort levels. The default, `off`, and `minimum` requests use `low` instead. The reasoning selector omits unsupported levels. Catalog prices per million tokens are $4 input, $20 output, $0.20 cache reads, and $5 cache writes. Copilot billing remains governed by your plan.
755 755
756+GPT-6 Sol and GPT-6 Luna are available through OpenAI API keys, OpenAI Codex subscriptions, and GitHub Copilot. Select `gpt-6-sol` or `gpt-6-luna` with `--provider openai`, `openai-responses`, `openai-codex`, or `github-copilot`. Both use the Responses API, support up to 128,000 output tokens, and expose `low` through `max` reasoning. OpenAI and Codex entries use a 272,000-token context window, while Copilot entries use 1,000,000 tokens. Access through subscription providers depends on account availability and organization policy.
757+
756 You can add additional Gemini model IDs to `models.json` under the `google` provider.758 You can add additional Gemini model IDs to `models.json` under the `google` provider.
757 759
758 ### Gemini Enterprise Agent Platform (formerly Google Vertex AI)760 ### Gemini Enterprise Agent Platform (formerly Google Vertex AI)
M docs/providers.md +16 -16
@@ -114,10 +114,10 @@ use Chat Completions without `reasoning_effort`; their reasoning is managed by t
114114 endpoint. All three routes send user/agent initiator metadata and image-request
115115 headers where appropriate.
116116
117-As of September 8, 2026, the catalog includes 27 public chat models: Claude
118-Fable 5/5.1, Haiku 4.5, Opus 4.7/4.8/4.8 Fast/5, Sonnet 5, Gemini
117+As of September 22, 2026, the catalog includes 30 public chat models: Claude
118+Fable 5/5.1, Haiku 4.5, Opus 4.7/4.8/4.8 Fast/5/5.5, Sonnet 5, Gemini
119119 3.5/3.6/3.7/3.8 Flash, GPT-5 mini, GPT-5.3-Codex, GPT-5.4/5.4 mini/5.5,
120-GPT-5.6 Luna/Sol/Terra, GPT-6 Astra, Grok 4.5/4.6, Kimi K2.7 Code/K3,
120+GPT-5.6 Luna/Sol/Terra, GPT-6 Astra/Luna/Sol, Grok 4.5/4.6, Kimi K2.7 Code/K3,
121121 and MAI-Code-1-Flash/1.1-Flash. MAI-Code-1-Flash uses the public picker ID
122122 `mai-code-1-flash-picker` and is scheduled to retire on September 10, 2026.
123123
@@ -139,24 +139,24 @@ September 1, 2026, except for individual annual Copilot Pro and Pro+ subscribers
139139 Eligible subscribers can add it through `$ZOT_HOME/models.json`.
140140 See [GitHub's model retirement history and plan exceptions](https://docs.github.com/en/copilot/reference/ai-models/supported-models#model-retirement-history).
141141
142-## GPT-6 Astra
142+## GPT-6 models
143143
144-Select `gpt-6-astra` with provider `openai`, `openai-responses`,
145-`openai-codex`, or `github-copilot`, for example:
144+Select `gpt-6-astra`, `gpt-6-sol`, or `gpt-6-luna` with provider `openai`,
145+`openai-responses`, `openai-codex`, or `github-copilot`, for example:
146146
147147 ```bash
148-zot --provider github-copilot --model gpt-6-astra
148+zot --provider github-copilot --model gpt-6-sol
149149 ```
150150
151-Astra uses the Responses API and supports `low`, `medium`, `high`, `xhigh`,
152-and `max` reasoning. OpenAI API-key and Codex subscription entries use the
153-272,000-token short-context tier by default; the Copilot entry uses a
154-1,050,000-token context window. All entries include the 128,000-token output
155-limit and standard token prices, including the higher rates for prompts above
156-272,000 tokens. Subscription access depends on your
157-plan, rollout, and organization policy; catalog availability does not grant access.
158-See the [OpenAI model specifications](https://developers.openai.com/api/docs/models/gpt-6-astra)
159-and [GitHub Copilot availability](https://github.blog/changelog/2026-09-04-gpt-6-astra-is-generally-available-in-github-copilot/).
151+All three use the Responses API, accept image input, support `low`, `medium`,
152+`high`, `xhigh`, and `max` reasoning, and allow up to 128,000 output tokens.
153+OpenAI API-key and Codex subscription entries use a 272,000-token context
154+window. Copilot uses 1,050,000 tokens for Astra and 1,000,000 tokens for Sol
155+and Luna. Standard per-million-token prices are $10 input and $50 output for
156+Astra, $2 input and $10 output for Sol, and $0.10 input and $0.50 output for
157+Luna. Prompts above 272,000 tokens use each model's long-context price tier.
158+Subscription access depends on your plan, rollout, and organization policy.
159+Catalog availability does not grant access.
160160
161161 ## API-key providers
162162
@@ -114,10 +114,10 @@ use Chat Completions without `reasoning_effort`; their reasoning is managed by t
114 endpoint. All three routes send user/agent initiator metadata and image-request114 endpoint. All three routes send user/agent initiator metadata and image-request
115 headers where appropriate.115 headers where appropriate.
116 116
117-As of September 8, 2026, the catalog includes 27 public chat models: Claude117+As of September 22, 2026, the catalog includes 30 public chat models: Claude
118-Fable 5/5.1, Haiku 4.5, Opus 4.7/4.8/4.8 Fast/5, Sonnet 5, Gemini118+Fable 5/5.1, Haiku 4.5, Opus 4.7/4.8/4.8 Fast/5/5.5, Sonnet 5, Gemini
119 3.5/3.6/3.7/3.8 Flash, GPT-5 mini, GPT-5.3-Codex, GPT-5.4/5.4 mini/5.5,119 3.5/3.6/3.7/3.8 Flash, GPT-5 mini, GPT-5.3-Codex, GPT-5.4/5.4 mini/5.5,
120-GPT-5.6 Luna/Sol/Terra, GPT-6 Astra, Grok 4.5/4.6, Kimi K2.7 Code/K3,120+GPT-5.6 Luna/Sol/Terra, GPT-6 Astra/Luna/Sol, Grok 4.5/4.6, Kimi K2.7 Code/K3,
121 and MAI-Code-1-Flash/1.1-Flash. MAI-Code-1-Flash uses the public picker ID121 and MAI-Code-1-Flash/1.1-Flash. MAI-Code-1-Flash uses the public picker ID
122 `mai-code-1-flash-picker` and is scheduled to retire on September 10, 2026.122 `mai-code-1-flash-picker` and is scheduled to retire on September 10, 2026.
123 123
@@ -139,24 +139,24 @@ September 1, 2026, except for individual annual Copilot Pro and Pro+ subscribers
139 Eligible subscribers can add it through `$ZOT_HOME/models.json`.139 Eligible subscribers can add it through `$ZOT_HOME/models.json`.
140 See [GitHub's model retirement history and plan exceptions](https://docs.github.com/en/copilot/reference/ai-models/supported-models#model-retirement-history).140 See [GitHub's model retirement history and plan exceptions](https://docs.github.com/en/copilot/reference/ai-models/supported-models#model-retirement-history).
141 141
142-## GPT-6 Astra142+## GPT-6 models
143 143
144-Select `gpt-6-astra` with provider `openai`, `openai-responses`,144+Select `gpt-6-astra`, `gpt-6-sol`, or `gpt-6-luna` with provider `openai`,
145-`openai-codex`, or `github-copilot`, for example:145+`openai-responses`, `openai-codex`, or `github-copilot`, for example:
146 146
147 ```bash147 ```bash
148-zot --provider github-copilot --model gpt-6-astra148+zot --provider github-copilot --model gpt-6-sol
149 ```149 ```
150 150
151-Astra uses the Responses API and supports `low`, `medium`, `high`, `xhigh`,151+All three use the Responses API, accept image input, support `low`, `medium`,
152-and `max` reasoning. OpenAI API-key and Codex subscription entries use the152+`high`, `xhigh`, and `max` reasoning, and allow up to 128,000 output tokens.
153-272,000-token short-context tier by default; the Copilot entry uses a153+OpenAI API-key and Codex subscription entries use a 272,000-token context
154-1,050,000-token context window. All entries include the 128,000-token output154+window. Copilot uses 1,050,000 tokens for Astra and 1,000,000 tokens for Sol
155-limit and standard token prices, including the higher rates for prompts above155+and Luna. Standard per-million-token prices are $10 input and $50 output for
156-272,000 tokens. Subscription access depends on your156+Astra, $2 input and $10 output for Sol, and $0.10 input and $0.50 output for
157-plan, rollout, and organization policy; catalog availability does not grant access.157+Luna. Prompts above 272,000 tokens use each model's long-context price tier.
158-See the [OpenAI model specifications](https://developers.openai.com/api/docs/models/gpt-6-astra)158+Subscription access depends on your plan, rollout, and organization policy.
159-and [GitHub Copilot availability](https://github.blog/changelog/2026-09-04-gpt-6-astra-is-generally-available-in-github-copilot/).159+Catalog availability does not grant access.
160 160
161 ## API-key providers161 ## API-key providers
162 162
M packages/provider/catalog_builtin.go +3 -1
@@ -146,7 +146,7 @@ var builtinCatalog = []Model{
146146 {Provider: "fireworks", ID: "accounts/fireworks/routers/glm-5p1-fast", DisplayName: "GLM 5.1 Fast", ContextWindow: 202800, MaxOutput: 131072, Reasoning: true, PriceInput: 2.8, PriceOutput: 8.8, PriceCacheRead: 0.52, BaseURL: "https://api.fireworks.ai/inference"},
147147 {Provider: "fireworks", ID: "accounts/fireworks/routers/kimi-k2p6-turbo", DisplayName: "Kimi K2.6 Turbo", ContextWindow: 262000, MaxOutput: 262000, Reasoning: true, PriceInput: 2, PriceOutput: 8, PriceCacheRead: 0.3, BaseURL: "https://api.fireworks.ai/inference"},
148148 // ----- github-copilot -----
149- // Public chat models checked against GitHub's supported-model list on 2026-09-08.
149+ // Public chat models checked against GitHub's supported-model list on 2026-09-22.
150150 // New model limits and token prices: https://models.dev/api.json (github-copilot).
151151 // Copilot's fast Opus model ID comes from the inference API's available-model list.
152152 {Provider: "github-copilot", ID: "claude-fable-5", DisplayName: "Claude Fable 5", ContextWindow: 1000000, MaxOutput: 128000, Reasoning: true, AdaptiveThinking: true, PriceInput: 10, PriceOutput: 50, PriceCacheRead: 1, PriceCacheWrite: 12.5, BaseURL: "https://api.individual.githubcopilot.com"},
@@ -178,6 +178,8 @@ var builtinCatalog = []Model{
178178 {Provider: "github-copilot", ID: "gpt-5.6-terra", DisplayName: "GPT-5.6 Terra", API: APIResponses, ContextWindow: 400000, MaxOutput: 128000, Reasoning: true, PriceInput: 0, PriceOutput: 0, PriceCacheRead: 0, BaseURL: "https://api.individual.githubcopilot.com"},
179179 {Provider: "github-copilot", ID: "gpt-5.6-luna", DisplayName: "GPT-5.6 Luna", API: APIResponses, ContextWindow: 400000, MaxOutput: 128000, Reasoning: true, PriceInput: 0, PriceOutput: 0, PriceCacheRead: 0, BaseURL: "https://api.individual.githubcopilot.com"},
180180 {Provider: "github-copilot", ID: "gpt-6-astra", DisplayName: "GPT-6 Astra", API: APIResponses, ContextWindow: 1050000, MaxOutput: 128000, Reasoning: true, PriceInput: 10, PriceOutput: 50, PriceCacheRead: 1, PriceCacheWrite: 12.5, PriceTierInputTokens: 272000, PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25, BaseURL: "https://api.individual.githubcopilot.com"},
181+ {Provider: "github-copilot", ID: "gpt-6-sol", DisplayName: "GPT-6 Sol", API: APIResponses, ContextWindow: 1000000, MaxOutput: 128000, Reasoning: true, PriceInput: 2, PriceOutput: 10, PriceCacheRead: 0.2, PriceCacheWrite: 2.5, PriceTierInputTokens: 272000, PriceInputAbove: 4, PriceOutputAbove: 15, PriceCacheReadAbove: 0.4, PriceCacheWriteAbove: 5, BaseURL: "https://api.individual.githubcopilot.com"},
182+ {Provider: "github-copilot", ID: "gpt-6-luna", DisplayName: "GPT-6 Luna", API: APIResponses, ContextWindow: 1000000, MaxOutput: 128000, Reasoning: true, PriceInput: 0.1, PriceOutput: 0.5, PriceCacheRead: 0.01, PriceCacheWrite: 0.125, PriceTierInputTokens: 272000, PriceInputAbove: 0.2, PriceOutputAbove: 0.75, PriceCacheReadAbove: 0.02, PriceCacheWriteAbove: 0.25, BaseURL: "https://api.individual.githubcopilot.com"},
181183 // ----- google -----
182184 {Provider: "google", ID: "gemini-3-flash-preview", DisplayName: "Gemini 3 Flash Preview", ContextWindow: 1048576, MaxOutput: 65536, Reasoning: true, PriceInput: 0.5, PriceOutput: 3, PriceCacheRead: 0.05, BaseURL: "https://generativelanguage.googleapis.com/v1beta"},
183185 {Provider: "google", ID: "gemini-3-pro-preview", DisplayName: "Gemini 3 Pro Preview", ContextWindow: 1048576, MaxOutput: 65536, Reasoning: true, PriceInput: 2, PriceOutput: 12, PriceCacheRead: 0.2, BaseURL: "https://generativelanguage.googleapis.com/v1beta"},
@@ -146,7 +146,7 @@ var builtinCatalog = []Model{
146 {Provider: "fireworks", ID: "accounts/fireworks/routers/glm-5p1-fast", DisplayName: "GLM 5.1 Fast", ContextWindow: 202800, MaxOutput: 131072, Reasoning: true, PriceInput: 2.8, PriceOutput: 8.8, PriceCacheRead: 0.52, BaseURL: "https://api.fireworks.ai/inference"},146 {Provider: "fireworks", ID: "accounts/fireworks/routers/glm-5p1-fast", DisplayName: "GLM 5.1 Fast", ContextWindow: 202800, MaxOutput: 131072, Reasoning: true, PriceInput: 2.8, PriceOutput: 8.8, PriceCacheRead: 0.52, BaseURL: "https://api.fireworks.ai/inference"},
147 {Provider: "fireworks", ID: "accounts/fireworks/routers/kimi-k2p6-turbo", DisplayName: "Kimi K2.6 Turbo", ContextWindow: 262000, MaxOutput: 262000, Reasoning: true, PriceInput: 2, PriceOutput: 8, PriceCacheRead: 0.3, BaseURL: "https://api.fireworks.ai/inference"},147 {Provider: "fireworks", ID: "accounts/fireworks/routers/kimi-k2p6-turbo", DisplayName: "Kimi K2.6 Turbo", ContextWindow: 262000, MaxOutput: 262000, Reasoning: true, PriceInput: 2, PriceOutput: 8, PriceCacheRead: 0.3, BaseURL: "https://api.fireworks.ai/inference"},
148 // ----- github-copilot -----148 // ----- github-copilot -----
149- // Public chat models checked against GitHub's supported-model list on 2026-09-08.149+ // Public chat models checked against GitHub's supported-model list on 2026-09-22.
150 // New model limits and token prices: https://models.dev/api.json (github-copilot).150 // New model limits and token prices: https://models.dev/api.json (github-copilot).
151 // Copilot's fast Opus model ID comes from the inference API's available-model list.151 // Copilot's fast Opus model ID comes from the inference API's available-model list.
152 {Provider: "github-copilot", ID: "claude-fable-5", DisplayName: "Claude Fable 5", ContextWindow: 1000000, MaxOutput: 128000, Reasoning: true, AdaptiveThinking: true, PriceInput: 10, PriceOutput: 50, PriceCacheRead: 1, PriceCacheWrite: 12.5, BaseURL: "https://api.individual.githubcopilot.com"},152 {Provider: "github-copilot", ID: "claude-fable-5", DisplayName: "Claude Fable 5", ContextWindow: 1000000, MaxOutput: 128000, Reasoning: true, AdaptiveThinking: true, PriceInput: 10, PriceOutput: 50, PriceCacheRead: 1, PriceCacheWrite: 12.5, BaseURL: "https://api.individual.githubcopilot.com"},
@@ -178,6 +178,8 @@ var builtinCatalog = []Model{
178 {Provider: "github-copilot", ID: "gpt-5.6-terra", DisplayName: "GPT-5.6 Terra", API: APIResponses, ContextWindow: 400000, MaxOutput: 128000, Reasoning: true, PriceInput: 0, PriceOutput: 0, PriceCacheRead: 0, BaseURL: "https://api.individual.githubcopilot.com"},178 {Provider: "github-copilot", ID: "gpt-5.6-terra", DisplayName: "GPT-5.6 Terra", API: APIResponses, ContextWindow: 400000, MaxOutput: 128000, Reasoning: true, PriceInput: 0, PriceOutput: 0, PriceCacheRead: 0, BaseURL: "https://api.individual.githubcopilot.com"},
179 {Provider: "github-copilot", ID: "gpt-5.6-luna", DisplayName: "GPT-5.6 Luna", API: APIResponses, ContextWindow: 400000, MaxOutput: 128000, Reasoning: true, PriceInput: 0, PriceOutput: 0, PriceCacheRead: 0, BaseURL: "https://api.individual.githubcopilot.com"},179 {Provider: "github-copilot", ID: "gpt-5.6-luna", DisplayName: "GPT-5.6 Luna", API: APIResponses, ContextWindow: 400000, MaxOutput: 128000, Reasoning: true, PriceInput: 0, PriceOutput: 0, PriceCacheRead: 0, BaseURL: "https://api.individual.githubcopilot.com"},
180 {Provider: "github-copilot", ID: "gpt-6-astra", DisplayName: "GPT-6 Astra", API: APIResponses, ContextWindow: 1050000, MaxOutput: 128000, Reasoning: true, PriceInput: 10, PriceOutput: 50, PriceCacheRead: 1, PriceCacheWrite: 12.5, PriceTierInputTokens: 272000, PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25, BaseURL: "https://api.individual.githubcopilot.com"},180 {Provider: "github-copilot", ID: "gpt-6-astra", DisplayName: "GPT-6 Astra", API: APIResponses, ContextWindow: 1050000, MaxOutput: 128000, Reasoning: true, PriceInput: 10, PriceOutput: 50, PriceCacheRead: 1, PriceCacheWrite: 12.5, PriceTierInputTokens: 272000, PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25, BaseURL: "https://api.individual.githubcopilot.com"},
181+ {Provider: "github-copilot", ID: "gpt-6-sol", DisplayName: "GPT-6 Sol", API: APIResponses, ContextWindow: 1000000, MaxOutput: 128000, Reasoning: true, PriceInput: 2, PriceOutput: 10, PriceCacheRead: 0.2, PriceCacheWrite: 2.5, PriceTierInputTokens: 272000, PriceInputAbove: 4, PriceOutputAbove: 15, PriceCacheReadAbove: 0.4, PriceCacheWriteAbove: 5, BaseURL: "https://api.individual.githubcopilot.com"},
182+ {Provider: "github-copilot", ID: "gpt-6-luna", DisplayName: "GPT-6 Luna", API: APIResponses, ContextWindow: 1000000, MaxOutput: 128000, Reasoning: true, PriceInput: 0.1, PriceOutput: 0.5, PriceCacheRead: 0.01, PriceCacheWrite: 0.125, PriceTierInputTokens: 272000, PriceInputAbove: 0.2, PriceOutputAbove: 0.75, PriceCacheReadAbove: 0.02, PriceCacheWriteAbove: 0.25, BaseURL: "https://api.individual.githubcopilot.com"},
181 // ----- google -----183 // ----- google -----
182 {Provider: "google", ID: "gemini-3-flash-preview", DisplayName: "Gemini 3 Flash Preview", ContextWindow: 1048576, MaxOutput: 65536, Reasoning: true, PriceInput: 0.5, PriceOutput: 3, PriceCacheRead: 0.05, BaseURL: "https://generativelanguage.googleapis.com/v1beta"},184 {Provider: "google", ID: "gemini-3-flash-preview", DisplayName: "Gemini 3 Flash Preview", ContextWindow: 1048576, MaxOutput: 65536, Reasoning: true, PriceInput: 0.5, PriceOutput: 3, PriceCacheRead: 0.05, BaseURL: "https://generativelanguage.googleapis.com/v1beta"},
183 {Provider: "google", ID: "gemini-3-pro-preview", DisplayName: "Gemini 3 Pro Preview", ContextWindow: 1048576, MaxOutput: 65536, Reasoning: true, PriceInput: 2, PriceOutput: 12, PriceCacheRead: 0.2, BaseURL: "https://generativelanguage.googleapis.com/v1beta"},185 {Provider: "google", ID: "gemini-3-pro-preview", DisplayName: "Gemini 3 Pro Preview", ContextWindow: 1048576, MaxOutput: 65536, Reasoning: true, PriceInput: 2, PriceOutput: 12, PriceCacheRead: 0.2, BaseURL: "https://generativelanguage.googleapis.com/v1beta"},
M packages/provider/copilot_catalog_test.go +1 -1
@@ -8,7 +8,7 @@ import (
88 func TestCopilotCatalogCoversPublicChatModels(t *testing.T) {
99 groups := map[string][]string{
1010 APIAnthropicMessages: {"claude-fable-5", "claude-fable-5.1", "claude-haiku-4.5", "claude-opus-4.7", "claude-opus-4.8", "claude-opus-4.8-fast", "claude-opus-5", "claude-opus-5.5", "claude-sonnet-5"},
11- APIResponses: {"gpt-5-mini", "gpt-5.3-codex", "gpt-5.4", "gpt-5.4-mini", "gpt-5.5", "gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-6-astra", "grok-4.5", "grok-4.6", "mai-code-1-flash-picker", "mai-code-1.1-flash"},
11+ APIResponses: {"gpt-5-mini", "gpt-5.3-codex", "gpt-5.4", "gpt-5.4-mini", "gpt-5.5", "gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-6-astra", "gpt-6-luna", "gpt-6-sol", "grok-4.5", "grok-4.6", "mai-code-1-flash-picker", "mai-code-1.1-flash"},
1212 APICompletions: {"gemini-3.5-flash", "gemini-3.6-flash", "gemini-3.7-flash", "gemini-3.8-flash", "kimi-k2.7-code", "kimi-k3"},
1313 }
1414 for api, ids := range groups {
@@ -8,7 +8,7 @@ import (
8 func TestCopilotCatalogCoversPublicChatModels(t *testing.T) {8 func TestCopilotCatalogCoversPublicChatModels(t *testing.T) {
9 groups := map[string][]string{9 groups := map[string][]string{
10 APIAnthropicMessages: {"claude-fable-5", "claude-fable-5.1", "claude-haiku-4.5", "claude-opus-4.7", "claude-opus-4.8", "claude-opus-4.8-fast", "claude-opus-5", "claude-opus-5.5", "claude-sonnet-5"},10 APIAnthropicMessages: {"claude-fable-5", "claude-fable-5.1", "claude-haiku-4.5", "claude-opus-4.7", "claude-opus-4.8", "claude-opus-4.8-fast", "claude-opus-5", "claude-opus-5.5", "claude-sonnet-5"},
11- APIResponses: {"gpt-5-mini", "gpt-5.3-codex", "gpt-5.4", "gpt-5.4-mini", "gpt-5.5", "gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-6-astra", "grok-4.5", "grok-4.6", "mai-code-1-flash-picker", "mai-code-1.1-flash"},11+ APIResponses: {"gpt-5-mini", "gpt-5.3-codex", "gpt-5.4", "gpt-5.4-mini", "gpt-5.5", "gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-6-astra", "gpt-6-luna", "gpt-6-sol", "grok-4.5", "grok-4.6", "mai-code-1-flash-picker", "mai-code-1.1-flash"},
12 APICompletions: {"gemini-3.5-flash", "gemini-3.6-flash", "gemini-3.7-flash", "gemini-3.8-flash", "kimi-k2.7-code", "kimi-k3"},12 APICompletions: {"gemini-3.5-flash", "gemini-3.6-flash", "gemini-3.7-flash", "gemini-3.8-flash", "kimi-k2.7-code", "kimi-k3"},
13 }13 }
14 for api, ids := range groups {14 for api, ids := range groups {
M packages/provider/discover_copilot_test.go +1 -1
@@ -97,7 +97,7 @@ func TestModelAvailabilityFiltersWithoutDeletingCatalog(t *testing.T) {
9797 t.Error("empty availability did not hide models")
9898 }
9999 SetModelAvailability("github-copilot", nil)
100- if len(ModelsForProvider("github-copilot")) != 28 {
100+ if len(ModelsForProvider("github-copilot")) != 30 {
101101 t.Error("clearing restriction did not restore catalog")
102102 }
103103 }
@@ -97,7 +97,7 @@ func TestModelAvailabilityFiltersWithoutDeletingCatalog(t *testing.T) {
97 t.Error("empty availability did not hide models")97 t.Error("empty availability did not hide models")
98 }98 }
99 SetModelAvailability("github-copilot", nil)99 SetModelAvailability("github-copilot", nil)
100- if len(ModelsForProvider("github-copilot")) != 28 {100+ if len(ModelsForProvider("github-copilot")) != 30 {
101 t.Error("clearing restriction did not restore catalog")101 t.Error("clearing restriction did not restore catalog")
102 }102 }
103 }103 }
M packages/provider/extra_models.go +10 -0
@@ -53,6 +53,16 @@ var supplementCatalog = []Model{
5353 PriceInput: 10, PriceOutput: 50, PriceCacheRead: 1, PriceCacheWrite: 12.5,
5454 PriceTierInputTokens: 272000,
5555 PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25},
56+ {Provider: "openai-responses", ID: "gpt-6-sol", DisplayName: "GPT-6 Sol (Responses)", API: APIResponses,
57+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
58+ PriceInput: 2, PriceOutput: 10, PriceCacheRead: 0.2, PriceCacheWrite: 2.5,
59+ PriceTierInputTokens: 272000,
60+ PriceInputAbove: 4, PriceOutputAbove: 15, PriceCacheReadAbove: 0.4, PriceCacheWriteAbove: 5},
61+ {Provider: "openai-responses", ID: "gpt-6-luna", DisplayName: "GPT-6 Luna (Responses)", API: APIResponses,
62+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
63+ PriceInput: 0.1, PriceOutput: 0.5, PriceCacheRead: 0.01, PriceCacheWrite: 0.125,
64+ PriceTierInputTokens: 272000,
65+ PriceInputAbove: 0.2, PriceOutputAbove: 0.75, PriceCacheReadAbove: 0.02, PriceCacheWriteAbove: 0.25},
5666 {Provider: "openai-responses", ID: "gpt-5", DisplayName: "GPT-5 (Responses)",
5767 ContextWindow: 400000, MaxOutput: 128000, Reasoning: true,
5868 PriceInput: 1.25, PriceOutput: 10.00, PriceCacheRead: 0.125},
@@ -53,6 +53,16 @@ var supplementCatalog = []Model{
53 PriceInput: 10, PriceOutput: 50, PriceCacheRead: 1, PriceCacheWrite: 12.5,53 PriceInput: 10, PriceOutput: 50, PriceCacheRead: 1, PriceCacheWrite: 12.5,
54 PriceTierInputTokens: 272000,54 PriceTierInputTokens: 272000,
55 PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25},55 PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25},
56+ {Provider: "openai-responses", ID: "gpt-6-sol", DisplayName: "GPT-6 Sol (Responses)", API: APIResponses,
57+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
58+ PriceInput: 2, PriceOutput: 10, PriceCacheRead: 0.2, PriceCacheWrite: 2.5,
59+ PriceTierInputTokens: 272000,
60+ PriceInputAbove: 4, PriceOutputAbove: 15, PriceCacheReadAbove: 0.4, PriceCacheWriteAbove: 5},
61+ {Provider: "openai-responses", ID: "gpt-6-luna", DisplayName: "GPT-6 Luna (Responses)", API: APIResponses,
62+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
63+ PriceInput: 0.1, PriceOutput: 0.5, PriceCacheRead: 0.01, PriceCacheWrite: 0.125,
64+ PriceTierInputTokens: 272000,
65+ PriceInputAbove: 0.2, PriceOutputAbove: 0.75, PriceCacheReadAbove: 0.02, PriceCacheWriteAbove: 0.25},
56 {Provider: "openai-responses", ID: "gpt-5", DisplayName: "GPT-5 (Responses)",66 {Provider: "openai-responses", ID: "gpt-5", DisplayName: "GPT-5 (Responses)",
57 ContextWindow: 400000, MaxOutput: 128000, Reasoning: true,67 ContextWindow: 400000, MaxOutput: 128000, Reasoning: true,
58 PriceInput: 1.25, PriceOutput: 10.00, PriceCacheRead: 0.125},68 PriceInput: 1.25, PriceOutput: 10.00, PriceCacheRead: 0.125},
M packages/provider/gpt6_astra_test.go +87 -0
@@ -6,6 +6,93 @@ import (
66 "testing"
77 )
88
9+func TestGPT6SolAndLunaCatalog(t *testing.T) {
10+ models := []struct {
11+ id string
12+ input float64
13+ output float64
14+ cacheRead float64
15+ cacheWrite float64
16+ inputAbove float64
17+ outAbove float64
18+ readAbove float64
19+ writeAbove float64
20+ }{
21+ {"gpt-6-sol", 2, 10, 0.2, 2.5, 4, 15, 0.4, 5},
22+ {"gpt-6-luna", 0.1, 0.5, 0.01, 0.125, 0.2, 0.75, 0.02, 0.25},
23+ }
24+ for _, model := range models {
25+ for _, name := range []string{"openai", "openai-responses", "openai-codex", "github-copilot"} {
26+ t.Run(name+"/"+model.id, func(t *testing.T) {
27+ m, err := FindModel(name, model.id)
28+ if err != nil {
29+ t.Fatal(err)
30+ }
31+ wantContext := 272000
32+ if name == "github-copilot" {
33+ wantContext = 1000000
34+ }
35+ if m.API != APIResponses || m.ContextWindow != wantContext || m.MaxOutput != 128000 || !m.Reasoning || m.Speculative {
36+ t.Fatalf("unexpected model capabilities: %+v", m)
37+ }
38+ if m.PriceInput != model.input || m.PriceOutput != model.output || m.PriceCacheRead != model.cacheRead || m.PriceCacheWrite != model.cacheWrite {
39+ t.Fatalf("unexpected standard prices: %+v", m)
40+ }
41+ if m.PriceTierInputTokens != 272000 || m.PriceInputAbove != model.inputAbove || m.PriceOutputAbove != model.outAbove || m.PriceCacheReadAbove != model.readAbove || m.PriceCacheWriteAbove != model.writeAbove {
42+ t.Fatalf("unexpected long-context prices: %+v", m)
43+ }
44+ wantLevels := []string{"", "low", "medium", "high", "xhigh", "max"}
45+ if got := AvailableReasoningLevels(m); !slices.Equal(got, wantLevels) {
46+ t.Fatalf("reasoning levels = %q, want %q", got, wantLevels)
47+ }
48+ })
49+ }
50+ }
51+}
52+
53+func TestGPT6SolAndLunaResponsesReasoning(t *testing.T) {
54+ copilot := NewGithubCopilotClient("test-token").(*copilotClient).router
55+ clients := map[string]*codexClient{
56+ "openai": NewOpenAIResponsesNamed("test-token", "", "openai").(*renamedClient).inner.(*codexClient),
57+ "openai-responses": NewOpenAIResponsesNamed("test-token", "", "openai-responses").(*renamedClient).inner.(*codexClient),
58+ "openai-codex": NewOpenAICodex("test-token", "test-account", "").(*codexClient),
59+ "github-copilot": copilot.byAPI[APIResponses].(*codexClient),
60+ }
61+ for name, client := range clients {
62+ for _, model := range []string{"gpt-6-sol", "gpt-6-luna"} {
63+ t.Run(name+"/"+model, func(t *testing.T) {
64+ wire, err := client.buildRequest(Request{Model: model, Reasoning: "max"})
65+ if err != nil {
66+ t.Fatal(err)
67+ }
68+ if wire.Model != model || wire.Reasoning == nil || wire.Reasoning.Effort != "max" {
69+ t.Fatalf("unexpected request: %+v", wire)
70+ }
71+ })
72+ }
73+ }
74+}
75+
76+func TestGPT6SolAndLunaCopilotDispatch(t *testing.T) {
77+ router := NewGithubCopilotClient("test-token").(*copilotClient).router
78+ completions := &routeCaptureClient{name: "github-copilot"}
79+ responses := &routeCaptureClient{name: "github-copilot"}
80+ router.fallback = completions
81+ router.byAPI[APIResponses] = responses
82+
83+ for _, model := range []string{"gpt-6-sol", "gpt-6-luna"} {
84+ stream, err := router.Stream(context.Background(), Request{Model: model})
85+ if err != nil {
86+ t.Fatal(err)
87+ }
88+ for range stream {
89+ }
90+ }
91+ if !slices.Equal(responses.models, []string{"gpt-6-sol", "gpt-6-luna"}) || len(completions.models) != 0 {
92+ t.Fatalf("Responses models = %v, Completions models = %v", responses.models, completions.models)
93+ }
94+}
95+
996 func TestGPT6AstraCatalog(t *testing.T) {
1097 for _, name := range []string{"openai", "openai-responses", "openai-codex", "github-copilot"} {
1198 t.Run(name, func(t *testing.T) {
@@ -6,6 +6,93 @@ import (
6 "testing"6 "testing"
7 )7 )
8 8
9+func TestGPT6SolAndLunaCatalog(t *testing.T) {
10+ models := []struct {
11+ id string
12+ input float64
13+ output float64
14+ cacheRead float64
15+ cacheWrite float64
16+ inputAbove float64
17+ outAbove float64
18+ readAbove float64
19+ writeAbove float64
20+ }{
21+ {"gpt-6-sol", 2, 10, 0.2, 2.5, 4, 15, 0.4, 5},
22+ {"gpt-6-luna", 0.1, 0.5, 0.01, 0.125, 0.2, 0.75, 0.02, 0.25},
23+ }
24+ for _, model := range models {
25+ for _, name := range []string{"openai", "openai-responses", "openai-codex", "github-copilot"} {
26+ t.Run(name+"/"+model.id, func(t *testing.T) {
27+ m, err := FindModel(name, model.id)
28+ if err != nil {
29+ t.Fatal(err)
30+ }
31+ wantContext := 272000
32+ if name == "github-copilot" {
33+ wantContext = 1000000
34+ }
35+ if m.API != APIResponses || m.ContextWindow != wantContext || m.MaxOutput != 128000 || !m.Reasoning || m.Speculative {
36+ t.Fatalf("unexpected model capabilities: %+v", m)
37+ }
38+ if m.PriceInput != model.input || m.PriceOutput != model.output || m.PriceCacheRead != model.cacheRead || m.PriceCacheWrite != model.cacheWrite {
39+ t.Fatalf("unexpected standard prices: %+v", m)
40+ }
41+ if m.PriceTierInputTokens != 272000 || m.PriceInputAbove != model.inputAbove || m.PriceOutputAbove != model.outAbove || m.PriceCacheReadAbove != model.readAbove || m.PriceCacheWriteAbove != model.writeAbove {
42+ t.Fatalf("unexpected long-context prices: %+v", m)
43+ }
44+ wantLevels := []string{"", "low", "medium", "high", "xhigh", "max"}
45+ if got := AvailableReasoningLevels(m); !slices.Equal(got, wantLevels) {
46+ t.Fatalf("reasoning levels = %q, want %q", got, wantLevels)
47+ }
48+ })
49+ }
50+ }
51+}
52+
53+func TestGPT6SolAndLunaResponsesReasoning(t *testing.T) {
54+ copilot := NewGithubCopilotClient("test-token").(*copilotClient).router
55+ clients := map[string]*codexClient{
56+ "openai": NewOpenAIResponsesNamed("test-token", "", "openai").(*renamedClient).inner.(*codexClient),
57+ "openai-responses": NewOpenAIResponsesNamed("test-token", "", "openai-responses").(*renamedClient).inner.(*codexClient),
58+ "openai-codex": NewOpenAICodex("test-token", "test-account", "").(*codexClient),
59+ "github-copilot": copilot.byAPI[APIResponses].(*codexClient),
60+ }
61+ for name, client := range clients {
62+ for _, model := range []string{"gpt-6-sol", "gpt-6-luna"} {
63+ t.Run(name+"/"+model, func(t *testing.T) {
64+ wire, err := client.buildRequest(Request{Model: model, Reasoning: "max"})
65+ if err != nil {
66+ t.Fatal(err)
67+ }
68+ if wire.Model != model || wire.Reasoning == nil || wire.Reasoning.Effort != "max" {
69+ t.Fatalf("unexpected request: %+v", wire)
70+ }
71+ })
72+ }
73+ }
74+}
75+
76+func TestGPT6SolAndLunaCopilotDispatch(t *testing.T) {
77+ router := NewGithubCopilotClient("test-token").(*copilotClient).router
78+ completions := &routeCaptureClient{name: "github-copilot"}
79+ responses := &routeCaptureClient{name: "github-copilot"}
80+ router.fallback = completions
81+ router.byAPI[APIResponses] = responses
82+
83+ for _, model := range []string{"gpt-6-sol", "gpt-6-luna"} {
84+ stream, err := router.Stream(context.Background(), Request{Model: model})
85+ if err != nil {
86+ t.Fatal(err)
87+ }
88+ for range stream {
89+ }
90+ }
91+ if !slices.Equal(responses.models, []string{"gpt-6-sol", "gpt-6-luna"}) || len(completions.models) != 0 {
92+ t.Fatalf("Responses models = %v, Completions models = %v", responses.models, completions.models)
93+ }
94+}
95+
9 func TestGPT6AstraCatalog(t *testing.T) {96 func TestGPT6AstraCatalog(t *testing.T) {
10 for _, name := range []string{"openai", "openai-responses", "openai-codex", "github-copilot"} {97 for _, name := range []string{"openai", "openai-responses", "openai-codex", "github-copilot"} {
11 t.Run(name, func(t *testing.T) {98 t.Run(name, func(t *testing.T) {
M packages/provider/models.go +28 -0
@@ -415,6 +415,20 @@ var Catalog = []Model{
415415 PriceTierInputTokens: 272000,
416416 PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25,
417417 },
418+ {
419+ Provider: "openai", ID: "gpt-6-sol", DisplayName: "GPT-6 Sol", API: APIResponses,
420+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
421+ PriceInput: 2, PriceOutput: 10, PriceCacheRead: 0.2, PriceCacheWrite: 2.5,
422+ PriceTierInputTokens: 272000,
423+ PriceInputAbove: 4, PriceOutputAbove: 15, PriceCacheReadAbove: 0.4, PriceCacheWriteAbove: 5,
424+ },
425+ {
426+ Provider: "openai", ID: "gpt-6-luna", DisplayName: "GPT-6 Luna", API: APIResponses,
427+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
428+ PriceInput: 0.1, PriceOutput: 0.5, PriceCacheRead: 0.01, PriceCacheWrite: 0.125,
429+ PriceTierInputTokens: 272000,
430+ PriceInputAbove: 0.2, PriceOutputAbove: 0.75, PriceCacheReadAbove: 0.02, PriceCacheWriteAbove: 0.25,
431+ },
418432
419433 // ---- OpenAI Codex / ChatGPT subscription backend ----
420434 // Same model ids as the OpenAI family, but routed through the
@@ -468,6 +482,20 @@ var Catalog = []Model{
468482 PriceTierInputTokens: 272000,
469483 PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25,
470484 },
485+ {
486+ Provider: "openai-codex", ID: "gpt-6-sol", DisplayName: "GPT-6 Sol", API: APIResponses,
487+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
488+ PriceInput: 2, PriceOutput: 10, PriceCacheRead: 0.2, PriceCacheWrite: 2.5,
489+ PriceTierInputTokens: 272000,
490+ PriceInputAbove: 4, PriceOutputAbove: 15, PriceCacheReadAbove: 0.4, PriceCacheWriteAbove: 5,
491+ },
492+ {
493+ Provider: "openai-codex", ID: "gpt-6-luna", DisplayName: "GPT-6 Luna", API: APIResponses,
494+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
495+ PriceInput: 0.1, PriceOutput: 0.5, PriceCacheRead: 0.01, PriceCacheWrite: 0.125,
496+ PriceTierInputTokens: 272000,
497+ PriceInputAbove: 0.2, PriceOutputAbove: 0.75, PriceCacheReadAbove: 0.02, PriceCacheWriteAbove: 0.25,
498+ },
471499 }
472500
473501 // DefaultModel is used when the user does not specify one.
@@ -415,6 +415,20 @@ var Catalog = []Model{
415 PriceTierInputTokens: 272000,415 PriceTierInputTokens: 272000,
416 PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25,416 PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25,
417 },417 },
418+ {
419+ Provider: "openai", ID: "gpt-6-sol", DisplayName: "GPT-6 Sol", API: APIResponses,
420+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
421+ PriceInput: 2, PriceOutput: 10, PriceCacheRead: 0.2, PriceCacheWrite: 2.5,
422+ PriceTierInputTokens: 272000,
423+ PriceInputAbove: 4, PriceOutputAbove: 15, PriceCacheReadAbove: 0.4, PriceCacheWriteAbove: 5,
424+ },
425+ {
426+ Provider: "openai", ID: "gpt-6-luna", DisplayName: "GPT-6 Luna", API: APIResponses,
427+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
428+ PriceInput: 0.1, PriceOutput: 0.5, PriceCacheRead: 0.01, PriceCacheWrite: 0.125,
429+ PriceTierInputTokens: 272000,
430+ PriceInputAbove: 0.2, PriceOutputAbove: 0.75, PriceCacheReadAbove: 0.02, PriceCacheWriteAbove: 0.25,
431+ },
418 432
419 // ---- OpenAI Codex / ChatGPT subscription backend ----433 // ---- OpenAI Codex / ChatGPT subscription backend ----
420 // Same model ids as the OpenAI family, but routed through the434 // Same model ids as the OpenAI family, but routed through the
@@ -468,6 +482,20 @@ var Catalog = []Model{
468 PriceTierInputTokens: 272000,482 PriceTierInputTokens: 272000,
469 PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25,483 PriceInputAbove: 20, PriceOutputAbove: 75, PriceCacheReadAbove: 2, PriceCacheWriteAbove: 25,
470 },484 },
485+ {
486+ Provider: "openai-codex", ID: "gpt-6-sol", DisplayName: "GPT-6 Sol", API: APIResponses,
487+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
488+ PriceInput: 2, PriceOutput: 10, PriceCacheRead: 0.2, PriceCacheWrite: 2.5,
489+ PriceTierInputTokens: 272000,
490+ PriceInputAbove: 4, PriceOutputAbove: 15, PriceCacheReadAbove: 0.4, PriceCacheWriteAbove: 5,
491+ },
492+ {
493+ Provider: "openai-codex", ID: "gpt-6-luna", DisplayName: "GPT-6 Luna", API: APIResponses,
494+ ContextWindow: 272000, MaxOutput: 128000, Reasoning: true,
495+ PriceInput: 0.1, PriceOutput: 0.5, PriceCacheRead: 0.01, PriceCacheWrite: 0.125,
496+ PriceTierInputTokens: 272000,
497+ PriceInputAbove: 0.2, PriceOutputAbove: 0.75, PriceCacheReadAbove: 0.02, PriceCacheWriteAbove: 0.25,
498+ },
471 }499 }
472 500
473 // DefaultModel is used when the user does not specify one.501 // DefaultModel is used when the user does not specify one.
M packages/provider/reasoning.go +2 -2
@@ -259,7 +259,7 @@ func OpenAICompatAnthropicEffort(level string) string {
259259 }
260260
261261 // OpenAICodexReasoningEffort maps zot levels onto the Responses API effort
262-// enum. GPT-5.6 and GPT-6 Astra support native max; other models clamp max to xhigh.
262+// enum. GPT-5.6 and GPT-6 support native max; other models clamp max to xhigh.
263263 func OpenAICodexReasoningEffort(level, model string) string {
264264 switch NormalizeReasoning(level) {
265265 case "minimum", "low":
@@ -282,5 +282,5 @@ func OpenAICodexReasoningEffort(level, model string) string {
282282
283283 func supportsResponsesMaxEffort(model string) bool {
284284 id := strings.ToLower(model)
285- return strings.HasPrefix(id, "gpt-5.6-") || id == "gpt-6-astra"
285+ return strings.HasPrefix(id, "gpt-5.6-") || id == "gpt-6-astra" || id == "gpt-6-sol" || id == "gpt-6-luna"
286286 }
@@ -259,7 +259,7 @@ func OpenAICompatAnthropicEffort(level string) string {
259 }259 }
260 260
261 // OpenAICodexReasoningEffort maps zot levels onto the Responses API effort261 // OpenAICodexReasoningEffort maps zot levels onto the Responses API effort
262-// enum. GPT-5.6 and GPT-6 Astra support native max; other models clamp max to xhigh.262+// enum. GPT-5.6 and GPT-6 support native max; other models clamp max to xhigh.
263 func OpenAICodexReasoningEffort(level, model string) string {263 func OpenAICodexReasoningEffort(level, model string) string {
264 switch NormalizeReasoning(level) {264 switch NormalizeReasoning(level) {
265 case "minimum", "low":265 case "minimum", "low":
@@ -282,5 +282,5 @@ func OpenAICodexReasoningEffort(level, model string) string {
282 282
283 func supportsResponsesMaxEffort(model string) bool {283 func supportsResponsesMaxEffort(model string) bool {
284 id := strings.ToLower(model)284 id := strings.ToLower(model)
285- return strings.HasPrefix(id, "gpt-5.6-") || id == "gpt-6-astra"285+ return strings.HasPrefix(id, "gpt-5.6-") || id == "gpt-6-astra" || id == "gpt-6-sol" || id == "gpt-6-luna"
286 }286 }
M packages/provider/reasoning_test.go +4 -0
@@ -16,6 +16,8 @@ func TestAvailableReasoningLevels(t *testing.T) {
1616 {name: "responses", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-5.5"}, want: []string{"", "low", "medium", "high", "xhigh"}},
1717 {name: "responses native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-5.6-sol"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
1818 {name: "astra native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-6-astra"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
19+ {name: "sol native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-6-sol"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
20+ {name: "luna native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-6-luna"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
1921 {name: "adaptive", model: Model{Reasoning: true, AdaptiveThinking: true}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
2022 {name: "adaptive compatible", model: Model{Reasoning: true, AdaptiveThinkingCompat: true}, want: []string{"", "high"}},
2123 {name: "gemini pro", model: Model{Provider: "google", ID: "gemini-3-pro-preview", Reasoning: true}, want: []string{"", "low", "high"}},
@@ -136,6 +138,8 @@ func TestReasoningEffortMappings(t *testing.T) {
136138 {"max", "gpt-5.5", "high", "max", "xhigh", 32768, "max"},
137139 {"max", "gpt-6-astra", "high", "max", "max", 32768, "max"},
138140 {"max", "GPT-6-ASTRA", "high", "max", "max", 32768, "max"},
141+ {"max", "gpt-6-sol", "high", "max", "max", 32768, "max"},
142+ {"max", "gpt-6-luna", "high", "max", "max", 32768, "max"},
139143 {"max", "gpt-6-unknown", "high", "max", "xhigh", 32768, "max"},
140144 }
141145 for _, tc := range cases {
@@ -16,6 +16,8 @@ func TestAvailableReasoningLevels(t *testing.T) {
16 {name: "responses", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-5.5"}, want: []string{"", "low", "medium", "high", "xhigh"}},16 {name: "responses", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-5.5"}, want: []string{"", "low", "medium", "high", "xhigh"}},
17 {name: "responses native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-5.6-sol"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},17 {name: "responses native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-5.6-sol"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
18 {name: "astra native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-6-astra"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},18 {name: "astra native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-6-astra"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
19+ {name: "sol native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-6-sol"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
20+ {name: "luna native max", model: Model{Reasoning: true, API: APIResponses, ID: "gpt-6-luna"}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
19 {name: "adaptive", model: Model{Reasoning: true, AdaptiveThinking: true}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},21 {name: "adaptive", model: Model{Reasoning: true, AdaptiveThinking: true}, want: []string{"", "low", "medium", "high", "xhigh", "max"}},
20 {name: "adaptive compatible", model: Model{Reasoning: true, AdaptiveThinkingCompat: true}, want: []string{"", "high"}},22 {name: "adaptive compatible", model: Model{Reasoning: true, AdaptiveThinkingCompat: true}, want: []string{"", "high"}},
21 {name: "gemini pro", model: Model{Provider: "google", ID: "gemini-3-pro-preview", Reasoning: true}, want: []string{"", "low", "high"}},23 {name: "gemini pro", model: Model{Provider: "google", ID: "gemini-3-pro-preview", Reasoning: true}, want: []string{"", "low", "high"}},
@@ -136,6 +138,8 @@ func TestReasoningEffortMappings(t *testing.T) {
136 {"max", "gpt-5.5", "high", "max", "xhigh", 32768, "max"},138 {"max", "gpt-5.5", "high", "max", "xhigh", 32768, "max"},
137 {"max", "gpt-6-astra", "high", "max", "max", 32768, "max"},139 {"max", "gpt-6-astra", "high", "max", "max", 32768, "max"},
138 {"max", "GPT-6-ASTRA", "high", "max", "max", 32768, "max"},140 {"max", "GPT-6-ASTRA", "high", "max", "max", 32768, "max"},
141+ {"max", "gpt-6-sol", "high", "max", "max", 32768, "max"},
142+ {"max", "gpt-6-luna", "high", "max", "max", 32768, "max"},
139 {"max", "gpt-6-unknown", "high", "max", "xhigh", 32768, "max"},143 {"max", "gpt-6-unknown", "high", "max", "xhigh", 32768, "max"},
140 }144 }
141 for _, tc := range cases {145 for _, tc := range cases {

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close