Merge pull request #3605 from Jay1/jay/gpt-5-5-native-sisyphus

feat(agents): add GPT-5.5 native Sisyphus support
This commit is contained in:
acamq
2026-04-23 20:52:14 -06:00
committed by GitHub
7 changed files with 101 additions and 28 deletions
+30
View File
@@ -23,6 +23,23 @@ describe("getHephaestusPromptSource", () => {
expect(source3).toBe("gpt-5-4");
});
test("returns 'gpt-5-4' for gpt-5.5 models", () => {
// given
const model1 = "openai/gpt-5.5";
const model2 = "openai/gpt-5-5";
const model3 = "github-copilot/gpt-5.5";
// when
const source1 = getHephaestusPromptSource(model1);
const source2 = getHephaestusPromptSource(model2);
const source3 = getHephaestusPromptSource(model3);
// then
expect(source1).toBe("gpt-5-4");
expect(source2).toBe("gpt-5-4");
expect(source3).toBe("gpt-5-4");
});
test("returns 'gpt-5-3-codex' for GPT 5.3 Codex models", () => {
// given
const model1 = "openai/gpt-5.3-codex";
@@ -96,6 +113,19 @@ describe("getHephaestusPrompt", () => {
expect(prompt).toContain("<tool_usage_rules>");
});
test("GPT 5.5 model returns GPT-5.4 optimized prompt", () => {
// given
const model = "openai/gpt-5.5";
// when
const prompt = getHephaestusPrompt(model);
// then
expect(prompt).toContain("You build context by examining");
expect(prompt).toContain("Never chain together bash commands");
expect(prompt).toContain("<tool_usage_rules>");
});
test("GPT 5.3-codex model returns GPT-5.3 prompt", () => {
// given
const model = "openai/gpt-5.3-codex";
+2 -2
View File
@@ -1,6 +1,6 @@
import type { AgentConfig } from "@opencode-ai/sdk";
import type { AgentMode, AgentPromptMetadata } from "../types";
import { isGpt5_4Model, isGpt5_3CodexModel } from "../types";
import { isGpt5_3CodexModel, isGptNativeSisyphusModel } from "../types";
import type {
AvailableAgent,
AvailableTool,
@@ -21,7 +21,7 @@ export type HephaestusPromptSource = "gpt-5-4" | "gpt-5-3-codex" | "gpt";
export function getHephaestusPromptSource(
model?: string,
): HephaestusPromptSource {
if (model && isGpt5_4Model(model)) {
if (model && isGptNativeSisyphusModel(model)) {
return "gpt-5-4";
}
if (model && isGpt5_3CodexModel(model)) {
+2 -2
View File
@@ -1,6 +1,6 @@
import type { AgentConfig } from "@opencode-ai/sdk";
import type { AgentMode, AgentPromptMetadata } from "./types";
import { isGptModel, isGeminiModel, isGpt5_4Model } from "./types";
import { isGptModel, isGeminiModel, isGptNativeSisyphusModel } from "./types";
import {
buildGeminiToolMandate,
buildGeminiDelegationOverride,
@@ -480,7 +480,7 @@ export function createSisyphusAgent(
const categories = availableCategories ?? [];
const agents = availableAgents ?? [];
if (isGpt5_4Model(model)) {
if (isGptNativeSisyphusModel(model)) {
const prompt = buildGpt54SisyphusPrompt(
model,
agents,
+37 -17
View File
@@ -1,26 +1,46 @@
import { describe, test, expect } from "bun:test";
import { isGptModel, isGeminiModel, isGlmModel, isGpt5_4Model, isMiniMaxModel } from "./types";
import {
isGptModel,
isGeminiModel,
isGlmModel,
isGptNativeSisyphusModel,
isMiniMaxModel,
} from "./types";
describe("isGpt5_4Model", () => {
test("detects gpt-5.4 models", () => {
expect(isGpt5_4Model("openai/gpt-5.4")).toBe(true);
expect(isGpt5_4Model("openai/gpt-5-4")).toBe(true);
expect(isGpt5_4Model("openai/gpt-5.4-codex")).toBe(true);
expect(isGpt5_4Model("github-copilot/gpt-5.4")).toBe(true);
expect(isGpt5_4Model("venice/gpt-5-4")).toBe(true);
describe("isGptNativeSisyphusModel", () => {
test("allows GPT-5.x where x >= 4", () => {
expect(isGptNativeSisyphusModel("openai/gpt-5.4")).toBe(true);
expect(isGptNativeSisyphusModel("openai/gpt-5-4")).toBe(true);
expect(isGptNativeSisyphusModel("openai/gpt-5.5")).toBe(true);
expect(isGptNativeSisyphusModel("openai/gpt-5-5")).toBe(true);
expect(isGptNativeSisyphusModel("openai/gpt-5.9")).toBe(true);
expect(isGptNativeSisyphusModel("openai/gpt-5-9")).toBe(true);
expect(isGptNativeSisyphusModel("openai/gpt-5.10")).toBe(true);
expect(isGptNativeSisyphusModel("openai/gpt-5-10")).toBe(true);
});
test("does not match other GPT models", () => {
expect(isGpt5_4Model("openai/gpt-5.3-codex")).toBe(false);
expect(isGpt5_4Model("openai/gpt-5.1")).toBe(false);
expect(isGpt5_4Model("openai/gpt-4o")).toBe(false);
expect(isGpt5_4Model("github-copilot/gpt-4o")).toBe(false);
test("allows with various providers and suffixes", () => {
expect(isGptNativeSisyphusModel("github-copilot/gpt-5.4")).toBe(true);
expect(isGptNativeSisyphusModel("venice/gpt-5-4")).toBe(true);
expect(isGptNativeSisyphusModel("openai/gpt-5.4-codex")).toBe(true);
expect(isGptNativeSisyphusModel("openai/gpt-5.5-mini")).toBe(true);
});
test("does not match non-GPT models", () => {
expect(isGpt5_4Model("anthropic/claude-opus-4-7")).toBe(false);
expect(isGpt5_4Model("google/gemini-3.1-pro")).toBe(false);
expect(isGpt5_4Model("openai/o1")).toBe(false);
test("rejects GPT-5.x where x < 4", () => {
expect(isGptNativeSisyphusModel("openai/gpt-5.3-codex")).toBe(false);
expect(isGptNativeSisyphusModel("openai/gpt-5.1")).toBe(false);
expect(isGptNativeSisyphusModel("openai/gpt-5-0")).toBe(false);
});
test("rejects other GPT models", () => {
expect(isGptNativeSisyphusModel("openai/gpt-4o")).toBe(false);
expect(isGptNativeSisyphusModel("github-copilot/gpt-4o")).toBe(false);
});
test("rejects non-GPT models", () => {
expect(isGptNativeSisyphusModel("anthropic/claude-opus-4-7")).toBe(false);
expect(isGptNativeSisyphusModel("google/gemini-3.1-pro")).toBe(false);
expect(isGptNativeSisyphusModel("openai/o1")).toBe(false);
});
});
+4 -2
View File
@@ -79,9 +79,11 @@ export function isGptModel(model: string): boolean {
return modelName.includes("gpt");
}
export function isGpt5_4Model(model: string): boolean {
const GPT_NATIVE_SISYPHUS_RE = /gpt-5[.-](?:[4-9]|\d{2,})/i;
export function isGptNativeSisyphusModel(model: string): boolean {
const modelName = extractModelName(model).toLowerCase();
return modelName.includes("gpt-5.4") || modelName.includes("gpt-5-4");
return GPT_NATIVE_SISYPHUS_RE.test(modelName);
}
export function isGpt5_3CodexModel(model: string): boolean {