mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 06:04:51 +00:00
Merge pull request #358 from default-anton/migrate-glm-4.7-to-openai
Migrate zai provider from Anthropic to OpenAI-compatible API
This commit is contained in:
commit
04a764742e
4 changed files with 34 additions and 29 deletions
|
|
@ -258,7 +258,7 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process xAi models
|
// Process zAi models
|
||||||
if (data.zai?.models) {
|
if (data.zai?.models) {
|
||||||
for (const [modelId, model] of Object.entries(data.zai.models)) {
|
for (const [modelId, model] of Object.entries(data.zai.models)) {
|
||||||
const m = model as ModelsDevModel;
|
const m = model as ModelsDevModel;
|
||||||
|
|
@ -268,9 +268,9 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
|
||||||
models.push({
|
models.push({
|
||||||
id: modelId,
|
id: modelId,
|
||||||
name: m.name || modelId,
|
name: m.name || modelId,
|
||||||
api: supportsImage ? "openai-completions" : "anthropic-messages",
|
api: "openai-completions",
|
||||||
provider: "zai",
|
provider: "zai",
|
||||||
baseUrl: supportsImage ? "https://api.z.ai/api/coding/paas/v4" : "https://api.z.ai/api/anthropic",
|
baseUrl: "https://api.z.ai/api/coding/paas/v4",
|
||||||
reasoning: m.reasoning === true,
|
reasoning: m.reasoning === true,
|
||||||
input: supportsImage ? ["text", "image"] : ["text"],
|
input: supportsImage ? ["text", "image"] : ["text"],
|
||||||
cost: {
|
cost: {
|
||||||
|
|
@ -279,11 +279,9 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
|
||||||
cacheRead: m.cost?.cache_read || 0,
|
cacheRead: m.cost?.cache_read || 0,
|
||||||
cacheWrite: m.cost?.cache_write || 0,
|
cacheWrite: m.cost?.cache_write || 0,
|
||||||
},
|
},
|
||||||
...(supportsImage ? {
|
compat: {
|
||||||
compat: {
|
supportsDeveloperRole: false,
|
||||||
supportsDeveloperRole: false,
|
},
|
||||||
},
|
|
||||||
} : {}),
|
|
||||||
contextWindow: m.limit?.context || 4096,
|
contextWindow: m.limit?.context || 4096,
|
||||||
maxTokens: m.limit?.output || 4096,
|
maxTokens: m.limit?.output || 4096,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6978,9 +6978,10 @@ export const MODELS = {
|
||||||
"glm-4.5": {
|
"glm-4.5": {
|
||||||
id: "glm-4.5",
|
id: "glm-4.5",
|
||||||
name: "GLM-4.5",
|
name: "GLM-4.5",
|
||||||
api: "anthropic-messages",
|
api: "openai-completions",
|
||||||
provider: "zai",
|
provider: "zai",
|
||||||
baseUrl: "https://api.z.ai/api/anthropic",
|
baseUrl: "https://api.z.ai/api/coding/paas/v4",
|
||||||
|
compat: {"supportsDeveloperRole":false},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
input: ["text"],
|
input: ["text"],
|
||||||
cost: {
|
cost: {
|
||||||
|
|
@ -6991,13 +6992,14 @@ export const MODELS = {
|
||||||
},
|
},
|
||||||
contextWindow: 131072,
|
contextWindow: 131072,
|
||||||
maxTokens: 98304,
|
maxTokens: 98304,
|
||||||
} satisfies Model<"anthropic-messages">,
|
} satisfies Model<"openai-completions">,
|
||||||
"glm-4.5-air": {
|
"glm-4.5-air": {
|
||||||
id: "glm-4.5-air",
|
id: "glm-4.5-air",
|
||||||
name: "GLM-4.5-Air",
|
name: "GLM-4.5-Air",
|
||||||
api: "anthropic-messages",
|
api: "openai-completions",
|
||||||
provider: "zai",
|
provider: "zai",
|
||||||
baseUrl: "https://api.z.ai/api/anthropic",
|
baseUrl: "https://api.z.ai/api/coding/paas/v4",
|
||||||
|
compat: {"supportsDeveloperRole":false},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
input: ["text"],
|
input: ["text"],
|
||||||
cost: {
|
cost: {
|
||||||
|
|
@ -7008,13 +7010,14 @@ export const MODELS = {
|
||||||
},
|
},
|
||||||
contextWindow: 131072,
|
contextWindow: 131072,
|
||||||
maxTokens: 98304,
|
maxTokens: 98304,
|
||||||
} satisfies Model<"anthropic-messages">,
|
} satisfies Model<"openai-completions">,
|
||||||
"glm-4.5-flash": {
|
"glm-4.5-flash": {
|
||||||
id: "glm-4.5-flash",
|
id: "glm-4.5-flash",
|
||||||
name: "GLM-4.5-Flash",
|
name: "GLM-4.5-Flash",
|
||||||
api: "anthropic-messages",
|
api: "openai-completions",
|
||||||
provider: "zai",
|
provider: "zai",
|
||||||
baseUrl: "https://api.z.ai/api/anthropic",
|
baseUrl: "https://api.z.ai/api/coding/paas/v4",
|
||||||
|
compat: {"supportsDeveloperRole":false},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
input: ["text"],
|
input: ["text"],
|
||||||
cost: {
|
cost: {
|
||||||
|
|
@ -7025,7 +7028,7 @@ export const MODELS = {
|
||||||
},
|
},
|
||||||
contextWindow: 131072,
|
contextWindow: 131072,
|
||||||
maxTokens: 98304,
|
maxTokens: 98304,
|
||||||
} satisfies Model<"anthropic-messages">,
|
} satisfies Model<"openai-completions">,
|
||||||
"glm-4.5v": {
|
"glm-4.5v": {
|
||||||
id: "glm-4.5v",
|
id: "glm-4.5v",
|
||||||
name: "GLM-4.5V",
|
name: "GLM-4.5V",
|
||||||
|
|
@ -7047,9 +7050,10 @@ export const MODELS = {
|
||||||
"glm-4.6": {
|
"glm-4.6": {
|
||||||
id: "glm-4.6",
|
id: "glm-4.6",
|
||||||
name: "GLM-4.6",
|
name: "GLM-4.6",
|
||||||
api: "anthropic-messages",
|
api: "openai-completions",
|
||||||
provider: "zai",
|
provider: "zai",
|
||||||
baseUrl: "https://api.z.ai/api/anthropic",
|
baseUrl: "https://api.z.ai/api/coding/paas/v4",
|
||||||
|
compat: {"supportsDeveloperRole":false},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
input: ["text"],
|
input: ["text"],
|
||||||
cost: {
|
cost: {
|
||||||
|
|
@ -7060,7 +7064,7 @@ export const MODELS = {
|
||||||
},
|
},
|
||||||
contextWindow: 204800,
|
contextWindow: 204800,
|
||||||
maxTokens: 131072,
|
maxTokens: 131072,
|
||||||
} satisfies Model<"anthropic-messages">,
|
} satisfies Model<"openai-completions">,
|
||||||
"glm-4.6v": {
|
"glm-4.6v": {
|
||||||
id: "glm-4.6v",
|
id: "glm-4.6v",
|
||||||
name: "GLM-4.6V",
|
name: "GLM-4.6V",
|
||||||
|
|
@ -7082,9 +7086,10 @@ export const MODELS = {
|
||||||
"glm-4.7": {
|
"glm-4.7": {
|
||||||
id: "glm-4.7",
|
id: "glm-4.7",
|
||||||
name: "GLM-4.7",
|
name: "GLM-4.7",
|
||||||
api: "anthropic-messages",
|
api: "openai-completions",
|
||||||
provider: "zai",
|
provider: "zai",
|
||||||
baseUrl: "https://api.z.ai/api/anthropic",
|
baseUrl: "https://api.z.ai/api/coding/paas/v4",
|
||||||
|
compat: {"supportsDeveloperRole":false},
|
||||||
reasoning: true,
|
reasoning: true,
|
||||||
input: ["text"],
|
input: ["text"],
|
||||||
cost: {
|
cost: {
|
||||||
|
|
@ -7095,6 +7100,6 @@ export const MODELS = {
|
||||||
},
|
},
|
||||||
contextWindow: 204800,
|
contextWindow: 204800,
|
||||||
maxTokens: 131072,
|
maxTokens: 131072,
|
||||||
} satisfies Model<"anthropic-messages">,
|
} satisfies Model<"openai-completions">,
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
|
||||||
|
|
@ -460,13 +460,15 @@ function convertMessages(
|
||||||
};
|
};
|
||||||
|
|
||||||
const textBlocks = msg.content.filter((b) => b.type === "text") as TextContent[];
|
const textBlocks = msg.content.filter((b) => b.type === "text") as TextContent[];
|
||||||
if (textBlocks.length > 0) {
|
// Filter out empty text blocks to avoid API validation errors
|
||||||
|
const nonEmptyTextBlocks = textBlocks.filter((b) => b.text && b.text.trim().length > 0);
|
||||||
|
if (nonEmptyTextBlocks.length > 0) {
|
||||||
// GitHub Copilot requires assistant content as a string, not an array.
|
// GitHub Copilot requires assistant content as a string, not an array.
|
||||||
// Sending as array causes Claude models to re-answer all previous prompts.
|
// Sending as array causes Claude models to re-answer all previous prompts.
|
||||||
if (model.provider === "github-copilot") {
|
if (model.provider === "github-copilot") {
|
||||||
assistantMsg.content = textBlocks.map((b) => sanitizeSurrogates(b.text)).join("");
|
assistantMsg.content = nonEmptyTextBlocks.map((b) => sanitizeSurrogates(b.text)).join("");
|
||||||
} else {
|
} else {
|
||||||
assistantMsg.content = textBlocks.map((b) => {
|
assistantMsg.content = nonEmptyTextBlocks.map((b) => {
|
||||||
return { type: "text", text: sanitizeSurrogates(b.text) };
|
return { type: "text", text: sanitizeSurrogates(b.text) };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -556,7 +556,7 @@ describe("Generate E2E Tests", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe.skipIf(!process.env.ZAI_API_KEY)("zAI Provider (glm-4.5-air via Anthropic Messages)", () => {
|
describe.skipIf(!process.env.ZAI_API_KEY)("zAI Provider (glm-4.5-air via OpenAI Completions)", () => {
|
||||||
const llm = getModel("zai", "glm-4.5-air");
|
const llm = getModel("zai", "glm-4.5-air");
|
||||||
|
|
||||||
it("should complete basic text generation", { retry: 3 }, async () => {
|
it("should complete basic text generation", { retry: 3 }, async () => {
|
||||||
|
|
@ -572,11 +572,11 @@ describe("Generate E2E Tests", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip("should handle thinking mode", { retry: 3 }, async () => {
|
it.skip("should handle thinking mode", { retry: 3 }, async () => {
|
||||||
await handleThinking(llm, { thinkingEnabled: true, thinkingBudgetTokens: 2048 });
|
await handleThinking(llm, { reasoningEffort: "medium" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle multi-turn with thinking and tools", { retry: 3 }, async () => {
|
it("should handle multi-turn with thinking and tools", { retry: 3 }, async () => {
|
||||||
await multiTurn(llm, { thinkingEnabled: true, thinkingBudgetTokens: 2048 });
|
await multiTurn(llm, { reasoningEffort: "medium" });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue