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, input: 272_000,
output: 128_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?.() 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 () => { test("deduplicates concurrent Codex token refreshes", async () => {
let auth = { let auth = {
type: "oauth" as const, type: "oauth" as const,

View file

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