Skip to content

feat: Implement agent graph definitions#1282

Merged
jsonbailey merged 13 commits intofeat/ai-sdk-next-releasefrom
jb/aic-2202/agent-graph-definitions
Apr 20, 2026
Merged

feat: Implement agent graph definitions#1282
jsonbailey merged 13 commits intofeat/ai-sdk-next-releasefrom
jb/aic-2202/agent-graph-definitions

Conversation

@jsonbailey
Copy link
Copy Markdown
Contributor

@jsonbailey jsonbailey commented Apr 15, 2026

Summary

  • Implements the AIGRAPH spec: AgentGraphDefinition, AgentGraphNode, and graph type definitions (LDAgentGraphFlagValue, LDGraphEdge, LDGraphMetricSummary, LDGraphTrackData)
  • Implements the AIGRAPHTRACK spec: full LDGraphTracker interface and LDGraphTrackerImpl with UUID v4 runId generation, at-most-once semantics (with warnings on duplicate calls), multi-fire edge-level methods, and cross-process resumption via URL-safe Base64 token
  • Adds agentGraph() and createGraphTracker() methods to LDAIClient / LDAIClientImpl; validates graph connectivity, root presence, and that all referenced agent configs are enabled before returning a graph

Test plan

  • yarn workspace @launchdarkly/server-sdk-ai test — 175 tests pass across 8 suites
  • AgentGraphDefinition.test.ts — 28 tests covering buildNodes, collectAllKeys, traverse (BFS order + context mutation), reverseTraverse (longest-path depth), node queries, createTracker
  • LDGraphTrackerImpl.test.ts — 30 tests covering runId generation, resumption token encoding/decoding, fromResumptionToken round-trip, at-most-once warning behavior, edge-level multi-fire
  • agentGraph.test.ts — 9 tests covering disabled-when-no-root, disconnected-node detection, disabled-child-config, happy-path single- and multi-node graphs, usage event tracking, createGraphTracker round-trip

🤖 Generated with Claude Code


Note

Medium Risk
Adds new public agentGraph/createGraphTracker APIs plus new traversal and tracking behavior, which can affect flag evaluation, logging, and telemetry emission. Risk is moderated by extensive unit tests, but the new graph validation and resumption token parsing/encoding could impact runtime behavior if misused.

Overview
Introduces agent graph support in @launchdarkly/server-sdk-ai: new AgentGraphDefinition/AgentGraphNode types with forward (traverse) and reverse (reverseTraverse) BFS traversal, parent/child queries, and graph-level tracker creation.

Extends the client API with LDAIClient.agentGraph() and createGraphTracker(), including connectivity validation (root required, no disconnected nodes) and a requirement that all referenced agent configs evaluate as enabled; failures return a disabled graph and emit debug logs.

Upgrades LDGraphTrackerImpl to include a per-invocation runId, resumption tokens (base64url) for cross-process correlation, and explicit at-most-once semantics for graph-level metrics with warning logs on duplicates, while keeping edge-level tracking multi-fire. Adds a new runnable example (examples/agent-graph-traversal) and comprehensive test coverage for the new graph and tracker behavior.

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


Open in Devin Review

@github-actions
Copy link
Copy Markdown
Contributor

@launchdarkly/js-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 25623 bytes
Compressed size limit: 29000
Uncompressed size: 125843 bytes

@github-actions
Copy link
Copy Markdown
Contributor

@launchdarkly/browser size report
This is the brotli compressed size of the ESM build.
Compressed size: 179375 bytes
Compressed size limit: 200000
Uncompressed size: 829982 bytes

@github-actions
Copy link
Copy Markdown
Contributor

@launchdarkly/js-client-sdk size report
This is the brotli compressed size of the ESM build.
Compressed size: 31655 bytes
Compressed size limit: 34000
Uncompressed size: 112792 bytes

@github-actions
Copy link
Copy Markdown
Contributor

@launchdarkly/js-client-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 37169 bytes
Compressed size limit: 38000
Uncompressed size: 204305 bytes

@jsonbailey jsonbailey marked this pull request as ready for review April 15, 2026 22:20
@jsonbailey jsonbailey requested a review from a team as a code owner April 15, 2026 22:20
@jsonbailey jsonbailey changed the title feat: implement agent graph definitions (AIGRAPH + AIGRAPHTRACK) feat: Implement agent graph definitions Apr 15, 2026
cursor[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor

@joker23 joker23 left a comment

Choose a reason for hiding this comment

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

I think the bot comments need to be addressed before merging

cursor[bot]

This comment was marked as resolved.

cursor[bot]

This comment was marked as resolved.

cursor[bot]

This comment was marked as resolved.

cursor[bot]

This comment was marked as resolved.

jsonbailey and others added 9 commits April 20, 2026 10:03
Add AgentGraphDefinition, AgentGraphNode, LDGraphTracker, and
LDGraphTrackerImpl per the AIGRAPH and AIGRAPHTRACK specs, along with
the agentGraph() and createGraphTracker() methods on LDAIClientImpl.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Impl

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pological sort

- Add _hasCycle() DFS validation to agentGraph() — cyclic graphs now return
  { enabled: false } instead of hanging reverseTraverse indefinitely
- Replace _computeLongestPathDepths BFS with Kahn's topological sort + DP,
  which is correct for DAGs and terminates in O(V+E)
- Remove dead stores _context and _graphKey from AgentGraphDefinition constructor

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…om terminals

Cyclic graphs are valid (supported in the LD UI and by frameworks like LangGraph).
Replace depth-sorted reverseTraverse with upward BFS from terminal nodes via
getParentNodes(), matching the Python SDK implementation:

- Remove _hasCycle() and cycle rejection from agentGraph() — cyclic graphs now
  pass validation and traverse safely
- Drop _computeLongestPathDepths() entirely
- reverseTraverse: BFS upward from terminalNodes(), visited set prevents cycles
  from looping, root is always deferred and invoked last
- Fully cyclic graphs (no terminals) return early without invoking fn, same as Python

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Addresses PR feedback: when _ldMeta.enabled is false, agentGraph() was
still returning { enabled: true, graph } despite the AgentGraphDefinition
documenting that enabled graphs are always true. Now returns disabled early
if the flag is explicitly disabled.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Demonstrates forward and reverse BFS traversal of an agent graph,
including when to choose each direction based on framework requirements
(parent-first vs child-first construction). Includes README with
framework-specific guidance and tracker usage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ion.test.ts post-rebase

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jsonbailey jsonbailey force-pushed the jb/aic-2202/agent-graph-definitions branch from c92271e to 6056929 Compare April 20, 2026 15:06
cursor[bot]

This comment was marked as resolved.

jsonbailey and others added 2 commits April 20, 2026 10:37
- agentGraph() now accepts an optional variables param and passes it to
  each node's _agentConfigInternal call so Mustache templates in agent
  instructions are interpolated correctly
- _agentConfigInternal now accepts and forwards graphKey so node-level
  trackers are correlated with their parent graph in the backend
- Added ordering note to reverseTraverse JSDoc: within a BFS level,
  sibling visit order is not guaranteed (consistent with Python behavior)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jsonbailey jsonbailey requested a review from joker23 April 20, 2026 15:41
devin-ai-integration[bot]

This comment was marked as resolved.

Comment thread packages/sdk/server-ai/examples/agent-graph-traversal/package.json
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.

nit: if appropriate, consider opening a tech debt ticket to make e2e test for this example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cursor[bot]

This comment was marked as resolved.

…orded

Both trackInvocationSuccess and trackInvocationFailure share the same
guard (this._summary.success !== undefined), so hardcoding the method
name in the message was incorrect when the opposite method was called
first. Replaced with a neutral message that applies in both cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 7 additional findings in Devin Review.

Open in Devin Review

Comment thread packages/sdk/server-ai/src/api/graph/AgentGraphDefinition.ts
@jsonbailey jsonbailey merged commit 092e38a into feat/ai-sdk-next-release Apr 20, 2026
44 checks passed
@jsonbailey jsonbailey deleted the jb/aic-2202/agent-graph-definitions branch April 20, 2026 18:06
@github-actions github-actions Bot mentioned this pull request Apr 20, 2026
jsonbailey added a commit that referenced this pull request Apr 21, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>browser: 0.1.16</summary>

##
[0.1.16](browser-v0.1.15...browser-v0.1.16)
(2026-04-21)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-client-sdk bumped from 4.6.0 to 4.6.1
</details>

<details><summary>browser-telemetry: 1.0.32</summary>

##
[1.0.32](browser-telemetry-v1.0.31...browser-telemetry-v1.0.32)
(2026-04-21)


### Bug Fixes

* correct typeof comparisons in browser SDK
([#1301](#1301))
([f4bd636](f4bd636))
* **js-client-sdk:** better `undefined` handling
([#1303](#1303))
([4818678](4818678))


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/js-client-sdk bumped from 4.6.0 to 4.6.1
</details>

<details><summary>js-client-sdk: 4.6.1</summary>

##
[4.6.1](js-client-sdk-v4.6.0...js-client-sdk-v4.6.1)
(2026-04-21)


### Bug Fixes

* correct typeof comparisons in browser SDK
([#1301](#1301))
([f4bd636](f4bd636))
* **js-client-sdk:** better `undefined` handling
([#1303](#1303))
([4818678](4818678))
</details>

<details><summary>react-sdk: 0.2.2</summary>

##
[0.2.2](react-sdk-v0.2.1...react-sdk-v0.2.2)
(2026-04-21)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @launchdarkly/js-client-sdk bumped from ^4.6.0 to ^4.6.1
</details>

<details><summary>server-sdk-ai: 0.17.0</summary>

##
[0.17.0](server-sdk-ai-v0.16.8...server-sdk-ai-v0.17.0)
(2026-04-21)


### ⚠ BREAKING CHANGES

* Flatten JudgeResponse and EvalScore into new LDJudgeResult
([#1284](#1284))
* Add per-execution runId, at-most-once tracking, and cross-process
tracker resumption
([#1270](#1270))

### Features

* Add per-execution runId, at-most-once tracking, and cross-process
tracker resumption
([#1270](#1270))
([fc25ab7](fc25ab7))
* Flatten JudgeResponse and EvalScore into new LDJudgeResult
([#1284](#1284))
([aba1221](aba1221))
* Implement agent graph definitions
([#1282](#1282))
([e7d08e5](e7d08e5))
* simplify evaluation schema to flat score/reasoning shape
([#1286](#1286))
([c132e9f](c132e9f))


### Bug Fixes

* Add support for graph metric tracking
([#1269](#1269))
([034a89d](034a89d))
</details>

<details><summary>server-sdk-ai-langchain: 0.5.5</summary>

##
[0.5.5](server-sdk-ai-langchain-v0.5.4...server-sdk-ai-langchain-v0.5.5)
(2026-04-21)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/server-sdk-ai bumped from ^0.16.8 to ^0.17.0
  * peerDependencies
* @launchdarkly/server-sdk-ai bumped from ^0.15.0 || ^0.16.0 to ^0.17.0
</details>

<details><summary>server-sdk-ai-openai: 0.5.5</summary>

##
[0.5.5](server-sdk-ai-openai-v0.5.4...server-sdk-ai-openai-v0.5.5)
(2026-04-21)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/server-sdk-ai bumped from ^0.16.8 to ^0.17.0
  * peerDependencies
* @launchdarkly/server-sdk-ai bumped from ^0.15.0 || ^0.16.0 to ^0.17.0
</details>

<details><summary>server-sdk-ai-vercel: 0.5.5</summary>

##
[0.5.5](server-sdk-ai-vercel-v0.5.4...server-sdk-ai-vercel-v0.5.5)
(2026-04-21)


### Dependencies

* The following workspace dependencies were updated
  * devDependencies
    * @launchdarkly/server-sdk-ai bumped from ^0.16.8 to ^0.17.0
  * peerDependencies
* @launchdarkly/server-sdk-ai bumped from ^0.15.0 || ^0.16.0 to ^0.17.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]
> **Medium Risk**
> Primarily a version/changelog bump, but it publishes
`@launchdarkly/server-sdk-ai` `0.17.0` with documented breaking API
changes that can impact downstream consumers and provider peer
dependency resolution.
> 
> **Overview**
> Bumps release versions across the monorepo via
`.release-please-manifest.json`, updating `@launchdarkly/server-sdk-ai`
to `0.17.0`, `@launchdarkly/js-client-sdk` to `4.6.1`, and related
packages (`@launchdarkly/browser`, `@launchdarkly/react-sdk`,
`@launchdarkly/browser-telemetry`, and AI provider packages)
accordingly.
> 
> Updates package metadata, changelogs, examples, and embedded
SDK/wrapper version strings (e.g., `BrowserInfo` and `LDReactClient`) to
reflect the new releases, including `server-sdk-ai`’s `0.17.0`
breaking-change notes and provider peer dependency bumps to `^0.17.0`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
e7f8c09. 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>
Co-authored-by: jsonbailey <jbailey@launchdarkly.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.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.

3 participants