Rename conversation to thread in codex exec (#4482)

This commit is contained in:
pakrym-oai
2025-09-29 20:18:30 -07:00
committed by GitHub
parent a8edc57740
commit ea82f86662
11 changed files with 211 additions and 229 deletions

View File

@@ -1,10 +1,10 @@
// based on event types from codex-rs/exec/src/exec_events.rs
import type { ConversationItem } from "./items";
import type { ThreadItem } from "./items";
export type SessionCreatedEvent = {
type: "session.created";
session_id: string;
export type ThreadStartedEvent = {
type: "thread.started";
thread_id: string;
};
export type TurnStartedEvent = {
@@ -22,31 +22,41 @@ export type TurnCompletedEvent = {
usage: Usage;
};
export type TurnFailedEvent = {
type: "turn.failed";
error: ThreadError;
};
export type ItemStartedEvent = {
type: "item.started";
item: ConversationItem;
item: ThreadItem;
};
export type ItemUpdatedEvent = {
type: "item.updated";
item: ConversationItem;
item: ThreadItem;
};
export type ItemCompletedEvent = {
type: "item.completed";
item: ConversationItem;
item: ThreadItem;
};
export type ConversationErrorEvent = {
export type ThreadError = {
message: string;
};
export type ThreadErrorEvent = {
type: "error";
message: string;
};
export type ConversationEvent =
| SessionCreatedEvent
export type ThreadEvent =
| ThreadStartedEvent
| TurnStartedEvent
| TurnCompletedEvent
| TurnFailedEvent
| ItemStartedEvent
| ItemUpdatedEvent
| ItemCompletedEvent
| ConversationErrorEvent;
| ThreadErrorEvent;

View File

@@ -6,7 +6,7 @@ export type CodexExecArgs = {
baseUrl?: string;
apiKey?: string;
sessionId?: string | null;
threadId?: string | null;
};
export class CodexExec {
@@ -17,8 +17,8 @@ export class CodexExec {
async *run(args: CodexExecArgs): AsyncGenerator<string> {
const commandArgs: string[] = ["exec", "--experimental-json"];
if (args.sessionId) {
commandArgs.push("resume", args.sessionId, args.input);
if (args.threadId) {
commandArgs.push("resume", args.threadId, args.input);
} else {
commandArgs.push(args.input);
}

View File

@@ -1,15 +1,17 @@
export type {
ConversationEvent,
SessionCreatedEvent,
ThreadEvent,
ThreadStartedEvent,
TurnStartedEvent,
TurnCompletedEvent,
TurnFailedEvent,
ItemStartedEvent,
ItemUpdatedEvent,
ItemCompletedEvent,
ConversationErrorEvent,
ThreadError,
ThreadErrorEvent,
} from "./events";
export type {
ConversationItem,
ThreadItem,
AssistantMessageItem,
ReasoningItem,
CommandExecutionItem,

View File

@@ -78,17 +78,7 @@ export type SessionItem = {
session_id: string;
};
export type ConversationItem =
| AssistantMessageItem
| ReasoningItem
| CommandExecutionItem
| FileChangeItem
| McpToolCallItem
| WebSearchItem
| TodoListItem
| ErrorItem;
export type ConversationItemDetails =
export type ThreadItem =
| AssistantMessageItem
| ReasoningItem
| CommandExecutionItem

View File

@@ -1,15 +1,15 @@
import { CodexOptions } from "./codexOptions";
import { ConversationEvent } from "./events";
import { ThreadEvent } from "./events";
import { CodexExec } from "./exec";
import { ConversationItem } from "./items";
import { ThreadItem } from "./items";
export type RunResult = {
items: ConversationItem[];
items: ThreadItem[];
finalResponse: string;
};
export type RunStreamedResult = {
events: AsyncGenerator<ConversationEvent>;
events: AsyncGenerator<ThreadEvent>;
};
export type Input = string;
@@ -29,17 +29,17 @@ export class Thread {
return { events: this.runStreamedInternal(input) };
}
private async *runStreamedInternal(input: string): AsyncGenerator<ConversationEvent> {
private async *runStreamedInternal(input: string): AsyncGenerator<ThreadEvent> {
const generator = this.exec.run({
input,
baseUrl: this.options.baseUrl,
apiKey: this.options.apiKey,
sessionId: this.id,
threadId: this.id,
});
for await (const item of generator) {
const parsed = JSON.parse(item) as ConversationEvent;
if (parsed.type === "session.created") {
this.id = parsed.session_id;
const parsed = JSON.parse(item) as ThreadEvent;
if (parsed.type === "thread.started") {
this.id = parsed.thread_id;
}
yield parsed;
}
@@ -47,7 +47,7 @@ export class Thread {
async run(input: string): Promise<RunResult> {
const generator = this.runStreamedInternal(input);
const items: ConversationItem[] = [];
const items: ThreadItem[] = [];
let finalResponse: string = "";
for await (const event of generator) {
if (event.type === "item.completed") {