


















11// Github Copilot tests cover models plugin behavior.
22import { createProviderUsageFetch, makeResponse } from "openclaw/plugin-sdk/test-env";
33import { beforeEach, describe, expect, it, vi } from "vitest";
4-import { buildCopilotModelDefinition, getDefaultCopilotModelIds } from "./models-defaults.js";
54import { deriveCopilotApiBaseUrlFromToken, resolveCopilotApiToken } from "./token.js";
65import { fetchCopilotUsage } from "./usage.js";
76@@ -54,108 +53,6 @@ function requireResolvedModel(ctx: ProviderResolveDynamicModelContext) {
5453return result;
5554}
565557-describe("github-copilot model defaults", () => {
58-describe("getDefaultCopilotModelIds", () => {
59-it("includes claude-opus-4.7", () => {
60-expect(getDefaultCopilotModelIds()).toContain("claude-opus-4.7");
61-expect(getDefaultCopilotModelIds()).toContain("claude-opus-4.6");
62-});
63-64-it("includes claude-opus-4.8", () => {
65-expect(getDefaultCopilotModelIds()).toContain("claude-opus-4.8");
66-});
67-68-it("includes claude-sonnet-4.6", () => {
69-expect(getDefaultCopilotModelIds()).toContain("claude-sonnet-4.6");
70-});
71-72-it("excludes retired and old Claude fallback rows", () => {
73-expect(getDefaultCopilotModelIds()).not.toContain("claude-sonnet-4");
74-expect(getDefaultCopilotModelIds()).not.toContain("claude-sonnet-4.5");
75-expect(getDefaultCopilotModelIds()).not.toContain("claude-opus-4.5");
76-expect(getDefaultCopilotModelIds()).not.toContain("claude-haiku-4.5");
77-expect(getDefaultCopilotModelIds()).not.toContain("grok-code-fast-1");
78-});
79-80-it("returns a mutable copy", () => {
81-const a = getDefaultCopilotModelIds();
82-const b = getDefaultCopilotModelIds();
83-expect(a).not.toBe(b);
84-expect(a).toEqual(b);
85-});
86-});
87-88-describe("buildCopilotModelDefinition", () => {
89-it("builds a valid definition for claude-sonnet-4.6", () => {
90-const def = buildCopilotModelDefinition("claude-sonnet-4.6");
91-expect(def.id).toBe("claude-sonnet-4.6");
92-expect(def.api).toBe("anthropic-messages");
93-expect(def.compat).toBeUndefined();
94-});
95-96-it.each(["claude-haiku-4.5", "claude-sonnet-4-5"])(
97-"disables eager tool streaming for Copilot Claude 4.5 model %s",
98-(modelId) => {
99-expect(buildCopilotModelDefinition(modelId).compat).toEqual({
100-supportsEagerToolInputStreaming: false,
101-});
102-},
103-);
104-105-it("uses static metadata overrides for gpt-5.5 fallback rows", () => {
106-const def = buildCopilotModelDefinition("gpt-5.5");
107-expect(def).toEqual({
108-id: "gpt-5.5",
109-name: "GPT-5.5",
110-api: "openai-responses",
111-reasoning: true,
112-input: ["text", "image"],
113-cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
114-contextWindow: 400_000,
115-maxTokens: 128_000,
116-});
117-});
118-119-it("uses static metadata overrides for Claude Opus 1M fallback rows", () => {
120-const def = buildCopilotModelDefinition("claude-opus-4.7-1m-internal");
121-expect(def).toEqual({
122-id: "claude-opus-4.7-1m-internal",
123-name: "Claude Opus 4.7 (1M context)",
124-api: "anthropic-messages",
125-reasoning: true,
126-input: ["text", "image"],
127-cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
128-contextWindow: 1_000_000,
129-maxTokens: 64_000,
130-thinkingLevelMap: { xhigh: "xhigh", max: null },
131-compat: { supportedReasoningEfforts: ["low", "medium", "high", "xhigh"] },
132-});
133-});
134-135-it("trims whitespace from model id", () => {
136-const def = buildCopilotModelDefinition(" gpt-4o ");
137-expect(def.id).toBe("gpt-4o");
138-expect(def.api).toBe("openai-responses");
139-});
140-141-it("routes Gemini models through Chat Completions with Copilot compat flags", () => {
142-const def = buildCopilotModelDefinition("gemini-3.1-pro-preview");
143-expect(def.api).toBe("openai-completions");
144-expect(def.compat).toEqual({
145-supportsStore: false,
146-supportsDeveloperRole: false,
147-supportsUsageInStreaming: false,
148-maxTokensField: "max_tokens",
149-});
150-});
151-152-it("throws on empty model id", () => {
153-expect(() => buildCopilotModelDefinition("")).toThrow("Model id required");
154-expect(() => buildCopilotModelDefinition(" ")).toThrow("Model id required");
155-});
156-});
157-});
158-15956describe("resolveCopilotForwardCompatModel", () => {
16057it("returns undefined for empty modelId", () => {
16158expect(resolveCopilotForwardCompatModel(createMockCtx(""))).toBeUndefined();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。