You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit d720896
Browse filesBrowse the repository at this point in the historyBrowse files
Merge origin/main into jdupont/aic-3672-release-1-0
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>
Copy file name to clipboardExpand all lines: AGENTS.md
+3-5Lines changed: 3 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -86,14 +86,12 @@ Every public module has a committed API report at `packages/<package>/api-report
86
86
87
87
PRs are squash-merged with the PR title as the commit message, and release-please builds each package's changelog from those messages.
88
88
89
-
-**A change to an experimental feature uses that feature's scope:**`evaluations` (Evaluations from Code). `feat`, `fix` and `perf` commits with that scope are listed under **Experimental** (`changelog-sections` in `release-please-config.json`), for example `feat(evaluations): score rows in parallel`. Any other scope, such as `client`or `skills`, lists the change as a core feature or fix. Agent Skills is core, so `feat(skills):`lands under Features.
90
-
-**Use exactly one scope.**`feat(evaluations,client):` matches no Experimental row, so it lands under Features.
89
+
-**A change to an experimental feature uses that feature's scope.**`feat`, `fix` and `perf` commits with that scope are listed under **Experimental** (`changelog-sections` in `release-please-config.json`). No feature is experimental now. Any other scope, such as `client`, `skills`or `evaluations`, lists the change as a core feature or fix. Agent Skills and Evaluations from Code are core, so `feat(skills):`and `feat(evaluations):` land under Features.
90
+
-**Use exactly one scope.**`feat(beta,client):` matches no Experimental row, so it lands under Features.
91
91
-**A PR that changes both core and experimental behaviour** should be split. If it can't be, add a `BEGIN_COMMIT_OVERRIDE` block to its description with one conventional-commit line per change. An override also corrects a merged PR's title, as long as the release PR hasn't merged yet.
92
-
-**A breaking experimental change** uses `!` while the package is 0.x: `feat(evaluations)!:` bumps the minor version, which is what an experimental break is allowed. After 1.0, `!` would force a major release. Use `feat(evaluations):` without `!` instead, and say the change is breaking in the title.
92
+
-**A breaking experimental change** uses `!` while the package is 0.x: `feat(beta)!:` bumps the minor version, which is what an experimental break is allowed. After 1.0, `!` would force a major release. Use `feat(beta):` without `!` instead, and say the change is breaking in the title.
93
93
-**When a feature is promoted to core,** remove its rows from `changelog-sections`.
94
94
95
-
The rule is specified in `TESTING.md` §0.3 in `launchdarkly/ai-sdks-monorepo`.
96
-
97
95
## Package Hierarchy
98
96
99
97
The monorepo is organized into three tiers plus a convenience barrel. Dependencies only flow **downward** — never sideways between packages in the same tier, and never upward.
From 1.0.0 every package in this SDK is released at the same version, so install them at matching versions. Each package depends on `launchdarkly-ai-server` within the same major (`>=1.0,<2`), and a breaking change in any package is a new major for all of them. Names exported from `launchdarkly_ai_server.experimental` are the exception: they may change in a minor release.
97
+
98
+
Every third-party floor sits on the release line CI tests: the same major as the tested version for a 1.x or later library, the same minor for a 0.x one, where a minor release may break. A floor that was below that line was raised to the tested version; a floor already on it stayed where it was.
`launchdarkly-ai-python` is a thin barrel that re-exports all of `launchdarkly-ai-server`. The base LaunchDarkly Python SDK is a peer dependency rather than a bundled one, so install `launchdarkly-server-sdk` alongside it. `init_client()` discovers it at runtime, or you can skip it entirely by passing a pre-initialized client with `init_client(client=my_client)`.
108
+
`launchdarkly-ai-python` is a thin barrel that re-exports all of `launchdarkly-ai-server`. The base LaunchDarkly Python SDK is an optional dependency rather than a bundled one; the `[ld]` extra installs `launchdarkly-server-sdk`. `init_client()` discovers it at runtime, or you can skip it entirely by passing a pre-initialized client with `init_client(client=my_client)`.
103
109
104
110
**With telemetry** (recommended for production) — traces export to the LaunchDarkly Observability dashboard:
No code changes are needed — `init_client()` detects whether the OTel packages are present at runtime and configures the tracer provider automatically. If they are absent, the SDK logs a one-time warning and continues normally.
@@ -574,7 +580,7 @@ When running inside `graph()`, every node's events carry the graph key, tool inv
574
580
575
581
### Optional dependencies
576
582
577
-
The OpenTelemetry SDK packages are **optional** — detected at runtime via `importlib`. The LaunchDarkly server SDK (`launchdarkly-server-sdk`) is also an optional dependency; pass a pre-initialized client to `init_client(client=...)` if you bring your own.
583
+
The OpenTelemetry SDK packages are **optional** — detected at runtime via `importlib`. The LaunchDarkly server SDK (`launchdarkly-server-sdk`) is also an optional dependency, installed by the `[ld]` extra; pass a pre-initialized client to `init_client(client=...)` if you bring your own.
578
584
579
585
**OTel packages** (installed via `pip install "launchdarkly-ai-python[otel]"` or `pip install "launchdarkly-ai-server[otel]"`):
580
586
-**If installed:**`init_client()` sets up a `TracerProvider` with a GZIP-compressed OTLP HTTP exporter and W3C trace-context/baggage propagators — no code changes needed.
Set `ANTHROPIC_API_KEY` in your environment (the Anthropic SDK reads it automatically).
@@ -74,6 +74,15 @@ to_claude_agents(
74
74
)
75
75
```
76
76
77
+
### Output limit and thinking
78
+
79
+
-`max_tokens` in the config's model parameters sets the output-token limit for each model request. The Agent SDK has no option for it, so the handler sets `CLAUDE_CODE_MAX_OUTPUT_TOKENS` in the environment of the Claude Code process. Without `max_tokens`, Claude Code uses its own default. A `CLAUDE_CODE_MAX_OUTPUT_TOKENS` in the `env` of a Claude Code settings file, including `~/.claude.json`, wins over `max_tokens`.
80
+
- Thinking is off unless the config sets `thinking` or `max_thinking_tokens`. Models that reject disabled thinking, such as `claude-fable-5`, still use their own default. Claude Code lowers a thinking budget to one less than `max_tokens`, so when a config sets both, keep `max_tokens` above the budget.
81
+
82
+
#### Migrating from a version that used Claude Code's thinking default
83
+
84
+
Earlier versions passed no thinking setting when the config had none, so Claude Code chose one: adaptive thinking on models that support it, and a 31,999-token budget on others such as `claude-haiku-4-5`. A run now thinks only when its config asks. To keep thinking, set it in the config's model parameters, for example `{"thinking": {"type": "adaptive"}}`.
# NativeTool sentinels for Claude Code built-in capabilities
61
61
ClaudeBash: NativeTool
@@ -141,7 +141,7 @@ The CLI also writes its own `AssistantMessage`, with `model` set to the literal
141
141
an API call fails and after a response stops at `max_output_tokens`. It is not a model response:
142
142
it gets no `chat` span and never joins the conversation a later span reports.
143
143
144
-
**Important:** a bare `return` inside `async for` abandons the generator. Python's asyncio finalizer will try to `aclose()` it later and may raise `RuntimeError: aclose(): asynchronous generator is already running` if the generator is still suspended inside a real SDK `await`. Always use `break` + explicit `aclose()`. See **Appendix A.4** in `TESTING.md`.
144
+
**Important:** a bare `return` inside `async for` abandons the generator. Python's asyncio finalizer will try to `aclose()` it later and may raise `RuntimeError: aclose(): asynchronous generator is already running` if the generator is still suspended inside a real SDK `await`. Always use `break` + explicit `aclose()`.
145
145
146
146
### 4. Telemetry
147
147
@@ -236,6 +236,6 @@ Span names and attributes are described in [Implementation Details → Telemetry
236
236
## Common Pitfalls
237
237
238
238
-**MCP tool name prefix**: tools registered in the MCP server are accessible as `mcp__tool-mcp__<name>`. The `allowed_tools` list must use this prefix; omitting it will cause the agent to not invoke any tools.
239
-
-**Async generator teardown**: always use `break` inside `async for` (not `return`) and wrap the loop in `try/finally: await gen.aclose()`. See TESTING.md Appendix A.4.
239
+
-**Async generator teardown**: always use `break` inside `async for` (not `return`) and wrap the loop in `try/finally: await gen.aclose()`.
240
240
-**`message.usage` shape**: the raw usage dict from the `claude_agent_sdk` is passed through directly to `parse_usage`. It accepts `input_tokens`/`output_tokens` which the SDK provides.
241
241
-**Native tools** (`ClaudeWebSearch`, etc.) are registered in `tool_handlers` as `NativeTool` sentinel instances (not callables). The handler's `_partition_tools` function separates them from user-defined tools — native tools go into `native_tool_names` for the agent's built-in access, user tools go through the MCP server.
0 commit comments