chore: merge dev into v2

This commit is contained in:
Aiden Cline 2026-07-12 20:03:34 +00:00
commit 4a0868d4f2
4 changed files with 122239 additions and 66811 deletions

View file

@ -303,7 +303,13 @@ export async function CodexAuthPlugin(input: PluginInput, options: CodexAuthPlug
input: 272_000,
output: 128_000,
}
: model.limit,
: model.id.includes("gpt-5.6")
? {
context: 500_000,
input: 372_000,
output: 128_000,
}
: model.limit,
},
]),
)

View file

@ -149,6 +149,30 @@ describe("plugin.codex", () => {
await enabled.dispose?.()
})
test("uses Codex context limits for OAuth GPT models", async () => {
const hooks = await CodexAuthPlugin({} as never)
const limit = { context: 1_050_000, input: 922_000, output: 128_000 }
const provider = {
models: Object.fromEntries(
["gpt-5.4", "gpt-5.5", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"].map((id) => [
id,
{ id, api: { id }, limit, cost: {} },
]),
),
}
const models = await hooks.provider!.models!(provider as never, { auth: { type: "oauth" } } as never)
expect(models["gpt-5.4"]?.limit).toEqual(limit)
expect(models["gpt-5.5"]?.limit).toEqual({ context: 400_000, input: 272_000, output: 128_000 })
expect(models["gpt-5.6-sol"]?.limit).toEqual({ context: 500_000, input: 372_000, output: 128_000 })
expect(models["gpt-5.6-terra"]?.limit).toEqual({ context: 500_000, input: 372_000, output: 128_000 })
expect(models["gpt-5.6-luna"]?.limit).toEqual({ context: 500_000, input: 372_000, output: 128_000 })
expect(await hooks.provider!.models!(provider as never, { auth: { type: "api" } } as never)).toBe(
provider.models as never,
)
})
test("deduplicates concurrent Codex token refreshes", async () => {
let auth = {
type: "oauth" as const,

View file

@ -161,10 +161,10 @@ it.instance(
const providers = yield* list
expect(providers[ProviderV2.ID.anthropic]).toBeDefined()
const models = Object.keys(providers[ProviderV2.ID.anthropic].models)
expect(models).toContain("claude-sonnet-4-20250514")
expect(models).toContain("claude-sonnet-4-6")
expect(models.length).toBe(1)
}),
{ config: { provider: { anthropic: { whitelist: ["claude-sonnet-4-20250514"] } } } },
{ config: { provider: { anthropic: { whitelist: ["claude-sonnet-4-6"] } } } },
)
it.instance(
@ -303,10 +303,10 @@ it.instance("getModel returns model for valid provider/model", () =>
Effect.gen(function* () {
yield* setProcessEnv("ANTHROPIC_API_KEY", "test-api-key")
const provider = yield* Provider.Service
const model = yield* provider.getModel(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-20250514"))
const model = yield* provider.getModel(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-6"))
expect(model).toBeDefined()
expect(String(model.providerID)).toBe("anthropic")
expect(String(model.id)).toBe("claude-sonnet-4-20250514")
expect(String(model.id)).toBe("claude-sonnet-4-6")
const language = yield* provider.getLanguage(model)
expect(language).toBeDefined()
}),
@ -437,7 +437,7 @@ it.instance(
"model options are merged from existing model",
Effect.gen(function* () {
const providers = yield* list
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-20250514"]
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-6"]
expect(model.options.customOption).toBe("custom-value")
}),
{
@ -445,7 +445,7 @@ it.instance(
provider: {
anthropic: {
options: { apiKey: "test-api-key" },
models: { "claude-sonnet-4-20250514": { options: { customOption: "custom-value" } } },
models: { "claude-sonnet-4-6": { options: { customOption: "custom-value" } } },
},
},
},
@ -551,7 +551,7 @@ it.instance(
Effect.gen(function* () {
yield* set("ANTHROPIC_API_KEY", "test-api-key")
const providers = yield* list
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-20250514"]
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-6"]
expect(model.name).toBe("Custom Name for Sonnet")
expect(model.capabilities.toolcall).toBe(true)
expect(model.capabilities.attachment).toBe(true)
@ -559,7 +559,7 @@ it.instance(
}),
{
config: {
provider: { anthropic: { models: { "claude-sonnet-4-20250514": { name: "Custom Name for Sonnet" } } } },
provider: { anthropic: { models: { "claude-sonnet-4-6": { name: "Custom Name for Sonnet" } } } },
},
},
)
@ -592,16 +592,16 @@ it.instance(
const providers = yield* list
expect(providers[ProviderV2.ID.anthropic]).toBeDefined()
const models = Object.keys(providers[ProviderV2.ID.anthropic].models)
expect(models).toContain("claude-sonnet-4-20250514")
expect(models).not.toContain("claude-opus-4-20250514")
expect(models).toContain("claude-sonnet-4-6")
expect(models).not.toContain("claude-opus-4-6")
expect(models.length).toBe(1)
}),
{
config: {
provider: {
anthropic: {
whitelist: ["claude-sonnet-4-20250514", "claude-opus-4-20250514"],
blacklist: ["claude-opus-4-20250514"],
whitelist: ["claude-sonnet-4-6", "claude-opus-4-6"],
blacklist: ["claude-opus-4-6"],
},
},
},
@ -775,9 +775,9 @@ it.instance(
const model = yield* Provider.use.getSmallModel(ProviderV2.ID.anthropic)
expect(model).toBeDefined()
expect(String(model?.providerID)).toBe("anthropic")
expect(String(model?.id)).toBe("claude-sonnet-4-20250514")
expect(String(model?.id)).toBe("claude-sonnet-4-6")
}),
{ config: { small_model: "anthropic/claude-sonnet-4-20250514" } },
{ config: { small_model: "anthropic/claude-sonnet-4-6" } },
)
it.instance(
@ -1096,8 +1096,8 @@ it.instance(
it.instance("getModel returns consistent results", () =>
Effect.gen(function* () {
yield* set("ANTHROPIC_API_KEY", "test-api-key")
const model1 = yield* Provider.use.getModel(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-20250514"))
const model2 = yield* Provider.use.getModel(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-20250514"))
const model1 = yield* Provider.use.getModel(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-6"))
const model2 = yield* Provider.use.getModel(ProviderV2.ID.anthropic, ModelV2.ID.make("claude-sonnet-4-6"))
expect(model1.providerID).toEqual(model2.providerID)
expect(model1.id).toEqual(model2.id)
expect(model1).toEqual(model2)
@ -1459,7 +1459,7 @@ it.instance("model variants are generated for reasoning models", () =>
yield* set("ANTHROPIC_API_KEY", "test-api-key")
const providers = yield* list
// Claude sonnet 4 has reasoning capability
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-20250514"]
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-6"]
expect(model.capabilities.reasoning).toBe(true)
expect(model.variants).toBeDefined()
expect(Object.keys(model.variants!).length).toBeGreaterThan(0)
@ -1471,7 +1471,7 @@ it.instance(
Effect.gen(function* () {
yield* set("ANTHROPIC_API_KEY", "test-api-key")
const providers = yield* list
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-20250514"]
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-6"]
expect(model.variants).toBeDefined()
expect(model.variants!["high"]).toBeUndefined()
// max variant should still exist
@ -1481,7 +1481,7 @@ it.instance(
config: {
provider: {
anthropic: {
models: { "claude-sonnet-4-20250514": { variants: { high: { disabled: true } } } },
models: { "claude-sonnet-4-6": { variants: { high: { disabled: true } } } },
},
},
},
@ -1493,7 +1493,7 @@ it.instance(
Effect.gen(function* () {
yield* set("ANTHROPIC_API_KEY", "test-api-key")
const providers = yield* list
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-20250514"]
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-6"]
expect(model.variants!["high"]).toBeDefined()
expect(model.variants!["high"].thinking.budgetTokens).toBe(20000)
}),
@ -1502,7 +1502,7 @@ it.instance(
provider: {
anthropic: {
models: {
"claude-sonnet-4-20250514": {
"claude-sonnet-4-6": {
variants: { high: { thinking: { type: "enabled", budgetTokens: 20000 } } },
},
},
@ -1517,7 +1517,7 @@ it.instance(
Effect.gen(function* () {
yield* set("ANTHROPIC_API_KEY", "test-api-key")
const providers = yield* list
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-20250514"]
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-6"]
expect(model.variants!["max"]).toBeDefined()
expect(model.variants!["max"].disabled).toBeUndefined()
expect(model.variants!["max"].customField).toBe("test")
@ -1527,7 +1527,7 @@ it.instance(
provider: {
anthropic: {
models: {
"claude-sonnet-4-20250514": {
"claude-sonnet-4-6": {
variants: { max: { disabled: false, customField: "test" } },
},
},
@ -1542,7 +1542,7 @@ it.instance(
Effect.gen(function* () {
yield* set("ANTHROPIC_API_KEY", "test-api-key")
const providers = yield* list
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-20250514"]
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-6"]
expect(model.variants).toBeDefined()
expect(Object.keys(model.variants!).length).toBe(0)
}),
@ -1551,8 +1551,13 @@ it.instance(
provider: {
anthropic: {
models: {
"claude-sonnet-4-20250514": {
variants: { high: { disabled: true }, max: { disabled: true } },
"claude-sonnet-4-6": {
variants: {
low: { disabled: true },
medium: { disabled: true },
high: { disabled: true },
max: { disabled: true },
},
},
},
},
@ -1566,7 +1571,7 @@ it.instance(
Effect.gen(function* () {
yield* set("ANTHROPIC_API_KEY", "test-api-key")
const providers = yield* list
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-20250514"]
const model = providers[ProviderV2.ID.anthropic].models["claude-sonnet-4-6"]
expect(model.variants!["high"]).toBeDefined()
// Should have both the generated thinking config and the custom option
expect(model.variants!["high"].thinking).toBeDefined()
@ -1577,7 +1582,7 @@ it.instance(
provider: {
anthropic: {
models: {
"claude-sonnet-4-20250514": { variants: { high: { extraOption: "custom-value" } } },
"claude-sonnet-4-6": { variants: { high: { extraOption: "custom-value" } } },
},
},
},

File diff suppressed because it is too large Load diff