mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-13 19:46:16 +03:00
fix(core): temporarily stop syncing w/ /models api for sign in w/ chatgpt due to openai bugs (#53466)
This commit is contained in:
committed by
GitHub
Unverified
parent
3ca0ac718b
commit
209346a0fe
@@ -1,14 +1,15 @@
|
||||
import type { IntegrationOAuthMethodRegistration } from "@opencode/plugin/effect/integration"
|
||||
import type { Context } from "@opencode/plugin/effect/plugin"
|
||||
import { define } from "@opencode/plugin/effect/plugin"
|
||||
import { Deferred, Duration, Effect, Option, Schema, Semaphore, Stream } from "effect"
|
||||
// import { Deferred, Duration, Effect, Option, Schema, Semaphore, Stream } from "effect"
|
||||
import { Deferred, Effect, Option, Schema, Semaphore, Stream } from "effect"
|
||||
import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
|
||||
import type { Server, ServerResponse } from "node:http"
|
||||
import { App } from "../../app.js"
|
||||
import { Credential } from "../../credential.js"
|
||||
import { Bus } from "../../bus.js"
|
||||
import { Integration } from "../../integration.js"
|
||||
import { IntegrationConnection } from "../../integration/connection.js"
|
||||
// import { IntegrationConnection } from "../../integration/connection.js"
|
||||
import { Model } from "../../model.js"
|
||||
import { OauthCallbackPage } from "../../oauth/page.js"
|
||||
import { Provider } from "../../provider.js"
|
||||
@@ -36,6 +37,12 @@ const fallbackModels = new Set([
|
||||
"gpt-5.6-terra-fast",
|
||||
"gpt-6-astra",
|
||||
"gpt-6-astra-fast",
|
||||
"gpt-6-luna",
|
||||
"gpt-6-luna-fast",
|
||||
"gpt-6-sol",
|
||||
"gpt-6-sol-fast",
|
||||
"gpt-6.1-sol",
|
||||
"gpt-6.1-sol-fast",
|
||||
])
|
||||
const nonRetryableSharingCodes = [
|
||||
"subscription_sharing_usage_limit_exceeded",
|
||||
@@ -204,22 +211,22 @@ export const ChatGPTPlugin = define({
|
||||
const credentials = yield* Credential.Service
|
||||
const loading = Semaphore.makeUnsafe(1)
|
||||
let chatgpt: Credential.OAuth | undefined
|
||||
let available: ReadonlyArray<RemoteModel> | undefined
|
||||
// let available: ReadonlyArray<RemoteModel> | undefined
|
||||
let source: Effect.Success<ReturnType<typeof ctx.integration.connection.active>>
|
||||
|
||||
const load = Effect.fn("ChatGPTPlugin.load")(function* () {
|
||||
const previous = IntegrationConnection.key(source)
|
||||
// const previous = IntegrationConnection.key(source)
|
||||
const connection = yield* ctx.integration.connection.active(integrationID)
|
||||
const credential = connection
|
||||
? yield* ctx.integration.connection.resolve(connection).pipe(Effect.orElseSucceed(() => undefined))
|
||||
: undefined
|
||||
chatgpt = credential?.type === "oauth" && credential.methodID === methodID ? credential : undefined
|
||||
source = chatgpt ? connection : undefined
|
||||
if (previous !== IntegrationConnection.key(source)) {
|
||||
const metadata = Option.getOrUndefined(decodeMetadata(chatgpt?.metadata))
|
||||
const stored = metadata ? yield* ctx.storage.get(modelCacheKey(metadata.clientID)) : undefined
|
||||
available = Option.getOrUndefined(decodeCachedModels(stored))
|
||||
}
|
||||
// if (previous !== IntegrationConnection.key(source)) {
|
||||
// const metadata = Option.getOrUndefined(decodeMetadata(chatgpt?.metadata))
|
||||
// const stored = metadata ? yield* ctx.storage.get(modelCacheKey(metadata.clientID)) : undefined
|
||||
// available = Option.getOrUndefined(decodeCachedModels(stored))
|
||||
// }
|
||||
})
|
||||
|
||||
yield* ctx.integration.transform((editor) => {
|
||||
@@ -272,9 +279,10 @@ export const ChatGPTPlugin = define({
|
||||
if (!updated) return
|
||||
providers.add({
|
||||
info: updated.provider,
|
||||
models: available
|
||||
? deriveModels(available, Array.from(item.models.values()))
|
||||
: Array.from(item.models.values()).filter((model) => fallbackModels.has(model.id)),
|
||||
// models: available
|
||||
// ? deriveModels(available, Array.from(item.models.values()))
|
||||
// : Array.from(item.models.values()).filter((model) => fallbackModels.has(model.id)),
|
||||
models: Array.from(item.models.values()).filter((model) => fallbackModels.has(model.id)),
|
||||
sourceConnection: source,
|
||||
})
|
||||
})
|
||||
@@ -288,55 +296,53 @@ export const ChatGPTPlugin = define({
|
||||
draft.enabled = false
|
||||
return
|
||||
}
|
||||
if (available && !available.some((remote) => remote.slug === (draft.modelID ?? draft.id))) {
|
||||
draft.enabled = false
|
||||
return
|
||||
}
|
||||
// if (available && !available.some((remote) => remote.slug === (draft.modelID ?? draft.id))) {
|
||||
// draft.enabled = false
|
||||
// return
|
||||
// }
|
||||
draft.cost = []
|
||||
})
|
||||
}
|
||||
})
|
||||
const refreshModels = Effect.fn("ChatGPTPlugin.refreshModels")(function* () {
|
||||
const connection = source
|
||||
const credential =
|
||||
connection?.type === "credential"
|
||||
? (yield* credentials.get(Credential.ID.make(connection.id)))?.value
|
||||
: undefined
|
||||
if (credential?.type !== "oauth" || credential.methodID !== methodID || credential.expires <= Date.now() + 60_000)
|
||||
return
|
||||
const metadata = Option.getOrUndefined(decodeMetadata(credential.metadata))
|
||||
if (!metadata) return
|
||||
const models = yield* fetchModels(credential.access, ctx.app).pipe(
|
||||
Effect.timeout(15_000),
|
||||
Effect.catch(() => Effect.logWarning("failed to refresh ChatGPT models").pipe(Effect.as(undefined))),
|
||||
)
|
||||
if (!models) return
|
||||
yield* loading.withPermit(
|
||||
Effect.gen(function* () {
|
||||
if (
|
||||
IntegrationConnection.key(connection) !== IntegrationConnection.key(source) ||
|
||||
IntegrationConnection.key(connection) !==
|
||||
IntegrationConnection.key(yield* ctx.integration.connection.active(integrationID))
|
||||
)
|
||||
return
|
||||
if (JSON.stringify(models) === JSON.stringify(available)) return
|
||||
yield* ctx.storage.set(modelCacheKey(metadata.clientID), models)
|
||||
available = models
|
||||
yield* ctx.provider.reload()
|
||||
}),
|
||||
)
|
||||
})
|
||||
const reload = () =>
|
||||
loading
|
||||
.withPermit(load().pipe(Effect.andThen(ctx.provider.reload())))
|
||||
.pipe(Effect.andThen(refreshModels().pipe(Effect.forkScoped, Effect.asVoid)))
|
||||
// const refreshModels = Effect.fn("ChatGPTPlugin.refreshModels")(function* () {
|
||||
// const connection = source
|
||||
// const credential =
|
||||
// connection?.type === "credential"
|
||||
// ? (yield* credentials.get(Credential.ID.make(connection.id)))?.value
|
||||
// : undefined
|
||||
// if (credential?.type !== "oauth" || credential.methodID !== methodID || credential.expires <= Date.now() + 60_000)
|
||||
// return
|
||||
// const metadata = Option.getOrUndefined(decodeMetadata(credential.metadata))
|
||||
// if (!metadata) return
|
||||
// const models = yield* fetchModels(credential.access, ctx.app).pipe(
|
||||
// Effect.timeout(15_000),
|
||||
// Effect.catch(() => Effect.logWarning("failed to refresh ChatGPT models").pipe(Effect.as(undefined))),
|
||||
// )
|
||||
// if (!models) return
|
||||
// yield* loading.withPermit(
|
||||
// Effect.gen(function* () {
|
||||
// if (
|
||||
// IntegrationConnection.key(connection) !== IntegrationConnection.key(source) ||
|
||||
// IntegrationConnection.key(connection) !==
|
||||
// IntegrationConnection.key(yield* ctx.integration.connection.active(integrationID))
|
||||
// )
|
||||
// return
|
||||
// if (JSON.stringify(models) === JSON.stringify(available)) return
|
||||
// yield* ctx.storage.set(modelCacheKey(metadata.clientID), models)
|
||||
// available = models
|
||||
// yield* ctx.provider.reload()
|
||||
// }),
|
||||
// )
|
||||
// })
|
||||
const reload = () => loading.withPermit(load().pipe(Effect.andThen(ctx.provider.reload())))
|
||||
// .pipe(Effect.andThen(refreshModels().pipe(Effect.forkScoped, Effect.asVoid)))
|
||||
yield* bus.subscribe(Credential.Event.Switched).pipe(
|
||||
Stream.filter((event) => event.data.integrationID === integrationID),
|
||||
Stream.runForEach(reload),
|
||||
Effect.forkScoped({ startImmediately: true }),
|
||||
)
|
||||
yield* refreshModels().pipe(Effect.forkScoped)
|
||||
yield* Effect.sleep(Duration.minutes(15)).pipe(Effect.andThen(refreshModels), Effect.forever, Effect.forkScoped)
|
||||
// yield* refreshModels().pipe(Effect.forkScoped)
|
||||
// yield* Effect.sleep(Duration.minutes(15)).pipe(Effect.andThen(refreshModels), Effect.forever, Effect.forkScoped)
|
||||
}),
|
||||
} satisfies PluginInternal.InternalPlugin)
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ import { OpenAIResponses } from "@opencode/ai/protocols/openai-responses"
|
||||
import { AIError, HttpContext, RateLimitError } from "@opencode/ai"
|
||||
import { classifyProviderFailure } from "@opencode/ai/provider-error"
|
||||
import { describe, expect } from "bun:test"
|
||||
import { DateTime, Deferred, Effect, Schedule } from "effect"
|
||||
// import { DateTime, Deferred, Effect, Schedule } from "effect"
|
||||
import { DateTime, Effect, Schedule } from "effect"
|
||||
import { HttpClient, HttpClientResponse } from "effect/unstable/http"
|
||||
import { exportJWK, generateKeyPair, SignJWT } from "jose"
|
||||
import { App } from "@opencode/core/app"
|
||||
@@ -540,149 +541,149 @@ describe("ChatGPTPlugin", () => {
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("merges account models with catalog metadata and leaves input budgeting to compaction", () =>
|
||||
Effect.gen(function* () {
|
||||
const catalog = yield* Provider.Service
|
||||
const models = yield* Model.Service
|
||||
const credentials = yield* Credential.Service
|
||||
const kv = yield* KV.Service
|
||||
yield* catalog.transform((editor) => {
|
||||
editor.update(Provider.ID.openai, (provider) => {
|
||||
provider.package = "@opencode/ai/providers/openai"
|
||||
})
|
||||
editor.models.update(Provider.ID.openai, Model.ID.make("gpt-5.6-sol"), (model) => {
|
||||
model.limit = { context: 1_050_000, input: 922_000, output: 128_000 }
|
||||
model.capabilities = { tools: true, input: ["text", "image", "pdf"], output: ["text"] }
|
||||
model.variants = [
|
||||
{ id: Model.VariantID.make("low"), settings: { reasoningEffort: "low" } },
|
||||
{ id: Model.VariantID.make("high"), settings: { reasoningEffort: "high" } },
|
||||
]
|
||||
})
|
||||
editor.models.update(Provider.ID.openai, Model.ID.make("gpt-5.5"), () => {})
|
||||
})
|
||||
yield* PluginHost.storage(kv, ChatGPTPlugin.id).set("models:oaiapp_issued", [
|
||||
{
|
||||
slug: "gpt-5.6-sol",
|
||||
display_name: "GPT-5.6-Sol",
|
||||
visibility: "list",
|
||||
supported_in_api: true,
|
||||
context_window: 272_000,
|
||||
input_modalities: ["text", "image"],
|
||||
supported_reasoning_levels: [{ effort: "low" }, { effort: "ultra" }],
|
||||
},
|
||||
{
|
||||
slug: "gpt-6-future",
|
||||
display_name: "GPT-6-Future",
|
||||
visibility: "list",
|
||||
supported_in_api: true,
|
||||
context_window: 272_000,
|
||||
input_modalities: ["text"],
|
||||
supported_reasoning_levels: [],
|
||||
},
|
||||
])
|
||||
yield* credentials.create({
|
||||
integrationID: Integration.ID.make("openai"),
|
||||
value: Credential.OAuth.make({
|
||||
type: "oauth",
|
||||
methodID: Integration.MethodID.make("chatgpt-token-sharing"),
|
||||
access: "chatgpt-token",
|
||||
refresh: "refresh",
|
||||
expires: Date.now() + 60 * 60_000,
|
||||
metadata: { clientID: "oaiapp_issued" },
|
||||
}),
|
||||
})
|
||||
yield* addPlugin()
|
||||
|
||||
const available = (yield* models.available()).filter((model) => model.providerID === Provider.ID.openai)
|
||||
expect(available.map((model) => model.id).sort()).toEqual([
|
||||
Model.ID.make("gpt-5.6-sol"),
|
||||
Model.ID.make("gpt-6-future"),
|
||||
])
|
||||
const sol = required(available.find((model) => model.id === "gpt-5.6-sol"))
|
||||
expect(sol.name).toBe("GPT-5.6-Sol")
|
||||
expect(sol.capabilities.input).toEqual(["text", "image"])
|
||||
expect(sol.variants.map((variant) => variant.id)).toEqual([
|
||||
Model.VariantID.make("low"),
|
||||
Model.VariantID.make("ultra"),
|
||||
])
|
||||
expect(sol.limit).toEqual({ context: 272_000, output: 128_000 })
|
||||
expect(sol.cost).toEqual([])
|
||||
expect(sol.settings?.compaction).toEqual({ type: "summary" })
|
||||
const future = required(available.find((model) => model.id === "gpt-6-future"))
|
||||
expect(future.name).toBe("GPT-6-Future")
|
||||
expect(future.package).toBe("@opencode/ai/providers/openai")
|
||||
expect(future.limit).toEqual({ context: 272_000, output: 32_000 })
|
||||
}),
|
||||
)
|
||||
|
||||
it.live("shows catalog models while account models refresh in the background and saves them to KV", () =>
|
||||
Effect.gen(function* () {
|
||||
const catalog = yield* Provider.Service
|
||||
const models = yield* Model.Service
|
||||
const credentials = yield* Credential.Service
|
||||
const kv = yield* KV.Service
|
||||
yield* catalog.transform((editor) => {
|
||||
editor.update(Provider.ID.openai, (provider) => {
|
||||
provider.package = "@opencode/ai/providers/openai"
|
||||
})
|
||||
for (const id of ["gpt-5.5", "gpt-6-astra", "gpt-6-sol"])
|
||||
editor.models.update(Provider.ID.openai, Model.ID.make(id), () => {})
|
||||
})
|
||||
const requested = yield* Deferred.make<void>()
|
||||
const release = yield* Deferred.make<void>()
|
||||
const remote = [
|
||||
{
|
||||
slug: "gpt-6-future",
|
||||
display_name: "GPT-6-Future",
|
||||
visibility: "list",
|
||||
supported_in_api: true,
|
||||
context_window: 272_000,
|
||||
input_modalities: ["text"],
|
||||
},
|
||||
]
|
||||
const http = HttpClient.make((request) =>
|
||||
Effect.gen(function* () {
|
||||
expect(request.url).toBe("https://api.openai.com/v1/models")
|
||||
expect(request.headers.authorization).toBe("Bearer chatgpt-token")
|
||||
yield* Deferred.succeed(requested, undefined)
|
||||
yield* Deferred.await(release)
|
||||
return HttpClientResponse.fromWeb(request, Response.json({ models: remote }))
|
||||
}),
|
||||
)
|
||||
yield* addPlugin(http)
|
||||
yield* credentials.create({
|
||||
integrationID: Integration.ID.make("openai"),
|
||||
value: Credential.OAuth.make({
|
||||
type: "oauth",
|
||||
methodID: Integration.MethodID.make("chatgpt-token-sharing"),
|
||||
access: "chatgpt-token",
|
||||
refresh: "refresh",
|
||||
expires: Date.now() + 60 * 60_000,
|
||||
metadata: { clientID: "oaiapp_issued" },
|
||||
}),
|
||||
})
|
||||
yield* Deferred.await(requested).pipe(Effect.timeout("2 seconds"))
|
||||
expect((yield* models.available()).filter((model) => model.providerID === Provider.ID.openai).map((model) => model.id)).toEqual([
|
||||
Model.ID.make("gpt-5.5"),
|
||||
Model.ID.make("gpt-6-astra"),
|
||||
])
|
||||
const storage = PluginHost.storage(kv, ChatGPTPlugin.id)
|
||||
expect(yield* storage.get("models:oaiapp_issued")).toBeUndefined()
|
||||
|
||||
yield* Deferred.succeed(release, undefined)
|
||||
const available = yield* models.available().pipe(
|
||||
Effect.repeat({
|
||||
until: (current) => current.some((model) => model.providerID === Provider.ID.openai && model.id === "gpt-6-future"),
|
||||
schedule: Schedule.spaced("10 millis"),
|
||||
}),
|
||||
Effect.timeout("2 seconds"),
|
||||
)
|
||||
expect(available.filter((model) => model.providerID === Provider.ID.openai).map((model) => model.id)).toEqual([
|
||||
Model.ID.make("gpt-6-future"),
|
||||
])
|
||||
expect(yield* storage.get("models:oaiapp_issued")).toEqual(remote)
|
||||
}),
|
||||
)
|
||||
// it.effect("merges account models with catalog metadata and leaves input budgeting to compaction", () =>
|
||||
// Effect.gen(function* () {
|
||||
// const catalog = yield* Provider.Service
|
||||
// const models = yield* Model.Service
|
||||
// const credentials = yield* Credential.Service
|
||||
// const kv = yield* KV.Service
|
||||
// yield* catalog.transform((editor) => {
|
||||
// editor.update(Provider.ID.openai, (provider) => {
|
||||
// provider.package = "@opencode/ai/providers/openai"
|
||||
// })
|
||||
// editor.models.update(Provider.ID.openai, Model.ID.make("gpt-5.6-sol"), (model) => {
|
||||
// model.limit = { context: 1_050_000, input: 922_000, output: 128_000 }
|
||||
// model.capabilities = { tools: true, input: ["text", "image", "pdf"], output: ["text"] }
|
||||
// model.variants = [
|
||||
// { id: Model.VariantID.make("low"), settings: { reasoningEffort: "low" } },
|
||||
// { id: Model.VariantID.make("high"), settings: { reasoningEffort: "high" } },
|
||||
// ]
|
||||
// })
|
||||
// editor.models.update(Provider.ID.openai, Model.ID.make("gpt-5.5"), () => {})
|
||||
// })
|
||||
// yield* PluginHost.storage(kv, ChatGPTPlugin.id).set("models:oaiapp_issued", [
|
||||
// {
|
||||
// slug: "gpt-5.6-sol",
|
||||
// display_name: "GPT-5.6-Sol",
|
||||
// visibility: "list",
|
||||
// supported_in_api: true,
|
||||
// context_window: 272_000,
|
||||
// input_modalities: ["text", "image"],
|
||||
// supported_reasoning_levels: [{ effort: "low" }, { effort: "ultra" }],
|
||||
// },
|
||||
// {
|
||||
// slug: "gpt-6-future",
|
||||
// display_name: "GPT-6-Future",
|
||||
// visibility: "list",
|
||||
// supported_in_api: true,
|
||||
// context_window: 272_000,
|
||||
// input_modalities: ["text"],
|
||||
// supported_reasoning_levels: [],
|
||||
// },
|
||||
// ])
|
||||
// yield* credentials.create({
|
||||
// integrationID: Integration.ID.make("openai"),
|
||||
// value: Credential.OAuth.make({
|
||||
// type: "oauth",
|
||||
// methodID: Integration.MethodID.make("chatgpt-token-sharing"),
|
||||
// access: "chatgpt-token",
|
||||
// refresh: "refresh",
|
||||
// expires: Date.now() + 60 * 60_000,
|
||||
// metadata: { clientID: "oaiapp_issued" },
|
||||
// }),
|
||||
// })
|
||||
// yield* addPlugin()
|
||||
//
|
||||
// const available = (yield* models.available()).filter((model) => model.providerID === Provider.ID.openai)
|
||||
// expect(available.map((model) => model.id).sort()).toEqual([
|
||||
// Model.ID.make("gpt-5.6-sol"),
|
||||
// Model.ID.make("gpt-6-future"),
|
||||
// ])
|
||||
// const sol = required(available.find((model) => model.id === "gpt-5.6-sol"))
|
||||
// expect(sol.name).toBe("GPT-5.6-Sol")
|
||||
// expect(sol.capabilities.input).toEqual(["text", "image"])
|
||||
// expect(sol.variants.map((variant) => variant.id)).toEqual([
|
||||
// Model.VariantID.make("low"),
|
||||
// Model.VariantID.make("ultra"),
|
||||
// ])
|
||||
// expect(sol.limit).toEqual({ context: 272_000, output: 128_000 })
|
||||
// expect(sol.cost).toEqual([])
|
||||
// expect(sol.settings?.compaction).toEqual({ type: "summary" })
|
||||
// const future = required(available.find((model) => model.id === "gpt-6-future"))
|
||||
// expect(future.name).toBe("GPT-6-Future")
|
||||
// expect(future.package).toBe("@opencode/ai/providers/openai")
|
||||
// expect(future.limit).toEqual({ context: 272_000, output: 32_000 })
|
||||
// }),
|
||||
// )
|
||||
//
|
||||
// it.live("shows catalog models while account models refresh in the background and saves them to KV", () =>
|
||||
// Effect.gen(function* () {
|
||||
// const catalog = yield* Provider.Service
|
||||
// const models = yield* Model.Service
|
||||
// const credentials = yield* Credential.Service
|
||||
// const kv = yield* KV.Service
|
||||
// yield* catalog.transform((editor) => {
|
||||
// editor.update(Provider.ID.openai, (provider) => {
|
||||
// provider.package = "@opencode/ai/providers/openai"
|
||||
// })
|
||||
// for (const id of ["gpt-5.5", "gpt-6-astra", "gpt-6-sol"])
|
||||
// editor.models.update(Provider.ID.openai, Model.ID.make(id), () => {})
|
||||
// })
|
||||
// const requested = yield* Deferred.make<void>()
|
||||
// const release = yield* Deferred.make<void>()
|
||||
// const remote = [
|
||||
// {
|
||||
// slug: "gpt-6-future",
|
||||
// display_name: "GPT-6-Future",
|
||||
// visibility: "list",
|
||||
// supported_in_api: true,
|
||||
// context_window: 272_000,
|
||||
// input_modalities: ["text"],
|
||||
// },
|
||||
// ]
|
||||
// const http = HttpClient.make((request) =>
|
||||
// Effect.gen(function* () {
|
||||
// expect(request.url).toBe("https://api.openai.com/v1/models")
|
||||
// expect(request.headers.authorization).toBe("Bearer chatgpt-token")
|
||||
// yield* Deferred.succeed(requested, undefined)
|
||||
// yield* Deferred.await(release)
|
||||
// return HttpClientResponse.fromWeb(request, Response.json({ models: remote }))
|
||||
// }),
|
||||
// )
|
||||
// yield* addPlugin(http)
|
||||
// yield* credentials.create({
|
||||
// integrationID: Integration.ID.make("openai"),
|
||||
// value: Credential.OAuth.make({
|
||||
// type: "oauth",
|
||||
// methodID: Integration.MethodID.make("chatgpt-token-sharing"),
|
||||
// access: "chatgpt-token",
|
||||
// refresh: "refresh",
|
||||
// expires: Date.now() + 60 * 60_000,
|
||||
// metadata: { clientID: "oaiapp_issued" },
|
||||
// }),
|
||||
// })
|
||||
// yield* Deferred.await(requested).pipe(Effect.timeout("2 seconds"))
|
||||
// expect((yield* models.available()).filter((model) => model.providerID === Provider.ID.openai).map((model) => model.id)).toEqual([
|
||||
// Model.ID.make("gpt-5.5"),
|
||||
// Model.ID.make("gpt-6-astra"),
|
||||
// ])
|
||||
// const storage = PluginHost.storage(kv, ChatGPTPlugin.id)
|
||||
// expect(yield* storage.get("models:oaiapp_issued")).toBeUndefined()
|
||||
//
|
||||
// yield* Deferred.succeed(release, undefined)
|
||||
// const available = yield* models.available().pipe(
|
||||
// Effect.repeat({
|
||||
// until: (current) => current.some((model) => model.providerID === Provider.ID.openai && model.id === "gpt-6-future"),
|
||||
// schedule: Schedule.spaced("10 millis"),
|
||||
// }),
|
||||
// Effect.timeout("2 seconds"),
|
||||
// )
|
||||
// expect(available.filter((model) => model.providerID === Provider.ID.openai).map((model) => model.id)).toEqual([
|
||||
// Model.ID.make("gpt-6-future"),
|
||||
// ])
|
||||
// expect(yield* storage.get("models:oaiapp_issued")).toEqual(remote)
|
||||
// }),
|
||||
// )
|
||||
|
||||
it.effect("routes ChatGPT over HTTP with only the listed catalog fallback models", () =>
|
||||
Effect.gen(function* () {
|
||||
@@ -737,8 +738,12 @@ describe("ChatGPTPlugin", () => {
|
||||
"gpt-5.6-terra",
|
||||
"gpt-5.6-terra-fast",
|
||||
"gpt-6-astra-fast",
|
||||
"gpt-6-luna",
|
||||
"gpt-6-luna-fast",
|
||||
"gpt-6-sol",
|
||||
"gpt-6-sol-fast",
|
||||
"gpt-6.1-sol",
|
||||
"gpt-6.1-sol-fast",
|
||||
])
|
||||
catalog.models.update(Provider.ID.openai, Model.ID.make(id), () => {})
|
||||
})
|
||||
@@ -784,8 +789,6 @@ describe("ChatGPTPlugin", () => {
|
||||
"gpt-5",
|
||||
"gpt-5.04-astra",
|
||||
"gpt-4.99",
|
||||
"gpt-6-sol",
|
||||
"gpt-6.1-sol",
|
||||
])
|
||||
expect(yield* models.get(Provider.ID.openai, Model.ID.make(id))).toBeUndefined()
|
||||
expect((yield* models.available()).filter((model) => model.providerID === Provider.ID.openai).map((model) => model.id).sort()).toEqual(
|
||||
@@ -800,6 +803,12 @@ describe("ChatGPTPlugin", () => {
|
||||
"gpt-5.6-terra-fast",
|
||||
"gpt-6-astra",
|
||||
"gpt-6-astra-fast",
|
||||
"gpt-6-luna",
|
||||
"gpt-6-luna-fast",
|
||||
"gpt-6-sol",
|
||||
"gpt-6-sol-fast",
|
||||
"gpt-6.1-sol",
|
||||
"gpt-6.1-sol-fast",
|
||||
].map((id) => Model.ID.make(id)),
|
||||
)
|
||||
}),
|
||||
@@ -946,9 +955,9 @@ describe("ChatGPTPlugin", () => {
|
||||
const credentials = yield* Credential.Service
|
||||
const providerID = Provider.ID.openai
|
||||
const baseID = Model.ID.make("gpt-5.5")
|
||||
const modelID = Model.ID.make("gpt-5.5-model")
|
||||
const variantID = Model.ID.make("gpt-5.5-variant")
|
||||
const kv = yield* KV.Service
|
||||
const modelID = Model.ID.make("gpt-5.6-sol")
|
||||
const variantID = Model.ID.make("gpt-6-astra")
|
||||
// const kv = yield* KV.Service
|
||||
yield* catalog.transform((editor) => {
|
||||
editor.update(providerID, (provider) => {
|
||||
provider.package = "@opencode/ai/providers/openai/responses"
|
||||
@@ -975,17 +984,17 @@ describe("ChatGPTPlugin", () => {
|
||||
})
|
||||
: Credential.Key.make({ type: "key", key: "sk-test" }),
|
||||
})
|
||||
if (connection === "chatgpt")
|
||||
yield* PluginHost.storage(kv, ChatGPTPlugin.id).set("models:oaiapp_issued", [
|
||||
{
|
||||
slug: "gpt-5.5",
|
||||
display_name: "GPT-5.5",
|
||||
visibility: "list",
|
||||
supported_in_api: true,
|
||||
context_window: 272_000,
|
||||
input_modalities: ["text"],
|
||||
},
|
||||
])
|
||||
// if (connection === "chatgpt")
|
||||
// yield* PluginHost.storage(kv, ChatGPTPlugin.id).set("models:oaiapp_issued", [
|
||||
// {
|
||||
// slug: "gpt-5.5",
|
||||
// display_name: "GPT-5.5",
|
||||
// visibility: "list",
|
||||
// supported_in_api: true,
|
||||
// context_window: 272_000,
|
||||
// input_modalities: ["text"],
|
||||
// },
|
||||
// ])
|
||||
yield* addPlugin()
|
||||
yield* addLegacyPlugin()
|
||||
const resolver = yield* ModelResolver.Service
|
||||
|
||||
Reference in New Issue
Block a user