Repository navigation
chore(AIC-3672): release every Python package as 1.0.0 - #242
Merged
Merged
Conversation
- release-please-config.json: "release-as": "1.0.0" on all 14 packages, so the next release PR proposes 1.0.0 for every package instead of a 0.x minor. - Internal pins: every package that depends on launchdarkly-ai-server now requires >=1.0.0,<2 (11 handlers had >=0.4.1; ai and typesafe had no bound). - uv.lock refreshed for the new specifiers. release-as must be removed straight after the release, or every later release PR proposes 1.0.0 again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 28, 2026
jeffdupont
added a commit
that referenced
this pull request
Oct 28, 2026
…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>
jeffdupont
added a commit
that referenced
this pull request
Oct 29, 2026
Python half of [AIC-3598](https://launchdarkly.atlassian.net/browse/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; #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](https://claude.com/claude-code) [AIC-3598]: https://launchdarkly.atlassian.net/browse/AIC-3598?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!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 **`TypedDict`s**, and return **`NativeGraphRunner`** instead of untyped namespaces. > > README adds **1.0 synchronized versioning** policy for the SDK. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit bdd635b. 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>
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
marked this pull request as ready for review
October 29, 2026 21:06
andrewklatzke
self-requested a review
October 30, 2026 18:21
andrewklatzke
approved these changes
Oct 30, 2026
jeffdupont
added a commit
to launchdarkly/js-ai-sdk
that referenced
this pull request
Oct 30, 2026
Steps 1 and 3 of [AIC-3673](https://launchdarkly.atlassian.net/browse/AIC-3673). The Python half is launchdarkly/python-ai-sdk#242. ## What this does - **`release-as: 1.0.0`** on all 14 packages in `release-please-config.json`. The `node-workspace` plugin updates the internal dependency ranges. - **Publish jobs for `litellm-agents` and `litellm-messages`.** They had none, so `@launchdarkly/ai-litellm-*-0.2.0` was tagged but never published. Both are also added to the manual-publish choices. `changelog-sections` is left alone: #181 (merged) removed the evaluations Experimental rows when it promoted Evaluations from Code to core. ##⚠️ npm setup: trusted publishers still to confirm for 5 of 14 packages The 26 Oct release run ([40393827352](https://github.com/launchdarkly/js-ai-sdk/actions/runs/40393827352)) failed 3 publish jobs, and the litellm packages have never had a job: | Package | On npm | Failure | |---|---|---| | `@launchdarkly/ai-typesafe` | 0.0.0 placeholder | `E404 … PUT @launchdarkly/ai-typesafe`: the package doesn't exist, and OIDC can't create it | | `@launchdarkly/ai-vercel-agents` | 0.0.0 placeholder | `E403 OIDC permission denied` | | `@launchdarkly/ai-vercel-messages` | 0.0.0 placeholder | `E403 OIDC permission denied` | | `@launchdarkly/ai-litellm-agents` | 0.0.0 placeholder | no publish job (added here) | | `@launchdarkly/ai-litellm-messages` | 0.0.0 placeholder | no publish job (added here) | Before the release PR merges, an npm org admin needs to: 1. ~~Publish a 0.0.0 placeholder for `ai-typesafe`, `ai-litellm-agents` and `ai-litellm-messages`.~~ Done: all three are on npm at 0.0.0 (checked 29 Oct). 2. Add a trusted publisher (`launchdarkly/js-ai-sdk`, workflow `release-please.yml`) to all five. Otherwise 1.0.0 ships 9 of 14 packages. ## Merge this last Merge this only after the items below are done. Anything merged before the release PR (#171) merges ships in 1.0.0, and a `!` change merged after 1.0 forces 2.0. - [x] #181 feat(evaluations)!: promote Evaluations from Code to core. After it, `@launchdarkly/ai-server/experimental` exports nothing. - [x] #180 fix(SEC-9507)!: dispatch tools only from the active variation's config.tools - [x] #183 fix(claude-agents)!: honour max_tokens and disable thinking by default - [x] #111 feat(AIC-3439)!: wildcard handlers accept only named providers (merged 29 Oct) - [x] npm placeholders (above) - [ ] Trusted publishers on all five packages (above; needs an npm org admin to confirm) - [ ] #192 fix(AIC-3592): make native LangGraph hand-offs complete (ready for review; spec launchdarkly/ai-sdks-monorepo#118) - [ ] #194 fix(AIC-3573): never send a NativeTool to the model as a function tool (ready for review; spec launchdarkly/ai-sdks-monorepo#116) - [ ] #190 feat(client)!: capture conversation content by default and add configure() (approved; breaking, so it must land before #171) - [ ] #196 test(AIC-3716): run the OpenAI native graph with a tool on the real SDK (test only; optional for the release) Not in 1.0: #187 (Shadow Requests, closed). 1.0 ships with nothing experimental. ## After merging 1. Confirm the regenerated #171 lists 1.0.0 for all 14 packages and its CI is green, then merge it. 2. Install each package from npm into an empty project and import its entry points, in both ESM and CJS (AIC-3673 step 5). 3. Open a PR removing `release-as` straight away. ## Checks - The workflow YAML parses: 14 per-package publish jobs plus release-please and the canary. The new jobs are copies of `release-typesafe`. - No local build was run: this is config only, made through the GitHub API. 🤖 Generated with [Claude Code](https://claude.com/claude-code) [AIC-3673]: https://launchdarkly.atlassian.net/browse/AIC-3673?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > Prepares the monorepo for a coordinated **1.0.0** npm release by setting **`release-as: "1.0.0"`** on all 14 workspaces in `release-please-config.json` (the `node-workspace` plugin will align internal dependency ranges when the release PR lands). > > The **`release-please`** workflow now fully covers **`litellm-agents`** and **`litellm-messages`**: they appear in manual `workflow_dispatch` package choices, expose release-please job outputs, and get dedicated **`release-litellm-*`** publish jobs (build, attest, npm publish) matching the other packages—closing the gap where LiteLLM tags could be created without a publish step. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit af882d4. 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Steps 1 and 2 of AIC-3672. The JS half is AIC-3673.
What this does
release-as: 1.0.0on all 14 packages inrelease-please-config.json. Without it, release-please keeps bumping 0.x minors, so the next release PR would shiplaunchdarkly-ai-server0.6.0 instead of 1.0.0.launchdarkly-ai-servernow requires>=1.0.0,<2. release-please doesn't update these for Python. fix(AIC-3598)!: make Python packaging and public types GA-ready #218 (merged) set them to>=0.6,<2so either release order resolves; this tightens them to the 1.0 line.uv.lockneeds no change: uv records workspace dependencies without a version specifier.uv lock --checkpasses.changelog-sectionsis 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.launchdarkly_ai_server.experimentalis public.__all__(merged 29 Oct)#241 (Shadow Requests) is closed; 1.0 ships with nothing experimental.
After merging
release-asstraight away, or every later release PR proposes 1.0.0 again.Checks
release-please-config.jsonparses as JSON, withrelease-as: 1.0.0on all 14 packages. The first push wrote the lines with literal backslashes; fixed in d720896.make test: 3,711 passed, 18 skipped (before fix(AIC-3590): build Python langchain-agents with langchain.agents.create_agent #175 and fix(graph): report a node's own judge scores on its node_done stream event #236 merged; CI is the current check) (with the parent checkout's.envLD URIs blanked; see AIC-3593)uv lock --checkpasses🤖 Generated with Claude Code
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 inrelease-please-config.json(corelaunchdarkly-ai-server, barrel, and all handler packages).Tightens internal PyPI pins from
launchdarkly-ai-server>=0.6,<2to>=1.0.0,<2in each handlerpyproject.tomland inpackages/ai(includingotel/ldextras). Published wheels will require the 1.0 server line once those versions ship.Reviewed by Cursor Bugbot for commit ae9f2cc. Bugbot is set up for automated code reviews on this repo. Configure here.