mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Add AbortSignal support to TypeScript SDK (#6378)
## Summary
Adds AbortSignal support to the TypeScript SDK for canceling thread
execution using AbortController.
## Changes
- Add `signal?: AbortSignal` property to `TurnOptions` type
- Pass signal through Thread class methods to exec layer
- Add signal parameter to `CodexExecArgs`
- Leverage Node.js native `spawn()` signal support for automatic
cancellation
- Add comprehensive test coverage (6 tests covering all abort scenarios)
## Implementation
The implementation uses Node.js's built-in AbortSignal support in
`spawn()` (available since Node v15, SDK requires >=18), which
automatically handles:
- Checking if already aborted before starting
- Killing the child process when abort is triggered
- Emitting appropriate error events
- All cleanup operations
This is a one-line change to the core implementation (`signal:
args.signal` passed to spawn), making it simple, reliable, and
maintainable.
## Usage Example
```typescript
import { Codex } from '@openai/codex-sdk';
const codex = new Codex({ apiKey: 'your-api-key' });
const thread = codex.startThread();
// Create AbortController
const controller = new AbortController();
// Run with abort signal
const resultPromise = thread.run("Your prompt here", {
signal: controller.signal
});
// Cancel anytime
controller.abort('User requested cancellation');
```
## Testing
All tests pass (23 total across SDK):
- ✅ Aborts when signal is already aborted (both run and runStreamed)
- ✅ Aborts during execution/iteration
- ✅ Completes normally when not aborted
- ✅ Backward compatible (signal is optional)
Tests verified to fail correctly when signal support is removed (no
false positives).
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: pakrym-oai <pakrym@openai.com>
This commit is contained in:
co-authored by
Claude
pakrym-oai
parent
c95bd345ea
commit
439bc5dbbe
@@ -24,6 +24,8 @@ export type CodexExecArgs = {
|
||||
outputSchemaFile?: string;
|
||||
// --config model_reasoning_effort
|
||||
modelReasoningEffort?: ModelReasoningEffort;
|
||||
// AbortSignal to cancel the execution
|
||||
signal?: AbortSignal;
|
||||
// --config sandbox_workspace_write.network_access
|
||||
networkAccessEnabled?: boolean;
|
||||
// --config features.web_search_request
|
||||
@@ -69,7 +71,10 @@ export class CodexExec {
|
||||
}
|
||||
|
||||
if (args.networkAccessEnabled !== undefined) {
|
||||
commandArgs.push("--config", `sandbox_workspace_write.network_access=${args.networkAccessEnabled}`);
|
||||
commandArgs.push(
|
||||
"--config",
|
||||
`sandbox_workspace_write.network_access=${args.networkAccessEnabled}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (args.webSearchEnabled !== undefined) {
|
||||
@@ -105,6 +110,7 @@ export class CodexExec {
|
||||
|
||||
const child = spawn(this.executablePath, commandArgs, {
|
||||
env,
|
||||
signal: args.signal,
|
||||
});
|
||||
|
||||
let spawnError: unknown | null = null;
|
||||
|
||||
@@ -86,6 +86,7 @@ export class Thread {
|
||||
skipGitRepoCheck: options?.skipGitRepoCheck,
|
||||
outputSchemaFile: schemaPath,
|
||||
modelReasoningEffort: options?.modelReasoningEffort,
|
||||
signal: turnOptions.signal,
|
||||
networkAccessEnabled: options?.networkAccessEnabled,
|
||||
webSearchEnabled: options?.webSearchEnabled,
|
||||
approvalPolicy: options?.approvalPolicy,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export type TurnOptions = {
|
||||
/** JSON schema describing the expected agent output. */
|
||||
outputSchema?: unknown;
|
||||
/** AbortSignal to cancel the turn. */
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user