Repository navigation
feat(AIC-3655)!: promote Agent Skills to core - #14
Draft
jeffdupont wants to merge 1 commit into
Draft
jeffdupont wants to merge 1 commit into
jeffdupont wants to merge 1 commit into
Conversation
Agent Skills move from aiserver/experimental to package aiserver. The implementation moves from internal/skills into aiserver (git mv, skills_*.go), which removes the import cycle that kept aiserver from exporting skills. Helpers that were exported only within the internal package (ClearState, SetEmitterForTesting, SetLogger) are unexported. Shutdown still clears skills state through the internal/bridge hook. aiserver/experimental no longer exports any skills name; it keeps Evaluations from Code. Import github.com/launchdarkly/go-ai-sdk/aiserver instead of aiserver/experimental for skills; nothing else changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 23, 2026
jeffdupont
added a commit
to launchdarkly/js-ai-sdk
that referenced
this pull request
Oct 26, 2026
Jira: [AIC-3655](https://launchdarkly.atlassian.net/browse/AIC-3655) > **Do not merge** until the blockers linked on AIC-3655 are fixed. This PR releases together with the Python and Go promotion PRs (links added later). ## What changed - **Agent Skills is core.** All 35 Agent Skills names (functions, stores, watcher, constants, factories and types) are exported from the `@launchdarkly/ai-server` root with the same spelling, and are **removed** from `@launchdarkly/ai-server/experimental`. This is breaking under the 0.x rule, so it bumps the minor version. - `@launchdarkly/ai-node` gets the names from its root through its existing `export *`. Its `/experimental` entry keeps working and still re-exports Evaluations from Code. - Evaluations from Code stays experimental. The `/experimental` entry point stays. - The API reports (`etc/ai-server.api.md`, `etc/ai-server-experimental.api.md`) are regenerated. The skills names are added to `api-surface/ai-server.txt` as `+` (joining) and marked `-` (leaving) in `api-surface/ai-server.experimental.txt`. - The `skills` rows are removed from `changelog-sections` in `release-please-config.json`. AGENTS.md now says `skills` is a core scope. - The shutdown hook is renamed from `experimental Agent Skills` to `Agent Skills`. The no-store error message now points to `@launchdarkly/ai-server`. Core doc comments no longer call Agent Skills experimental. - Tests: the root export snapshot now includes the skills values, the experimental entry exports only the Evaluations values, a new test checks that the API reports list every skills name at the root and none in the experimental report, and the lifecycle test now expects the `Agent Skills` hook after loading the root and no experimental hook. - The integration fixtures import skills from the root and check that `getSkill` is on the root and not on either `/experimental` subpath. - The READMEs and both agents.md files are updated, including the promotion note. - **Usage IDs:** `main` reports no `experimental.*` skills usage IDs, so this PR adds none. When the skills usage-reporting work (AIC-3555) lands in this SDK, it must use `client.*` IDs. ## Migration Change the import path from `'@launchdarkly/ai-server/experimental'` to `'@launchdarkly/ai-server'` (or from `'@launchdarkly/ai-node/experimental'` to `'@launchdarkly/ai-node'`). Nothing else changes: names, signatures and behavior are the same. ## Test plan Run in the worktree after `yarn install`: - [x] `yarn code:check`: exit 0 - [x] `yarn build`: exit 0 - [x] `yarn typecheck`: exit 0 - [x] `yarn test`: exit 0 (client: 1826 passed, 11 skipped) - [x] `yarn test:integration`: exit 0 (36 passed) - [x] `yarn api:surface`: exit 0 - [x] `yarn test:api-surface`, `yarn test:api-breaking`, `yarn lint:pkg`: exit 0 - [x] `yarn workspace @launchdarkly/ai-server api:check`: exit 0 - [ ] `yarn api:check`: exit 1, only because `packages/claude-agents/etc/ai-claude-agents.api.md` is already out of date on `main` (`ClaudeAgentsHostOptions` came in after the report was last generated). This PR doesn't touch that package. 🤖 Generated with [Claude Code](https://claude.com/claude-code) [AIC-3655]: https://launchdarkly.atlassian.net/browse/AIC-3655?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ ## Related PRs Releases together with: - launchdarkly/python-ai-sdk#210 - launchdarkly/go-ai-sdk#14 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > **Agent Skills moves from `@launchdarkly/ai-server/experimental` to the package root** (and the same via `@launchdarkly/ai-node`). All skills APIs—stores, accessors, `writeSkills`/`watchSkills`, types—are removed from the experimental entry point; **Evaluations from Code** remains on `/experimental` only. This is a **breaking** 0.x change: imports must switch from `.../experimental` to the root; names and behavior are unchanged. > > API Extractor reports and `api-surface/*.txt` are updated accordingly; `skills` is dropped from release-please **Experimental** changelog sections and AGENTS.md now treats `skills` as a core scope. Docs call out that loading the **root** now pulls in Node built-ins (`node:fs`, `node:path`, etc.) for skills, which can break non-Node edge runtimes (tracked as AIC-3674). > > Implementation follow-ups: shutdown hook renamed to `Agent Skills`; skills helpers emit **`client.*` `$ld:ai:sdk:usage` IDs**; `watchSkills` uses `writeSkillsInternal` so only the watcher reports usage. Tests, webpack integration fixtures, and re-export assertions are aligned with the new surface. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit ecef311. 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>
jeffdupont
added a commit
to launchdarkly/python-ai-sdk
that referenced
this pull request
Oct 26, 2026
Promotes Agent Skills from `launchdarkly_ai_server.experimental.skills` to the package root. Jira: [AIC-3655](https://launchdarkly.atlassian.net/browse/AIC-3655). > **Do not merge yet.** This PR must not merge until the blockers linked on AIC-3655 are fixed. It releases together with the JS and Go promotion PRs (links to be added). ## Migration Import Agent Skills names from `launchdarkly_ai_server` instead of `launchdarkly_ai_server.experimental.skills`. Nothing else changes: the names, signatures and behaviour are the same. ```python # before from launchdarkly_ai_server.experimental.skills import get_skill, write_skills # after from launchdarkly_ai_server import get_skill, write_skills ``` This is a breaking change (`!`), which bumps the minor version while the package is 0.x. ## What changed - **Root exports.** All 24 names that `experimental/skills.py` exported are now in `launchdarkly_ai_server.__all__`, same spelling. `launchdarkly-ai-python` re-exports root `__all__` with `import *`, so it gets them with no code change; its existing re-export tests cover it. - **Experimental module removed.** `experimental/skills.py` is deleted. `experimental/__init__.py` is only a docstring, so nothing else there referenced it. Evaluations from Code stays in `experimental.evaluations`, untouched. - **API reports.** Regenerated with `make api-report`: the skills names appear in `launchdarkly_ai_server.txt`, and `launchdarkly_ai_server.experimental.skills.txt` is deleted. - **Changelog.** The three `skills` → Experimental rows are removed from `changelog-sections` in `release-please-config.json`, so `feat(skills):` now lands under Features. - **Docs.** The client README, the `launchdarkly-ai-python` README, `packages/client/agents.md` and `AGENTS.md` no longer call Agent Skills experimental. Code samples import from the root. - **Core strings.** Docstrings and error messages in `skills_core.py`, `skills_watch.py`, `types.py`, `types_validation.py`, `shutdown_hooks.py` and `lifecycle.py` no longer name the experimental module. For example, the "no skill store" error now says `set_skill_store(store) from launchdarkly_ai_server`. - **Usage IDs.** None. `main` reports no skills usage IDs today, so this PR adds none. When skills usage reporting is added, it must use `client.*` IDs, not `experimental.*`. - **Unchanged behaviour.** `parse_ai_config` still passes `skills` through unvalidated, and `skill_refs` still validates it. `shutdown()` still clears the skill store through the internal shutdown hook. The lifecycle module still imports no skills module. ## Tests - `test_skills.py`: every skills name is in root `__all__` and on the root module. `launchdarkly_ai_server.experimental.skills` raises `ImportError`, and `launchdarkly_ai_server.experimental` has none of the names. - `test_public_surface.py`: the skills names are added to the `ROOT_SURFACE` snapshot. - `test_lifecycle.py`: the "core loads no experimental module" check now checks `evaluations` and `experimental` only, since the root now imports the skills modules. - The skills test suites and `conftest.py` import from the root. ## Test plan Run in the PR worktree after `uv sync` (exit 0): - [x] `make lint` — exit 0 - [x] `make format-check` — exit 0 - [x] `make typecheck` — exit 0 (`Success: no issues found in 101 source files`) - [x] `make api-report-check` — exit 0 (`14 API reports are current`) - [x] `uv run pytest -q packages/client packages/ai` — 1709 passed, 1 skipped - [ ] `make test` — exit 2: 3282 passed, 18 skipped, 3 failed. The same 3 tests fail on unmodified `origin/main` (e3afb3f) in the same checkout, and CI on `main` is green. None of them involves skills: - `test_lifecycle.py::TestInitClientSDKKeyPath::test_uses_options_sdk_key_over_env_var` and `::test_retries_after_a_failed_init_instead_of_replaying_it`: they get a staging `stream_uri`. My unverified guess is a local `.env` above the checkout leaking into the full run. Both pass when run alone. - `opencode-agents/tests/test_handler.py::TestProcess::test_a_fake_opencode_is_started_spoken_to_and_stopped`: on macOS the temp path comes back as `/var/...` in one place and `/private/var/...` in another. 🤖 Generated with [Claude Code](https://claude.com/claude-code) [AIC-3655]: https://launchdarkly.atlassian.net/browse/AIC-3655?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ ## Related PRs Releases together with: - launchdarkly/js-ai-sdk#159 - launchdarkly/go-ai-sdk#14 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > **Promotes Agent Skills from experimental to the stable `launchdarkly_ai_server` package root**, with a breaking migration from `launchdarkly_ai_server.experimental.skills` to root imports (same names and behavior). The experimental skills module is removed, API reports and `ROOT_SURFACE` tests are updated, and release-please no longer routes `feat(skills):` to the Experimental changelog. > > **Skills helpers now emit the standard SDK helper usage event** (`report_usage` with `client.*` IDs); `watch_skills` reconciles via internal `_write_skills` so background reconciles do not double-count `writeSkills`. Docs and samples (`client`/`ai` READMEs, `AGENTS.md`, claude-agents) are aligned; **Evaluations from Code** remains the only experimental surface. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a6e1fde. 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>
XieX
added a commit
that referenced
this pull request
Oct 28, 2026
## Summary Renames the Agent Skills delivery store, so Go matches launchdarkly/python-ai-sdk#223 and launchdarkly/js-ai-sdk#172. The spec change is launchdarkly/ai-sdks-monorepo#96, which follows launchdarkly/ai-sdks-monorepo#95. **Why.** FDv2 is still Early Access, and the base SDKs keep it out of their public type names. The store is now named for its source rather than its protocol. | Before | After | | --- | --- | | `FDv2SkillStore` | `LaunchDarklySkillStore` | | `NewFDv2SkillStore` | `NewLaunchDarklySkillStore` | | `FDv2SkillStoreOptions` | `LaunchDarklySkillStoreOptions` | | `FDv2Mode` | `LaunchDarklySkillStoreMode` | | `FDv2ModeStream` / `FDv2ModePoll` | `LaunchDarklySkillStoreModeStream` / `LaunchDarklySkillStoreModePoll` | **No deprecated aliases.** No Go version has been released: there are no tags or GitHub releases, and the release-please manifest is at `0.0.0`. So this is a clean rename, as in Python. TypeScript kept aliases because 0.5.0 shipped the old names. The rename covers `internal/skills`, the `aiserver/experimental` aliases and wrappers, the documented-surface test list, error and log strings that name the type, `README.md` and `agents.md`. **Unchanged:** the `internal/skills/fdv2_*.go` file names, the wire-kind constants (`FDv2PayloadKind`, `FDv2ObjectKind`), the unexported `newFDv2Reader`, the `TestFDv2*` test names, and prose that describes the FDv2 protocol. **Conflicts with #14.** #14 (promote Agent Skills to core) moves these files into `aiserver/skills_*.go` and keeps the FDv2 names. Whichever lands second has to carry the rename across. If #14 lands first, rerunning the same word-boundary replacement over `aiserver/` redoes this PR. ## Checks - `go build ./...`, `go vet ./...` and `go test -race ./...` pass. - `gofmt -l .` is clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Overview** > **Breaking rename** of the experimental Agent Skills delivery store public API so Go aligns with the Python and JS AI SDKs: types are named for LaunchDarkly as the content source rather than the FDv2 wire protocol. > > Public symbols move from `FDv2SkillStore` / `NewFDv2SkillStore` / `FDv2SkillStoreOptions` / `FDv2Mode` to **`LaunchDarklySkillStore`**, **`NewLaunchDarklySkillStore`**, **`LaunchDarklySkillStoreOptions`**, and **`LaunchDarklySkillStoreMode`** (with `LaunchDarklySkillStoreModeStream` / `LaunchDarklySkillStoreModePoll`). The change threads through `internal/skills`, `aiserver/experimental` aliases, README/agents docs, the pinned `skillsSurface` test list, and user-facing error/log strings (including `ErrStoreClosed` and `noStoreMessage`). > > **No deprecated aliases** — the package has not shipped a release yet. **Behavior and FDv2 transport are unchanged**: `fdv2_store.go` / `fdv2_reader.go` filenames, internal reader helpers, and `TestFDv2*` names stay as-is. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 4cd495a. 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>
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.
Jira: AIC-3655 (Go coverage: AIC-3656)
What changed
aiserver/experimentalexported is now exported byaiserverwith the same name and signature (Skill,SkillStore,SetSkillStore,SkillRefs,GetSkill*,AllSkills,WriteSkills,WriteAllSkills,WatchSkills,WatchAllSkills,FDv2SkillStore, theReason*/Action*/OnUnavailable*/FDv2Mode*constants, theErr*sentinels, …). Nothing is renamed.aiserver/experimental. That package keeps Evaluations from Code.internal/skills/accessors.goimportedaiserver, soaiservercould not export skills. The implementation now lives in packageaiserver(git mv internal/skills/*.go aiserver/skills_*.go, so history follows). Unexported helpers stay unexported. Three names that were exported only inside the internal package are now unexported:ClearState→clearSkillState,SetEmitterForTesting→setSkillEmitterForTesting,SetLogger→setSkillLogger. A duplicateskillKeyREinparse.gowas dropped; it had the same pattern as the skills one.internal/bridgeOnShutdownhook, registered at package init, in the same order as before. Core does not importaiserver/experimental.aiserver.SetSkillStore/aiserver.NewFDv2SkillStore/aiserver.NewInMemorySkillStore.mainreports no skills usage IDs (skills never track, and a test asserts it), so none were added. AIC-3555's SDK work must useclient.*.aiserver/skills_*_test.go. The public-surface skills tests fromexperimental/skills_test.goare inaiserver/skills_public_test.go(package aiserver_test).rootSurfaceinaiserver/surface_test.gonow lists the skills names, andTestNoExperimentalNameOnRootalso checks that skills names are on the root and that the wire constants stay unexported. The experimental surface test pins evaluations only, so a skills name left inexperimentalwould fail it.aiserver/experimental/README.mdandagents.mdtoaiserver/README.mdandaiserver/agents.md. The root README, AGENTS.md,experimental/doc.goand theaiserverpackage doc no longer call skills experimental.Migration
For Agent Skills, import
github.com/launchdarkly/go-ai-sdk/aiserverinstead ofgithub.com/launchdarkly/go-ai-sdk/aiserver/experimental, then changeexperimental.Xtoaiserver.X. Nothing else changes.Release
This releases together with the JS and Python promotion PRs (links added later). It is not on the 30 Oct critical path.
Test plan
make format-check: exit 0make vet(go vet ./...): exit 0make build(go build ./...): exit 0go test ./...: exit 0go test -race -shuffle=on ./...(CI's command): exit 0, 15 packages okGOOS=windows go vet ./aiserver/...: exit 0 (non-POSIXskills_materialize_other.gostill compiles)🤖 Generated with Claude Code
Related PRs
Releases together with: