@outputai/http 0.4.1-dev.92bc2fb.0 → 0.4.1-next.43c9293.0

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.
package/dist/cost.d.ts CHANGED
@@ -1,16 +1,9 @@
1
1
  import { KyResponse } from 'ky';
2
- export type RequestCost = {
3
- total: number;
4
- components?: Array<{
5
- name: string;
6
- value: number;
7
- }>;
8
- };
9
2
  /**
10
3
  * Attach cost information to the trace of an HTTP Request using the response
11
4
  *
12
5
  * @param response - The response of the HTTP Request to attach the information
13
- * @param cost - The cost information
6
+ * @param value - The price of the HTTP request
14
7
  * @returns
15
8
  */
16
- export declare const addRequestCost: (response: KyResponse | Response, cost: RequestCost) => void;
9
+ export declare const addRequestCost: (response: KyResponse | Response, value: number) => void;
package/dist/cost.js CHANGED
@@ -4,15 +4,16 @@ import { requestIdSymbol } from './consts.js';
4
4
  * Attach cost information to the trace of an HTTP Request using the response
5
5
  *
6
6
  * @param response - The response of the HTTP Request to attach the information
7
- * @param cost - The cost information
7
+ * @param value - The price of the HTTP request
8
8
  * @returns
9
9
  */
10
- export const addRequestCost = (response, cost) => {
10
+ export const addRequestCost = (response, value) => {
11
11
  const eventId = Reflect.get(response, requestIdSymbol);
12
12
  if (!eventId) {
13
13
  console.warn('addRequestCost(): The "response" argument did not originate from @outputai/http, no costs were added.');
14
14
  return;
15
15
  }
16
- Tracing.addEventAttribute({ eventId, name: Tracing.Attribute.COST, value: cost });
17
- emitEvent('cost:http:request', { requestId: eventId, url: response.url, cost });
16
+ const attribute = new Tracing.Attribute.HTTPRequestCost(response.url, eventId, value);
17
+ Tracing.addEventAttribute({ eventId, attribute });
18
+ emitEvent('cost:http:request', attribute);
18
19
  };
package/dist/cost.spec.js CHANGED
@@ -1,14 +1,28 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
2
  import { requestIdSymbol } from './consts.js';
3
- vi.mock('@outputai/core/sdk_activity_integration', () => ({
4
- Tracing: {
5
- addEventAttribute: vi.fn(),
6
- Attribute: {
7
- COST: 'cost'
3
+ vi.mock('@outputai/core/sdk_activity_integration', () => {
4
+ class HTTPRequestCost {
5
+ static TYPE = 'http:request:cost';
6
+ type = HTTPRequestCost.TYPE;
7
+ url;
8
+ requestId;
9
+ total;
10
+ constructor(url, requestId, total) {
11
+ this.url = url;
12
+ this.requestId = requestId;
13
+ this.total = total;
8
14
  }
9
- },
10
- emitEvent: vi.fn()
11
- }));
15
+ }
16
+ return {
17
+ Tracing: {
18
+ addEventAttribute: vi.fn(),
19
+ Attribute: {
20
+ HTTPRequestCost
21
+ }
22
+ },
23
+ emitEvent: vi.fn()
24
+ };
25
+ });
12
26
  import { Tracing, emitEvent } from '@outputai/core/sdk_activity_integration';
13
27
  import { addRequestCost } from './cost.js';
14
28
  const tracing = vi.mocked(Tracing, true);
@@ -24,7 +38,7 @@ describe('addRequestCost', () => {
24
38
  });
25
39
  it('shortcircuits when the response has no http request id', () => {
26
40
  const response = new Response();
27
- const cost = { total: 1 };
41
+ const cost = 1;
28
42
  addRequestCost(response, cost);
29
43
  expect(console.warn).toHaveBeenCalledWith('addRequestCost(): The "response" argument did not originate from @outputai/http, no costs were added.');
30
44
  expect(tracing.addEventAttribute).not.toHaveBeenCalled();
@@ -33,56 +47,36 @@ describe('addRequestCost', () => {
33
47
  it('records cost on the trace event when the response carries the request id', () => {
34
48
  const response = new Response(undefined, { status: 200 });
35
49
  Reflect.set(response, requestIdSymbol, 'evt-cost-1');
36
- const cost = { total: 2.5 };
50
+ const cost = 2.5;
37
51
  addRequestCost(response, cost);
38
52
  expect(console.warn).not.toHaveBeenCalled();
39
53
  expect(tracing.addEventAttribute).toHaveBeenCalledWith({
40
54
  eventId: 'evt-cost-1',
41
- name: Tracing.Attribute.COST,
42
- value: cost
43
- });
44
- expect(emit).toHaveBeenCalledWith('cost:http:request', {
45
- requestId: 'evt-cost-1',
46
- url: response.url,
47
- cost
55
+ attribute: expect.objectContaining({
56
+ type: Tracing.Attribute.HTTPRequestCost.TYPE,
57
+ url: response.url,
58
+ requestId: 'evt-cost-1',
59
+ total: cost
60
+ })
48
61
  });
62
+ const attribute = tracing.addEventAttribute.mock.calls[0][0].attribute;
63
+ expect(emit).toHaveBeenCalledWith('cost:http:request', attribute);
49
64
  });
50
- it('forwards multiple components to tracing', () => {
65
+ it('records zero cost on the trace event', () => {
51
66
  const response = new Response();
52
67
  Reflect.set(response, requestIdSymbol, 'evt-cost-2');
53
- const cost = {
54
- total: 10,
55
- components: [
56
- { name: 'input', value: 3 },
57
- { name: 'output', value: 7 }
58
- ]
59
- };
68
+ const cost = 0;
60
69
  addRequestCost(response, cost);
61
70
  expect(tracing.addEventAttribute).toHaveBeenCalledWith({
62
71
  eventId: 'evt-cost-2',
63
- name: Tracing.Attribute.COST,
64
- value: cost
65
- });
66
- expect(emit).toHaveBeenCalledWith('cost:http:request', {
67
- requestId: 'evt-cost-2',
68
- url: response.url,
69
- cost
70
- });
71
- });
72
- it('forwards an empty components array to tracing', () => {
73
- const response = new Response();
74
- Reflect.set(response, requestIdSymbol, 'evt-cost-3');
75
- const cost = { total: 1, components: [] };
76
- addRequestCost(response, cost);
77
- expect(tracing.addEventAttribute).toHaveBeenCalledWith({
78
- eventId: 'evt-cost-3',
79
- name: Tracing.Attribute.COST,
80
- value: cost
81
- });
82
- expect(emit).toHaveBeenCalledWith('cost:http:request', {
83
- requestId: 'evt-cost-3',
84
- url: response.url,
85
- cost
72
+ attribute: expect.objectContaining({
73
+ type: Tracing.Attribute.HTTPRequestCost.TYPE,
74
+ url: response.url,
75
+ requestId: 'evt-cost-2',
76
+ total: cost
77
+ })
86
78
  });
79
+ const attribute = tracing.addEventAttribute.mock.calls[0][0].attribute;
80
+ expect(emit).toHaveBeenCalledWith('cost:http:request', attribute);
87
81
  });
88
82
  });
@@ -16,7 +16,7 @@ export const logRequest = async ({ requestId, request }) => {
16
16
  ...(config.logVerbose && { headers: redactHeaders(request.headers), body: await parseBody(request) })
17
17
  }
18
18
  });
19
- Tracing.addEventAttribute({ eventId: requestId, name: 'requestId', value: requestId });
19
+ Tracing.addEventAttribute({ eventId: requestId, attribute: new Tracing.Attribute.HTTPRequestCount(request.url, requestId) });
20
20
  };
21
21
  /**
22
22
  * Sends the trace error event for an http response with error status
@@ -1,13 +1,28 @@
1
1
  import { describe, it, expect, vi, beforeEach } from 'vitest';
2
2
  import { Response, Request } from 'undici';
3
- vi.mock('@outputai/core/sdk_activity_integration', () => ({
4
- Tracing: {
5
- addEventStart: vi.fn(),
6
- addEventEnd: vi.fn(),
7
- addEventError: vi.fn(),
8
- addEventAttribute: vi.fn()
3
+ vi.mock('@outputai/core/sdk_activity_integration', () => {
4
+ class HTTPRequestCount {
5
+ static TYPE = 'http:request:count';
6
+ type = HTTPRequestCount.TYPE;
7
+ url;
8
+ requestId;
9
+ constructor(url, requestId) {
10
+ this.url = url;
11
+ this.requestId = requestId;
12
+ }
9
13
  }
10
- }));
14
+ return {
15
+ Tracing: {
16
+ addEventStart: vi.fn(),
17
+ addEventEnd: vi.fn(),
18
+ addEventError: vi.fn(),
19
+ addEventAttribute: vi.fn(),
20
+ Attribute: {
21
+ HTTPRequestCount
22
+ }
23
+ }
24
+ };
25
+ });
11
26
  import { Tracing } from '@outputai/core/sdk_activity_integration';
12
27
  const tracing = vi.mocked(Tracing, true);
13
28
  /** Loads logger with optional verbose tracing env so `config.js` is evaluated fresh. */
@@ -29,11 +44,14 @@ beforeEach(() => {
29
44
  });
30
45
  describe('fetch/logger', () => {
31
46
  describe('logRequest', () => {
32
- const expectRequestIdAttribute = (requestId) => {
47
+ const expectRequestCountAttribute = (requestId, url) => {
33
48
  expect(tracing.addEventAttribute).toHaveBeenCalledWith({
34
49
  eventId: requestId,
35
- name: 'requestId',
36
- value: requestId
50
+ attribute: expect.objectContaining({
51
+ type: Tracing.Attribute.HTTPRequestCount.TYPE,
52
+ url,
53
+ requestId
54
+ })
37
55
  });
38
56
  };
39
57
  it('records minimal details when verbose is off', async () => {
@@ -49,14 +67,14 @@ describe('fetch/logger', () => {
49
67
  url: 'https://api.example.com/r'
50
68
  }
51
69
  });
52
- expectRequestIdAttribute('req-1');
70
+ expectRequestCountAttribute('req-1', 'https://api.example.com/r');
53
71
  });
54
72
  it('defaults method to GET', async () => {
55
73
  const { logRequest } = await logLogger(false);
56
74
  const request = new Request('https://x.test');
57
75
  await logRequest({ requestId: 'r2', request });
58
76
  expect(tracing.addEventStart.mock.calls[0][0].details.method).toBe('GET');
59
- expectRequestIdAttribute('r2');
77
+ expectRequestCountAttribute('r2', 'https://x.test/');
60
78
  });
61
79
  it('includes redacted headers and parsed body when verbose is on', async () => {
62
80
  const { logRequest } = await logLogger(true);
@@ -81,7 +99,7 @@ describe('fetch/logger', () => {
81
99
  body: { x: 1 }
82
100
  }
83
101
  });
84
- expectRequestIdAttribute('req-v');
102
+ expectRequestCountAttribute('req-v', 'https://api.example.com/p');
85
103
  });
86
104
  });
87
105
  describe('logError', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outputai/http",
3
- "version": "0.4.1-dev.92bc2fb.0",
3
+ "version": "0.4.1-next.43c9293.0",
4
4
  "description": "Framework abstraction to make HTTP calls with tracing",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,7 +11,7 @@
11
11
  "dependencies": {
12
12
  "ky": "1.14.3",
13
13
  "undici": "8.1.0",
14
- "@outputai/core": "0.4.1-dev.92bc2fb.0"
14
+ "@outputai/core": "0.4.1-next.43c9293.0"
15
15
  },
16
16
  "license": "Apache-2.0",
17
17
  "publishConfig": {