@abassey/aid 0.1.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.
Files changed (53) hide show
  1. package/dist/agents/index.cjs +741 -0
  2. package/dist/agents/index.d.cts +78 -0
  3. package/dist/agents/index.d.ts +78 -0
  4. package/dist/agents/index.js +741 -0
  5. package/dist/ai-AWJOUXFM.js +9 -0
  6. package/dist/ai-DOAYJKKI.cjs +9 -0
  7. package/dist/chunk-2TNYBUNK.js +124 -0
  8. package/dist/chunk-3LGKZRGY.cjs +124 -0
  9. package/dist/chunk-AUR2BBB5.cjs +1436 -0
  10. package/dist/chunk-IJLTRQF4.cjs +276 -0
  11. package/dist/chunk-JPD7UBAZ.js +58 -0
  12. package/dist/chunk-M4RQALTT.js +276 -0
  13. package/dist/chunk-NB65IHJE.cjs +58 -0
  14. package/dist/chunk-YNIEOBDF.js +1436 -0
  15. package/dist/client/index.cjs +18 -0
  16. package/dist/client/index.d.cts +8 -0
  17. package/dist/client/index.d.ts +8 -0
  18. package/dist/client/index.js +18 -0
  19. package/dist/errors-CUVTnseb.d.ts +13 -0
  20. package/dist/errors-CgCce4cK.d.cts +158 -0
  21. package/dist/errors-CgCce4cK.d.ts +158 -0
  22. package/dist/errors-zAPbTlpe.d.cts +13 -0
  23. package/dist/eval/index.cjs +308 -0
  24. package/dist/eval/index.d.cts +106 -0
  25. package/dist/eval/index.d.ts +106 -0
  26. package/dist/eval/index.js +308 -0
  27. package/dist/index.cjs +35 -0
  28. package/dist/index.d.cts +107 -0
  29. package/dist/index.d.ts +107 -0
  30. package/dist/index.js +35 -0
  31. package/dist/middleware/index.cjs +201 -0
  32. package/dist/middleware/index.d.cts +36 -0
  33. package/dist/middleware/index.d.ts +36 -0
  34. package/dist/middleware/index.js +201 -0
  35. package/dist/observability/index.cjs +147 -0
  36. package/dist/observability/index.d.cts +30 -0
  37. package/dist/observability/index.d.ts +30 -0
  38. package/dist/observability/index.js +147 -0
  39. package/dist/react/index.cjs +253 -0
  40. package/dist/react/index.d.cts +64 -0
  41. package/dist/react/index.d.ts +64 -0
  42. package/dist/react/index.js +253 -0
  43. package/dist/serve/index.cjs +545 -0
  44. package/dist/serve/index.d.cts +69 -0
  45. package/dist/serve/index.d.ts +69 -0
  46. package/dist/serve/index.js +545 -0
  47. package/dist/types-BJReASS-.d.cts +196 -0
  48. package/dist/types-BJReASS-.d.ts +196 -0
  49. package/dist/types-CguX3F16.d.cts +173 -0
  50. package/dist/types-CrFH-_qp.d.cts +68 -0
  51. package/dist/types-DvdzPmW0.d.ts +173 -0
  52. package/dist/types-qfE32ADy.d.ts +68 -0
  53. package/package.json +144 -0
@@ -0,0 +1,201 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+ var _chunk3LGKZRGYcjs = require('../chunk-3LGKZRGY.cjs');
6
+
7
+
8
+
9
+ var _chunkNB65IHJEcjs = require('../chunk-NB65IHJE.cjs');
10
+
11
+ // src/middleware/retry.ts
12
+ var DEFAULT_RETRYABLE_CODES = ["rate_limit", "network", "timeout"];
13
+ var DEFAULT_BASE_DELAY = 1e3;
14
+ function sleep(ms) {
15
+ return new Promise((resolve) => setTimeout(resolve, ms));
16
+ }
17
+ function retry(config = {}) {
18
+ const maxAttempts = _nullishCoalesce(config.maxAttempts, () => ( 3));
19
+ const baseDelay = _nullishCoalesce(config._baseDelay, () => ( DEFAULT_BASE_DELAY));
20
+ return {
21
+ name: "retry",
22
+ async execute(request, next, context) {
23
+ let lastError;
24
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
25
+ try {
26
+ const result = await next(request);
27
+ return result;
28
+ } catch (error) {
29
+ lastError = error instanceof Error ? error : new Error(String(error));
30
+ if (error instanceof _chunk3LGKZRGYcjs.AidError) {
31
+ if (!DEFAULT_RETRYABLE_CODES.includes(error.code)) {
32
+ throw error;
33
+ }
34
+ }
35
+ if (attempt >= maxAttempts - 1) {
36
+ throw lastError;
37
+ }
38
+ let delay = baseDelay * Math.pow(2, attempt);
39
+ if (error instanceof _chunk3LGKZRGYcjs.AidError && error.retryAfter != null) {
40
+ const retryAfterMs = error.retryAfter * 1e3;
41
+ delay = Math.max(retryAfterMs, delay);
42
+ }
43
+ await sleep(delay);
44
+ }
45
+ }
46
+ throw lastError;
47
+ }
48
+ };
49
+ }
50
+
51
+ // src/middleware/cache.ts
52
+ function cache(config) {
53
+ const store = /* @__PURE__ */ new Map();
54
+ function makeKey(request) {
55
+ return JSON.stringify({ model: request.model, messages: request.messages });
56
+ }
57
+ function promote(key) {
58
+ const entry = store.get(key);
59
+ if (entry) {
60
+ store.delete(key);
61
+ store.set(key, entry);
62
+ }
63
+ }
64
+ function evictOldest() {
65
+ while (store.size > config.maxSize) {
66
+ const oldestKey = store.keys().next().value;
67
+ if (oldestKey !== void 0) {
68
+ store.delete(oldestKey);
69
+ const newFrontKey = store.keys().next().value;
70
+ if (newFrontKey !== void 0) {
71
+ promote(newFrontKey);
72
+ }
73
+ } else {
74
+ break;
75
+ }
76
+ }
77
+ }
78
+ return {
79
+ name: "cache",
80
+ async execute(request, next, context) {
81
+ const key = makeKey(request);
82
+ const cached = store.get(key);
83
+ if (cached) {
84
+ const now = Date.now();
85
+ if (now - cached.timestamp <= config.ttl * 1e3) {
86
+ store.delete(key);
87
+ store.set(key, cached);
88
+ return cached.response;
89
+ }
90
+ store.delete(key);
91
+ }
92
+ const response = await next(request);
93
+ store.set(key, { response, timestamp: Date.now() });
94
+ evictOldest();
95
+ return response;
96
+ }
97
+ };
98
+ }
99
+
100
+ // src/middleware/cost-guard.ts
101
+ function costGuard(options) {
102
+ const { maxDailyUsd } = options;
103
+ let cumulativeCost = 0;
104
+ let lastResetDate = (/* @__PURE__ */ new Date()).toDateString();
105
+ return {
106
+ name: "cost-guard",
107
+ async execute(request, next, context) {
108
+ const today = (/* @__PURE__ */ new Date()).toDateString();
109
+ if (today !== lastResetDate) {
110
+ cumulativeCost = 0;
111
+ lastResetDate = today;
112
+ }
113
+ if (cumulativeCost >= maxDailyUsd) {
114
+ throw new (0, _chunk3LGKZRGYcjs.AidError)(
115
+ "cost_limit",
116
+ `Daily cost limit of $${maxDailyUsd} exceeded (cumulative: $${cumulativeCost.toFixed(4)})`
117
+ );
118
+ }
119
+ const response = await next(request);
120
+ cumulativeCost += response.cost;
121
+ return response;
122
+ }
123
+ };
124
+ }
125
+
126
+ // src/middleware/tracing.ts
127
+ function tracing(options) {
128
+ const store = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.store]), () => ( _chunkNB65IHJEcjs.globalTraceStore));
129
+ return {
130
+ name: "tracing",
131
+ async execute(request, next, _context) {
132
+ const startTime = Date.now();
133
+ const id = crypto.randomUUID();
134
+ let providerName = "unknown";
135
+ try {
136
+ providerName = _chunk3LGKZRGYcjs.resolveProvider.call(void 0, request.model).providerName;
137
+ } catch (e2) {
138
+ }
139
+ const parent = _chunkNB65IHJEcjs.traceContext.getStore();
140
+ const firstUserMsg = request.messages.find((m) => m.role === "user");
141
+ const promptText = typeof _optionalChain([firstUserMsg, 'optionalAccess', _2 => _2.content]) === "string" ? firstUserMsg.content : "";
142
+ const promptPrefix = promptText.slice(0, 40).replace(/\n/g, " ");
143
+ const name = _optionalChain([options, 'optionalAccess', _3 => _3.nameFrom]) ? options.nameFrom(request) : promptPrefix ? `${request.model}:${promptPrefix}` : request.model;
144
+ try {
145
+ const response = await next(request);
146
+ const endTime = Date.now();
147
+ try {
148
+ store.add({
149
+ id,
150
+ parentId: _optionalChain([parent, 'optionalAccess', _4 => _4.id]),
151
+ name,
152
+ startTime,
153
+ endTime,
154
+ durationMs: endTime - startTime,
155
+ model: response.model,
156
+ provider: providerName,
157
+ tokens: response.tokens,
158
+ cost: response.cost,
159
+ status: "ok",
160
+ metadata: {}
161
+ });
162
+ } catch (e) {
163
+ console.warn("tracing: failed to record span", e);
164
+ }
165
+ return response;
166
+ } catch (error) {
167
+ const endTime = Date.now();
168
+ try {
169
+ store.add({
170
+ id,
171
+ parentId: _optionalChain([parent, 'optionalAccess', _5 => _5.id]),
172
+ name,
173
+ startTime,
174
+ endTime,
175
+ durationMs: endTime - startTime,
176
+ model: request.model,
177
+ provider: providerName,
178
+ tokens: { input: 0, output: 0, total: 0 },
179
+ cost: 0,
180
+ status: "error",
181
+ error: {
182
+ message: error instanceof Error ? error.message : String(error),
183
+ code: _optionalChain([error, 'optionalAccess', _6 => _6.code])
184
+ },
185
+ metadata: {}
186
+ });
187
+ } catch (e) {
188
+ console.warn("tracing: failed to record error span", e);
189
+ }
190
+ throw error;
191
+ }
192
+ }
193
+ };
194
+ }
195
+
196
+
197
+
198
+
199
+
200
+
201
+ exports.cache = cache; exports.costGuard = costGuard; exports.executePipeline = _chunk3LGKZRGYcjs.executePipeline; exports.retry = retry; exports.tracing = tracing;
@@ -0,0 +1,36 @@
1
+ import { e as RetryConfig, M as Middleware, P as ProviderRequest, c as AiResponse } from '../types-BJReASS-.cjs';
2
+ export { i as MiddlewareContext } from '../types-BJReASS-.cjs';
3
+ import { T as TracingOptions } from '../types-CrFH-_qp.cjs';
4
+
5
+ declare function retry(config?: RetryConfig): Middleware;
6
+
7
+ interface CacheConfig {
8
+ ttl: number;
9
+ maxSize: number;
10
+ }
11
+ /**
12
+ * Creates a cache middleware that stores responses keyed by model + messages.
13
+ * Uses a Map as LRU cache. Cache key: JSON.stringify({model, messages}).
14
+ * Stores {response, timestamp}. On execute: check cache, if hit and not
15
+ * expired return cached, else call next and store result.
16
+ * Evict oldest entries when maxSize exceeded.
17
+ */
18
+ declare function cache(config: CacheConfig): Middleware;
19
+
20
+ interface CostGuardOptions {
21
+ maxDailyUsd: number;
22
+ }
23
+ declare function costGuard(options: CostGuardOptions): Middleware;
24
+
25
+ /**
26
+ * Execute a middleware pipeline, composing middlewares right-to-left so that
27
+ * the first middleware in the array is the outermost wrapper.
28
+ *
29
+ * Each middleware's `next` calls the next middleware in the chain.
30
+ * The final `next` invokes the actual provider call.
31
+ */
32
+ declare function executePipeline(middlewares: Middleware[], request: ProviderRequest, providerCall: (request: ProviderRequest) => Promise<AiResponse>): Promise<AiResponse>;
33
+
34
+ declare function tracing(options?: TracingOptions): Middleware;
35
+
36
+ export { Middleware, cache, costGuard, executePipeline, retry, tracing };
@@ -0,0 +1,36 @@
1
+ import { e as RetryConfig, M as Middleware, P as ProviderRequest, c as AiResponse } from '../types-BJReASS-.js';
2
+ export { i as MiddlewareContext } from '../types-BJReASS-.js';
3
+ import { T as TracingOptions } from '../types-qfE32ADy.js';
4
+
5
+ declare function retry(config?: RetryConfig): Middleware;
6
+
7
+ interface CacheConfig {
8
+ ttl: number;
9
+ maxSize: number;
10
+ }
11
+ /**
12
+ * Creates a cache middleware that stores responses keyed by model + messages.
13
+ * Uses a Map as LRU cache. Cache key: JSON.stringify({model, messages}).
14
+ * Stores {response, timestamp}. On execute: check cache, if hit and not
15
+ * expired return cached, else call next and store result.
16
+ * Evict oldest entries when maxSize exceeded.
17
+ */
18
+ declare function cache(config: CacheConfig): Middleware;
19
+
20
+ interface CostGuardOptions {
21
+ maxDailyUsd: number;
22
+ }
23
+ declare function costGuard(options: CostGuardOptions): Middleware;
24
+
25
+ /**
26
+ * Execute a middleware pipeline, composing middlewares right-to-left so that
27
+ * the first middleware in the array is the outermost wrapper.
28
+ *
29
+ * Each middleware's `next` calls the next middleware in the chain.
30
+ * The final `next` invokes the actual provider call.
31
+ */
32
+ declare function executePipeline(middlewares: Middleware[], request: ProviderRequest, providerCall: (request: ProviderRequest) => Promise<AiResponse>): Promise<AiResponse>;
33
+
34
+ declare function tracing(options?: TracingOptions): Middleware;
35
+
36
+ export { Middleware, cache, costGuard, executePipeline, retry, tracing };
@@ -0,0 +1,201 @@
1
+ import {
2
+ AidError,
3
+ executePipeline,
4
+ resolveProvider
5
+ } from "../chunk-2TNYBUNK.js";
6
+ import {
7
+ globalTraceStore,
8
+ traceContext
9
+ } from "../chunk-JPD7UBAZ.js";
10
+
11
+ // src/middleware/retry.ts
12
+ var DEFAULT_RETRYABLE_CODES = ["rate_limit", "network", "timeout"];
13
+ var DEFAULT_BASE_DELAY = 1e3;
14
+ function sleep(ms) {
15
+ return new Promise((resolve) => setTimeout(resolve, ms));
16
+ }
17
+ function retry(config = {}) {
18
+ const maxAttempts = config.maxAttempts ?? 3;
19
+ const baseDelay = config._baseDelay ?? DEFAULT_BASE_DELAY;
20
+ return {
21
+ name: "retry",
22
+ async execute(request, next, context) {
23
+ let lastError;
24
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
25
+ try {
26
+ const result = await next(request);
27
+ return result;
28
+ } catch (error) {
29
+ lastError = error instanceof Error ? error : new Error(String(error));
30
+ if (error instanceof AidError) {
31
+ if (!DEFAULT_RETRYABLE_CODES.includes(error.code)) {
32
+ throw error;
33
+ }
34
+ }
35
+ if (attempt >= maxAttempts - 1) {
36
+ throw lastError;
37
+ }
38
+ let delay = baseDelay * Math.pow(2, attempt);
39
+ if (error instanceof AidError && error.retryAfter != null) {
40
+ const retryAfterMs = error.retryAfter * 1e3;
41
+ delay = Math.max(retryAfterMs, delay);
42
+ }
43
+ await sleep(delay);
44
+ }
45
+ }
46
+ throw lastError;
47
+ }
48
+ };
49
+ }
50
+
51
+ // src/middleware/cache.ts
52
+ function cache(config) {
53
+ const store = /* @__PURE__ */ new Map();
54
+ function makeKey(request) {
55
+ return JSON.stringify({ model: request.model, messages: request.messages });
56
+ }
57
+ function promote(key) {
58
+ const entry = store.get(key);
59
+ if (entry) {
60
+ store.delete(key);
61
+ store.set(key, entry);
62
+ }
63
+ }
64
+ function evictOldest() {
65
+ while (store.size > config.maxSize) {
66
+ const oldestKey = store.keys().next().value;
67
+ if (oldestKey !== void 0) {
68
+ store.delete(oldestKey);
69
+ const newFrontKey = store.keys().next().value;
70
+ if (newFrontKey !== void 0) {
71
+ promote(newFrontKey);
72
+ }
73
+ } else {
74
+ break;
75
+ }
76
+ }
77
+ }
78
+ return {
79
+ name: "cache",
80
+ async execute(request, next, context) {
81
+ const key = makeKey(request);
82
+ const cached = store.get(key);
83
+ if (cached) {
84
+ const now = Date.now();
85
+ if (now - cached.timestamp <= config.ttl * 1e3) {
86
+ store.delete(key);
87
+ store.set(key, cached);
88
+ return cached.response;
89
+ }
90
+ store.delete(key);
91
+ }
92
+ const response = await next(request);
93
+ store.set(key, { response, timestamp: Date.now() });
94
+ evictOldest();
95
+ return response;
96
+ }
97
+ };
98
+ }
99
+
100
+ // src/middleware/cost-guard.ts
101
+ function costGuard(options) {
102
+ const { maxDailyUsd } = options;
103
+ let cumulativeCost = 0;
104
+ let lastResetDate = (/* @__PURE__ */ new Date()).toDateString();
105
+ return {
106
+ name: "cost-guard",
107
+ async execute(request, next, context) {
108
+ const today = (/* @__PURE__ */ new Date()).toDateString();
109
+ if (today !== lastResetDate) {
110
+ cumulativeCost = 0;
111
+ lastResetDate = today;
112
+ }
113
+ if (cumulativeCost >= maxDailyUsd) {
114
+ throw new AidError(
115
+ "cost_limit",
116
+ `Daily cost limit of $${maxDailyUsd} exceeded (cumulative: $${cumulativeCost.toFixed(4)})`
117
+ );
118
+ }
119
+ const response = await next(request);
120
+ cumulativeCost += response.cost;
121
+ return response;
122
+ }
123
+ };
124
+ }
125
+
126
+ // src/middleware/tracing.ts
127
+ function tracing(options) {
128
+ const store = options?.store ?? globalTraceStore;
129
+ return {
130
+ name: "tracing",
131
+ async execute(request, next, _context) {
132
+ const startTime = Date.now();
133
+ const id = crypto.randomUUID();
134
+ let providerName = "unknown";
135
+ try {
136
+ providerName = resolveProvider(request.model).providerName;
137
+ } catch {
138
+ }
139
+ const parent = traceContext.getStore();
140
+ const firstUserMsg = request.messages.find((m) => m.role === "user");
141
+ const promptText = typeof firstUserMsg?.content === "string" ? firstUserMsg.content : "";
142
+ const promptPrefix = promptText.slice(0, 40).replace(/\n/g, " ");
143
+ const name = options?.nameFrom ? options.nameFrom(request) : promptPrefix ? `${request.model}:${promptPrefix}` : request.model;
144
+ try {
145
+ const response = await next(request);
146
+ const endTime = Date.now();
147
+ try {
148
+ store.add({
149
+ id,
150
+ parentId: parent?.id,
151
+ name,
152
+ startTime,
153
+ endTime,
154
+ durationMs: endTime - startTime,
155
+ model: response.model,
156
+ provider: providerName,
157
+ tokens: response.tokens,
158
+ cost: response.cost,
159
+ status: "ok",
160
+ metadata: {}
161
+ });
162
+ } catch (e) {
163
+ console.warn("tracing: failed to record span", e);
164
+ }
165
+ return response;
166
+ } catch (error) {
167
+ const endTime = Date.now();
168
+ try {
169
+ store.add({
170
+ id,
171
+ parentId: parent?.id,
172
+ name,
173
+ startTime,
174
+ endTime,
175
+ durationMs: endTime - startTime,
176
+ model: request.model,
177
+ provider: providerName,
178
+ tokens: { input: 0, output: 0, total: 0 },
179
+ cost: 0,
180
+ status: "error",
181
+ error: {
182
+ message: error instanceof Error ? error.message : String(error),
183
+ code: error?.code
184
+ },
185
+ metadata: {}
186
+ });
187
+ } catch (e) {
188
+ console.warn("tracing: failed to record error span", e);
189
+ }
190
+ throw error;
191
+ }
192
+ }
193
+ };
194
+ }
195
+ export {
196
+ cache,
197
+ costGuard,
198
+ executePipeline,
199
+ retry,
200
+ tracing
201
+ };
@@ -0,0 +1,147 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+ var _chunkNB65IHJEcjs = require('../chunk-NB65IHJE.cjs');
6
+
7
+ // src/observability/trace.ts
8
+ async function trace(name, fn, options) {
9
+ const id = crypto.randomUUID();
10
+ const startTime = Date.now();
11
+ const metadata = { ..._nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.metadata]), () => ( {})) };
12
+ const parent = _chunkNB65IHJEcjs.traceContext.getStore();
13
+ const activeSpan = {
14
+ get id() {
15
+ return id;
16
+ },
17
+ get name() {
18
+ return name;
19
+ },
20
+ annotate(key, value) {
21
+ metadata[key] = value;
22
+ }
23
+ };
24
+ try {
25
+ const result = await _chunkNB65IHJEcjs.traceContext.run(
26
+ activeSpan,
27
+ () => fn(activeSpan)
28
+ );
29
+ const endTime = Date.now();
30
+ _chunkNB65IHJEcjs.globalTraceStore.add({
31
+ id,
32
+ parentId: _optionalChain([parent, 'optionalAccess', _2 => _2.id]),
33
+ name,
34
+ startTime,
35
+ endTime,
36
+ durationMs: endTime - startTime,
37
+ model: "trace",
38
+ provider: "trace",
39
+ tokens: { input: 0, output: 0, total: 0 },
40
+ cost: 0,
41
+ status: "ok",
42
+ metadata
43
+ });
44
+ return result;
45
+ } catch (error) {
46
+ const endTime = Date.now();
47
+ _chunkNB65IHJEcjs.globalTraceStore.add({
48
+ id,
49
+ parentId: _optionalChain([parent, 'optionalAccess', _3 => _3.id]),
50
+ name,
51
+ startTime,
52
+ endTime,
53
+ durationMs: endTime - startTime,
54
+ model: "trace",
55
+ provider: "trace",
56
+ tokens: { input: 0, output: 0, total: 0 },
57
+ cost: 0,
58
+ status: "error",
59
+ error: {
60
+ message: error instanceof Error ? error.message : String(error)
61
+ },
62
+ metadata
63
+ });
64
+ throw error;
65
+ }
66
+ }
67
+
68
+ // src/observability/cost-tracker.ts
69
+ function resolvePeriod(period) {
70
+ if (typeof period === "object" && "from" in period) {
71
+ return period;
72
+ }
73
+ const now = Date.now();
74
+ const d = new Date(now);
75
+ const todayMidnight = Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
76
+ switch (period) {
77
+ case "today":
78
+ return { from: todayMidnight, to: now };
79
+ case "yesterday": {
80
+ const yesterdayMidnight = todayMidnight - 24 * 60 * 60 * 1e3;
81
+ return { from: yesterdayMidnight, to: todayMidnight };
82
+ }
83
+ case "this-week": {
84
+ const dayOfWeek = d.getUTCDay();
85
+ const daysToMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
86
+ const mondayMidnight = todayMidnight - daysToMonday * 24 * 60 * 60 * 1e3;
87
+ return { from: mondayMidnight, to: now };
88
+ }
89
+ case "this-month": {
90
+ const monthStart = Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), 1);
91
+ return { from: monthStart, to: now };
92
+ }
93
+ }
94
+ }
95
+ var CostTracker = class {
96
+ constructor(store) {
97
+ this.store = store;
98
+ }
99
+ report(period) {
100
+ const { from, to } = resolvePeriod(period);
101
+ const spans = this.store.list({ from, to }).filter((s) => s.model !== "trace");
102
+ const totalTokens = { input: 0, output: 0, total: 0 };
103
+ let totalCost = 0;
104
+ const byModel = {};
105
+ const byProvider = {};
106
+ for (const span of spans) {
107
+ totalCost += span.cost;
108
+ totalTokens.input += span.tokens.input;
109
+ totalTokens.output += span.tokens.output;
110
+ totalTokens.total += span.tokens.total;
111
+ if (!byModel[span.model]) {
112
+ byModel[span.model] = {
113
+ cost: 0,
114
+ calls: 0,
115
+ tokens: { input: 0, output: 0, total: 0 }
116
+ };
117
+ }
118
+ byModel[span.model].cost += span.cost;
119
+ byModel[span.model].calls += 1;
120
+ byModel[span.model].tokens.input += span.tokens.input;
121
+ byModel[span.model].tokens.output += span.tokens.output;
122
+ byModel[span.model].tokens.total += span.tokens.total;
123
+ if (!byProvider[span.provider]) {
124
+ byProvider[span.provider] = { cost: 0, calls: 0 };
125
+ }
126
+ byProvider[span.provider].cost += span.cost;
127
+ byProvider[span.provider].calls += 1;
128
+ }
129
+ return {
130
+ totalCost,
131
+ totalTokens,
132
+ calls: spans.length,
133
+ byModel,
134
+ byProvider,
135
+ period: { from, to }
136
+ };
137
+ }
138
+ };
139
+ function costReport(period) {
140
+ return new CostTracker(_chunkNB65IHJEcjs.globalTraceStore).report(period);
141
+ }
142
+
143
+
144
+
145
+
146
+
147
+ exports.CostTracker = CostTracker; exports.InMemoryTraceStore = _chunkNB65IHJEcjs.InMemoryTraceStore; exports.costReport = costReport; exports.trace = trace;
@@ -0,0 +1,30 @@
1
+ import { A as ActiveSpan, a as TraceStore, S as Span, b as SpanFilter, C as CostPeriod, c as CostReport } from '../types-CrFH-_qp.cjs';
2
+ export { M as ModelCostBreakdown, T as TracingOptions } from '../types-CrFH-_qp.cjs';
3
+ import '../types-BJReASS-.cjs';
4
+
5
+ declare function trace<T>(name: string, fn: (span: ActiveSpan) => Promise<T>, options?: {
6
+ metadata?: Record<string, unknown>;
7
+ }): Promise<T>;
8
+
9
+ declare class InMemoryTraceStore implements TraceStore {
10
+ private spans;
11
+ private order;
12
+ private maxSpans;
13
+ constructor(options?: {
14
+ maxSpans?: number;
15
+ });
16
+ add(span: Span): void;
17
+ get(id: string): Span | undefined;
18
+ list(filter?: SpanFilter): Span[];
19
+ clear(): void;
20
+ }
21
+
22
+ declare class CostTracker {
23
+ private store;
24
+ constructor(store: TraceStore);
25
+ report(period: CostPeriod): CostReport;
26
+ }
27
+ /** Convenience: create a CostTracker with the global store and generate a report. */
28
+ declare function costReport(period: CostPeriod): CostReport;
29
+
30
+ export { ActiveSpan, CostPeriod, CostReport, CostTracker, InMemoryTraceStore, Span, SpanFilter, TraceStore, costReport, trace };
@@ -0,0 +1,30 @@
1
+ import { A as ActiveSpan, a as TraceStore, S as Span, b as SpanFilter, C as CostPeriod, c as CostReport } from '../types-qfE32ADy.js';
2
+ export { M as ModelCostBreakdown, T as TracingOptions } from '../types-qfE32ADy.js';
3
+ import '../types-BJReASS-.js';
4
+
5
+ declare function trace<T>(name: string, fn: (span: ActiveSpan) => Promise<T>, options?: {
6
+ metadata?: Record<string, unknown>;
7
+ }): Promise<T>;
8
+
9
+ declare class InMemoryTraceStore implements TraceStore {
10
+ private spans;
11
+ private order;
12
+ private maxSpans;
13
+ constructor(options?: {
14
+ maxSpans?: number;
15
+ });
16
+ add(span: Span): void;
17
+ get(id: string): Span | undefined;
18
+ list(filter?: SpanFilter): Span[];
19
+ clear(): void;
20
+ }
21
+
22
+ declare class CostTracker {
23
+ private store;
24
+ constructor(store: TraceStore);
25
+ report(period: CostPeriod): CostReport;
26
+ }
27
+ /** Convenience: create a CostTracker with the global store and generate a report. */
28
+ declare function costReport(period: CostPeriod): CostReport;
29
+
30
+ export { ActiveSpan, CostPeriod, CostReport, CostTracker, InMemoryTraceStore, Span, SpanFilter, TraceStore, costReport, trace };