feat(agents): simplify GPT detection to name-based check, add hephaestus providers (venice uses gpt-5.3-codex)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -2,11 +2,17 @@ import { describe, test, expect } from "bun:test";
|
||||
import { isGptModel, isGeminiModel } from "./types";
|
||||
|
||||
describe("isGptModel", () => {
|
||||
test("standard openai provider models", () => {
|
||||
test("standard openai provider gpt models", () => {
|
||||
expect(isGptModel("openai/gpt-5.2")).toBe(true);
|
||||
expect(isGptModel("openai/gpt-4o")).toBe(true);
|
||||
expect(isGptModel("openai/o1")).toBe(true);
|
||||
expect(isGptModel("openai/o3-mini")).toBe(true);
|
||||
});
|
||||
|
||||
test("o-series models are not gpt by name", () => {
|
||||
expect(isGptModel("openai/o1")).toBe(false);
|
||||
expect(isGptModel("openai/o3-mini")).toBe(false);
|
||||
expect(isGptModel("litellm/o1")).toBe(false);
|
||||
expect(isGptModel("litellm/o3-mini")).toBe(false);
|
||||
expect(isGptModel("litellm/o4-mini")).toBe(false);
|
||||
});
|
||||
|
||||
test("github copilot gpt models", () => {
|
||||
@@ -17,9 +23,6 @@ describe("isGptModel", () => {
|
||||
test("litellm proxied gpt models", () => {
|
||||
expect(isGptModel("litellm/gpt-5.2")).toBe(true);
|
||||
expect(isGptModel("litellm/gpt-4o")).toBe(true);
|
||||
expect(isGptModel("litellm/o1")).toBe(true);
|
||||
expect(isGptModel("litellm/o3-mini")).toBe(true);
|
||||
expect(isGptModel("litellm/o4-mini")).toBe(true);
|
||||
});
|
||||
|
||||
test("other proxied gpt models", () => {
|
||||
@@ -27,6 +30,11 @@ describe("isGptModel", () => {
|
||||
expect(isGptModel("custom-provider/gpt-5.2")).toBe(true);
|
||||
});
|
||||
|
||||
test("venice provider gpt models", () => {
|
||||
expect(isGptModel("venice/gpt-5.2")).toBe(true);
|
||||
expect(isGptModel("venice/gpt-4o")).toBe(true);
|
||||
});
|
||||
|
||||
test("gpt4 prefix without hyphen (legacy naming)", () => {
|
||||
expect(isGptModel("litellm/gpt4o")).toBe(true);
|
||||
expect(isGptModel("ollama/gpt4")).toBe(true);
|
||||
|
||||
@@ -70,14 +70,9 @@ function extractModelName(model: string): string {
|
||||
return model.includes("/") ? model.split("/").pop() ?? model : model
|
||||
}
|
||||
|
||||
const GPT_MODEL_PREFIXES = ["gpt-", "gpt4", "o1", "o3", "o4"]
|
||||
|
||||
export function isGptModel(model: string): boolean {
|
||||
if (model.startsWith("openai/") || model.startsWith("github-copilot/gpt-"))
|
||||
return true
|
||||
|
||||
const modelName = extractModelName(model).toLowerCase()
|
||||
return GPT_MODEL_PREFIXES.some((prefix) => modelName.startsWith(prefix))
|
||||
return modelName.includes("gpt")
|
||||
}
|
||||
|
||||
const GEMINI_PROVIDERS = ["google/", "google-vertex/"]
|
||||
|
||||
@@ -589,8 +589,8 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
|
||||
}
|
||||
})
|
||||
|
||||
test("hephaestus is NOT created when only github-copilot is connected (gpt-5.3-codex unavailable via github-copilot)", async () => {
|
||||
// #given - github-copilot provider has models available, but no cache
|
||||
test("hephaestus IS created when github-copilot is connected with a GPT model", async () => {
|
||||
// #given - github-copilot provider has gpt-5.3-codex available
|
||||
const fetchSpy = spyOn(shared, "fetchAvailableModels").mockResolvedValue(
|
||||
new Set(["github-copilot/gpt-5.3-codex"])
|
||||
)
|
||||
@@ -600,8 +600,8 @@ describe("createBuiltinAgents with requiresProvider gating (hephaestus)", () =>
|
||||
// #when
|
||||
const agents = await createBuiltinAgents([], {}, undefined, TEST_DEFAULT_MODEL, undefined, undefined, [], {})
|
||||
|
||||
// #then - hephaestus requires openai/opencode, github-copilot alone is insufficient
|
||||
expect(agents.hephaestus).toBeUndefined()
|
||||
// #then - github-copilot is now a valid provider for hephaestus
|
||||
expect(agents.hephaestus).toBeDefined()
|
||||
} finally {
|
||||
fetchSpy.mockRestore()
|
||||
cacheSpy.mockRestore()
|
||||
|
||||
@@ -168,14 +168,14 @@ describe("AGENT_MODEL_REQUIREMENTS", () => {
|
||||
expect(primary.providers[0]).toBe("opencode")
|
||||
})
|
||||
|
||||
test("hephaestus requires openai/opencode provider (not github-copilot since gpt-5.3-codex unavailable there)", () => {
|
||||
test("hephaestus supports openai, github-copilot, venice, and opencode providers", () => {
|
||||
// #given - hephaestus agent requirement
|
||||
const hephaestus = AGENT_MODEL_REQUIREMENTS["hephaestus"]
|
||||
|
||||
// #when - accessing hephaestus requirement
|
||||
// #then - requiresProvider is set to openai and opencode only (github-copilot removed)
|
||||
// #then - requiresProvider includes openai, github-copilot, venice, and opencode
|
||||
expect(hephaestus).toBeDefined()
|
||||
expect(hephaestus.requiresProvider).toEqual(["openai", "opencode"])
|
||||
expect(hephaestus.requiresProvider).toEqual(["openai", "github-copilot", "venice", "opencode"])
|
||||
expect(hephaestus.requiresModel).toBeUndefined()
|
||||
})
|
||||
|
||||
|
||||
@@ -24,9 +24,10 @@ export const AGENT_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
|
||||
},
|
||||
hephaestus: {
|
||||
fallbackChain: [
|
||||
{ providers: ["openai", "opencode"], model: "gpt-5.3-codex", variant: "medium" },
|
||||
{ providers: ["openai", "venice", "opencode"], model: "gpt-5.3-codex", variant: "medium" },
|
||||
{ providers: ["github-copilot"], model: "gpt-5.2", variant: "medium" },
|
||||
],
|
||||
requiresProvider: ["openai", "opencode"],
|
||||
requiresProvider: ["openai", "github-copilot", "venice", "opencode"],
|
||||
},
|
||||
oracle: {
|
||||
fallbackChain: [
|
||||
|
||||
Reference in New Issue
Block a user