From ea5e3e034e1eb10a79afc13f5022ec4114ac9969 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 1 May 2026 17:57:49 +0900 Subject: [PATCH] fix(model): allow artistry category fallbacks Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/shared/model-requirements.test.ts | 4 ++-- src/shared/model-requirements.ts | 1 - src/tools/delegate-task/tools.test.ts | 25 ++++++++++++------------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/shared/model-requirements.test.ts b/src/shared/model-requirements.test.ts index 6befdc59e..027ed04d8 100644 --- a/src/shared/model-requirements.test.ts +++ b/src/shared/model-requirements.test.ts @@ -605,12 +605,12 @@ describe("requiresModel field in categories", () => { expect(deep.requiresModel).toBeUndefined() }) - test("artistry category has requiresModel set to gemini-3.1-pro", () => { + test("artistry category no longer hard-requires gemini-3.1-pro", () => { // given const artistry = CATEGORY_MODEL_REQUIREMENTS["artistry"] // when / #then - expect(artistry.requiresModel).toBe("gemini-3.1-pro") + expect(artistry.requiresModel).toBeUndefined() }) }) diff --git a/src/shared/model-requirements.ts b/src/shared/model-requirements.ts index 786de3637..019da4d16 100644 --- a/src/shared/model-requirements.ts +++ b/src/shared/model-requirements.ts @@ -254,7 +254,6 @@ export const CATEGORY_MODEL_REQUIREMENTS: Record = { }, { providers: ["openai", "github-copilot", "opencode", "vercel"], model: "gpt-5.5" }, ], - requiresModel: "gemini-3.1-pro", }, quick: { fallbackChain: [ diff --git a/src/tools/delegate-task/tools.test.ts b/src/tools/delegate-task/tools.test.ts index 2abd75a71..a10711228 100644 --- a/src/tools/delegate-task/tools.test.ts +++ b/src/tools/delegate-task/tools.test.ts @@ -381,7 +381,7 @@ describe("sisyphus-task", () => { } //#when - await tool.execute(args as DelegateTaskArgs, toolContext) + await tool.execute(args, toolContext) //#then expect(args.load_skills).toEqual(["playwright", "git-master"]) @@ -444,7 +444,7 @@ describe("sisyphus-task", () => { } //#when - await tool.execute(args as DelegateTaskArgs, toolContext) + await tool.execute(args, toolContext) //#then expect(args.load_skills).toEqual([]) @@ -755,8 +755,8 @@ describe("sisyphus-task", () => { expect(result).toBeNull() }) - test("blocks requiresModel when availability is known and missing the required model", () => { - // given - artistry has requiresModel: gemini-3.1-pro + test("allows artistry to use its fallback chain when gemini is missing", () => { + // given - artistry can fall back from gemini to another capable model const categoryName = "artistry" const availableModels = new Set(["anthropic/claude-opus-4-7"]) @@ -767,11 +767,12 @@ describe("sisyphus-task", () => { }) // then - expect(result).toBeNull() + expect(result).not.toBeNull() + expect(result?.model).toBe("google/gemini-3.1-pro") }) - test("blocks requiresModel when availability is empty", () => { - // given - artistry has requiresModel: gemini-3.1-pro + test("allows artistry when availability is empty", () => { + // given - empty availability should not disable fallback-capable categories const categoryName = "artistry" const availableModels = new Set() @@ -782,7 +783,8 @@ describe("sisyphus-task", () => { }) // then - expect(result).toBeNull() + expect(result).not.toBeNull() + expect(result?.model).toBe("google/gemini-3.1-pro") }) test("bypasses requiresModel when explicit user config provided", () => { @@ -1825,7 +1827,7 @@ describe("sisyphus-task", () => { //#given a session with a previous message that has variant "max" const { createDelegateTask } = require("./tools") - const promptMock = mock(async (input: any) => { + const promptMock = mock(async () => { return { data: {} } }) @@ -3144,8 +3146,6 @@ describe("sisyphus-task", () => { test("should resolve agent-browser skill even when browserProvider is not set", async () => { // given - delegate_task without browserProvider const { createDelegateTask } = require("./tools") - let promptBody: any - const mockManager = { launch: async () => ({}) } const mockClient = { app: { agents: async () => ({ data: [] }) }, @@ -3153,8 +3153,7 @@ describe("sisyphus-task", () => { session: { get: async () => ({ data: { directory: "/project" } }), create: async () => ({ data: { id: "ses_no_browser_provider" } }), - prompt: async (input: any) => { - promptBody = input.body + prompt: async () => { return { data: {} } }, messages: async () => ({