Skip to content

fix(AIC-3598)!: make Python packaging and public types GA-ready - #218

Merged
jeffdupont merged 12 commits into
mainfrom
fix/AIC-3598-packaging-ga
Oct 29, 2026
Merged

jeffdupont merged 12 commits into
mainfrom
fix/AIC-3598-packaging-ga

Conversation

@jeffdupont

@jeffdupont jeffdupont commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Python half of AIC-3598. The spec change is launchdarkly/ai-sdks-monorepo#91.

Packaging

  • Classifiers. All 14 packages say Development Status :: 5 - Production/Stable. The two vercel-* packages had no classifiers at all.

  • Third-party floors move to the version CI tests wherever the old floor crossed a breaking line (a major for 1.x+ libraries, a minor for 0.x):

    • langchain-core>=1.6, langgraph>=1.2, openai>=2.44, openai-agents>=0.17
    • anthropic>=0.113, httpx>=0.28, typesafe-sdk>=0.7

    The rule, as the shared spec states it: a floor sits on the line CI tests, the same major as the tested version for a 1.x+ library and the same minor for a 0.x one. The README says so.

    Floors already on the tested major stay put (opentelemetry-api>=1.25, litellm>=1.83).

  • [ld] extra on launchdarkly-ai-server and launchdarkly-ai-python installs launchdarkly-server-sdk>=9.18.3,<10. It's an extra rather than a dependency so bring-your-own-client installs stay lean, as client/AGENTS.md requires. The READMEs and the init_client error message point to it.

  • Undeclared LangChain provider packages, found by the new check. Both langchain packages imported langchain_openai and langchain_anthropic without declaring them, the Python side of the JS @langchain/anthropic gap:

    • langchain-agents now depends on langchain-openai, its default model, and offers [anthropic] and [aws] extras.
    • langchain-messages now depends on langchain-openai, its default model, as langchain-agents does, and offers [anthropic] and [aws].
    • The Anthropic and OpenAI imports are now guarded with an install hint, as Bedrock's already was.
  • Internal ranges: every package pins launchdarkly-ai-server>=0.6,<2. The native graph adapters import NativeGraphRunner, which published server 0.5.0 lacks, so >=0.4.1 would let a handler resolve to a core it can't import from. >=0.6 resolves whichever lands first, this PR's 0.6.0 or the 1.0.0 cut; chore(AIC-3672): release every Python package as 1.0.0 #242 (AIC-3672) tightens it to >=1.0.0,<2.

Public types

  • LDClientInterface becomes a Protocol. It was a plain class with async methods, which matched neither the synchronous ldclient.LDClient nor the "maybe awaitable" way core calls it. ldclient.LDClient now satisfies it structurally; checked with mypy in both directions (a client missing track is rejected). init_client and get_client return it. variation, flush and close may be async; track must be synchronous (-> None), because no call site awaits it.
  • tool_handlers on the handler protocol and in every handler is typed Mapping[str, Callable[..., Any] | NativeTool] instead of dict[str, Any], so a caller's precisely typed dict is accepted. Offline evaluations pass a NativeTool to the handler unwrapped, so langchain-agents now checks callable() before calling. It used to raise TypeError: 'NativeTool' object is not callable; there's a test, and it fails without the fix.
  • Native graph adapters (to_lang_graph, to_openai_agents, to_claude_agents, to_litellm_agents, to_vercel_agents):
    • take Awaitable[GraphDefinition]
    • take a per-package options TypedDict exported from the root
    • return the new core NativeGraphRunner protocol. They return a small class rather than a SimpleNamespace, because mypy accepts any SimpleNamespace as any protocol.

Packaging check (make check-packaging, new CI job packaging)

scripts/check_packaging.py installs each wheel alone, with no extras, into an empty venv, which proves core loads without launchdarkly-server-sdk. It imports every public module and __all__ name. Then it checks that every module the source imports unconditionally, lazy importlib.import_module calls included, comes from a distribution the package declares; installed through some other dependency is not enough. That found undeclared pydantic in four packages and openai in litellm-agents, now declared. Each declared extra gets its own venv and must import what EXTRA_IMPORTS lists for it; an extra with no entry fails. Internal dependencies resolve to this commit's wheels and third-party ones from PyPI. Each import is resolved by its full dotted name to the distribution that owns it, so a namespace package such as opentelemetry.sdk needs opentelemetry-sdk declared; that found langgraph.prebuilt undeclared in langchain-agents. The 22 runs go through a thread pool.

Checks

  • make lint, make format-check, make typecheck (no issues in 104 files), make api-report-check (15 reports current)
  • make test: 3,651 passed, 18 skipped
  • make check-packaging: all 14 packages and 8 extras pass; removing pydantic from vercel-agents makes it fail with pydantic (from pydantic, not declared)

Versioning

The README documents the 1.0 rule: from 1.0.0, every package is released at the same version.

🤖 Generated with Claude Code


Note

Overview
Prepares the Python AI SDK monorepo for GA by tightening packaging, install docs, and public types, plus a CI gate that catches undeclared dependencies workspace tests miss.

Packaging and installs. All packages move to Production/Stable classifiers; third-party floors are raised to versions CI exercises (LangChain 1.x, OpenAI 2.x, etc.). launchdarkly-ai-server[ld] and launchdarkly-ai-python[ld] now install bounded launchdarkly-server-sdk; READMEs drop separate launchdarkly-server-sdk lines. Handlers pin launchdarkly-ai-server>=0.6,<2. LangChain packages declare langchain-openai and add [anthropic] / [aws] extras with guarded import errors; missing deps like pydantic and langgraph-prebuilt are added where the new checker found gaps.

make check-packaging + CI packaging job. New scripts/check_packaging.py builds wheels, installs each package (and each extra) in an isolated venv, validates public __all__ imports, and asserts every unconditional/lazy import is owned by a declared distribution—not a transitive install.

Public API typing. LDClientInterface is a Protocol aligned with real ldclient usage; get_client / init_client return it. tool_handlers is Mapping[str, Callable[..., Any] | NativeTool] across core and handlers (LangChain agents reject unwrapped NativeTool). Native graph to_* adapters take Awaitable[GraphDefinition], export per-package options TypedDicts, and return NativeGraphRunner instead of untyped namespaces.

README adds 1.0 synchronized versioning policy for the SDK.

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

jeffdupont and others added 3 commits October 26, 2026 12:52
- Production/Stable classifiers on all 14 packages (vercel-* had none).
- Raise third-party floors that crossed a breaking line to the tested
  versions in uv.lock (langchain-core, langgraph, openai, openai-agents,
  anthropic, httpx, typesafe-sdk).
- Add an optional [ld] extra for launchdarkly-server-sdk on
  launchdarkly-ai-server and launchdarkly-ai-python; READMEs install it.
- LDClientInterface becomes a Protocol that ldclient.LDClient satisfies;
  init_client and get_client return it.
- Handler protocol and every handler type tool_handlers as
  dict[str, Callable | NativeTool]; offline evaluations pass a NativeTool
  through unwrapped, so langchain-agents now guards with callable().
- Native graph adapters take Awaitable[GraphDefinition], a per-package
  options TypedDict, and return NativeGraphRunner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…heck

- scripts/check_packaging.py (make check-packaging, CI job "packaging")
  installs each wheel into an empty virtualenv with its documented install
  command, imports every public module and __all__ name, and checks every
  module the source imports unconditionally is installed, lazy
  importlib.import_module calls included. Internal dependencies resolve to
  this commit's wheels; third-party ones from PyPI.
- The check found langchain-agents and langchain-messages importing
  langchain_openai and langchain_anthropic without declaring them, the
  Python side of the JS @langchain/anthropic gap. langchain-agents now
  depends on langchain-openai (its default model) and offers [anthropic]
  and [aws] extras; langchain-messages offers [openai], [anthropic], [aws].
  The Anthropic and OpenAI imports are guarded with an install hint, like
  Bedrock's.
- README: document the 1.0 versioning rule (lockstep per language).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jeffdupont jeffdupont changed the title fix(AIC-3598): make Python packaging and public types GA-ready fix(AIC-3598)!: make Python packaging and public types GA-ready Oct 27, 2026
…itle

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jeffdupont added a commit to launchdarkly/js-ai-sdk that referenced this pull request Oct 27, 2026
…angchain/anthropic (#170)

TypeScript half of
[AIC-3598](https://launchdarkly.atlassian.net/browse/AIC-3598). The spec
is in launchdarkly/ai-sdks-monorepo#91 (TESTING.md §5.3, §1.4, A.21).
The Python half is launchdarkly/python-ai-sdk#218.

## Changes

- **`toolHandlers` on the handler contract.** `ProviderHandler.stream`
and `createHandler`'s input types took `Record<string, any>`. They now
take `Record<string, ToolHandlerFn | NativeTool>`, which matches the
blocking call signature and what apps already pass.
- The union is the real contract, not functions only: offline
evaluations (`evaluations-runner.ts`) pass the trajectory recorder's map
to the handler without `wrapToolHandlers`, so a `NativeTool` arrives
unwrapped.
- Five handlers typed the map narrower, which the old `any` hid:
`claude-agents`, `claude-messages`, `langchain-agents`,
`litellm-messages` and `openai-messages`. They now accept the union.
- Runtime behavior is unchanged, except in `claude-agents`' MCP tool
executor. It now guards with `typeof handler !== 'function'`, so a raw
`NativeTool` gets the "No handler registered" error instead of `handler
is not a function`. There's a test, and it fails without the fix.
- **`@langchain/anthropic`** is declared by
`@launchdarkly/ai-langchain-agents` as an optional peer plus a
devDependency, the same pattern as `@langchain/aws`. The package
dynamically imports it for Anthropic nodes. `toolHandlers` on the
app-facing API was already typed.
- **`zod`** is declared by `@launchdarkly/ai-langchain-agents`
(`^4.4.3`, like its siblings). `native-graph.ts` imports it statically
and was getting it through LangChain.
- **Packaging check, `yarn check:packaging`**, added to the CI build
job:
- It fails when a package's built `dist` imports a package it doesn't
declare, static or dynamic.
- It then packs every workspace, installs all the tarballs into one
empty project, and loads every `exports` subpath through both
`require()` and `import()`.
- The scan has unit tests (`yarn test:check-packaging`). It found the
`zod` gap above.
- **README** documents the 1.0 rule: from 1.0.0, every package is
released at the same version.

## Breaking (the reason for the `!`)

`ProviderHandler.stream`'s declaration changed, so
`scripts/api-breaking.mjs` will flag it. A custom handler whose `stream`
typed `toolHandlers` narrower than the union no longer type-checks.
Before 1.0 the `!` bumps the minor version, and AIC-3673 cuts 1.0 next.
If owners judge it compatible, `api-compatible` is the alternative.

## Checks

- `yarn build`, `yarn typecheck` (0 errors), `yarn code:check`, `yarn
sherif`
- `yarn api:check` (only `ai-server.api.md` changed, the `stream` line)
and `yarn api:surface`
- `yarn test`: every workspace passes
- `yarn check:packaging`: 14 packages declare every import, and all 16
entry points load
- `yarn.lock` is unchanged

## Known, out of scope

- `@langchain/anthropic@1.5.1` (the pinned dev version, as in
`langchain-messages`) asks for `@langchain/core@^1.2.1`, while the
lockfile resolves 1.1.49. That predates this change.
- In both SDKs, `claude-agents` recognises a native tool only through
the tracking stub's `NATIVE_TOOL_KEY`. On the offline evaluations path a
raw `NativeTool` is therefore not wired to Claude's built-in tool.
That's an evaluations behavior, so it's left for a follow-up.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


[AIC-3598]:
https://launchdarkly.atlassian.net/browse/AIC-3598?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Overview**
> Tightens the public **handler contract** so `toolHandlers` is
consistently `Record<string, ToolHandlerFn | NativeTool>` on blocking
and streaming paths (replacing `Record<string, any>` on
`ProviderHandler.stream` and internal handler helpers). Provider
packages that narrowed the map are aligned, and **claude-agents** MCP
execution now rejects unwrapped `NativeTool` values (offline
evaluations) with the same “no handler” error instead of calling a
non-function.
> 
> **Packaging and release hygiene:** adds `yarn check:packaging` (plus
unit tests and CI after full build) to flag undeclared imports in built
`dist` and to verify packed tarballs install and every export loads via
`require()` and `import()`. **@launchdarkly/ai-langchain-agents**
declares missing **`zod`** and optional peer **`@langchain/anthropic`**
for its dynamic Anthropic import. README documents **lockstep versioning
from 1.0.0**.
> 
> **Breaking:** `ProviderHandler.stream`'s `toolHandlers` type changed;
custom handlers with a narrower `stream` signature may need updates.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
dd78326. 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: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved by keeping both sides:
- claude-agents: ClaudeNativeGraphOptions export plus main's skills handler.
- openai-agents: OpenAINativeGraphOptions plus main's create_openai_agents_handler
  rename; build_output_type stays private, as main made it in #224.
- opencode-agents handler: main's secrets import plus this branch's NativeTool.
- API reports regenerated with make api-report.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jeffdupont
jeffdupont marked this pull request as ready for review October 28, 2026 16:39
@jeffdupont
jeffdupont requested a review from a team as a code owner October 28, 2026 16:39

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

A few comments from a review pass, each checked against the code at this head:

  • The biggest one is the LDClientInterface.track() contract (types.py): the new docstring and return type allow an async track, but the SDK never awaits it.
  • The rest are about packaging-check coverage, tool_handlers typing, dependency floors, install hints and CI speed.

Comment thread scripts/check_packaging.py Resolved
Comment thread packages/openai-messages/pyproject.toml Resolved
Comment thread scripts/check_packaging.py Resolved
…e packaging check

- LDClientInterface.track() is typed -> None again and documented as synchronous:
  no call site awaits it, so an async track would drop every $ld:ai:* event.
- tool_handlers takes Mapping[str, Callable[..., Any] | NativeTool] everywhere it is
  only read, so a caller's precisely typed dict is accepted; drops the dict() copies.
- check_packaging installs every declared extra in its own venv and imports what it
  promises; an extra with no EXTRA_IMPORTS entry fails. Override extras are derived
  from pyproject. Runs go through a thread pool with buffered output.
- LangChain install hints name the package extra; the READMEs list the extras.
- README states that dependency floors are the CI-tested versions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@jeffdupont jeffdupont left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Re-review of 1304692. Four of the six earlier points are resolved: track() is synchronous again, tool_handlers is a Mapping, the extras are installed and import-checked, and the install hints name the extras. A mypy probe against the head types accepts a real ldclient.LDClient, rejects a client with async def track, and accepts a dict[str, Callable[[dict[str, Any]], str]] passed as tool_handlers. I found no call site that awaits track(), and none that mutates tool_handlers.

Three things are still open:

  1. The packaging check can't fail on an undeclared import that another dependency installs. Today pydantic is imported unconditionally by openai-agents, litellm-agents, vercel-agents and vercel-messages, and openai by litellm-agents, and none of them declares it. TESTING.md section 5.3 in ai-sdks-monorepo#91 requires each one to be declared.
  2. Core's import scan only runs in a venv that has [ld] installed. An unguarded import ldclient in core would pass, even though section 5.3 says core must load without the base SDK.
  3. The internal floor is still launchdarkly-ai-server>=0.4.1. No 0.4.1 release exists, and the handlers now import NativeGraphRunner, which the published 0.5.0 does not have. #242 raises the floor to >=1.0.0,<2, so this PR is only safe if #242 merges before the next release PR.

The floors policy (your point 4) is now written down, but its wording disagrees with the spec text and with some of the floors. See the inline comment on README.md.

Comment thread scripts/check_packaging.py Resolved
Comment thread scripts/check_packaging.py Resolved
Comment thread packages/claude-agents/pyproject.toml Resolved
Comment thread README.md Resolved
…out extras

- check_packaging: an unconditional import must come from a distribution the
  package declares. Installed is no longer enough: a module another dependency
  pulls in fails. Base runs install with no extras, so core is proven to load
  without launchdarkly-server-sdk; [ld] is now an extra run like the others.
- Declare what the stricter check found: pydantic in openai-agents,
  litellm-agents, vercel-agents and vercel-messages; openai in litellm-agents.
- Internal pins: launchdarkly-ai-server>=1.0.0,<2 everywhere. The native graph
  adapters import NativeGraphRunner, which published server 0.5.0 lacks.
- README states the floor rule spec 5.3 uses: same major as the tested version
  for 1.x+, same minor for 0.x.
- Tests: core is checked without extras, an undeclared dynamic import fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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

Stale Bugbot comment from a previous run.

Comment thread packages/ai/pyproject.toml Resolved
jeffdupont and others added 2 commits October 28, 2026 15:41
…resolves

>=1.0.0,<2 could not resolve if a release went out before release-as 1.0.0
lands (Bugbot). >=0.6 still excludes server 0.5.0, which lacks
NativeGraphRunner; this PR's breaking change makes core's next 0.x release
0.6.0, and 1.0.0 satisfies it too. #242 tightens it to >=1.0.0,<2 at the cut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g-ga

# Conflicts:
#	packages/client/api-report/launchdarkly_ai_server.txt

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

Thanks for working through all of this. I checked each fix at this head: track() is synchronous and documented that way, tool_handlers is a Mapping with the copies gone, every extra is installed and import-checked, the install hints name the extras, the checks run in parallel, and the floor rule is written down. The declared-distribution check, the core-without-extras run and the >=0.6,<2 internal floor all look right too. Release PR #231 already takes core to 0.6.0, so the floor resolves whichever release goes out first.

Approving. A few non-blocking nits, none of which need to hold this up:

  1. Private-spec reference. The module docstring of tests/test_check_packaging.py (line 1) cites the private spec document and a section number. #234, merged to main today but not yet in this branch, removed every such reference from the .py files, so merging this would add one back. Stating the rule in plain words, as #234 did elsewhere, would fix it. The PR description cites section numbers as well.
  2. Namespace packages in the declared-import check (latent). The scan reduces each import to its top-level name, so a module like opentelemetry maps to several distributions. A future unguarded lazy from opentelemetry.sdk ... in core would pass, because opentelemetry-api is declared, even though opentelemetry-sdk is only in [otel]. Every such import in core is guarded today, so nothing is broken. Mapping the full dotted module to its distribution (or special-casing namespace packages) would close the gap.
  3. LangChain default-model consistency. Both LangChain packages default to OpenAI, but langchain-agents depends on langchain-openai directly while langchain-messages offers it as [openai]. A bare pip install launchdarkly-ai-langchain-messages therefore fails on its default path, though with a clear hint. If that difference is intentional, ignore this.

jeffdupont and others added 2 commits October 29, 2026 08:39
…chain-openai is a dependency

Review nits from XieX:
- check_packaging keeps each import's full dotted name and maps it to the
  distribution that owns its file, so a namespace package such as
  opentelemetry.sdk needs opentelemetry-sdk declared, not any opentelemetry-*.
  It found langgraph.prebuilt (from langgraph-prebuilt) undeclared in
  langchain-agents; declared at >=1.1.
- langchain-messages depends on langchain-openai, its default model, as
  langchain-agents does, so a bare install works; the [openai] extra is gone.
- The test module docstring no longer cites the private spec.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jeffdupont

Copy link
Copy Markdown
Contributor Author

Thanks @XieX. All three nits are in f3fbe8a:

  1. Private-spec reference. The test module docstring no longer cites the spec, and the PR description no longer cites section numbers. I also merged main, so fix(AIC-3568)!: give the barrel core's __all__, and drop private-spec references #234's cleanup is in this branch; a search of the .py files and scripts/ for the spec name or section signs now finds nothing.
  2. Namespace packages. The scan keeps each import's full dotted name, and inside the venv each module resolves to the distribution that owns its file, falling back to the top-level lookup only for a namespace leaf with no file. So opentelemetry.sdk needs opentelemetry-sdk declared. It caught a real one straight away: langchain-agents imports langgraph.prebuilt, which comes from langgraph-prebuilt, a dependency of langgraph that we didn't declare. It's now declared at >=1.1. test_a_namespace_package_needs_its_own_distribution_declared covers the case.
  3. LangChain default model. Not intentional. langchain-messages now depends on langchain-openai, as langchain-agents does, so a bare install works on the default path. The [openai] extra is gone (it was never released), and the README says so.

Local: make test 3,711 passed, make check-packaging 22/22 (14 packages, 8 extras).

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f3fbe8a. Configure here.

Comment thread packages/client/README.md Resolved
launchdarkly-server-sdk is now an extra, so an install without it succeeds and
then init_client() raises. The handler and barrel READMEs and the client
telemetry install now match the root README and the other handlers (Bugbot).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jeffdupont
jeffdupont merged commit 5860b40 into main Oct 29, 2026
10 checks passed
@jeffdupont
jeffdupont deleted the fix/AIC-3598-packaging-ga branch October 29, 2026 15:53
@github-actions github-actions Bot mentioned this pull request Oct 29, 2026
jeffdupont added a commit that referenced this pull request Oct 29, 2026
Takes main's pyproject.toml files (with #218's new dependencies) and keeps this
branch's internal pin, launchdarkly-ai-server>=1.0.0,<2, in all 13.

Also fixes release-please-config.json: 12727f3 wrote the release-as lines with
literal backslashes (\"release-as\": \"1.0.0\"), which is invalid JSON. The
file now parses, with release-as 1.0.0 on all 14 packages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jeffdupont added a commit that referenced this pull request Oct 30, 2026
Steps 1 and 2 of
[AIC-3672](https://launchdarkly.atlassian.net/browse/AIC-3672). The JS
half is AIC-3673.

## What this does

- **`release-as: 1.0.0`** on all 14 packages in
`release-please-config.json`. Without it, release-please keeps bumping
0.x minors, so the next release PR would ship `launchdarkly-ai-server`
0.6.0 instead of 1.0.0.
- **Internal pins.** Every package that depends on
`launchdarkly-ai-server` now requires `>=1.0.0,<2`. release-please
doesn't update these for Python. #218 (merged) set them to `>=0.6,<2` so
either release order resolves; this tightens them to the 1.0 line.
- **`uv.lock`** needs no change: uv records workspace dependencies
without a version specifier. `uv lock --check` passes.

`changelog-sections` is left alone. #235 removes the evaluations
Experimental rows when it promotes Evaluations from Code to core.

## Merge this last

Merge this after the PRs below. Anything merged before the release PR
(#231) merges ships in 1.0.0, and a `!` change merged after 1.0 forces
2.0.

- [x] #218 fix(AIC-3598)!: packaging and public types (merged 29 Oct)
- [x] #235 feat(evaluations)!: promote Evaluations from Code to core
(merged 29 Oct). After it merges, nothing in
`launchdarkly_ai_server.experimental` is public.
- [x] #237 fix(claude-agents)!: honour max_tokens and disable thinking
by default (merged 29 Oct)
- [ ] #136 feat(AIC-3439): wildcard handlers accept only named providers
(approved; conflicts with main, needs a merge of main)
- [x] #234 fix(AIC-3568)!: give the barrel core's `__all__` (merged 29
Oct)
- [ ] #246 fix(AIC-3592): make native LangGraph hand-offs complete (spec
launchdarkly/ai-sdks-monorepo#118)
- [ ] #248 fix(AIC-3573): never send a NativeTool to the model as a
function tool (spec launchdarkly/ai-sdks-monorepo#116)
- [ ] #240 feat(client): add result variant and value to the
feature_flag span event (approved, mergeable)
- [ ] #251 fix(AIC-3716): build OpenAI native graph node tools with
FunctionTool (review required; touches the same loop as #248)

#241 (Shadow Requests) is closed; 1.0 ships with nothing experimental.

## After merging

1. Confirm the regenerated #231 lists 1.0.0 for all 14 packages, then
merge it.
2. Install each package from PyPI into an empty venv and import its
public entry points (AIC-3672 step 5).
3. Open a PR removing `release-as` straight away, or every later release
PR proposes 1.0.0 again.

## Checks

- `release-please-config.json` parses as JSON, with `release-as: 1.0.0`
on all 14 packages. The first push wrote the lines with literal
backslashes; fixed in d720896.

- `make test`: 3,711 passed, 18 skipped (before #175 and #236 merged; CI
is the current check) (with the parent checkout's `.env` LD URIs
blanked; see AIC-3593)
- `uv lock --check` passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)


[AIC-3672]:
https://launchdarkly.atlassian.net/browse/AIC-3672?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ




<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Overview**
> Prepares the **1.0.0 GA** cut for all 14 Python packages by teaching
release-please to release **1.0.0** instead of another **0.x** bump.
> 
> Adds **`release-as: "1.0.0"`** on every entry in
`release-please-config.json` (core `launchdarkly-ai-server`, barrel, and
all handler packages).
> 
> Tightens **internal PyPI pins** from `launchdarkly-ai-server>=0.6,<2`
to **`>=1.0.0,<2`** in each handler `pyproject.toml` and in
`packages/ai` (including **`otel`** / **`ld`** extras). Published wheels
will require the 1.0 server line once those versions ship.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ae9f2cc. 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: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: andrewklatzke <aklatzke@launchdarkly.com>
jeffdupont pushed a commit that referenced this pull request Oct 30, 2026
🤖 I have created a release *beep* *boop*
---


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

##
[1.0.0](launchdarkly-ai-server-0.5.0...launchdarkly-ai-server-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **client:** init_client raises when the LaunchDarkly client did not
initialize
([#254](#254))
* **evaluations:** route generation and judges to a scoped wildcard
handler only for its named providers, and accept two scoped wildcards of
one mode when their lists differ
* **AIC-3439:** let wildcard handlers accept only named providers
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **evaluations:** promote Evaluations from Code to core
([#235](#235))
* **client:** capture conversation content by default
([#213](#213))
* **evaluations:** remove default pass rate threshold
([#238](#238))
* **evaluations:** set default pass rate threshold
([#226](#226))
* **client:** spans carry launchdarkly.project_id instead of
highlight.project_id
* **AIC-3687:** rename create_openai_agent_handler to
create_openai_agents_handler
([#225](#225))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#223](#223))

### Features

* **AIC-3439:** let wildcard handlers accept only named providers
([454a4de](454a4de))
* **AIC-3687:** rename create_openai_agent_handler to
create_openai_agents_handler
([#225](#225))
([a7cdbc0](a7cdbc0))
* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))
* **client:** point judge spans at the run they graded
([#253](#253))
([863d423](863d423))
* **evaluations:** promote Evaluations from Code to core
([#235](#235))
([0bc43a5](0bc43a5))
* **evaluations:** remove default pass rate threshold
([#238](#238))
([882d099](882d099))
* **evaluations:** route generation and judges to a scoped wildcard
handler only for its named providers, and accept two scoped wildcards of
one mode when their lists differ
([454a4de](454a4de))
* **evaluations:** set default pass rate threshold
([#226](#226))
([7ee368c](7ee368c))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#223](#223))
([11f2c0b](11f2c0b))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
* **AIC-3601:** stop graph routing text inviting a router to answer for
its target
([#230](#230))
([27b8d09](27b8d09))
* **client:** init_client raises when the LaunchDarkly client did not
initialize
([#254](#254))
([6e66c00](6e66c00))
* **client:** stamp launchdarkly.project_id on the telemetry resource
([#229](#229))
([5347558](5347558))
* **evaluations:** copy inline tool schemas and name both sources on a
key collision
([#227](#227))
([bfbdd4c](bfbdd4c))
* **evaluations:** send criterion errors as errorMessage and skip
criteria for rows that did not generate
([#228](#228))
([8b05b56](8b05b56))
* **graph:** report a node's own judge scores on its node_done stream
event ([#236](#236))
([2f3f9ee](2f3f9ee))


### Documentation

* **AIC-3692:** say which project id attribute the telemetry resource
carries
([#239](#239))
([64eff43](64eff43))
* state that Agent Skills and Evaluations from Code need 1.0.0
([#191](#191))
([fe3ef08](fe3ef08))
</details>

<details><summary>launchdarkly-ai-python: 1.0.0</summary>

##
[1.0.0](launchdarkly-ai-python-0.4.0...launchdarkly-ai-python-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **evaluations:** promote Evaluations from Code to core
([#235](#235))

### Features

* **evaluations:** promote Evaluations from Code to core
([#235](#235))
([0bc43a5](0bc43a5))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))


### Documentation

* state that Agent Skills and Evaluations from Code need 1.0.0
([#191](#191))
([fe3ef08](fe3ef08))
</details>

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

##
[1.0.0](launchdarkly-ai-claude-agents-0.3.0...launchdarkly-ai-claude-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **claude-agents:** honour the config's max_tokens and disable thinking
unless the config asks
([#237](#237))
* **client:** capture conversation content by default
([#213](#213))
* **AIC-3685:** make the internal provider helpers private
([#224](#224))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#223](#223))

### Features

* **AIC-3685:** make the internal provider helpers private
([#224](#224))
([9afdb94](9afdb94))
* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))
* **skills:** rename FDv2SkillStore to LaunchDarklySkillStore
([#223](#223))
([11f2c0b](11f2c0b))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
* **claude-agents:** honour the config's max_tokens and disable thinking
unless the config asks
([#237](#237))
([a7ded1b](a7ded1b))
</details>

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

##
[1.0.0](launchdarkly-ai-claude-messages-0.3.0...launchdarkly-ai-claude-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **client:** capture conversation content by default
([#213](#213))

### Features

* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
* **AIC-3735:** send Claude Messages sampling parameters through
extra_body
([#256](#256))
([c6d0376](c6d0376))
</details>

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

##
[1.0.0](launchdarkly-ai-openai-agents-0.3.0...launchdarkly-ai-openai-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **client:** capture conversation content by default
([#213](#213))
* **AIC-3685:** make the internal provider helpers private
([#224](#224))
* **AIC-3687:** rename create_openai_agent_handler to
create_openai_agents_handler
([#225](#225))

### Features

* **AIC-3685:** make the internal provider helpers private
([#224](#224))
([9afdb94](9afdb94))
* **AIC-3687:** rename create_openai_agent_handler to
create_openai_agents_handler
([#225](#225))
([a7cdbc0](a7cdbc0))
* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
* **AIC-3716:** build OpenAI native graph node tools with FunctionTool
([#251](#251))
([b859b67](b859b67))
* **AIC-3726:** realign three usage IDs with the 1.0 factory names
([#252](#252))
([1c4d904](1c4d904))
</details>

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

##
[1.0.0](launchdarkly-ai-vercel-agents-0.2.0...launchdarkly-ai-vercel-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))

### Features

* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
</details>

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

##
[1.0.0](launchdarkly-ai-litellm-agents-0.2.0...launchdarkly-ai-litellm-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **client:** capture conversation content by default
([#213](#213))

### Features

* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
</details>

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

##
[1.0.0](launchdarkly-ai-openai-messages-0.3.0...launchdarkly-ai-openai-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **client:** capture conversation content by default
([#213](#213))

### Features

* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
* **AIC-3726:** realign three usage IDs with the 1.0 factory names
([#252](#252))
([1c4d904](1c4d904))
</details>

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

##
[1.0.0](launchdarkly-ai-vercel-messages-0.2.0...launchdarkly-ai-vercel-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))

### Features

* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
</details>

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

##
[1.0.0](launchdarkly-ai-litellm-messages-0.2.0...launchdarkly-ai-litellm-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **client:** capture conversation content by default
([#213](#213))

### Features

* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
</details>

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

##
[1.0.0](launchdarkly-ai-langchain-agents-0.3.0...launchdarkly-ai-langchain-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **evaluations:** route generation and judges to a scoped wildcard
handler only for its named providers, and accept two scoped wildcards of
one mode when their lists differ
* **AIC-3439:** let wildcard handlers accept only named providers
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **client:** capture conversation content by default
([#213](#213))

### Features

* **AIC-3439:** let wildcard handlers accept only named providers
([454a4de](454a4de))
* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))
* **evaluations:** route generation and judges to a scoped wildcard
handler only for its named providers, and accept two scoped wildcards of
one mode when their lists differ
([454a4de](454a4de))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3590:** build Python langchain-agents with
langchain.agents.create_agent
([#175](#175))
([8218626](8218626))
* **AIC-3592:** make native LangGraph hand-offs complete
([#246](#246))
([bfb738f](bfb738f))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
</details>

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

##
[1.0.0](launchdarkly-ai-langchain-messages-0.3.0...launchdarkly-ai-langchain-messages-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **evaluations:** route generation and judges to a scoped wildcard
handler only for its named providers, and accept two scoped wildcards of
one mode when their lists differ
* **AIC-3439:** let wildcard handlers accept only named providers
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **client:** capture conversation content by default
([#213](#213))

### Features

* **AIC-3439:** let wildcard handlers accept only named providers
([454a4de](454a4de))
* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))
* **evaluations:** route generation and judges to a scoped wildcard
handler only for its named providers, and accept two scoped wildcards of
one mode when their lists differ
([454a4de](454a4de))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3573:** never send a NativeTool to the model as a function tool
([#248](#248))
([73caeae](73caeae))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
* **AIC-3726:** realign three usage IDs with the 1.0 factory names
([#252](#252))
([1c4d904](1c4d904))
</details>

<details><summary>launchdarkly-ai-opencode-agents: 1.0.0</summary>

##
[1.0.0](launchdarkly-ai-opencode-agents-0.3.0...launchdarkly-ai-opencode-agents-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))

### Features

* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
</details>

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

##
[1.0.0](launchdarkly-ai-typesafe-0.2.0...launchdarkly-ai-typesafe-1.0.0)
(2026-10-30)


### ⚠ BREAKING CHANGES

* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
* **client:** capture conversation content by default
([#213](#213))

### Features

* **client:** add result variant and value to the feature_flag span
event ([#240](#240))
([040d487](040d487))
* **client:** capture conversation content by default
([#213](#213))
([77a7cf5](77a7cf5))


### Bug Fixes

* **AIC-3568:** give the barrel core's __all__, and drop private-spec
references
([#234](#234))
([88e57e6](88e57e6))
* **AIC-3598:** make Python packaging and public types GA-ready
([#218](#218))
([5860b40](5860b40))
</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 is a **Release Please** cut that moves every monorepo package to
**1.0.0** and records the GA release in changelogs. It updates
`.release-please-manifest.json`, each package’s `pyproject.toml` /
`__version__`, and prepends **1.0.0** notes to every `CHANGELOG.md`.
> 
> Handler and barrel packages now require
**`launchdarkly-ai-server>=1.0.0,<2`**, so installs must upgrade the
core client in lockstep with adapters.
> 
> There is **no new application logic** in this diff—only release
metadata. The changelog text still matters for reviewers: it summarizes
breaking work already on `main`, including **Evaluations from Code
promoted to core**, **conversation content captured by default**,
**`init_client` failing when LD init fails**, telemetry
**`launchdarkly.project_id`**, renames like **`LaunchDarklySkillStore`**
and **`create_openai_agents_handler`**, tightened **wildcard handler
routing**, and **GA packaging / public `__all__`** cleanup.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
2e904f7. 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