Skip to content

Commit d04efd4

Browse files
committed
feat: give codex system prompt via personality
1 parent fe3f90f commit d04efd4

6 files changed

Lines changed: 76 additions & 22 deletions

File tree

apps/code/src/main/services/agent/service.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -551,11 +551,18 @@ When creating pull requests, add the following footer at the end of the PR descr
551551
});
552552

553553
try {
554+
const systemPrompt = this.buildSystemPrompt(
555+
credentials,
556+
taskId,
557+
customInstructions,
558+
);
559+
554560
const acpConnection = await agent.run(taskId, taskRunId, {
555561
adapter,
556562
gatewayUrl: proxyUrl,
557563
codexBinaryPath: adapter === "codex" ? getCodexBinaryPath() : undefined,
558564
model,
565+
instructions: adapter === "codex" ? systemPrompt.append : undefined,
559566
processCallbacks: {
560567
onProcessSpawned: (info) => {
561568
this.processTracking.register(
@@ -656,12 +663,6 @@ When creating pull requests, add the following footer at the end of the PR descr
656663
}
657664
}
658665

659-
const systemPrompt = this.buildSystemPrompt(
660-
credentials,
661-
taskId,
662-
customInstructions,
663-
);
664-
665666
// Both adapters implement unstable_resumeSession:
666667
// - Claude: delegates to SDK's resumeSession with JSONL hydration
667668
// - Codex: delegates to codex-acp's loadSession internally
@@ -698,11 +699,6 @@ When creating pull requests, add the following footer at the end of the PR descr
698699
taskRunId,
699700
});
700701
}
701-
const systemPrompt = this.buildSystemPrompt(
702-
credentials,
703-
taskId,
704-
customInstructions,
705-
);
706702
const newSessionResponse = await connection.newSession({
707703
cwd: repoPath,
708704
mcpServers,

packages/agent/src/adapters/codex/codex-agent.ts

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -282,18 +282,49 @@ export class CodexAcpAgent extends BaseAcpAgent {
282282

283283
const response = await this.codexConnection.prompt(params);
284284

285-
// Emit PostHog usage notification
286-
if (this.sessionState?.taskRunId && response.usage) {
287-
await this.client.extNotification("_posthog/usage_update", {
285+
if (this.sessionState && response.usage) {
286+
// Accumulate token usage from the prompt response
287+
this.sessionState.accumulatedUsage.inputTokens +=
288+
response.usage.inputTokens ?? 0;
289+
this.sessionState.accumulatedUsage.outputTokens +=
290+
response.usage.outputTokens ?? 0;
291+
this.sessionState.accumulatedUsage.cachedReadTokens +=
292+
response.usage.cachedReadTokens ?? 0;
293+
this.sessionState.accumulatedUsage.cachedWriteTokens +=
294+
response.usage.cachedWriteTokens ?? 0;
295+
}
296+
297+
if (this.sessionState?.taskRunId) {
298+
const { accumulatedUsage } = this.sessionState;
299+
300+
await this.client.extNotification(POSTHOG_NOTIFICATIONS.TURN_COMPLETE, {
288301
sessionId: params.sessionId,
289-
used: {
290-
inputTokens: response.usage.inputTokens ?? 0,
291-
outputTokens: response.usage.outputTokens ?? 0,
292-
cachedReadTokens: response.usage.cachedReadTokens ?? 0,
293-
cachedWriteTokens: response.usage.cachedWriteTokens ?? 0,
302+
stopReason: response.stopReason ?? "end_turn",
303+
usage: {
304+
inputTokens: accumulatedUsage.inputTokens,
305+
outputTokens: accumulatedUsage.outputTokens,
306+
cachedReadTokens: accumulatedUsage.cachedReadTokens,
307+
cachedWriteTokens: accumulatedUsage.cachedWriteTokens,
308+
totalTokens:
309+
accumulatedUsage.inputTokens +
310+
accumulatedUsage.outputTokens +
311+
accumulatedUsage.cachedReadTokens +
312+
accumulatedUsage.cachedWriteTokens,
294313
},
295-
cost: null,
296314
});
315+
316+
if (response.usage) {
317+
await this.client.extNotification("_posthog/usage_update", {
318+
sessionId: params.sessionId,
319+
used: {
320+
inputTokens: response.usage.inputTokens ?? 0,
321+
outputTokens: response.usage.outputTokens ?? 0,
322+
cachedReadTokens: response.usage.cachedReadTokens ?? 0,
323+
cachedWriteTokens: response.usage.cachedWriteTokens ?? 0,
324+
},
325+
cost: null,
326+
});
327+
}
297328
}
298329

299330
return response;

packages/agent/src/adapters/codex/codex-client.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,34 @@ export function createCodexClient(
6060
},
6161

6262
async sessionUpdate(params: SessionNotification): Promise<void> {
63-
// Parse usage data from session updates
6463
const update = params.update as Record<string, unknown> | undefined;
6564
if (update?.sessionUpdate === "usage_update") {
6665
const used = update.used as number | undefined;
6766
const size = update.size as number | undefined;
6867
if (used !== undefined) sessionState.contextUsed = used;
6968
if (size !== undefined) sessionState.contextSize = size;
69+
70+
// Accumulate per-message token usage when available
71+
const inputTokens = update.inputTokens as number | undefined;
72+
const outputTokens = update.outputTokens as number | undefined;
73+
if (inputTokens !== undefined) {
74+
sessionState.accumulatedUsage.inputTokens += inputTokens;
75+
}
76+
if (outputTokens !== undefined) {
77+
sessionState.accumulatedUsage.outputTokens += outputTokens;
78+
}
79+
const cachedRead = update.cachedReadTokens as number | undefined;
80+
const cachedWrite = update.cachedWriteTokens as number | undefined;
81+
if (cachedRead !== undefined) {
82+
sessionState.accumulatedUsage.cachedReadTokens += cachedRead;
83+
}
84+
if (cachedWrite !== undefined) {
85+
sessionState.accumulatedUsage.cachedWriteTokens += cachedWrite;
86+
}
87+
7088
callbacks?.onUsageUpdate?.(update);
7189
}
7290

73-
// Forward to upstream client
7491
await upstreamClient.sessionUpdate(params);
7592
},
7693

packages/agent/src/adapters/codex/spawn.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export interface CodexProcessOptions {
1010
apiBaseUrl?: string;
1111
apiKey?: string;
1212
model?: string;
13+
instructions?: string;
1314
binaryPath?: string;
1415
logger?: Logger;
1516
processCallbacks?: ProcessSpawnedCallback;
@@ -42,6 +43,13 @@ function buildConfigArgs(options: CodexProcessOptions): string[] {
4243
args.push("-c", `model="${options.model}"`);
4344
}
4445

46+
if (options.instructions) {
47+
const escaped = options.instructions
48+
.replace(/\\/g, "\\\\")
49+
.replace(/"/g, '\\"');
50+
args.push("-c", `instructions="${escaped}"`);
51+
}
52+
4553
return args;
4654
}
4755

packages/agent/src/agent.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export class Agent {
131131
apiKey: gatewayConfig.apiKey,
132132
binaryPath: options.codexBinaryPath,
133133
model: sanitizedModel,
134+
instructions: options.instructions,
134135
}
135136
: undefined,
136137
});

packages/agent/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export interface TaskExecutionOptions {
112112
model?: string;
113113
gatewayUrl?: string;
114114
codexBinaryPath?: string;
115+
instructions?: string;
115116
processCallbacks?: ProcessSpawnedCallback;
116117
}
117118

0 commit comments

Comments
 (0)