Skip to content

Commit bea9503

Browse files
committed
Steering implementation
1 parent 921d466 commit bea9503

12 files changed

Lines changed: 957 additions & 59 deletions

examples/steering.ts

Lines changed: 444 additions & 0 deletions
Large diffs are not rendered by default.

examples/tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"compilerOptions": {
4+
"rootDir": ".",
5+
"declaration": false,
6+
"declarationMap": false,
7+
"sourceMap": false
8+
},
9+
"include": [
10+
"steering.ts"
11+
],
12+
"exclude": []
13+
}

package-lock.json

Lines changed: 59 additions & 53 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@
3333
"package:win-x64": "cd dist/bin && zip codex-acp-x64-windows.zip codex-acp-x64-windows.exe",
3434
"package:win-arm64": "cd dist/bin && zip codex-acp-arm64-windows.zip codex-acp-arm64-windows.exe",
3535
"start": "node --import tsx src/index.ts",
36+
"example:steering": "node --import tsx examples/steering.ts",
37+
"example:steering:multistep": "node --import tsx examples/steering.ts",
3638
"generate-types": "./node_modules/.bin/codex app-server generate-ts --out src/app-server",
3739
"test": "vitest run",
3840
"test:e2e": "npm run build && RUN_E2E_TESTS=true vitest run src/__tests__/CodexACPAgent/e2e",
3941
"test:watch": "vitest",
40-
"typecheck": "tsc --noEmit",
42+
"typecheck": "tsc --noEmit && tsc --noEmit -p examples/tsconfig.json",
4143
"codex-test": "tsx .claude/skills/run-codex/scripts/run-codex-test.ts"
4244
},
4345
"homepage": "https://github.com/agentclientprotocol/codex-acp#readme",
@@ -62,7 +64,7 @@
6264
},
6365
"dependencies": {
6466
"@agentclientprotocol/sdk": "^1.2.1",
65-
"@openai/codex": "^0.144.4",
67+
"@openai/codex": "^0.144.5",
6668
"diff": "^9.0.0",
6769
"open": "^11.0.0",
6870
"vscode-jsonrpc": "^9.0.1",

src/AcpExtensions.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import type {
22
ClientContext,
3+
ContentBlock,
34
LoadSessionResponse,
45
NewSessionResponse,
56
ResumeSessionResponse,
67
SessionId,
78
} from "@agentclientprotocol/sdk";
89

910
export const LEGACY_SET_SESSION_MODEL_METHOD = "session/set_model";
11+
export const SESSION_STEERING_METHOD = "_session/steering";
1012
export const GOAL_CONTROL_METHOD = "_codex/session/goal_control";
1113

1214
export type LegacySessionModel = {
@@ -43,13 +45,15 @@ export type ExtMethodRequest =
4345
AuthenticationStatusRequest
4446
| AuthenticationLogoutRequest
4547
| LegacySetSessionModelExtRequest
48+
| SessionSteeringExtRequest
4649
| GoalControlExtRequest
4750

4851
export function isExtMethodRequest(request: { method: string, params: Record<string, unknown> }): request is ExtMethodRequest {
4952
return request.method === "authentication/status"
5053
|| request.method === "authentication/logout"
5154
|| request.method === LEGACY_SET_SESSION_MODEL_METHOD
52-
|| request.method === GOAL_CONTROL_METHOD;
55+
|| request.method === GOAL_CONTROL_METHOD
56+
|| request.method === SESSION_STEERING_METHOD;
5357
}
5458

5559
export type AuthenticationStatusRequest = { method: "authentication/status", params: {} }
@@ -79,3 +83,24 @@ export async function legacySetSessionModel(
7983
): Promise<LegacySetSessionModelResponse> {
8084
return await connection.request<LegacySetSessionModelResponse, LegacySetSessionModelRequest>(LEGACY_SET_SESSION_MODEL_METHOD, params);
8185
}
86+
87+
export type SessionSteerRequest = {
88+
sessionId: SessionId;
89+
prompt: ContentBlock[];
90+
}
91+
92+
export type SessionSteeringResponse = {
93+
outcome: "injected" | "startedNewTurn";
94+
}
95+
96+
export type SessionSteeringExtRequest = {
97+
method: typeof SESSION_STEERING_METHOD;
98+
params: SessionSteerRequest;
99+
}
100+
101+
export async function steerSessionWithFallback(
102+
connection: Pick<ClientContext, "request">,
103+
params: SessionSteerRequest,
104+
): Promise<SessionSteeringResponse> {
105+
return await connection.request<SessionSteeringResponse, SessionSteerRequest>(SESSION_STEERING_METHOD, params);
106+
}

src/CodexAcpClient.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import type {
3737
ThreadGoalStatus,
3838
ThreadSourceKind,
3939
TurnCompletedNotification,
40+
TurnSteerResponse,
4041
UserInput,
4142
} from "./app-server/v2";
4243
import packageJson from "../package.json";
@@ -833,6 +834,14 @@ export class CodexAcpClient {
833834
});
834835
}
835836

837+
async steerTurn(params: { threadId: string, turnId: string, prompt: acp.ContentBlock[] }): Promise<TurnSteerResponse> {
838+
return await this.codexClient.turnSteer({
839+
threadId: params.threadId,
840+
expectedTurnId: params.turnId,
841+
input: buildPromptItems(params.prompt),
842+
});
843+
}
844+
836845
async fetchAvailableModels(): Promise<Model[]> {
837846
const models: Model[] = [];
838847
let cursor: string | null = null;

0 commit comments

Comments
 (0)