Skip to content

feat: pass context to runTools callbacks#1973

Open
HAYDEN-OAI wants to merge 2 commits into
mainfrom
codex/run-tools-context
Open

feat: pass context to runTools callbacks#1973
HAYDEN-OAI wants to merge 2 commits into
mainfrom
codex/run-tools-context

Conversation

@HAYDEN-OAI

Copy link
Copy Markdown
Contributor

Summary

  • add a typed toolContext option to both streaming and non-streaming runTools parameters
  • pass the same context value as the third argument to raw and parsed tool callbacks
  • remove toolContext before creating Chat Completions requests so it remains local to the runner
  • add runtime and compile-time coverage for context delivery, identity preservation, request omission, and type inference

Motivation

runTools users currently need closures or custom wrapper types to share per-run application state across tools defined in separate modules. This adds a first-class context channel while preserving existing callback signatures and keeping the context scoped to one runner invocation.

Resolves #597

Validation

  • pnpm run format
  • pnpm exec tsc --noEmit
  • pnpm exec jest tests/lib/ChatCompletionRunFunctions.test.ts --runInBand
  • git diff --check

@HAYDEN-OAI HAYDEN-OAI marked this pull request as ready for review July 6, 2026 19:28
@HAYDEN-OAI HAYDEN-OAI requested a review from a team as a code owner July 6, 2026 19:28
@HAYDEN-OAI HAYDEN-OAI requested a review from apcha-oai July 6, 2026 19:28
@openai-sdks

openai-sdks Bot commented Jul 6, 2026

Copy link
Copy Markdown

OkTest Summary

237/237 SDK tests passed in 10.881s for Node SDK PR #1973.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 153ms
tests/chat-completions-create.test.ts ✅ Passed 214ms
tests/chat-completions-stream.test.ts ✅ Passed 255ms
tests/files-content-binary.test.ts ✅ Passed 139ms
tests/files-create-multipart.test.ts ✅ Passed 200ms
tests/files-list-pagination.test.ts ✅ Passed 173ms
tests/initialize-config.test.ts ✅ Passed 177ms
tests/instance-isolation.test.ts ✅ Passed 110ms
tests/models-list.test.ts ✅ Passed 147ms
tests/responses-background-lifecycle.test.ts ✅ Passed 219ms
tests/responses-body-method-errors.test.ts ✅ Passed 346ms
tests/responses-cancel-timeout.test.ts ✅ Passed 205ms
tests/responses-cancel.test.ts ✅ Passed 244ms
tests/responses-compact-retries.test.ts ✅ Passed 280ms
tests/responses-compact.test.ts ✅ Passed 258ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 131ms
tests/responses-create-advanced.test.ts ✅ Passed 192ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.182s
tests/responses-create-errors.test.ts ✅ Passed 222ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 142ms
tests/responses-create-retries.test.ts ✅ Passed 321ms
tests/responses-create-stream-failures.test.ts ✅ Passed 226ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 2.169s
tests/responses-create-stream-wire.test.ts ✅ Passed 2.605s
tests/responses-create-stream.test.ts ✅ Passed 114ms
tests/responses-create-terminal-states.test.ts ✅ Passed 309ms
tests/responses-create-timeout.test.ts ✅ Passed 218ms
tests/responses-create.test.ts ✅ Passed 151ms
tests/responses-delete.test.ts ✅ Passed 217ms
tests/responses-input-items-errors.test.ts ✅ Passed 283ms
tests/responses-input-items-list.test.ts ✅ Passed 195ms
tests/responses-input-items-options.test.ts ✅ Passed 198ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 258ms
tests/responses-input-tokens-count.test.ts ✅ Passed 316ms
tests/responses-malformed-inputs.test.ts ✅ Passed 2.325s
tests/responses-not-found-errors.test.ts ✅ Passed 259ms
tests/responses-parse.test.ts ✅ Passed 229ms
tests/responses-retrieve-retries.test.ts ✅ Passed 391ms
tests/responses-retrieve.test.ts ✅ Passed 237ms
tests/responses-stored-method-errors.test.ts ✅ Passed 627ms
tests/retry-behavior.test.ts ✅ Passed 2.831s
tests/sdk-error-shape.test.ts ✅ Passed 328ms

View OkTest run #28820022281

SDK merge (2e47f5dd3b43) · head (312facbf6490) · base (95b54e589491) · OkTest (7fc645091b1a)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c0494b1fdc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/ChatCompletionRunner.ts

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified the linked #597 use case against the built declarations and both runner modes. The base revision rejects a three-argument callback/context-bearing call, while this head correctly infers context.eventId; the focused runner suite (21 tests), tsc --noEmit, and an additional streaming harness all pass. The same context object is preserved and toolContext is absent from every API request.

There is one blocking soundness issue: concrete context-bearing tools can still be invoked without a context, which compiles and then supplies undefined to a callback typed as receiving the concrete context. Details and a minimal reproduction are inline. Existing two-argument callbacks remain source/runtime compatible, CI's breaking-change check and SDK tests are green, and I found no other behavioral regressions.

/**
* Context to pass to each tool callback during this run.
*/
toolContext?: ToolContext;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Require context when callbacks require it

Because this property stays optional for a concrete ToolContext, the following compiles under strict (including against the built package):

const tool: RunnableToolFunction<string, { eventId: string }> = {
  type: 'function',
  function: { parameters: {}, description: 'x',
    function: (_args, _runner, context) => context.eventId },
};
ChatCompletionRunner.runTools(openai, { model, messages, tools: [tool] });

At runtime _runTools casts the omitted value to ToolContext and invokes the callback with undefined; the example throws while reading eventId. The resource helper also accepts this typed-tool form without toolContext, and the streaming params have the same issue. Please expose a context-bearing form/overload where toolContext is required, while retaining a separate optional/no-context form for existing callbacks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Passing global context into tools called by the runTools helper

2 participants