Skip to content

Commit

Permalink
Merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
ldhenry committed Jan 3, 2025
2 parents cfddcdc + 7f5c275 commit 6079a15
Show file tree
Hide file tree
Showing 46 changed files with 2,034 additions and 39 deletions.
4 changes: 2 additions & 2 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"packages/shared/common": "2.12.0",
"packages/shared/sdk-server": "2.10.0",
"packages/sdk/server-node": "9.7.2",
"packages/sdk/cloudflare": "2.6.2",
"packages/sdk/cloudflare": "2.6.3",
"packages/sdk/fastly": "0.0.1",
"packages/shared/sdk-server-edge": "2.5.2",
"packages/sdk/vercel": "1.3.21",
Expand All @@ -15,5 +15,5 @@
"packages/sdk/react-native": "10.9.3",
"packages/telemetry/node-server-sdk-otel": "1.1.2",
"packages/sdk/browser": "0.3.3",
"packages/sdk/server-ai": "0.6.0"
"packages/sdk/server-ai": "0.7.0"
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"packages/sdk/react-universal",
"packages/sdk/react-universal/example",
"packages/sdk/vercel",
"packages/sdk/svelte",
"packages/sdk/akamai-base",
"packages/sdk/akamai-base/example",
"packages/sdk/akamai-edgekv",
Expand Down
7 changes: 7 additions & 0 deletions packages/sdk/cloudflare/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ All notable changes to the LaunchDarkly SDK for Cloudflare Workers will be docum
* devDependencies
* @launchdarkly/js-server-sdk-common-edge bumped from 2.2.1 to 2.2.2

## [2.6.3](https://github.com/launchdarkly/js-core/compare/cloudflare-server-sdk-v2.6.2...cloudflare-server-sdk-v2.6.3) (2024-12-12)


### Bug Fixes

* Remove bundled dependency from package.json. ([#711](https://github.com/launchdarkly/js-core/issues/711)) ([0fb5375](https://github.com/launchdarkly/js-core/commit/0fb5375443a5137c3588d454465794eb530cb982))

## [2.6.2](https://github.com/launchdarkly/js-core/compare/cloudflare-server-sdk-v2.6.1...cloudflare-server-sdk-v2.6.2) (2024-11-14)


Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/cloudflare/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"module": "./dist/index.mjs",
"packageManager": "[email protected]",
"dependencies": {
"@launchdarkly/cloudflare-server-sdk": "2.6.2"
"@launchdarkly/cloudflare-server-sdk": "2.6.3"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20230321.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/cloudflare/jsr.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@launchdarkly/cloudflare-server-sdk",
"version": "2.6.2",
"version": "2.6.3",
"exports": "./src/index.ts",
"publish": {
"include": [
Expand Down
9 changes: 3 additions & 6 deletions packages/sdk/cloudflare/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@launchdarkly/cloudflare-server-sdk",
"version": "2.6.2",
"version": "2.6.3",
"description": "Cloudflare LaunchDarkly SDK",
"homepage": "https://github.com/launchdarkly/js-core/tree/main/packages/sdk/cloudflare",
"repository": {
Expand Down Expand Up @@ -41,10 +41,10 @@
},
"dependencies": {
"@cloudflare/workers-types": "^4.20230321.0",
"@launchdarkly/js-server-sdk-common-edge": "2.5.2",
"crypto-js": "^4.1.1"
},
"devDependencies": {
"@launchdarkly/js-server-sdk-common-edge": "2.5.2",
"@rollup/plugin-commonjs": "^25.0.4",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.2.1",
Expand Down Expand Up @@ -76,8 +76,5 @@
"ts-jest": "^29.1.0",
"typedoc": "0.25.0",
"typescript": "5.1.6"
},
"bundledDependencies": [
"@launchdarkly/js-server-sdk-common-edge"
]
}
}
2 changes: 1 addition & 1 deletion packages/sdk/cloudflare/src/createPlatformInfo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Info, PlatformData, SdkData } from '@launchdarkly/js-server-sdk-common-edge';

const name = '@launchdarkly/cloudflare-server-sdk';
const version = '2.6.2'; // x-release-please-version
const version = '2.6.3'; // x-release-please-version

class CloudflarePlatformInfo implements Info {
platformData(): PlatformData {
Expand Down
7 changes: 7 additions & 0 deletions packages/sdk/server-ai/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [0.7.0](https://github.com/launchdarkly/js-core/compare/server-sdk-ai-v0.6.0...server-sdk-ai-v0.7.0) (2024-12-17)


### Features

* Add support for tracking errors. ([#715](https://github.com/launchdarkly/js-core/issues/715)) ([02f1d3d](https://github.com/launchdarkly/js-core/commit/02f1d3daa711319a620a55b50481083980ab18f7))

## [0.6.0](https://github.com/launchdarkly/js-core/compare/server-sdk-ai-v0.5.0...server-sdk-ai-v0.6.0) (2024-12-10)


Expand Down
88 changes: 85 additions & 3 deletions packages/sdk/server-ai/__tests__/LDAIConfigTrackerImpl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,39 @@ it('tracks OpenAI usage', async () => {
);
});

it('tracks error when OpenAI metrics function throws', async () => {
const tracker = new LDAIConfigTrackerImpl(mockLdClient, configKey, variationKey, testContext);
jest.spyOn(global.Date, 'now').mockReturnValueOnce(1000).mockReturnValueOnce(2000);

const error = new Error('OpenAI API error');
await expect(
tracker.trackOpenAIMetrics(async () => {
throw error;
}),
).rejects.toThrow(error);

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:duration:total',
testContext,
{ configKey, variationKey },
1000,
);

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:generation',
testContext,
{ configKey, variationKey },
1,
);

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:generation:error',
testContext,
{ configKey, variationKey },
1,
);
});

it('tracks Bedrock conversation with successful response', () => {
const tracker = new LDAIConfigTrackerImpl(mockLdClient, configKey, variationKey, testContext);

Expand Down Expand Up @@ -196,11 +229,22 @@ it('tracks Bedrock conversation with error response', () => {
$metadata: { httpStatusCode: 400 },
};

// TODO: We may want a track failure.

tracker.trackBedrockConverseMetrics(response);

expect(mockTrack).not.toHaveBeenCalled();
expect(mockTrack).toHaveBeenCalledTimes(2);
expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:generation',
testContext,
{ configKey, variationKey },
1,
);

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:generation:error',
testContext,
{ configKey, variationKey },
1,
);
});

it('tracks tokens', () => {
Expand Down Expand Up @@ -304,3 +348,41 @@ it('summarizes tracked metrics', () => {
success: true,
});
});

it('tracks duration when async function throws', async () => {
const tracker = new LDAIConfigTrackerImpl(mockLdClient, configKey, variationKey, testContext);
jest.spyOn(global.Date, 'now').mockReturnValueOnce(1000).mockReturnValueOnce(2000);

const error = new Error('test error');
await expect(
tracker.trackDurationOf(async () => {
throw error;
}),
).rejects.toThrow(error);

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:duration:total',
testContext,
{ configKey, variationKey },
1000,
);
});

it('tracks error', () => {
const tracker = new LDAIConfigTrackerImpl(mockLdClient, configKey, variationKey, testContext);
tracker.trackError();

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:generation',
testContext,
{ configKey, variationKey },
1,
);

expect(mockTrack).toHaveBeenCalledWith(
'$ld:ai:generation:error',
testContext,
{ configKey, variationKey },
1,
);
});
2 changes: 1 addition & 1 deletion packages/sdk/server-ai/examples/bedrock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"dependencies": {
"@aws-sdk/client-bedrock-runtime": "^3.679.0",
"@launchdarkly/node-server-sdk": "^9.7.1",
"@launchdarkly/server-sdk-ai": "0.6.0"
"@launchdarkly/server-sdk-ai": "0.7.0"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/server-ai/examples/openai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"license": "Apache-2.0",
"dependencies": {
"@launchdarkly/node-server-sdk": "^9.7.1",
"@launchdarkly/server-sdk-ai": "0.6.0",
"@launchdarkly/server-sdk-ai": "0.7.0",
"openai": "^4.58.1"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/server-ai/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@launchdarkly/server-sdk-ai",
"version": "0.6.0",
"version": "0.7.0",
"description": "LaunchDarkly AI SDK for Server-Side JavaScript",
"homepage": "https://github.com/launchdarkly/js-core/tree/main/packages/sdk/server-ai",
"repository": {
Expand Down
38 changes: 27 additions & 11 deletions packages/sdk/server-ai/src/LDAIConfigTrackerImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@ export class LDAIConfigTrackerImpl implements LDAIConfigTracker {

async trackDurationOf<TRes>(func: () => Promise<TRes>): Promise<TRes> {
const startTime = Date.now();
const result = await func();
const endTime = Date.now();
const duration = endTime - startTime; // duration in milliseconds
this.trackDuration(duration);
return result;
try {
// Be sure to await here so that we can track the duration of the function and also handle errors.
const result = await func();
return result;
} finally {
const endTime = Date.now();
const duration = endTime - startTime; // duration in milliseconds
this.trackDuration(duration);
}
}

trackFeedback(feedback: { kind: LDFeedbackKind }): void {
Expand All @@ -49,6 +53,13 @@ export class LDAIConfigTrackerImpl implements LDAIConfigTracker {
trackSuccess(): void {
this._trackedMetrics.success = true;
this._ldClient.track('$ld:ai:generation', this._context, this._getTrackData(), 1);
this._ldClient.track('$ld:ai:generation:success', this._context, this._getTrackData(), 1);
}

trackError(): void {
this._trackedMetrics.success = false;
this._ldClient.track('$ld:ai:generation', this._context, this._getTrackData(), 1);
this._ldClient.track('$ld:ai:generation:error', this._context, this._getTrackData(), 1);
}

async trackOpenAIMetrics<
Expand All @@ -60,12 +71,17 @@ export class LDAIConfigTrackerImpl implements LDAIConfigTracker {
};
},
>(func: () => Promise<TRes>): Promise<TRes> {
const result = await this.trackDurationOf(func);
this.trackSuccess();
if (result.usage) {
this.trackTokens(createOpenAiUsage(result.usage));
try {
const result = await this.trackDurationOf(func);
this.trackSuccess();
if (result.usage) {
this.trackTokens(createOpenAiUsage(result.usage));
}
return result;
} catch (err) {
this.trackError();
throw err;
}
return result;
}

trackBedrockConverseMetrics<
Expand All @@ -82,7 +98,7 @@ export class LDAIConfigTrackerImpl implements LDAIConfigTracker {
if (res.$metadata?.httpStatusCode === 200) {
this.trackSuccess();
} else if (res.$metadata?.httpStatusCode && res.$metadata.httpStatusCode >= 400) {
// Potentially add error tracking in the future.
this.trackError();
}
if (res.metrics && res.metrics.latencyMs) {
this.trackDuration(res.metrics.latencyMs);
Expand Down
19 changes: 19 additions & 0 deletions packages/sdk/server-ai/src/api/config/LDAIConfigTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ export interface LDAIConfigTracker {
*/
trackSuccess(): void;

/**
* An error was encountered during generation.
*/
trackError(): void;

/**
* Track sentiment about the generation.
*
Expand All @@ -59,6 +64,12 @@ export interface LDAIConfigTracker {

/**
* Track the duration of execution of the provided function.
*
* If the provided function throws, then this method will also throw.
* In the case the provided function throws, this function will still record the duration.
*
* This function does not automatically record an error when the function throws.
*
* @param func The function to track the duration of.
* @returns The result of the function.
*/
Expand All @@ -67,6 +78,12 @@ export interface LDAIConfigTracker {
/**
* Track an OpenAI operation.
*
* This function will track the duration of the operation, the token usage, and the success or error status.
*
* If the provided function throws, then this method will also throw.
* In the case the provided function throws, this function will record the duration and an error.
* A failed operation will not have any token usage data.
*
* @param func Function which executes the operation.
* @returns The result of the operation.
*/
Expand All @@ -85,6 +102,8 @@ export interface LDAIConfigTracker {
/**
* Track an operation which uses Bedrock.
*
* This function will track the duration of the operation, the token usage, and the success or error status.
*
* @param res The result of the Bedrock operation.
* @returns The input operation.
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/server-node/src/platform/NodeRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function processProxyOptions(
};
if (proxyOptions.auth) {
parsedOptions.headers = {
'Proxy-Authorization': `Basic ${Buffer.from(proxyOptions.auth).toString('base64')}}`,
'Proxy-Authorization': `Basic ${Buffer.from(proxyOptions.auth).toString('base64')}`,
};
}

Expand Down
13 changes: 13 additions & 0 deletions packages/sdk/svelte/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/dist
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*

# Playwright
/test-results
Loading

0 comments on commit 6079a15

Please sign in to comment.