@forge/llm 0.2.0-next.2-experimental-f76634b → 0.2.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -102,4 +102,24 @@ describe('Error Handling', () => {
102
102
  traceId
103
103
  }, { code, message, context, ...extraFields }));
104
104
  });
105
+ it('should include atl-traceid when x-trace-id and x-b3-traceid is not present', async () => {
106
+ const code = 'UNSUPPORTED_AI_MODEL';
107
+ const message = 'Requested claude-3-5-sonnet-v2@20241022 not available for vendor: Claude';
108
+ const traceId = 'atl-trace-456';
109
+ const apiResponse = new Response(JSON.stringify({
110
+ code: code,
111
+ message: message
112
+ }), {
113
+ status: 400,
114
+ statusText: 'Bad Request',
115
+ headers: {
116
+ 'atl-traceid': traceId
117
+ }
118
+ });
119
+ await expect(async () => (0, error_handling_1.checkResponseError)(apiResponse)).rejects.toMatchError(new errors_1.ForgeLlmAPIError({
120
+ status: 400,
121
+ statusText: 'Bad Request',
122
+ traceId
123
+ }, { code, message }));
124
+ });
105
125
  });
@@ -10,8 +10,34 @@ function setupEnvironment(response) {
10
10
  const mockedFetch = jest.fn().mockResolvedValue(response || new Response(null, { status: 200 }));
11
11
  global.__forge_fetch__ = jest.fn((_ctx, path, options) => mockedFetch(path, options));
12
12
  }
13
+ jest.mock('@forge/api', () => {
14
+ const actual = jest.requireActual('@forge/api');
15
+ return {
16
+ ...actual,
17
+ __getRuntime: jest.fn(() => ({
18
+ tracing: { traceId: 'trace-test', spanId: 'span-test' }
19
+ }))
20
+ };
21
+ });
13
22
  describe('llm api', () => {
14
- it('should make ForgeLlm request', async () => {
23
+ it('should make ForgeLlm request with correct headers', async () => {
24
+ const llmResponse = (0, test_helpers_1.constructLlmResponse)();
25
+ const apiResponse = new Response(JSON.stringify(llmResponse), {
26
+ status: 200
27
+ });
28
+ const mockedFetch = jest.fn().mockResolvedValue(apiResponse);
29
+ global.__forge_fetch__ = jest.fn((_ctx, path, options) => mockedFetch(path, options));
30
+ const llmAPI = new llm_api_1.LlmApiImpl((0, fetch_wrapper_1.getFetchWrapper)());
31
+ const prompt = (0, test_helpers_1.constructPrompt)();
32
+ await llmAPI.chat(prompt);
33
+ const [[, options]] = mockedFetch.mock.calls;
34
+ expect(options.headers).toEqual({
35
+ 'Content-Type': 'application/json',
36
+ 'x-b3-traceid': 'trace-test',
37
+ 'x-b3-spanid': 'span-test'
38
+ });
39
+ });
40
+ it('should make ForgeLlm request with correct body', async () => {
15
41
  const llmResponse = (0, test_helpers_1.constructLlmResponse)();
16
42
  const apiResponse = new Response(JSON.stringify(llmResponse), {
17
43
  status: 200
@@ -34,7 +60,6 @@ describe('llm api', () => {
34
60
  const [[path, options]] = mockedFetch.mock.calls;
35
61
  expect(path).toBe('https://llm/claude-sonnet-4-20250514');
36
62
  expect(options.method).toBe('POST');
37
- expect(options.headers).toEqual({ 'Content-Type': 'application/json' });
38
63
  expect(JSON.parse(options.body)).toEqual({
39
64
  messages: [
40
65
  {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-wrapper.d.ts","sourceRoot":"","sources":["../src/fetch-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,WAAW,EAAe,MAAM,YAAY,CAAC;AAEnE,wBAAgB,eAAe,IAAI,WAAW,CAW7C"}
1
+ {"version":3,"file":"fetch-wrapper.d.ts","sourceRoot":"","sources":["../src/fetch-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,WAAW,EAAe,MAAM,YAAY,CAAC;AAEjF,wBAAgB,eAAe,IAAI,WAAW,CAc7C"}
@@ -1,14 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getFetchWrapper = void 0;
4
+ const api_1 = require("@forge/api");
4
5
  function getFetchWrapper() {
6
+ const { tracing } = (0, api_1.__getRuntime)();
5
7
  return async function (path, options) {
6
8
  const model = path?.split('/').pop();
7
9
  return await global.__forge_fetch__({ type: 'llm', model: model }, path, {
8
10
  ...options,
9
11
  headers: {
10
12
  ...options?.headers,
11
- 'Content-Type': 'application/json'
13
+ 'Content-Type': 'application/json',
14
+ 'x-b3-traceid': tracing.traceId,
15
+ 'x-b3-spanid': tracing.spanId
12
16
  }
13
17
  });
14
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/utils/error-handling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,UAAU,EAAoB,MAAM,WAAW,CAAC;AAE9F,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,UAAU,CAE9D;AAED,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB7E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAMnE"}
1
+ {"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/utils/error-handling.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,UAAU,EAAoB,MAAM,WAAW,CAAC;AAE9F,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,UAAU,CAE9D;AAED,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB7E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAMnE"}
@@ -4,7 +4,7 @@ exports.safeGetParsedBody = exports.checkResponseError = exports.isForgeError =
4
4
  const errors_1 = require("../errors");
5
5
  const text_1 = require("../text");
6
6
  function extractTraceId(response) {
7
- return response.headers.get('x-b3-traceid') || response.headers.get('x-trace-id');
7
+ return (response.headers.get('x-b3-traceid') || response.headers.get('x-trace-id') || response.headers.get('atl-traceid'));
8
8
  }
9
9
  function isForgeError(body) {
10
10
  return typeof body === 'object' && body !== null && 'code' in body && 'message' in body;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/llm",
3
- "version": "0.2.0-next.2-experimental-f76634b",
3
+ "version": "0.2.0-next.3",
4
4
  "description": "Forge LLM SDK",
5
5
  "main": "out/index.js",
6
6
  "types": "out/index.d.ts",
@@ -10,7 +10,7 @@
10
10
  "author": "Atlassian",
11
11
  "license": "SEE LICENSE IN LICENSE.txt",
12
12
  "dependencies": {
13
- "@forge/api": "^6.3.0-next.2-experimental-f76634b"
13
+ "@forge/api": "^6.3.0-next.2"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@types/node": "20.19.1",