feat(codex): add structured file edit output with diffs for restored sessions
Add structured output matching StructuredToolResult type for Codex
apply_patch operations when parsing rollout files. This enables the
frontend to render file edit diffs for restored Codex sessions, matching
the behavior of Claude agent file edits.
Note: For live streaming, the Codex SDK only provides file_change events
with {path, kind} without actual patch content. The structured diffs are
only available for restored sessions via rollout file parsing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -609,7 +609,6 @@ class CodexAgentSession implements AgentSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private *translateEvent(event: ThreadEvent): Generator<AgentStreamEvent> {
|
private *translateEvent(event: ThreadEvent): Generator<AgentStreamEvent> {
|
||||||
|
|
||||||
const permissionEvents = this.handlePermissionEvent(event);
|
const permissionEvents = this.handlePermissionEvent(event);
|
||||||
if (permissionEvents) {
|
if (permissionEvents) {
|
||||||
for (const permissionEvent of permissionEvents) {
|
for (const permissionEvent of permissionEvents) {
|
||||||
@@ -1147,8 +1146,17 @@ function finalizeRolloutFunctionCall(
|
|||||||
|
|
||||||
function handleRolloutCustomToolCall(payload: RolloutCustomToolCallPayload, events: AgentStreamEvent[]): void {
|
function handleRolloutCustomToolCall(payload: RolloutCustomToolCallPayload, events: AgentStreamEvent[]): void {
|
||||||
if (payload?.name === "apply_patch" && typeof payload.input === "string") {
|
if (payload?.name === "apply_patch" && typeof payload.input === "string") {
|
||||||
const files = parsePatchFiles(payload.input);
|
const patchText = payload.input;
|
||||||
|
const files = parsePatchFiles(patchText);
|
||||||
if (files.length) {
|
if (files.length) {
|
||||||
|
// Build structured output with the patch/diff for each file
|
||||||
|
const parsedEdits = files.map((file) => ({
|
||||||
|
filePath: file.path,
|
||||||
|
kind: file.kind,
|
||||||
|
// Include the full patch as diff - frontend will render it
|
||||||
|
diff: patchText,
|
||||||
|
}));
|
||||||
|
|
||||||
events.push({
|
events.push({
|
||||||
type: "timeline",
|
type: "timeline",
|
||||||
provider: "codex",
|
provider: "codex",
|
||||||
@@ -1158,7 +1166,12 @@ function handleRolloutCustomToolCall(payload: RolloutCustomToolCallPayload, even
|
|||||||
status: "completed",
|
status: "completed",
|
||||||
displayName: buildFileChangeSummary(files),
|
displayName: buildFileChangeSummary(files),
|
||||||
kind: "edit",
|
kind: "edit",
|
||||||
output: { files },
|
output: {
|
||||||
|
type: "file_edit" as const,
|
||||||
|
filePath: files[0]?.path ?? "unknown",
|
||||||
|
diff: patchText,
|
||||||
|
parsedEdits,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user