Просмотр исходного кода

fix(core): detect copilot PDF input support (#41854)

Aiden Cline 5 дней назад
Родитель
Сommit
b35c5fc985

+ 7 - 1
packages/core/src/github-copilot/models.ts

@@ -126,6 +126,12 @@ function build(id: Model.ID, remote: UsableModel, baseURL: string, previous?: Mo
   const image =
     (remote.capabilities.supports.vision ?? false) ||
     (remote.capabilities.limits.vision?.supported_media_types ?? []).some((item) => item.startsWith("image/"))
+  const pdf =
+    (remote.capabilities.supports.vision ?? false) &&
+    (remote.capabilities.limits.vision?.supported_media_types.includes("application/pdf") ?? false)
+  const input = ["text"]
+  if (image) input.push("image")
+  if (pdf) input.push("pdf")
   const prices = remote.billing?.token_prices
   // Copilot reports AIC per billing batch; OpenCode stores USD per million tokens.
   const usdPerMillion = prices && prices.batch_size > 0 ? 10_000 / prices.batch_size : 0
@@ -150,7 +156,7 @@ function build(id: Model.ID, remote: UsableModel, baseURL: string, previous?: Mo
     body: previous?.body,
     capabilities: {
       tools: remote.capabilities.supports.tool_calls,
-      input: image ? ["text", "image"] : ["text"],
+      input,
       output: ["text"],
     },
     variants: variants(remote, messages),

+ 27 - 1
packages/core/test/github-copilot/models.test.ts

@@ -27,8 +27,32 @@ test("defensively syncs advertised Copilot models", async () => {
                 max_context_window_tokens: 200000,
                 max_output_tokens: 16384,
                 max_prompt_tokens: 180000,
+                vision: {
+                  max_prompt_image_size: 10000000,
+                  max_prompt_images: 10,
+                  supported_media_types: ["image/png", "application/pdf"],
+                },
               },
-              supports: { tool_calls: true, reasoning_effort: ["low", "high"] },
+              supports: { tool_calls: true, vision: true, reasoning_effort: ["low", "high"] },
+            },
+          },
+          {
+            model_picker_enabled: true,
+            id: "vision-only",
+            name: "Vision only",
+            version: "vision-only-2026-06-01",
+            capabilities: {
+              family: "vision",
+              limits: {
+                max_output_tokens: 16384,
+                max_prompt_tokens: 180000,
+                vision: {
+                  max_prompt_image_size: 10000000,
+                  max_prompt_images: 10,
+                  supported_media_types: ["image/png"],
+                },
+              },
+              supports: { tool_calls: true, vision: true },
             },
           },
           {
@@ -67,6 +91,8 @@ test("defensively syncs advertised Copilot models", async () => {
       Model.VariantID.make("low"),
       Model.VariantID.make("high"),
     ])
+    expect(model?.capabilities.input).toEqual(["text", "image", "pdf"])
+    expect(models.get(Model.ID.make("vision-only"))?.capabilities.input).toEqual(["text", "image"])
     expect(models.get(Model.ID.make("utility"))?.enabled).toBe(false)
     expect(models.has(Model.ID.make("stale"))).toBe(false)
     expect(models.has(Model.ID.make("incomplete"))).toBe(false)