From d2c2a4cab1a7b42b3c40be3a6a74bdbe5fd1421c Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 9 Jul 2026 21:30:34 -0700 Subject: [PATCH] FN-7754: seed OpenAI GPT-5.6 Codex models into pi createFnAgent registry Wires the GPT-5.6 codenamed OpenAI Codex models (gpt-5.6-luna/sol/terra) into the engine pi model-registry seeding surface, mirroring the dashboard's /api/models supplemental merge so the models are no longer missing from pi. - Call mergeSupplementalOpenAiCodexModels() in createFnAgent (packages/engine/src/pi.ts) alongside the existing Anthropic supplemental merge - Add regression tests covering synthesis of missing GPT-5.6 rows and dedupe against pinned catalog entries - Update docs/settings-reference.md to describe the additive surfacing on both /api/models and the engine/pi registry-seeding path - Add a patch changeset for @runfusion/fusion Files changed: .changeset/fn-7754-openai-gpt-5-6-pi-surface.md | 7 +++ docs/settings-reference.md | 2 +- .../src/__tests__/pi-create-fn-agent.test.ts | 63 ++++++++++++++++++++++ packages/engine/src/pi.ts | 6 +++ 4 files changed, 77 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-7754 Fusion-Task-Lineage: b61b6812-c94b-46d8-b187-445ccdd6e4e9 Co-authored-by: Fusion (runfusion.ai) --- .../fn-7754-openai-gpt-5-6-pi-surface.md | 7 +++ docs/settings-reference.md | 2 +- .../src/__tests__/pi-create-fn-agent.test.ts | 63 +++++++++++++++++++ packages/engine/src/pi.ts | 6 ++ 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 .changeset/fn-7754-openai-gpt-5-6-pi-surface.md diff --git a/.changeset/fn-7754-openai-gpt-5-6-pi-surface.md b/.changeset/fn-7754-openai-gpt-5-6-pi-surface.md new file mode 100644 index 0000000000..cfac0ec744 --- /dev/null +++ b/.changeset/fn-7754-openai-gpt-5-6-pi-surface.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: The latest OpenAI GPT-5.6 models now appear everywhere, not just the Settings model list. +category: fix +dev: Wires mergeSupplementalOpenAiCodexModels into the engine pi createFnAgent registry-seeding surface (packages/engine/src/pi.ts) alongside the existing mergeSupplementalAnthropicModels call, mirroring register-model-routes.ts. FN-7745 only wired the dashboard /api/models route, so gpt-5.6-luna/sol/terra were absent on the pi surface. Additive, dedupe-safe; adds a pi-create-fn-agent regression test. diff --git a/docs/settings-reference.md b/docs/settings-reference.md index 5934d17aaa..91101fca35 100644 --- a/docs/settings-reference.md +++ b/docs/settings-reference.md @@ -977,7 +977,7 @@ When the Cursor Runtime plugin (`fusion-plugin-cursor-runtime`) is installed and When the Grok Runtime plugin (`fusion-plugin-grok-runtime`) is installed and the `useGrokCli` toggle is enabled (Settings → Authentication), Grok CLI-discovered models (`grok models`) are surfaced additively in `/api/models` under the `grok-cli` provider — id/name derived from the discovered model id/label. This surfacing is fetched through a short-TTL, single-flight cache so the model picker never spawns `grok` on every request; a missing/failed/unavailable Grok CLI binary simply yields zero `grok-cli` rows without affecting other providers. Disabling `useGrokCli` hides all `grok-cli` rows. Unlike Cursor (OAuth/session auth), Grok is API-key auth: the Settings card's status text guides operators to `GROK_API_KEY` or `~/.grok/user-settings.json` when the binary is available but no key is configured. -The three GPT-5.6 codenamed OpenAI Codex variants (`gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`) are additively surfaced under the `openai-codex` provider (FN-7745, mirroring the Anthropic/Z.ai supplemental-merge pattern above) so they appear in `/api/models` whenever `openai-codex` is configured — deduped against any pinned pi-ai catalog row that already carries one of the ids. +The three GPT-5.6 codenamed OpenAI Codex variants (`gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`) are additively surfaced under the `openai-codex` provider (FN-7745/FN-7754, mirroring the Anthropic/Z.ai supplemental-merge pattern above) so they appear both in dashboard `/api/models` and the engine/pi `createFnAgent` registry-seeding surface whenever `openai-codex` is configured — deduped against any pinned pi-ai catalog row that already carries one of the ids. ### Planning model diff --git a/packages/engine/src/__tests__/pi-create-fn-agent.test.ts b/packages/engine/src/__tests__/pi-create-fn-agent.test.ts index 8cce7063aa..3b8dd8b12f 100644 --- a/packages/engine/src/__tests__/pi-create-fn-agent.test.ts +++ b/packages/engine/src/__tests__/pi-create-fn-agent.test.ts @@ -1932,6 +1932,69 @@ describe("createFnAgent", () => { expect(anthropicRegistrations).toHaveLength(0); }); + it("synthesizes OpenAI Codex GPT-5.6 models from supplemental metadata when the pi registry lacks them", async () => { + // FNXC:ModelCatalog 2026-07-09-00:00: + // FN-7754 regression coverage for the createFnAgent registry-seeding surface: a pi catalog with no openai-codex provider/models must still surface all GPT-5.6 codenamed variants through the shared additive supplemental merge. + getAllMock.mockReturnValue([]); + findMock.mockImplementation((provider: string, modelId: string) => ({ provider, id: modelId })); + + const { createFnAgent } = await import("../pi.js"); + await createFnAgent({ + cwd: "/tmp", + systemPrompt: "test", + tools: "readonly", + defaultProvider: "openai-codex", + defaultModelId: "gpt-5.6-luna", + }); + + expect(registerProviderMock).toHaveBeenCalledWith("openai-codex", expect.objectContaining({ + models: expect.arrayContaining([ + expect.objectContaining({ id: "gpt-5.6-luna" }), + expect.objectContaining({ id: "gpt-5.6-sol" }), + expect.objectContaining({ id: "gpt-5.6-terra" }), + ]), + })); + expect(createAgentSessionMock).toHaveBeenCalledWith(expect.objectContaining({ + model: { provider: "openai-codex", id: "gpt-5.6-luna" }, + })); + }); + + it("does not duplicate OpenAI Codex GPT-5.6 rows already present in the pi registry", async () => { + const existingLunaRow = { + provider: "openai-codex", + id: "gpt-5.6-luna", + name: "GPT-5.6 Luna Upstream", + reasoning: true, + input: ["text"], + cost: { input: 1, output: 2 }, + contextWindow: 200_000, + maxTokens: 16_000, + }; + getAllMock.mockReturnValue([existingLunaRow]); + findMock.mockImplementation((provider: string, modelId: string) => ({ provider, id: modelId })); + + const { createFnAgent } = await import("../pi.js"); + await createFnAgent({ + cwd: "/tmp", + systemPrompt: "test", + tools: "readonly", + defaultProvider: "openai-codex", + defaultModelId: "gpt-5.6-luna", + }); + + const openAiCodexRegistrations = registerProviderMock.mock.calls.filter(([name]) => name === "openai-codex"); + expect(openAiCodexRegistrations).toHaveLength(1); + const registeredProvider = openAiCodexRegistrations[0]?.[1] as { models: Array<{ id: string; name?: string }> }; + const registeredModels = registeredProvider.models; + const lunaRows = registeredModels.filter((model) => model.id === "gpt-5.6-luna"); + expect(lunaRows).toHaveLength(1); + expect(lunaRows[0]).toMatchObject({ name: "GPT-5.6 Luna Upstream" }); + expect(registeredModels).toEqual(expect.arrayContaining([ + expect.objectContaining({ id: "gpt-5.6-sol" }), + expect.objectContaining({ id: "gpt-5.6-terra" }), + ])); + }); + // Restored v0.51.0 behavior: a subscription-OAuth `anthropic/` selection stays on // the built-in `anthropic` provider (pi-ai POSTs the OAuth token to /v1 with Claude Code // impersonation). No `/v1`-based `anthropic-subscription` provider is registered, and there diff --git a/packages/engine/src/pi.ts b/packages/engine/src/pi.ts index f5e01ac520..1c21d975e0 100644 --- a/packages/engine/src/pi.ts +++ b/packages/engine/src/pi.ts @@ -45,6 +45,7 @@ import { mergeBuiltInGrokProviderModels, mergeBuiltInZaiProviderModels, mergeSupplementalAnthropicModels, + mergeSupplementalOpenAiCodexModels, registerBuiltInGrokProvider, registerBuiltInZaiProvider, resolvePiExtensionProjectRoot, @@ -2121,6 +2122,11 @@ export async function createFnAgent(options: AgentOptions): Promise } modelRegistry.refresh(); mergeSupplementalAnthropicModels(modelRegistry, (message) => extensionsLog.warn(message)); + /* + * FNXC:ModelCatalog 2026-07-09-00:00: + * FN-7754 mirrors the dashboard register-model-routes.ts supplemental merge seam so the GPT-5.6 codenamed OpenAI-Codex models surface on the engine createFnAgent registry-seeding path, not just /api/models. FN-7745 only wired the dashboard surface; this merge is additive and dedupe-safe, so pinned catalog rows win and no duplicate ids are added. + */ + mergeSupplementalOpenAiCodexModels(modelRegistry, (message) => extensionsLog.warn(message)); // Build the pi built-in tool set. We deliberately do NOT use the bundled // `createCodingTools` / `createReadOnlyTools` presets — they're missing