@@ -4,6 +4,7 @@
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed GitHub Copilot Claude adaptive-thinking effort metadata to match manually checked Copilot model capabilities ([#4637](https://github.com/earendil-works/pi/issues/4637)).
|
||||
- Fixed OpenCode/OpenCode Go completion models that reject `prompt_cache_retention` to omit long-retention cache fields when `cacheRetention` is `long` ([#5702](https://github.com/earendil-works/pi/issues/5702)).
|
||||
|
||||
## [0.79.3] - 2026-06-13
|
||||
|
||||
@@ -196,6 +196,14 @@ const OPENCODE_OPENAI_COMPLETIONS_LONG_CACHE_RETENTION_UNSUPPORTED_MODELS = new
|
||||
"opencode-go:kimi-k2.6",
|
||||
]);
|
||||
|
||||
// Checked manually against the authenticated GitHub Copilot /models endpoint on 2026-06-15.
|
||||
// Keep this to narrow corrections over models.dev metadata instead of snapshotting Copilot's catalog.
|
||||
const GITHUB_COPILOT_THINKING_LEVEL_OVERRIDES = {
|
||||
"claude-opus-4.7": { minimal: "low" },
|
||||
"claude-opus-4.8": { minimal: "low" },
|
||||
"claude-sonnet-4.6": { minimal: "low", xhigh: "max" },
|
||||
} satisfies Record<string, NonNullable<Model<Api>["thinkingLevelMap"]>>;
|
||||
|
||||
function mergeThinkingLevelMap(model: Model<any>, map: NonNullable<Model<any>["thinkingLevelMap"]>): void {
|
||||
model.thinkingLevelMap = { ...model.thinkingLevelMap, ...map };
|
||||
}
|
||||
@@ -358,6 +366,12 @@ function applyThinkingLevelMetadata(model: Model<any>): void {
|
||||
// Ring reasons by default. Only high/xhigh have documented explicit effort controls.
|
||||
mergeThinkingLevelMap(model, ANT_LING_RING_THINKING_LEVEL_MAP);
|
||||
}
|
||||
if (model.provider === "github-copilot") {
|
||||
const override = GITHUB_COPILOT_THINKING_LEVEL_OVERRIDES[model.id];
|
||||
if (override) {
|
||||
mergeThinkingLevelMap(model, override);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getAnthropicMessagesCompat(provider: string, modelId: string): AnthropicMessagesCompat | undefined {
|
||||
|
||||
@@ -4194,7 +4194,7 @@ export const MODELS = {
|
||||
headers: {"User-Agent":"GitHubCopilotChat/0.35.0","Editor-Version":"vscode/1.107.0","Editor-Plugin-Version":"copilot-chat/0.35.0","Copilot-Integration-Id":"vscode-chat"},
|
||||
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
|
||||
reasoning: true,
|
||||
thinkingLevelMap: {"xhigh":"xhigh"},
|
||||
thinkingLevelMap: {"xhigh":"xhigh","minimal":"low"},
|
||||
input: ["text", "image"],
|
||||
cost: {
|
||||
input: 5,
|
||||
@@ -4214,7 +4214,7 @@ export const MODELS = {
|
||||
headers: {"User-Agent":"GitHubCopilotChat/0.35.0","Editor-Version":"vscode/1.107.0","Editor-Plugin-Version":"copilot-chat/0.35.0","Copilot-Integration-Id":"vscode-chat"},
|
||||
compat: {"forceAdaptiveThinking":true,"supportsTemperature":false},
|
||||
reasoning: true,
|
||||
thinkingLevelMap: {"xhigh":"xhigh"},
|
||||
thinkingLevelMap: {"xhigh":"xhigh","minimal":"low"},
|
||||
input: ["text", "image"],
|
||||
cost: {
|
||||
input: 5,
|
||||
@@ -4272,6 +4272,7 @@ export const MODELS = {
|
||||
headers: {"User-Agent":"GitHubCopilotChat/0.35.0","Editor-Version":"vscode/1.107.0","Editor-Plugin-Version":"copilot-chat/0.35.0","Copilot-Integration-Id":"vscode-chat"},
|
||||
compat: {"forceAdaptiveThinking":true},
|
||||
reasoning: true,
|
||||
thinkingLevelMap: {"minimal":"low","xhigh":"max"},
|
||||
input: ["text", "image"],
|
||||
cost: {
|
||||
input: 3,
|
||||
@@ -4831,6 +4832,42 @@ export const MODELS = {
|
||||
contextWindow: 262144,
|
||||
maxTokens: 32768,
|
||||
} satisfies Model<"google-generative-ai">,
|
||||
"gemma-4-E2B-it": {
|
||||
id: "gemma-4-E2B-it",
|
||||
name: "Gemma 4 E2B IT",
|
||||
api: "google-generative-ai",
|
||||
provider: "google",
|
||||
baseUrl: "https://generativelanguage.googleapis.com/v1beta",
|
||||
reasoning: true,
|
||||
thinkingLevelMap: {"off":null,"minimal":"MINIMAL","low":null,"medium":null,"high":"HIGH"},
|
||||
input: ["text", "image"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
} satisfies Model<"google-generative-ai">,
|
||||
"gemma-4-E4B-it": {
|
||||
id: "gemma-4-E4B-it",
|
||||
name: "Gemma 4 E4B IT",
|
||||
api: "google-generative-ai",
|
||||
provider: "google",
|
||||
baseUrl: "https://generativelanguage.googleapis.com/v1beta",
|
||||
reasoning: true,
|
||||
thinkingLevelMap: {"off":null,"minimal":"MINIMAL","low":null,"medium":null,"high":"HIGH"},
|
||||
input: ["text", "image"],
|
||||
cost: {
|
||||
input: 0,
|
||||
output: 0,
|
||||
cacheRead: 0,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 131072,
|
||||
maxTokens: 8192,
|
||||
} satisfies Model<"google-generative-ai">,
|
||||
},
|
||||
"google-vertex": {
|
||||
"gemini-1.5-flash": {
|
||||
@@ -9432,13 +9469,13 @@ export const MODELS = {
|
||||
thinkingLevelMap: {"minimal":null,"low":null,"medium":null,"high":"high","xhigh":"xhigh"},
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0.098,
|
||||
output: 0.196,
|
||||
input: 0.09,
|
||||
output: 0.18,
|
||||
cacheRead: 0.02,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 1048576,
|
||||
maxTokens: 4096,
|
||||
maxTokens: 65536,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"deepseek/deepseek-v4-pro": {
|
||||
id: "deepseek/deepseek-v4-pro",
|
||||
@@ -13304,6 +13341,25 @@ export const MODELS = {
|
||||
contextWindow: 262144,
|
||||
maxTokens: 131000,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"moonshotai/Kimi-K2.7-Code": {
|
||||
id: "moonshotai/Kimi-K2.7-Code",
|
||||
name: "Kimi K2.7 Code",
|
||||
api: "openai-completions",
|
||||
provider: "together",
|
||||
baseUrl: "https://api.together.ai/v1",
|
||||
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","supportsStrictMode":false,"supportsLongCacheRetention":false,"thinkingFormat":"together"},
|
||||
reasoning: true,
|
||||
thinkingLevelMap: {"minimal":null,"low":null,"medium":null},
|
||||
input: ["text"],
|
||||
cost: {
|
||||
input: 0.95,
|
||||
output: 4,
|
||||
cacheRead: 0.19,
|
||||
cacheWrite: 0,
|
||||
},
|
||||
contextWindow: 262144,
|
||||
maxTokens: 131072,
|
||||
} satisfies Model<"openai-completions">,
|
||||
"nvidia/nemotron-3-ultra-550b-a55b": {
|
||||
id: "nvidia/nemotron-3-ultra-550b-a55b",
|
||||
name: "Nemotron 3 Ultra 550B A55B",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { getModel } from "../src/models.ts";
|
||||
import { getModel, getSupportedThinkingLevels } from "../src/models.ts";
|
||||
import { streamAnthropic } from "../src/providers/anthropic.ts";
|
||||
import type { Context } from "../src/types.ts";
|
||||
|
||||
@@ -54,6 +54,16 @@ describe("Copilot Claude via Anthropic Messages", () => {
|
||||
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }],
|
||||
};
|
||||
|
||||
it("applies Copilot-specific adaptive thinking effort overrides", () => {
|
||||
const opus47 = getModel("github-copilot", "claude-opus-4.7");
|
||||
expect(opus47.thinkingLevelMap).toMatchObject({ minimal: "low", xhigh: "xhigh" });
|
||||
expect(getSupportedThinkingLevels(opus47)).toContain("xhigh");
|
||||
|
||||
const sonnet46 = getModel("github-copilot", "claude-sonnet-4.6");
|
||||
expect(sonnet46.thinkingLevelMap).toMatchObject({ minimal: "low", xhigh: "max" });
|
||||
expect(getSupportedThinkingLevels(sonnet46)).toContain("xhigh");
|
||||
});
|
||||
|
||||
it("uses Bearer auth, Copilot headers, and valid Anthropic Messages payload", async () => {
|
||||
const model = getModel("github-copilot", "claude-sonnet-4.6");
|
||||
expect(model.api).toBe("anthropic-messages");
|
||||
|
||||
Reference in New Issue
Block a user