Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions sdk/typescript/src/exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export type CodexExecArgs = {
outputSchemaFile?: string;
};

const INTERNAL_ORIGINATOR_ENV = "CODEX_INTERNAL_ORIGINATOR_OVERRIDE";
const TYPESCRIPT_SDK_ORIGINATOR = "codex_sdk_ts";

export class CodexExec {
private executablePath: string;
constructor(executablePath: string | null = null) {
Expand Down Expand Up @@ -59,6 +62,9 @@ export class CodexExec {
const env = {
...process.env,
};
if (!env[INTERNAL_ORIGINATOR_ENV]) {
env[INTERNAL_ORIGINATOR_ENV] = TYPESCRIPT_SDK_ORIGINATOR;
}
if (args.baseUrl) {
env.OPENAI_BASE_URL = args.baseUrl;
}
Expand Down
3 changes: 2 additions & 1 deletion sdk/typescript/tests/responsesProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export type ResponsesApiRequest = {
export type RecordedRequest = {
body: string;
json: ResponsesApiRequest;
headers: http.IncomingHttpHeaders;
};

function formatSseEvent(event: SseEvent): string {
Expand Down Expand Up @@ -90,7 +91,7 @@ export async function startResponsesTestProxy(
if (req.method === "POST" && req.url === "/responses") {
const body = await readRequestBody(req);
const json = JSON.parse(body);
requests.push({ body, json });
requests.push({ body, json, headers: { ...req.headers } });

const status = options.statusCode ?? 200;
res.statusCode = status;
Expand Down
24 changes: 24 additions & 0 deletions sdk/typescript/tests/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,30 @@ describe("Codex", () => {
await close();
}
});

it("sets the codex sdk originator header", async () => {
const { url, close, requests } = await startResponsesTestProxy({
statusCode: 200,
responseBodies: [sse(responseStarted(), assistantMessage("Hi!"), responseCompleted())],
});

try {
const client = new Codex({ codexPathOverride: codexExecPath, baseUrl: url, apiKey: "test" });

const thread = client.startThread();
await thread.run("Hello, originator!");

expect(requests.length).toBeGreaterThan(0);
const originatorHeader = requests[0]!.headers["originator"];
if (Array.isArray(originatorHeader)) {
expect(originatorHeader).toContain("codex_sdk_ts");
} else {
expect(originatorHeader).toBe("codex_sdk_ts");
}
} finally {
await close();
}
});
it("throws ThreadRunError on turn failures", async () => {
const { url, close } = await startResponsesTestProxy({
statusCode: 200,
Expand Down
Loading