Skip to content

Commit f7ce6d3

Browse files
committed
merge + conflicts
2 parents 8b3c69f + da0c9c6 commit f7ce6d3

65 files changed

Lines changed: 7150 additions & 1632 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/build/action.yml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,10 @@ inputs:
44
workspace_path:
55
description: 'Path to the package to build.'
66
required: true
7-
outputs:
8-
package-hashes:
9-
description: "base64-encoded sha256 hashes of distribution files"
10-
value: ${{ steps.package-hashes.outputs.package-hashes }}
117

128
runs:
139
using: composite
1410
steps:
1511
- name: Build distribution files
1612
shell: bash
1713
run: make -C ${{ inputs.workspace_path }} build
18-
19-
- name: Hash build files for provenance
20-
id: package-hashes
21-
shell: bash
22-
working-directory: ${{ inputs.workspace_path }}/dist
23-
run: |
24-
echo "package-hashes=$(sha256sum * | base64 -w0)" >> "$GITHUB_OUTPUT"

.github/workflows/ci.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
strategy:
1717
matrix:
18-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
18+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
1919

2020
steps:
2121
- uses: actions/checkout@v4
@@ -39,7 +39,7 @@ jobs:
3939

4040
strategy:
4141
matrix:
42-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
42+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
4343

4444
steps:
4545
- uses: actions/checkout@v4
@@ -59,7 +59,7 @@ jobs:
5959
runs-on: ubuntu-latest
6060
strategy:
6161
matrix:
62-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
62+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
6363

6464
steps:
6565
- uses: actions/checkout@v4
@@ -81,7 +81,7 @@ jobs:
8181

8282
strategy:
8383
matrix:
84-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
84+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
8585

8686
steps:
8787
- uses: actions/checkout@v4
@@ -101,7 +101,7 @@ jobs:
101101
runs-on: ubuntu-latest
102102
strategy:
103103
matrix:
104-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
104+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
105105

106106
steps:
107107
- uses: actions/checkout@v4
@@ -123,7 +123,7 @@ jobs:
123123

124124
strategy:
125125
matrix:
126-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
126+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
127127

128128
steps:
129129
- uses: actions/checkout@v4
@@ -143,7 +143,7 @@ jobs:
143143
runs-on: ubuntu-latest
144144
strategy:
145145
matrix:
146-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
146+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
147147

148148
steps:
149149
- uses: actions/checkout@v4
@@ -165,7 +165,7 @@ jobs:
165165

166166
strategy:
167167
matrix:
168-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
168+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
169169

170170
steps:
171171
- uses: actions/checkout@v4

.github/workflows/release-please.yml

Lines changed: 26 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,10 @@ jobs:
5858
needs: ['release-please']
5959
permissions:
6060
id-token: write # Needed for OIDC to get release secrets from AWS.
61+
attestations: write # Needed for actions/attest.
6162
if: ${{ needs.release-please.outputs.package-server-ai-released == 'true' }}
62-
outputs:
63-
package-hashes: ${{ steps.build.outputs.package-hashes }}
6463
steps:
6564
- uses: actions/checkout@v4
66-
with:
67-
fetch-depth: 0
6865

6966
- uses: ./.github/actions/ci
7067
with:
@@ -75,6 +72,11 @@ jobs:
7572
with:
7673
workspace_path: packages/sdk/server-ai
7774

75+
- name: Attest build provenance
76+
uses: actions/attest@v4
77+
with:
78+
subject-path: 'packages/sdk/server-ai/dist/*'
79+
7880
- uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.2.0
7981
name: 'Get PyPI token'
8082
with:
@@ -92,13 +94,10 @@ jobs:
9294
needs: ['release-please']
9395
permissions:
9496
id-token: write # Needed for OIDC to get release secrets from AWS.
97+
attestations: write # Needed for actions/attest.
9598
if: ${{ needs.release-please.outputs.package-server-ai-langchain-released == 'true' }}
96-
outputs:
97-
package-hashes: ${{ steps.build.outputs.package-hashes }}
9899
steps:
99100
- uses: actions/checkout@v4
100-
with:
101-
fetch-depth: 0
102101

103102
- uses: ./.github/actions/ci
104103
with:
@@ -109,6 +108,11 @@ jobs:
109108
with:
110109
workspace_path: packages/ai-providers/server-ai-langchain
111110

111+
- name: Attest build provenance
112+
uses: actions/attest@v4
113+
with:
114+
subject-path: 'packages/ai-providers/server-ai-langchain/dist/*'
115+
112116
- uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.2.0
113117
name: 'Get PyPI token'
114118
with:
@@ -140,57 +144,28 @@ jobs:
140144
workspace_path: ${{ inputs.workspace_path }}
141145

142146
- uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.2.0
143-
if: ${{ inputs.dry_run != true }}
147+
if: ${{ format('{0}', inputs.dry_run) != 'true' }}
144148
name: 'Get PyPI token'
145149
with:
146150
aws_assume_role: ${{ vars.AWS_ROLE_ARN }}
147151
ssm_parameter_pairs: '/production/common/releasing/pypi/token = PYPI_AUTH_TOKEN'
148152

149153
- name: Publish to PyPI
150-
if: ${{ inputs.dry_run != true }}
154+
if: ${{ format('{0}', inputs.dry_run) != 'true' }}
151155
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
152156
with:
153157
password: ${{ env.PYPI_AUTH_TOKEN }}
154158
packages-dir: ${{ inputs.workspace_path }}/dist/
155159

156-
release-server-ai-provenance:
157-
needs: ['release-please', 'release-server-ai']
158-
if: ${{ needs.release-please.outputs.package-server-ai-released == 'true' }}
159-
permissions:
160-
actions: read # Needed for detecting the GitHub Actions environment.
161-
id-token: write # Needed for provenance signing.
162-
contents: write # Needed for uploading assets to the release.
163-
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
164-
with:
165-
base64-subjects: "${{ needs.release-server-ai.outputs.package-hashes }}"
166-
upload-assets: true
167-
upload-tag-name: ${{ needs.release-please.outputs.package-server-ai-tag-name }}
168-
169-
release-server-ai-langchain-provenance:
170-
needs: ['release-please', 'release-server-ai-langchain']
171-
if: ${{ needs.release-please.outputs.package-server-ai-langchain-released == 'true' }}
172-
permissions:
173-
actions: read # Needed for detecting the GitHub Actions environment.
174-
id-token: write # Needed for provenance signing.
175-
contents: write # Needed for uploading assets to the release.
176-
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@5a775b367a56d5bd118a224a811bba288150a563 # v2.0.0
177-
with:
178-
base64-subjects: "${{ needs.release-server-ai-langchain.outputs.package-hashes }}"
179-
upload-assets: true
180-
upload-tag-name: ${{ needs.release-please.outputs.package-server-ai-langchain-tag-name }}
181-
182160
release-server-ai-openai:
183161
runs-on: ubuntu-latest
184162
needs: ['release-please']
185163
permissions:
186164
id-token: write # Needed for OIDC to get release secrets from AWS.
165+
attestations: write # Needed for actions/attest.
187166
if: ${{ needs.release-please.outputs.package-server-ai-openai-released == 'true' }}
188-
outputs:
189-
package-hashes: ${{ steps.build.outputs.package-hashes }}
190167
steps:
191168
- uses: actions/checkout@v4
192-
with:
193-
fetch-depth: 0
194169

195170
- uses: ./.github/actions/ci
196171
with:
@@ -201,6 +176,11 @@ jobs:
201176
with:
202177
workspace_path: packages/ai-providers/server-ai-openai
203178

179+
- name: Attest build provenance
180+
uses: actions/attest@v4
181+
with:
182+
subject-path: 'packages/ai-providers/server-ai-openai/dist/*'
183+
204184
- uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.2.0
205185
name: 'Get PyPI token'
206186
with:
@@ -213,31 +193,15 @@ jobs:
213193
password: ${{ env.PYPI_AUTH_TOKEN }}
214194
packages-dir: packages/ai-providers/server-ai-openai/dist/
215195

216-
release-server-ai-openai-provenance:
217-
needs: ['release-please', 'release-server-ai-openai']
218-
if: ${{ needs.release-please.outputs.package-server-ai-openai-released == 'true' }}
219-
permissions:
220-
actions: read # Needed for detecting the GitHub Actions environment.
221-
id-token: write # Needed for provenance signing.
222-
contents: write # Needed for uploading assets to the release.
223-
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
224-
with:
225-
base64-subjects: "${{ needs.release-server-ai-openai.outputs.package-hashes }}"
226-
upload-assets: true
227-
upload-tag-name: ${{ needs.release-please.outputs.package-server-ai-openai-tag-name }}
228-
229196
release-server-ai-optimization:
230197
runs-on: ubuntu-latest
231198
needs: ['release-please']
232199
permissions:
233200
id-token: write # Needed for OIDC to get release secrets from AWS.
201+
attestations: write # Needed for actions/attest.
234202
if: ${{ needs.release-please.outputs.package-server-ai-optimization-released == 'true' }}
235-
outputs:
236-
package-hashes: ${{ steps.build.outputs.package-hashes }}
237203
steps:
238204
- uses: actions/checkout@v4
239-
with:
240-
fetch-depth: 0
241205

242206
- uses: ./.github/actions/ci
243207
with:
@@ -248,6 +212,11 @@ jobs:
248212
with:
249213
workspace_path: packages/optimization
250214

215+
- name: Attest build provenance
216+
uses: actions/attest@v4
217+
with:
218+
subject-path: 'packages/optimization/dist/*'
219+
251220
- uses: launchdarkly/gh-actions/actions/release-secrets@release-secrets-v1.2.0
252221
name: 'Get PyPI token'
253222
with:
@@ -259,16 +228,3 @@ jobs:
259228
with:
260229
password: ${{ env.PYPI_AUTH_TOKEN }}
261230
packages-dir: packages/optimization/dist/
262-
263-
release-server-ai-optimization-provenance:
264-
needs: ['release-please', 'release-server-ai-optimization']
265-
if: ${{ needs.release-please.outputs.package-server-ai-optimization-released == 'true' }}
266-
permissions:
267-
actions: read # Needed for detecting the GitHub Actions environment.
268-
id-token: write # Needed for provenance signing.
269-
contents: write # Needed for uploading assets to the release.
270-
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
271-
with:
272-
base64-subjects: "${{ needs.release-server-ai-optimization.outputs.package-hashes }}"
273-
upload-assets: true
274-
upload-tag-name: ${{ needs.release-please.outputs.package-server-ai-optimization-tag-name }}

.github/workflows/stale.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
name: 'Close stale issues and PRs'
1+
name: "Close stale issues and PRs"
22
on:
33
workflow_dispatch:
44
schedule:
55
# Happen once per day at 1:30 AM
6-
- cron: '30 1 * * *'
6+
- cron: "30 1 * * *"
7+
8+
permissions:
9+
issues: write
10+
pull-requests: write
711

812
jobs:
913
sdk-close-stale:

.release-please-manifest.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
2-
"packages/sdk/server-ai": "0.16.1",
3-
"packages/ai-providers/server-ai-langchain": "0.3.2",
4-
"packages/ai-providers/server-ai-openai": "0.2.1"
2+
"packages/sdk/server-ai": "0.18.0",
3+
"packages/ai-providers/server-ai-langchain": "0.5.0",
4+
"packages/ai-providers/server-ai-openai": "0.4.0",
5+
"packages/optimization": "0.1.0"
56
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This repository contains LaunchDarkly AI SDK packages for Python, including the
77
| Package | PyPI | README |
88
| ------- | ---- | ------ |
99
| [launchdarkly-server-sdk-ai](packages/sdk/server-ai) | [![PyPI](https://img.shields.io/pypi/v/launchdarkly-server-sdk-ai.svg)](https://pypi.org/project/launchdarkly-server-sdk-ai/) | [README](packages/sdk/server-ai/README.md) |
10+
| [launchdarkly-server-sdk-ai-optimization](packages/optimization) | [![PyPI](https://img.shields.io/pypi/v/launchdarkly-server-sdk-ai-optimization.svg)](https://pypi.org/project/launchdarkly-server-sdk-ai-optimization/) | [README](packages/optimization/README.md) |
1011

1112
| AI Provider Packages | PyPI | README |
1213
| -------------------- | ---- | ------ |

packages/ai-providers/server-ai-langchain/CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,50 @@
11
# Changelog
22

3+
All notable changes to the LaunchDarkly Python AI LangChain provider package will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).
4+
5+
## [0.5.0](https://github.com/launchdarkly/python-server-sdk-ai/compare/launchdarkly-server-sdk-ai-langchain-0.4.1...launchdarkly-server-sdk-ai-langchain-0.5.0) (2026-04-21)
6+
7+
8+
### Features
9+
10+
* Updated to use per-execution tracker lifecycle via `create_tracker()` instead of static tracker instances
11+
* Renamed graph metrics method from `track_latency()` to `track_duration()` for consistency
12+
* Moved graph_key configuration from graph tracker instantiation to node tracker initialization
13+
* Removed graph_key parameter from node-level tracker methods as it is now set during tracker creation
14+
15+
### Dependencies
16+
17+
* Updated for compatibility with `launchdarkly-server-sdk-ai` 0.18.0
18+
19+
## [0.4.1](https://github.com/launchdarkly/python-server-sdk-ai/compare/launchdarkly-server-sdk-ai-langchain-0.4.0...launchdarkly-server-sdk-ai-langchain-0.4.1) (2026-04-07)
20+
21+
22+
### Bug Fixes
23+
24+
* Fixes agent graph tool calls in fanned out graphs ([#123](https://github.com/launchdarkly/python-server-sdk-ai/issues/123)) ([c140410](https://github.com/launchdarkly/python-server-sdk-ai/commit/c14041090643d1261881343fdd70b4079997b773))
25+
26+
## [0.4.0](https://github.com/launchdarkly/python-server-sdk-ai/compare/launchdarkly-server-sdk-ai-langchain-0.3.2...launchdarkly-server-sdk-ai-langchain-0.4.0) (2026-04-02)
27+
28+
29+
### ⚠ BREAKING CHANGES
30+
31+
* Bump minimum LangChain version to 1.0.0
32+
* Restructure provider factory and support additional create methods ([#102](https://github.com/launchdarkly/python-server-sdk-ai/issues/102))
33+
* Extract shared utilities to langchain_helper
34+
35+
### Features
36+
37+
* Add LangGraphAgentGraphRunner ([56ce0fd](https://github.com/launchdarkly/python-server-sdk-ai/commit/56ce0fd63b4301b58f33c17c55c4ecd47e9f8559))
38+
* Extract shared utilities to langchain_helper ([453c71c](https://github.com/launchdarkly/python-server-sdk-ai/commit/453c71c84adcc6b8a3e316a98907dcb511bc9d41))
39+
* Add get_ai_usage_from_response to langchain_helper ([4fab18f](https://github.com/launchdarkly/python-server-sdk-ai/commit/4fab18fa62375b6c97cb12a89225805c81ca4ee8))
40+
* Add get_tool_calls_from_response and sum_token_usage_from_messages to langchain_helper ([4fab18f](https://github.com/launchdarkly/python-server-sdk-ai/commit/4fab18fa62375b6c97cb12a89225805c81ca4ee8))
41+
* Drop support for python 3.9 ([#114](https://github.com/launchdarkly/python-server-sdk-ai/issues/114)) ([dc592c5](https://github.com/launchdarkly/python-server-sdk-ai/commit/dc592c5a2e2bf3bf679af14a9aa63e81678a69ab))
42+
43+
44+
### Bug Fixes
45+
46+
* Use time.perf_counter_ns() for sub-millisecond precision in duration calculations ([4fab18f](https://github.com/launchdarkly/python-server-sdk-ai/commit/4fab18fa62375b6c97cb12a89225805c81ca4ee8))
47+
348
## [0.3.2](https://github.com/launchdarkly/python-server-sdk-ai/compare/launchdarkly-server-sdk-ai-langchain-0.3.1...launchdarkly-server-sdk-ai-langchain-0.3.2) (2026-03-16)
449

550

packages/ai-providers/server-ai-langchain/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# LaunchDarkly AI SDK - LangChain Provider
22

3-
[![PyPI](https://img.shields.io/pypi/v/launchdarkly-server-sdk-ai-langchain.svg)](https://pypi.org/project/launchdarkly-server-sdk-ai-langchain/)
3+
[![Actions Status](https://github.com/launchdarkly/python-server-sdk-ai/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/launchdarkly/python-server-sdk-ai/actions/workflows/ci.yml)
4+
5+
[![PyPI](https://img.shields.io/pypi/v/launchdarkly-server-sdk-ai-langchain.svg?maxAge=2592000)](https://pypi.org/project/launchdarkly-server-sdk-ai-langchain/)
6+
[![PyPI](https://img.shields.io/pypi/pyversions/launchdarkly-server-sdk-ai-langchain.svg)](https://pypi.org/project/launchdarkly-server-sdk-ai-langchain/)
47

58
> [!CAUTION]
69
> This package is in pre-release and not subject to backwards compatibility
@@ -138,7 +141,7 @@ provider = await LangChainProvider.create(config)
138141
async def invoke():
139142
return await provider.invoke_model(messages)
140143

141-
response = await config.tracker.track_metrics_of(
144+
response = await config.tracker.track_metrics_of_async(
142145
invoke,
143146
lambda r: r.metrics
144147
)

0 commit comments

Comments
 (0)