@amodalai/runtime 0.3.64 → 0.3.65

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.
@@ -0,0 +1,105 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
7
+ import { HttpUsageSink } from './http-usage-sink.js';
8
+ function captureFetch(status = 200) {
9
+ const calls = [];
10
+ const fetchMock = vi.fn(async (input, init) => {
11
+ const url = String(input);
12
+ const body = typeof init?.body === 'string'
13
+ ? JSON.parse(init.body)
14
+ : { reports: [] };
15
+ const headers = init?.headers;
16
+ const authorization = headers?.['Authorization'] ?? '';
17
+ calls.push({ url, body, authorization });
18
+ return new Response(null, { status });
19
+ });
20
+ vi.stubGlobal('fetch', fetchMock);
21
+ return { fetchMock, calls };
22
+ }
23
+ function makeReport(scopeId) {
24
+ return {
25
+ sessionId: 'session-1',
26
+ scopeId,
27
+ model: 'claude-sonnet-4-20250514',
28
+ taskAgentRuns: 0,
29
+ tokens: { inputTokens: 100, outputTokens: 50, cachedTokens: 0 },
30
+ };
31
+ }
32
+ describe('HttpUsageSink', () => {
33
+ beforeEach(() => {
34
+ vi.useFakeTimers();
35
+ });
36
+ afterEach(() => {
37
+ vi.useRealTimers();
38
+ vi.unstubAllGlobals();
39
+ });
40
+ it('substitutes {agentId} in the URL template and sends with bearer auth', async () => {
41
+ const { calls } = captureFetch();
42
+ const sink = new HttpUsageSink({
43
+ url: 'https://api.example.com/api/agents/{agentId}/usage',
44
+ getBearerToken: () => 'deploy-jwt',
45
+ maxBatchSize: 1,
46
+ });
47
+ sink.log('agent-1', makeReport('end-user-x'));
48
+ await vi.runOnlyPendingTimersAsync();
49
+ expect(calls).toHaveLength(1);
50
+ expect(calls[0]?.url).toBe('https://api.example.com/api/agents/agent-1/usage');
51
+ expect(calls[0]?.authorization).toBe('Bearer deploy-jwt');
52
+ expect(calls[0]?.body.reports).toHaveLength(1);
53
+ expect(calls[0]?.body.reports[0]?.scopeId).toBe('end-user-x');
54
+ await sink.shutdown();
55
+ });
56
+ it('batches reports per agent regardless of scope', async () => {
57
+ const { calls } = captureFetch();
58
+ const sink = new HttpUsageSink({
59
+ url: 'https://api.example.com/usage',
60
+ getBearerToken: () => 'jwt',
61
+ maxBatchSize: 100,
62
+ });
63
+ sink.log('agent-1', makeReport('user-a'));
64
+ sink.log('agent-1', makeReport('user-b'));
65
+ sink.log('agent-1', makeReport(''));
66
+ await sink.flush();
67
+ expect(calls).toHaveLength(1);
68
+ expect(calls[0]?.body.reports.map((r) => r.scopeId).sort()).toEqual([
69
+ '',
70
+ 'user-a',
71
+ 'user-b',
72
+ ]);
73
+ await sink.shutdown();
74
+ });
75
+ it('keeps batches separate per agent', async () => {
76
+ const { calls } = captureFetch();
77
+ const sink = new HttpUsageSink({
78
+ url: 'https://api.example.com/api/agents/{agentId}/usage',
79
+ getBearerToken: () => 'jwt',
80
+ maxBatchSize: 100,
81
+ });
82
+ sink.log('agent-1', makeReport('user-a'));
83
+ sink.log('agent-2', makeReport('user-a'));
84
+ await sink.flush();
85
+ expect(calls).toHaveLength(2);
86
+ const urls = calls.map((c) => c.url).sort();
87
+ expect(urls).toEqual([
88
+ 'https://api.example.com/api/agents/agent-1/usage',
89
+ 'https://api.example.com/api/agents/agent-2/usage',
90
+ ]);
91
+ await sink.shutdown();
92
+ });
93
+ it('does not throw when fetch rejects (fire-and-forget)', async () => {
94
+ vi.stubGlobal('fetch', vi.fn(() => Promise.reject(new Error('network down'))));
95
+ const sink = new HttpUsageSink({
96
+ url: 'https://api.example.com/usage',
97
+ getBearerToken: () => 'jwt',
98
+ maxBatchSize: 1,
99
+ });
100
+ sink.log('agent-1', makeReport('user-a'));
101
+ await expect(sink.flush()).resolves.toBeUndefined();
102
+ await sink.shutdown();
103
+ });
104
+ });
105
+ //# sourceMappingURL=http-usage-sink.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-usage-sink.test.js","sourceRoot":"","sources":["../../../src/sinks/http-usage-sink.test.ts"],"names":[],"mappings":"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"}