Skip to content

docs: document Agent.clone list property sharing - #1705

Merged
seratch merged 3 commits into
openai:mainfrom
thegoodengineer:docs/agent-clone-list-sharing
Aug 16, 2026
Merged

seratch merged 3 commits into
openai:mainfrom
thegoodengineer:docs/agent-clone-list-sharing

Conversation

@thegoodengineer

Copy link
Copy Markdown
Contributor

Summary

Agent.clone() does not document how list properties are copied, and the real behavior is easy to get backwards. A clone and its original reference the same array for any list property that clone() does not override, so mutating that list through either agent changes both.

Current behavior on main, unmodified:

1. clone() WITHOUT overriding tools/handoffs
   cloned.tools === original.tools                      true
   cloned.handoffs === original.handoffs                true
   after cloned.tools.push -> original.tools.length     2
   original silently gained the tool                    true

2. clone() WITH tools overridden
   cloned.tools === original.tools                      false
   cloned.tools === the array passed to clone()         true

3. constructor stores the caller array by reference
   agent.tools === the array I passed in                true

4. entries themselves are shared
   cloned.tools[0] === original.tools[0]                true

5. inputGuardrails / outputGuardrails / mcpServers      all behave the same

This is not a new observation. The identical semantics were raised against the Python SDK in openai/openai-agents-python#1293, and the resolution there was to document them rather than change them: openai/openai-agents-python#1296 added a clone() docstring stating that new list objects are created only if overridden, but their contents are shared with the original.

That PR is also a good illustration of how easy this is to misread. The reporter's own reproduction asserted clone.tools is not original.tools, and the test failed in review, because the lists are in fact the same object.

The JS clone() JSDoc carries none of this. This change adds it so both SDKs describe the same contract.

Fix

JSDoc only. No behavior change and no API change.

The wording names the affected properties explicitly (tools, handoffs, mcpServers, inputGuardrails, outputGuardrails), separates the overridden case from the non-overridden one, states that list entries are shared in both cases, and shows the supported way to give a clone a list it owns:

const newAgent = agent.clone({ tools: [...agent.tools, extraTool] });

Test plan

Two tests in packages/agents-core/test/agent.test.ts. Both pin current behavior, so they pass before and after this change:

  • shares list properties between a clone and its original as documented
  • gives the clone its own array for a list property passed to clone

Because they are guards rather than regression tests, I verified they are load bearing by temporarily replacing the constructor assignments with copying versions (config.tools ? [...config.tools] : []) and confirming the first one fails:

FAIL  test/agent.test.ts > shares list properties between a clone and its original as documented
AssertionError: expected [ { type: 'function', ...(15) } ] to be [ ... ] // Object.is equality
  626|     // A property that clone() does not override is carried over by reference.
  627|     expect(clonedAgent.tools).toBe(originalAgent.tools);

Then reverted that experiment.

Commands run locally on Windows. pnpm is not available in this environment, so the package binaries were invoked directly:

  • vitest run test/agent.test.ts for agents-core: 95 passed
  • vitest run for all of agents-core: 90 failed, 5716 passed, 2 skipped
  • The same command on unmodified main: 90 failed, 5714 passed, 2 skipped
  • The failure set is identical in both runs. Those 90 are pre-existing on this platform, in the sandbox suites that assume POSIX path handling. The only difference is the two tests this PR adds, both passing.
  • tsc --noEmit -p tsconfig.json: clean
  • eslint on both changed files: clean
  • prettier --check on all changed files: clean
  • git diff --check: clean

Issue number

N/A. Cross-SDK documentation alignment with openai/openai-agents-python#1293 and openai/openai-agents-python#1296.

Checks

  • I've added new tests (if relevant)
  • I've added/updated the relevant documentation
  • I've run pnpm test and pnpm test:examples (pnpm is unavailable in this environment; the equivalent vitest runs are listed in the test plan above)
    • (If you made a major change) I've run pnpm test:integration
  • I've run .agents/skills/code-change-verification/scripts/run.sh
  • I've confirmed all verification steps pass
  • If using Codex, I've run /review before submitting this PR
  • I've added a changeset using pnpm changeset to indicate my changes

@changeset-bot

changeset-bot Bot commented Aug 16, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f6e2210

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@openai/agents-core Patch
@openai/agents-extensions Patch
@openai/agents-openai Patch
@openai/agents-realtime Patch
@openai/agents Patch
realtime-react-native Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@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: de3233ed02

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/agents-core/src/agent.ts Resolved

@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: 87ca931d14

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/agents-core/src/agent.ts Resolved
@seratch seratch added this to the 0.16.x milestone Aug 16, 2026
@seratch
seratch enabled auto-merge (squash) August 16, 2026 21:32
@seratch
seratch merged commit 8ece061 into openai:main Aug 16, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants