fix(core): await initial Copilot model sync
This commit is contained in:
parent
a0a6963beb
commit
fcb4534a82
2 changed files with 77 additions and 4 deletions
|
|
@ -196,6 +196,7 @@ export const GithubCopilotPlugin = define({
|
||||||
yield* ctx.integration.transform((draft) => {
|
yield* ctx.integration.transform((draft) => {
|
||||||
draft.method.update(oauth(ctx.app))
|
draft.method.update(oauth(ctx.app))
|
||||||
})
|
})
|
||||||
|
yield* load()
|
||||||
yield* ctx.catalog.transform((evt) => {
|
yield* ctx.catalog.transform((evt) => {
|
||||||
const item = evt.provider.get(ProviderV2.ID.githubCopilot)
|
const item = evt.provider.get(ProviderV2.ID.githubCopilot)
|
||||||
if (!item) return
|
if (!item) return
|
||||||
|
|
@ -227,7 +228,6 @@ export const GithubCopilotPlugin = define({
|
||||||
Stream.runForEach(refresh),
|
Stream.runForEach(refresh),
|
||||||
Effect.forkScoped({ startImmediately: true }),
|
Effect.forkScoped({ startImmediately: true }),
|
||||||
)
|
)
|
||||||
yield* refresh().pipe(Effect.forkScoped)
|
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.hook(
|
||||||
"sdk",
|
"sdk",
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import { AISDK } from "@opencode-ai/core/aisdk"
|
import { AISDK } from "@opencode-ai/core/aisdk"
|
||||||
import { App } from "@opencode-ai/core/app"
|
import { App } from "@opencode-ai/core/app"
|
||||||
import { describe, expect, test } from "bun:test"
|
import { describe, expect, test } from "bun:test"
|
||||||
import { Effect } from "effect"
|
import { Effect, Fiber } from "effect"
|
||||||
import { Catalog } from "@opencode-ai/core/catalog"
|
import { Catalog } from "@opencode-ai/core/catalog"
|
||||||
|
import { Credential } from "@opencode-ai/core/credential"
|
||||||
import { ModelV2 } from "@opencode-ai/core/model"
|
import { ModelV2 } from "@opencode-ai/core/model"
|
||||||
import { PluginV2 } from "@opencode-ai/core/plugin"
|
import { PluginV2 } from "@opencode-ai/core/plugin"
|
||||||
import { PluginHost } from "@opencode-ai/core/plugin/host"
|
import { PluginHost } from "@opencode-ai/core/plugin/host"
|
||||||
|
|
@ -15,11 +16,20 @@ import { PluginTestLayer } from "./fixture"
|
||||||
|
|
||||||
const it = testEffect(PluginTestLayer)
|
const it = testEffect(PluginTestLayer)
|
||||||
|
|
||||||
const addPlugin = Effect.fn(function* () {
|
const addPlugin = Effect.fn(function* (credential?: Credential.OAuth) {
|
||||||
const plugin = yield* PluginV2.Service
|
const plugin = yield* PluginV2.Service
|
||||||
const aisdk = yield* AISDK.Service
|
const aisdk = yield* AISDK.Service
|
||||||
const host = yield* PluginHost.make(plugin)
|
const host = yield* PluginHost.make(plugin)
|
||||||
yield* GithubCopilotPlugin.effect(host)
|
yield* GithubCopilotPlugin.effect({
|
||||||
|
...host,
|
||||||
|
integration: {
|
||||||
|
...host.integration,
|
||||||
|
connection: {
|
||||||
|
active: () => Effect.succeed(credential ? ({ type: "env", name: "TEST" } as const) : undefined),
|
||||||
|
resolve: () => Effect.succeed(credential),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function required<T>(value: T | undefined): T {
|
function required<T>(value: T | undefined): T {
|
||||||
|
|
@ -62,6 +72,69 @@ describe("GithubCopilotPlugin", () => {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
it.live("waits for initial Copilot models before exposing the connected catalog", () =>
|
||||||
|
Effect.acquireUseRelease(
|
||||||
|
Effect.sync(() => {
|
||||||
|
const requested = Promise.withResolvers<void>()
|
||||||
|
const release = Promise.withResolvers<void>()
|
||||||
|
const server = Bun.serve({
|
||||||
|
port: 0,
|
||||||
|
fetch: async () => {
|
||||||
|
requested.resolve()
|
||||||
|
await release.promise
|
||||||
|
return Response.json({
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
model_picker_enabled: true,
|
||||||
|
id: "gpt-5",
|
||||||
|
name: "GPT-5",
|
||||||
|
version: "gpt-5-2026-06-01",
|
||||||
|
supported_endpoints: ["/responses"],
|
||||||
|
capabilities: {
|
||||||
|
family: "gpt",
|
||||||
|
limits: { max_output_tokens: 16_384, max_prompt_tokens: 180_000 },
|
||||||
|
supports: { tool_calls: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return { release, requested, server }
|
||||||
|
}),
|
||||||
|
({ release, requested, server }) =>
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const catalog = yield* Catalog.Service
|
||||||
|
yield* catalog.transform((draft) => {
|
||||||
|
draft.provider.update(ProviderV2.ID.githubCopilot, () => {})
|
||||||
|
draft.model.update(ProviderV2.ID.githubCopilot, ModelV2.ID.make("stale"), () => {})
|
||||||
|
})
|
||||||
|
const credential = Credential.OAuth.make({
|
||||||
|
type: "oauth",
|
||||||
|
methodID: Integration.MethodID.make("device"),
|
||||||
|
access: "access",
|
||||||
|
refresh: "refresh",
|
||||||
|
expires: 0,
|
||||||
|
metadata: { apiEndpoint: server.url.origin },
|
||||||
|
})
|
||||||
|
|
||||||
|
const plugin = yield* addPlugin(credential).pipe(Effect.forkScoped({ startImmediately: true }))
|
||||||
|
yield* Effect.promise(() => requested.promise)
|
||||||
|
const pending = plugin.pollUnsafe() === undefined
|
||||||
|
release.resolve()
|
||||||
|
yield* Fiber.join(plugin)
|
||||||
|
|
||||||
|
expect(pending).toBe(true)
|
||||||
|
expect(yield* catalog.model.get(ProviderV2.ID.githubCopilot, ModelV2.ID.make("stale"))).toBeUndefined()
|
||||||
|
expect(yield* catalog.model.get(ProviderV2.ID.githubCopilot, ModelV2.ID.make("gpt-5"))).toBeDefined()
|
||||||
|
}),
|
||||||
|
({ release, server }) => {
|
||||||
|
release.resolve()
|
||||||
|
return Effect.promise(() => server.stop(true))
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
it.live("adds Copilot authentication and request metadata headers", () =>
|
it.live("adds Copilot authentication and request metadata headers", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const requests: Headers[] = []
|
const requests: Headers[] = []
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue