Skip to content

fix(AIC-3601): stop multi-edge routing text from asking a router for a final answer - #177

Merged
XieX merged 3 commits into
mainfrom
xie/aic-3601-routing-text
Oct 28, 2026
Merged

XieX merged 3 commits into
mainfrom
xie/aic-3601-routing-text

Conversation

@XieX

@XieX XieX commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

AIC-3601: when a graph node has more than one outgoing edge, the routing text told it to "Finish your own work and provide your final response". It also said to call a transfer tool "Only once you have your final answer". A node that only routes has no answer of its own, so this wording invites it to write the target agent's answer. In stream() that reply reaches the caller as chunk events. It also reaches the target as the [Previous agent response] block. In the Whodunit test app the router answered in another agent's voice. The wording is a likely cause of that, not a proven one.

This PR changes both strings in buildHandoffRouting (packages/client/src/graph.ts) to the wording pinned in the monorepo's TESTING.md §3.15a (launchdarkly/ai-sdks-monorepo#104, as of its latest commit c89e5f8). <target> is the edge's raw targetKey, not the sanitized tool name.

Text
Routing suffix \n\nComplete your task using your available tools first. Only once your own part is done, call exactly one transfer tool to route to the next agent. Do not answer the parts of the request that belong to the agent you route to.
Handoff tool result Handoff to <target> recorded. <target> takes over when your turn ends. Finish your own part, then end your turn. Do not answer for <target>.

The text still says recorded and using your available tools first, so the fix from #59 holds: a node with a real tool calls it before routing. The text does not branch on whether a node is a router. The graph schema has no router role, and a node with no tools can still write an answer and then route. The comment above the handoff handler now points to §3.15a for the reasoning. Routing behaviour is otherwise unchanged. Python and Go are getting the same strings byte for byte in separate PRs.

Tests

  • A new graph() multi-edge routing text block runs through both graph().invoke() and graph().stream(), for a root that has its own tool and for a root with no tools. It asserts exact strings for the instructions the handler received and for the value its __handoff_agent_b handler returned. It also asserts the tool and handler sets the handler received, and that the node's own tool still reaches the caller's handler.
  • The existing stream parity test now expects the new handoff result.
  • When graph.ts is reverted to main, these 5 tests fail.
  • packages/client: yarn test passes (1929 passed, 11 skipped), yarn typecheck passes, and biome check is clean.

🤖 Generated with Claude Code


Note

Overview
Fixes AIC-3601 by replacing multi-edge routing copy in buildHandoffRouting so router nodes stop being told to deliver a “final answer” (which pushed them to speak for the next agent).

The instruction suffix now says to finish your own part before calling one transfer tool, and explicitly not to answer portions of the request meant for the routed agent. The __handoff_* tool return string now states the target takes over when the turn ends, to finish the router’s part and end the turn, and not to answer for the target. Wording matches the monorepo pin in TESTING.md §3.15a; <target> remains the raw edge targetKey.

Tests add a graph() multi-edge routing text suite (pinned constants) covering invoke() and stream() for roots with and without their own tools, and update an existing parity expectation for the new handoff message.

Reviewed by Cursor Bugbot for commit 3f03005. Bugbot is set up for automated code reviews on this repo. Configure here.

…a final answer

The routing suffix and the handoff tool result told every multi-edge node to
"provide your final response" and to transfer "only once you have your final
answer". A node that only routes has no answer of its own, so the text invites
it to write the target agent's answer, which stream() emits as chunks and the
target receives as its previous agent response.

Use the wording pinned in the monorepo's TESTING.md section 3.15a. It keeps
"recorded" and "using your available tools first" from #59, so a node with a
real tool still calls it before routing, drops the final-answer phrasing, and
tells the node not to answer for the target. Python and Go carry the same
strings byte for byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@XieX
XieX requested a review from jeffdupont October 27, 2026 20:11

@jeffdupont jeffdupont 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.

Approving. Both strings match the spec in launchdarkly/ai-sdks-monorepo#104 exactly, and the new tests fail on the old wording. Client tests and typecheck pass.

Small follow-ups, none blocking:

  • The description cites spec commit 8284a10 and says live checks are required. The latest spec commit (1728f86) removed that, so please update it.
  • The comment at graph.ts:261-266 could be a one-line pointer to the spec.

@XieX
XieX merged commit 10cce54 into main Oct 28, 2026
11 checks passed
@XieX
XieX deleted the xie/aic-3601-routing-text branch October 28, 2026 14:47
@github-actions github-actions Bot mentioned this pull request Oct 27, 2026
jeffdupont pushed a commit that referenced this pull request Oct 30, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>@launchdarkly/ai-claude-agents: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-claude-agents-0.5.0...@launchdarkly/ai-claude-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.
* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
* **SEC-9507:** enable Claude native tools only when the active
variation attaches them
* **claude-agents:** honour the config's max_tokens and disable thinking
unless the config asks
([#183](#183))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#172](#172))
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))

### Features

* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
([8dbe2ec](8dbe2ec))
* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))
* **skills:** give Claude Agents runs the skills attached to their
variation ([#136](#136))
([df16ba0](df16ba0))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#172](#172))
([d3e7c5f](d3e7c5f))


### Bug Fixes

* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))
([c6c00fc](c6c00fc))
* **claude-agents:** honour the config's max_tokens and disable thinking
unless the config asks
([#183](#183))
([f58ce21](f58ce21))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))
* **SEC-9507:** dispatch litellm-messages tool calls only to tools
offered for the request
([6926e8a](6926e8a))
* **SEC-9507:** enable Claude native tools only when the active
variation attaches them
([6926e8a](6926e8a))
* **SEC-9507:** pass handlers only the tools attached to the active
variation
([6926e8a](6926e8a))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-claude-messages: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-claude-messages-0.5.0...@launchdarkly/ai-claude-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))

### Features

* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))
([c6c00fc](c6c00fc))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-langchain-agents: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-langchain-agents-0.5.0...@launchdarkly/ai-langchain-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.
* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
* **AIC-3439:** let wildcard handlers accept only named providers
([#111](#111))
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))

### Features

* **AIC-3439:** let wildcard handlers accept only named providers
([#111](#111))
([9371975](9371975))
* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
([8dbe2ec](8dbe2ec))
* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **AIC-3592:** make native LangGraph hand-offs complete
([#192](#192))
([025f2ce](025f2ce))
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))
([c6c00fc](c6c00fc))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-langchain-messages: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-langchain-messages-0.5.0...@launchdarkly/ai-langchain-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.
* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
* **AIC-3439:** let wildcard handlers accept only named providers
([#111](#111))
* **AIC-3686:** rename the LangChain and OpenAI messages factories to
*MessagesHandler
([#173](#173))

### Features

* **AIC-3439:** let wildcard handlers accept only named providers
([#111](#111))
([9371975](9371975))
* **AIC-3686:** rename the LangChain and OpenAI messages factories to
*MessagesHandler
([#173](#173))
([15a0d37](15a0d37))
* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
([8dbe2ec](8dbe2ec))
* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **AIC-3726:** realign three usage IDs with the 1.0 factory names
([#197](#197))
([fc83c7a](fc83c7a))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-litellm-agents: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-litellm-agents-0.2.0...@launchdarkly/ai-litellm-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.

### Features

* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-litellm-messages: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-litellm-messages-0.2.0...@launchdarkly/ai-litellm-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.
* **SEC-9507:** enable Claude native tools only when the active
variation attaches them
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))

### Features

* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))
([c6c00fc](c6c00fc))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))
* **SEC-9507:** dispatch litellm-messages tool calls only to tools
offered for the request
([6926e8a](6926e8a))
* **SEC-9507:** enable Claude native tools only when the active
variation attaches them
([6926e8a](6926e8a))
* **SEC-9507:** pass handlers only the tools attached to the active
variation
([6926e8a](6926e8a))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-node: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-node-0.4.0...@launchdarkly/ai-node-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **evaluations:** promote Evaluations from Code to core
([#181](#181))
* **AIC-3686:** rename the LangChain and OpenAI messages factories to
*MessagesHandler
([#173](#173))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#172](#172))

### Features

* **AIC-3686:** rename the LangChain and OpenAI messages factories to
*MessagesHandler
([#173](#173))
([15a0d37](15a0d37))
* **evaluations:** promote Evaluations from Code to core
([#181](#181))
([676a2ed](676a2ed))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#172](#172))
([d3e7c5f](d3e7c5f))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-openai-agents: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-openai-agents-0.5.0...@launchdarkly/ai-openai-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.
* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
* **AIC-3687:** rename createOpenAIAgentHandler to
createOpenAIAgentsHandler
([#174](#174))

### Features

* **AIC-3687:** rename createOpenAIAgentHandler to
createOpenAIAgentsHandler
([#174](#174))
([cfba4d2](cfba4d2))
* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
([8dbe2ec](8dbe2ec))
* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **AIC-3726:** realign three usage IDs with the 1.0 factory names
([#197](#197))
([fc83c7a](fc83c7a))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-openai-messages: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-openai-messages-0.5.0...@launchdarkly/ai-openai-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.
* **AIC-3686:** rename the LangChain and OpenAI messages factories to
*MessagesHandler
([#173](#173))
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))

### Features

* **AIC-3686:** rename the LangChain and OpenAI messages factories to
*MessagesHandler
([#173](#173))
([15a0d37](15a0d37))
* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))
([c6c00fc](c6c00fc))
* **AIC-3726:** realign three usage IDs with the 1.0 factory names
([#197](#197))
([fc83c7a](fc83c7a))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-otel: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-otel-0.3.0...@launchdarkly/ai-otel-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** spans carry launchdarkly.project_id instead of
highlight.project_id

### Bug Fixes

* **client:** stamp launchdarkly.project_id on the telemetry resource
([#176](#176))
([93fb412](93fb412))
</details>

<details><summary>@launchdarkly/ai-server: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-server-0.5.0...@launchdarkly/ai-server-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.
* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
* **AIC-3439:** let wildcard handlers accept only named providers
([#111](#111))
* **SEC-9507:** enable Claude native tools only when the active
variation attaches them
* **evaluations:** export each offline row as one trace
([#175](#175))
* **evaluations:** promote Evaluations from Code to core
([#181](#181))
* **evaluations:** remove default pass rate threshold
([#184](#184))
* **client:** spans carry launchdarkly.project_id instead of
highlight.project_id
* **AIC-3687:** rename createOpenAIAgentHandler to
createOpenAIAgentsHandler
([#174](#174))
* **AIC-3686:** rename the LangChain and OpenAI messages factories to
*MessagesHandler
([#173](#173))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#172](#172))
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))

### Features

* **AIC-3439:** let wildcard handlers accept only named providers
([#111](#111))
([9371975](9371975))
* **AIC-3686:** rename the LangChain and OpenAI messages factories to
*MessagesHandler
([#173](#173))
([15a0d37](15a0d37))
* **AIC-3687:** rename createOpenAIAgentHandler to
createOpenAIAgentsHandler
([#174](#174))
([cfba4d2](cfba4d2))
* **client:** add result variant and value to the feature_flag span
event ([#186](#186))
([8dbe2ec](8dbe2ec))
* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))
* **client:** point judge spans at the run they graded
([#200](#200))
([ba9c936](ba9c936))
* **evaluations:** export each offline row as one trace
([#175](#175))
([05a7eb1](05a7eb1))
* **evaluations:** promote Evaluations from Code to core
([#181](#181))
([676a2ed](676a2ed))
* **evaluations:** remove default pass rate threshold
([#184](#184))
([f3a3e37](f3a3e37))
* **skills:** give Claude Agents runs the skills attached to their
variation ([#136](#136))
([df16ba0](df16ba0))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#172](#172))
([d3e7c5f](d3e7c5f))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **AIC-3598:** type toolHandlers on the handler contract; declare
@langchain/anthropic
([#170](#170))
([c6c00fc](c6c00fc))
* **AIC-3601:** stop multi-edge routing text from asking a router for a
final answer
([#177](#177))
([10cce54](10cce54))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))
* **client:** stamp launchdarkly.project_id on the telemetry resource
([#176](#176))
([93fb412](93fb412))
* **evaluations:** update stale test import
([#189](#189))
([f4d8083](f4d8083))
* **evaluations:** warn once when a scorer returns an invalid score
([#199](#199))
([f43c888](f43c888))
* **graph:** report a node's own judge scores on its node_done stream
event ([#182](#182))
([1230f02](1230f02))
* **SEC-9507:** dispatch litellm-messages tool calls only to tools
offered for the request
([6926e8a](6926e8a))
* **SEC-9507:** enable Claude native tools only when the active
variation attaches them
([6926e8a](6926e8a))
* **SEC-9507:** pass handlers only the tools attached to the active
variation
([6926e8a](6926e8a))
</details>

<details><summary>@launchdarkly/ai-typesafe: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-typesafe-0.2.0...@launchdarkly/ai-typesafe-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.

### Features

* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-vercel-agents: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-vercel-agents-0.3.0...@launchdarkly/ai-vercel-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.

### Features

* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

<details><summary>@launchdarkly/ai-vercel-messages: 1.0.0</summary>

##
[1.0.0](https://github.com/launchdarkly/js-ai-sdk/compare/@launchdarkly/ai-vercel-messages-0.3.0...@launchdarkly/ai-vercel-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** conversation content is now captured on spans by default.
To keep it off, call configure({ options: { captureContent: false } })
once at startup.
* **client:** createHandler returns a new wrapper function rather than
adding providesFor to the function you pass and returning that same
function. Use the handler createHandler returns; the function you passed
in no longer carries providesFor.

### Features

* **client:** capture conversation content on spans by default and add
configure()
([d9c7fc3](d9c7fc3))


### Bug Fixes

* **AIC-3573:** never send a NativeTool to the model as a function tool
([#194](#194))
([ec43b85](ec43b85))
* **client:** return a new handler from createHandler instead of
changing the function passed in
([d9c7fc3](d9c7fc3))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/ai-server bumped from ^0.5.0 to ^1.0.0
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Overview**
> This **release-please** PR cuts **1.0.0** for every workspace package
(`@launchdarkly/ai-server`, `@launchdarkly/ai-node`, provider adapters,
`@launchdarkly/ai-otel`, `@launchdarkly/ai-typesafe`) by updating
`.release-please-manifest.json`, each `package.json` / `src/version.ts`,
and adding **1.0.0** changelog sections. Provider packages bump their
`@launchdarkly/ai-server` dependency to **^1.0.0**.
> 
> The release notes bundled here flag **breaking** upgrades integrators
must handle: **`configure()`** with **conversation content on spans by
default** (opt out via `captureContent: false`); **`createHandler`** now
returns a **new wrapper** instead of mutating the passed function;
renamed factories (**`*MessagesHandler`**,
**`createOpenAIAgentsHandler`**); **`LaunchDarklySkillStore`** (was
`FDv2SkillStore`); **Evaluations promoted to core** with offline
export/trace and threshold behavior changes; telemetry
**`launchdarkly.project_id`** (was `highlight.project_id`); richer
**`feature_flag`** span events; and **SEC-9507** tool scoping (native
tools and handlers only see tools on the active variation).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f87c9a6. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

2 participants