From 4f5224122ab4b2bd533a8afd0324680cc9f00f8b Mon Sep 17 00:00:00 2001 From: "paseo-bot[bot]" <266920839+paseo-bot[bot]@users.noreply.github.com> Date: Sat, 26 Sep 2026 19:54:47 +0200 Subject: [PATCH] fix(codex): invoke an inline skill steered into a running turn --- .../providers/codex-app-server-agent.test.ts | 48 +++++++++++++++++++ .../agent/providers/codex-app-server-agent.ts | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts b/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts index 329e30b488..dd7ebd4e4c 100644 --- a/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts +++ b/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts @@ -242,6 +242,54 @@ describe("Codex active-turn steering admission", () => { appServer.assertNoErrors(); }); + test("a steer resolves a Codex skill mentioned after prose into app-server skill input", async () => { + const appServer = createFakeCodexAppServer({ + "skills/list": () => ({ + data: [ + { + cwd: "/workspace/project", + skills: [ + { + name: "paseo-implement", + description: "Execute an existing Paseo plan.", + path: "/workspace/skills/paseo-implement/SKILL.md", + }, + ], + errors: [], + }, + ], + }), + "turn/steer": () => ({ turn: { id: "native-A" } }), + }); + const { session, paseoTurnId } = await startPublicSteeringSession(appServer); + + await expect( + session.steerActiveTurn!("Then use /paseo-implement to complete it.", { + expectedTurnId: paseoTurnId, + }), + ).resolves.toEqual({ status: "accepted" }); + + const steer = appServer.requests().find((request) => request.method === "turn/steer"); + expect(steer?.params).toEqual( + expect.objectContaining({ + input: [ + { + type: "skill", + name: "paseo-implement", + path: "/workspace/skills/paseo-implement/SKILL.md", + }, + { + type: "text", + text: "Then use $paseo-implement to complete it.", + text_elements: [], + }, + ], + }), + ); + await session.close(); + appServer.assertNoErrors(); + }); + test("a clearing steer denies every pending permission through its provider handler", async () => { const appServer = createFakeCodexAppServer({ "turn/steer": () => ({ turn: { id: "native-A" } }), diff --git a/packages/server/src/server/agent/providers/codex-app-server-agent.ts b/packages/server/src/server/agent/providers/codex-app-server-agent.ts index 2d8030ed09..744a8d8851 100644 --- a/packages/server/src/server/agent/providers/codex-app-server-agent.ts +++ b/packages/server/src/server/agent/providers/codex-app-server-agent.ts @@ -4365,7 +4365,7 @@ export class CodexAppServerAgentSession implements AgentSession { if (!this.matchesSteerAdmission({ client, threadId, nativeTurnId, foregroundTurnId })) { return { status: "unavailable" }; } - const input = await this.buildUserInput(prompt); + const input = await this.buildUserInput(await this.attachMentionedSkills(prompt)); if (!this.matchesSteerAdmission({ client, threadId, nativeTurnId, foregroundTurnId })) { return { status: "unavailable" }; }