@digilogiclabs/platform-core 1.13.0 → 1.15.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/{ConsoleEmail-CqXhZmFN.d.mts → ConsoleEmail-CO0OM4UT.d.ts} +2 -718
- package/dist/{ConsoleEmail-CqXhZmFN.d.ts → ConsoleEmail-DDB28vyS.d.mts} +2 -718
- package/dist/IAI-D8wA_i8N.d.mts +718 -0
- package/dist/IAI-D8wA_i8N.d.ts +718 -0
- package/dist/agents-Cd2eEX5M.d.mts +864 -0
- package/dist/agents-CntmA45w.d.ts +864 -0
- package/dist/agents.d.mts +2 -0
- package/dist/agents.d.ts +2 -0
- package/dist/agents.js +479 -0
- package/dist/agents.js.map +1 -0
- package/dist/agents.mjs +448 -0
- package/dist/agents.mjs.map +1 -0
- package/dist/auth.d.mts +186 -1
- package/dist/auth.d.ts +186 -1
- package/dist/auth.js +205 -0
- package/dist/auth.js.map +1 -1
- package/dist/auth.mjs +204 -0
- package/dist/auth.mjs.map +1 -1
- package/dist/index.d.mts +7 -563
- package/dist/index.d.ts +7 -563
- package/dist/index.js +436 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +431 -0
- package/dist/index.mjs.map +1 -1
- package/dist/testing.d.mts +3 -2
- package/dist/testing.d.ts +3 -2
- package/package.json +6 -1
|
@@ -0,0 +1,864 @@
|
|
|
1
|
+
import { x as AIToolCall, y as AITool, e as AIChatResponse, w as AIMessage, c as IAI, I as ICache, a as ILogger, d as AIChatRequest, b as ITracing, K as ISpan, D as AIUsageInfo } from './IAI-D8wA_i8N.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* IAIUsage - Per-tenant AI token tracking and cost allocation
|
|
5
|
+
*
|
|
6
|
+
* Provides infrastructure for:
|
|
7
|
+
* - Token usage tracking per tenant
|
|
8
|
+
* - Cost allocation and budgeting
|
|
9
|
+
* - Usage quotas and limits
|
|
10
|
+
* - Billing integration
|
|
11
|
+
* - Analytics and reporting
|
|
12
|
+
*/
|
|
13
|
+
type UsageCategory = "chat" | "completion" | "embedding" | "image" | "audio" | "video" | "fine_tuning";
|
|
14
|
+
type UsageInterval = "minute" | "hour" | "day" | "week" | "month" | "year";
|
|
15
|
+
interface UsageRecord {
|
|
16
|
+
id: string;
|
|
17
|
+
/** Tenant ID */
|
|
18
|
+
tenantId: string;
|
|
19
|
+
/** User ID (optional, for per-user tracking) */
|
|
20
|
+
userId?: string;
|
|
21
|
+
/** API key ID (optional) */
|
|
22
|
+
apiKeyId?: string;
|
|
23
|
+
/** Usage category */
|
|
24
|
+
category: UsageCategory;
|
|
25
|
+
/** AI provider */
|
|
26
|
+
provider: string;
|
|
27
|
+
/** Model used */
|
|
28
|
+
model: string;
|
|
29
|
+
/** Input tokens */
|
|
30
|
+
inputTokens: number;
|
|
31
|
+
/** Output tokens */
|
|
32
|
+
outputTokens: number;
|
|
33
|
+
/** Total tokens */
|
|
34
|
+
totalTokens: number;
|
|
35
|
+
/** Cost in USD */
|
|
36
|
+
costUsd: number;
|
|
37
|
+
/** Request latency in ms */
|
|
38
|
+
latencyMs: number;
|
|
39
|
+
/** Request ID for tracing */
|
|
40
|
+
requestId?: string;
|
|
41
|
+
/** Whether the request succeeded */
|
|
42
|
+
success: boolean;
|
|
43
|
+
/** Error message if failed */
|
|
44
|
+
error?: string;
|
|
45
|
+
/** Additional metadata */
|
|
46
|
+
metadata?: Record<string, unknown>;
|
|
47
|
+
/** Created timestamp */
|
|
48
|
+
createdAt: Date;
|
|
49
|
+
}
|
|
50
|
+
type QuotaType = "tokens" | "requests" | "cost";
|
|
51
|
+
interface Quota {
|
|
52
|
+
id: string;
|
|
53
|
+
/** Tenant ID */
|
|
54
|
+
tenantId: string;
|
|
55
|
+
/** Quota type */
|
|
56
|
+
type: QuotaType;
|
|
57
|
+
/** Category (or 'all' for global quota) */
|
|
58
|
+
category: UsageCategory | "all";
|
|
59
|
+
/** Quota limit */
|
|
60
|
+
limit: number;
|
|
61
|
+
/** Quota period */
|
|
62
|
+
period: UsageInterval;
|
|
63
|
+
/** Current usage */
|
|
64
|
+
used: number;
|
|
65
|
+
/** Period start date */
|
|
66
|
+
periodStart: Date;
|
|
67
|
+
/** Period end date */
|
|
68
|
+
periodEnd: Date;
|
|
69
|
+
/** Action when quota exceeded */
|
|
70
|
+
action: "block" | "warn" | "notify" | "overage";
|
|
71
|
+
/** Overage rate (for 'overage' action) */
|
|
72
|
+
overageRate?: number;
|
|
73
|
+
/** Alert thresholds (percentages) */
|
|
74
|
+
alertThresholds?: number[];
|
|
75
|
+
/** Whether quota is enabled */
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
}
|
|
78
|
+
interface QuotaStatus {
|
|
79
|
+
quota: Quota;
|
|
80
|
+
/** Current usage */
|
|
81
|
+
used: number;
|
|
82
|
+
/** Remaining */
|
|
83
|
+
remaining: number;
|
|
84
|
+
/** Usage percentage */
|
|
85
|
+
percentUsed: number;
|
|
86
|
+
/** Whether quota is exceeded */
|
|
87
|
+
exceeded: boolean;
|
|
88
|
+
/** Estimated time until reset */
|
|
89
|
+
resetsIn?: number;
|
|
90
|
+
/** Alerts triggered */
|
|
91
|
+
alertsTriggered: number[];
|
|
92
|
+
}
|
|
93
|
+
interface Budget {
|
|
94
|
+
id: string;
|
|
95
|
+
/** Tenant ID */
|
|
96
|
+
tenantId: string;
|
|
97
|
+
/** Budget name */
|
|
98
|
+
name: string;
|
|
99
|
+
/** Budget amount in USD */
|
|
100
|
+
amount: number;
|
|
101
|
+
/** Budget period */
|
|
102
|
+
period: UsageInterval;
|
|
103
|
+
/** Categories included in budget */
|
|
104
|
+
categories?: UsageCategory[];
|
|
105
|
+
/** Current spend */
|
|
106
|
+
spent: number;
|
|
107
|
+
/** Period start date */
|
|
108
|
+
periodStart: Date;
|
|
109
|
+
/** Period end date */
|
|
110
|
+
periodEnd: Date;
|
|
111
|
+
/** Alert thresholds (percentages) */
|
|
112
|
+
alertThresholds: number[];
|
|
113
|
+
/** Action when budget exceeded */
|
|
114
|
+
action: "block" | "warn" | "notify";
|
|
115
|
+
/** Whether budget is enabled */
|
|
116
|
+
enabled: boolean;
|
|
117
|
+
}
|
|
118
|
+
interface BudgetStatus {
|
|
119
|
+
budget: Budget;
|
|
120
|
+
/** Current spend */
|
|
121
|
+
spent: number;
|
|
122
|
+
/** Remaining */
|
|
123
|
+
remaining: number;
|
|
124
|
+
/** Spend percentage */
|
|
125
|
+
percentSpent: number;
|
|
126
|
+
/** Whether budget is exceeded */
|
|
127
|
+
exceeded: boolean;
|
|
128
|
+
/** Projected spend for full period */
|
|
129
|
+
projected: number;
|
|
130
|
+
/** Alerts triggered */
|
|
131
|
+
alertsTriggered: number[];
|
|
132
|
+
}
|
|
133
|
+
interface UsageInvoiceItem {
|
|
134
|
+
category: UsageCategory;
|
|
135
|
+
provider: string;
|
|
136
|
+
model: string;
|
|
137
|
+
inputTokens: number;
|
|
138
|
+
outputTokens: number;
|
|
139
|
+
totalTokens: number;
|
|
140
|
+
requests: number;
|
|
141
|
+
costUsd: number;
|
|
142
|
+
}
|
|
143
|
+
interface UsageInvoice {
|
|
144
|
+
id: string;
|
|
145
|
+
tenantId: string;
|
|
146
|
+
periodStart: Date;
|
|
147
|
+
periodEnd: Date;
|
|
148
|
+
items: UsageInvoiceItem[];
|
|
149
|
+
subtotal: number;
|
|
150
|
+
discounts?: Array<{
|
|
151
|
+
type: string;
|
|
152
|
+
amount: number;
|
|
153
|
+
description?: string;
|
|
154
|
+
}>;
|
|
155
|
+
total: number;
|
|
156
|
+
currency: string;
|
|
157
|
+
status: "draft" | "pending" | "paid" | "overdue";
|
|
158
|
+
dueDate?: Date;
|
|
159
|
+
paidAt?: Date;
|
|
160
|
+
createdAt: Date;
|
|
161
|
+
}
|
|
162
|
+
interface UsageSummary {
|
|
163
|
+
tenantId: string;
|
|
164
|
+
period: {
|
|
165
|
+
start: Date;
|
|
166
|
+
end: Date;
|
|
167
|
+
interval: UsageInterval;
|
|
168
|
+
};
|
|
169
|
+
totals: {
|
|
170
|
+
inputTokens: number;
|
|
171
|
+
outputTokens: number;
|
|
172
|
+
totalTokens: number;
|
|
173
|
+
requests: number;
|
|
174
|
+
successfulRequests: number;
|
|
175
|
+
failedRequests: number;
|
|
176
|
+
costUsd: number;
|
|
177
|
+
averageLatencyMs: number;
|
|
178
|
+
};
|
|
179
|
+
byCategory: Record<UsageCategory, {
|
|
180
|
+
inputTokens: number;
|
|
181
|
+
outputTokens: number;
|
|
182
|
+
totalTokens: number;
|
|
183
|
+
requests: number;
|
|
184
|
+
costUsd: number;
|
|
185
|
+
}>;
|
|
186
|
+
byModel: Record<string, {
|
|
187
|
+
inputTokens: number;
|
|
188
|
+
outputTokens: number;
|
|
189
|
+
totalTokens: number;
|
|
190
|
+
requests: number;
|
|
191
|
+
costUsd: number;
|
|
192
|
+
}>;
|
|
193
|
+
byUser?: Record<string, {
|
|
194
|
+
inputTokens: number;
|
|
195
|
+
outputTokens: number;
|
|
196
|
+
totalTokens: number;
|
|
197
|
+
requests: number;
|
|
198
|
+
costUsd: number;
|
|
199
|
+
}>;
|
|
200
|
+
}
|
|
201
|
+
interface UsageTrend {
|
|
202
|
+
tenantId: string;
|
|
203
|
+
period: {
|
|
204
|
+
start: Date;
|
|
205
|
+
end: Date;
|
|
206
|
+
interval: UsageInterval;
|
|
207
|
+
};
|
|
208
|
+
dataPoints: Array<{
|
|
209
|
+
timestamp: Date;
|
|
210
|
+
inputTokens: number;
|
|
211
|
+
outputTokens: number;
|
|
212
|
+
totalTokens: number;
|
|
213
|
+
requests: number;
|
|
214
|
+
costUsd: number;
|
|
215
|
+
}>;
|
|
216
|
+
growth: {
|
|
217
|
+
tokens: number;
|
|
218
|
+
requests: number;
|
|
219
|
+
cost: number;
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
interface CostBreakdown {
|
|
223
|
+
tenantId: string;
|
|
224
|
+
period: {
|
|
225
|
+
start: Date;
|
|
226
|
+
end: Date;
|
|
227
|
+
};
|
|
228
|
+
total: number;
|
|
229
|
+
byProvider: Record<string, number>;
|
|
230
|
+
byModel: Record<string, number>;
|
|
231
|
+
byCategory: Record<UsageCategory, number>;
|
|
232
|
+
byUser?: Record<string, number>;
|
|
233
|
+
}
|
|
234
|
+
interface UsageQuery {
|
|
235
|
+
tenantId: string;
|
|
236
|
+
startDate?: Date;
|
|
237
|
+
endDate?: Date;
|
|
238
|
+
category?: UsageCategory | UsageCategory[];
|
|
239
|
+
provider?: string | string[];
|
|
240
|
+
model?: string | string[];
|
|
241
|
+
userId?: string;
|
|
242
|
+
success?: boolean;
|
|
243
|
+
limit?: number;
|
|
244
|
+
offset?: number;
|
|
245
|
+
sortBy?: "createdAt" | "totalTokens" | "costUsd" | "latencyMs";
|
|
246
|
+
sortOrder?: "asc" | "desc";
|
|
247
|
+
}
|
|
248
|
+
interface UsageQueryResult {
|
|
249
|
+
records: UsageRecord[];
|
|
250
|
+
total: number;
|
|
251
|
+
aggregations: {
|
|
252
|
+
totalTokens: number;
|
|
253
|
+
totalCost: number;
|
|
254
|
+
averageLatency: number;
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
type AlertType = "quota_warning" | "quota_exceeded" | "budget_warning" | "budget_exceeded" | "anomaly";
|
|
258
|
+
interface UsageAlert {
|
|
259
|
+
id: string;
|
|
260
|
+
tenantId: string;
|
|
261
|
+
type: AlertType;
|
|
262
|
+
severity: "info" | "warning" | "critical";
|
|
263
|
+
message: string;
|
|
264
|
+
metadata: {
|
|
265
|
+
quotaId?: string;
|
|
266
|
+
budgetId?: string;
|
|
267
|
+
threshold?: number;
|
|
268
|
+
currentValue?: number;
|
|
269
|
+
limit?: number;
|
|
270
|
+
};
|
|
271
|
+
acknowledged: boolean;
|
|
272
|
+
acknowledgedAt?: Date;
|
|
273
|
+
acknowledgedBy?: string;
|
|
274
|
+
createdAt: Date;
|
|
275
|
+
}
|
|
276
|
+
interface AIUsageConfig {
|
|
277
|
+
/** Enable usage tracking */
|
|
278
|
+
enabled?: boolean;
|
|
279
|
+
/** Default quota period */
|
|
280
|
+
defaultQuotaPeriod?: UsageInterval;
|
|
281
|
+
/** Default budget period */
|
|
282
|
+
defaultBudgetPeriod?: UsageInterval;
|
|
283
|
+
/** Enable per-user tracking */
|
|
284
|
+
trackPerUser?: boolean;
|
|
285
|
+
/** Enable anomaly detection */
|
|
286
|
+
enableAnomalyDetection?: boolean;
|
|
287
|
+
/** Anomaly threshold (standard deviations) */
|
|
288
|
+
anomalyThreshold?: number;
|
|
289
|
+
/** Cost precision (decimal places) */
|
|
290
|
+
costPrecision?: number;
|
|
291
|
+
/** Retention period in days */
|
|
292
|
+
retentionDays?: number;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* IAIUsage - AI usage tracking interface
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```typescript
|
|
299
|
+
* const usage = platform.aiUsage;
|
|
300
|
+
*
|
|
301
|
+
* // Record usage after AI call
|
|
302
|
+
* await usage.record({
|
|
303
|
+
* tenantId: 'tenant_123',
|
|
304
|
+
* category: 'chat',
|
|
305
|
+
* provider: 'openai',
|
|
306
|
+
* model: 'gpt-4',
|
|
307
|
+
* inputTokens: 150,
|
|
308
|
+
* outputTokens: 300,
|
|
309
|
+
* totalTokens: 450,
|
|
310
|
+
* costUsd: 0.018,
|
|
311
|
+
* latencyMs: 1200,
|
|
312
|
+
* success: true,
|
|
313
|
+
* });
|
|
314
|
+
*
|
|
315
|
+
* // Check quota before making request
|
|
316
|
+
* const quotaStatus = await usage.checkQuota('tenant_123', 'tokens', 'chat');
|
|
317
|
+
* if (quotaStatus.exceeded) {
|
|
318
|
+
* throw new Error('Token quota exceeded');
|
|
319
|
+
* }
|
|
320
|
+
*
|
|
321
|
+
* // Get usage summary
|
|
322
|
+
* const summary = await usage.getSummary('tenant_123', 'month');
|
|
323
|
+
* console.log(`Total cost: $${summary.totals.costUsd}`);
|
|
324
|
+
* ```
|
|
325
|
+
*/
|
|
326
|
+
interface IAIUsage {
|
|
327
|
+
/**
|
|
328
|
+
* Record a usage event
|
|
329
|
+
*/
|
|
330
|
+
record(record: Omit<UsageRecord, "id" | "createdAt">): Promise<UsageRecord>;
|
|
331
|
+
/**
|
|
332
|
+
* Record multiple usage events (batch)
|
|
333
|
+
*/
|
|
334
|
+
recordBatch(records: Array<Omit<UsageRecord, "id" | "createdAt">>): Promise<UsageRecord[]>;
|
|
335
|
+
/**
|
|
336
|
+
* Query usage records
|
|
337
|
+
*/
|
|
338
|
+
query(query: UsageQuery): Promise<UsageQueryResult>;
|
|
339
|
+
/**
|
|
340
|
+
* Get a specific usage record
|
|
341
|
+
*/
|
|
342
|
+
getRecord(recordId: string): Promise<UsageRecord | null>;
|
|
343
|
+
/**
|
|
344
|
+
* Create or update a quota
|
|
345
|
+
*/
|
|
346
|
+
setQuota(quota: Omit<Quota, "id" | "used" | "periodStart" | "periodEnd">): Promise<Quota>;
|
|
347
|
+
/**
|
|
348
|
+
* Get a quota
|
|
349
|
+
*/
|
|
350
|
+
getQuota(tenantId: string, type: QuotaType, category: UsageCategory | "all"): Promise<Quota | null>;
|
|
351
|
+
/**
|
|
352
|
+
* List quotas for a tenant
|
|
353
|
+
*/
|
|
354
|
+
listQuotas(tenantId: string): Promise<Quota[]>;
|
|
355
|
+
/**
|
|
356
|
+
* Check quota status
|
|
357
|
+
*/
|
|
358
|
+
checkQuota(tenantId: string, type: QuotaType, category: UsageCategory | "all"): Promise<QuotaStatus>;
|
|
359
|
+
/**
|
|
360
|
+
* Check all quotas for a tenant
|
|
361
|
+
*/
|
|
362
|
+
checkAllQuotas(tenantId: string): Promise<QuotaStatus[]>;
|
|
363
|
+
/**
|
|
364
|
+
* Delete a quota
|
|
365
|
+
*/
|
|
366
|
+
deleteQuota(quotaId: string): Promise<void>;
|
|
367
|
+
/**
|
|
368
|
+
* Reset quota usage (admin only)
|
|
369
|
+
*/
|
|
370
|
+
resetQuota(quotaId: string): Promise<Quota>;
|
|
371
|
+
/**
|
|
372
|
+
* Create or update a budget
|
|
373
|
+
*/
|
|
374
|
+
setBudget(budget: Omit<Budget, "id" | "spent" | "periodStart" | "periodEnd">): Promise<Budget>;
|
|
375
|
+
/**
|
|
376
|
+
* Get a budget
|
|
377
|
+
*/
|
|
378
|
+
getBudget(budgetId: string): Promise<Budget | null>;
|
|
379
|
+
/**
|
|
380
|
+
* List budgets for a tenant
|
|
381
|
+
*/
|
|
382
|
+
listBudgets(tenantId: string): Promise<Budget[]>;
|
|
383
|
+
/**
|
|
384
|
+
* Check budget status
|
|
385
|
+
*/
|
|
386
|
+
checkBudget(budgetId: string): Promise<BudgetStatus>;
|
|
387
|
+
/**
|
|
388
|
+
* Check all budgets for a tenant
|
|
389
|
+
*/
|
|
390
|
+
checkAllBudgets(tenantId: string): Promise<BudgetStatus[]>;
|
|
391
|
+
/**
|
|
392
|
+
* Delete a budget
|
|
393
|
+
*/
|
|
394
|
+
deleteBudget(budgetId: string): Promise<void>;
|
|
395
|
+
/**
|
|
396
|
+
* Get usage summary for a tenant
|
|
397
|
+
*/
|
|
398
|
+
getSummary(tenantId: string, period: UsageInterval, date?: Date): Promise<UsageSummary>;
|
|
399
|
+
/**
|
|
400
|
+
* Get usage trends
|
|
401
|
+
*/
|
|
402
|
+
getTrends(tenantId: string, period: UsageInterval, dataPoints?: number): Promise<UsageTrend>;
|
|
403
|
+
/**
|
|
404
|
+
* Get cost breakdown
|
|
405
|
+
*/
|
|
406
|
+
getCostBreakdown(tenantId: string, startDate: Date, endDate: Date): Promise<CostBreakdown>;
|
|
407
|
+
/**
|
|
408
|
+
* Compare usage between periods
|
|
409
|
+
*/
|
|
410
|
+
comparePeriods(tenantId: string, period1Start: Date, period1End: Date, period2Start: Date, period2End: Date): Promise<{
|
|
411
|
+
period1: UsageSummary;
|
|
412
|
+
period2: UsageSummary;
|
|
413
|
+
changes: {
|
|
414
|
+
tokens: number;
|
|
415
|
+
requests: number;
|
|
416
|
+
cost: number;
|
|
417
|
+
latency: number;
|
|
418
|
+
};
|
|
419
|
+
}>;
|
|
420
|
+
/**
|
|
421
|
+
* Generate invoice for a period
|
|
422
|
+
*/
|
|
423
|
+
generateInvoice(tenantId: string, periodStart: Date, periodEnd: Date): Promise<UsageInvoice>;
|
|
424
|
+
/**
|
|
425
|
+
* Get an invoice
|
|
426
|
+
*/
|
|
427
|
+
getInvoice(invoiceId: string): Promise<UsageInvoice | null>;
|
|
428
|
+
/**
|
|
429
|
+
* List invoices for a tenant
|
|
430
|
+
*/
|
|
431
|
+
listInvoices(tenantId: string, options?: {
|
|
432
|
+
status?: UsageInvoice["status"];
|
|
433
|
+
limit?: number;
|
|
434
|
+
offset?: number;
|
|
435
|
+
}): Promise<{
|
|
436
|
+
invoices: UsageInvoice[];
|
|
437
|
+
total: number;
|
|
438
|
+
}>;
|
|
439
|
+
/**
|
|
440
|
+
* Mark invoice as paid
|
|
441
|
+
*/
|
|
442
|
+
markInvoicePaid(invoiceId: string): Promise<UsageInvoice>;
|
|
443
|
+
/**
|
|
444
|
+
* Get alerts for a tenant
|
|
445
|
+
*/
|
|
446
|
+
getAlerts(tenantId: string, options?: {
|
|
447
|
+
type?: AlertType;
|
|
448
|
+
acknowledged?: boolean;
|
|
449
|
+
limit?: number;
|
|
450
|
+
}): Promise<UsageAlert[]>;
|
|
451
|
+
/**
|
|
452
|
+
* Acknowledge an alert
|
|
453
|
+
*/
|
|
454
|
+
acknowledgeAlert(alertId: string, acknowledgedBy?: string): Promise<void>;
|
|
455
|
+
/**
|
|
456
|
+
* Acknowledge all alerts for a tenant
|
|
457
|
+
*/
|
|
458
|
+
acknowledgeAllAlerts(tenantId: string, acknowledgedBy?: string): Promise<number>;
|
|
459
|
+
/**
|
|
460
|
+
* Estimate cost for a request
|
|
461
|
+
*/
|
|
462
|
+
estimateCost(provider: string, model: string, inputTokens: number, outputTokens: number): Promise<number>;
|
|
463
|
+
/**
|
|
464
|
+
* Get token pricing for models
|
|
465
|
+
*/
|
|
466
|
+
getPricing(): Promise<Record<string, Record<string, {
|
|
467
|
+
inputPer1K: number;
|
|
468
|
+
outputPer1K: number;
|
|
469
|
+
}>>>;
|
|
470
|
+
/**
|
|
471
|
+
* Project usage for remainder of period
|
|
472
|
+
*/
|
|
473
|
+
projectUsage(tenantId: string, period: UsageInterval): Promise<{
|
|
474
|
+
projected: {
|
|
475
|
+
tokens: number;
|
|
476
|
+
cost: number;
|
|
477
|
+
requests: number;
|
|
478
|
+
};
|
|
479
|
+
confidence: number;
|
|
480
|
+
}>;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* MemoryAIUsage - In-memory implementation for testing
|
|
484
|
+
*/
|
|
485
|
+
declare class MemoryAIUsage implements IAIUsage {
|
|
486
|
+
private config;
|
|
487
|
+
private records;
|
|
488
|
+
private quotas;
|
|
489
|
+
private budgets;
|
|
490
|
+
private invoices;
|
|
491
|
+
private alerts;
|
|
492
|
+
private pricing;
|
|
493
|
+
constructor(config?: AIUsageConfig);
|
|
494
|
+
record(record: Omit<UsageRecord, "id" | "createdAt">): Promise<UsageRecord>;
|
|
495
|
+
recordBatch(records: Array<Omit<UsageRecord, "id" | "createdAt">>): Promise<UsageRecord[]>;
|
|
496
|
+
query(query: UsageQuery): Promise<UsageQueryResult>;
|
|
497
|
+
getRecord(recordId: string): Promise<UsageRecord | null>;
|
|
498
|
+
setQuota(quota: Omit<Quota, "id" | "used" | "periodStart" | "periodEnd">): Promise<Quota>;
|
|
499
|
+
getQuota(tenantId: string, type: QuotaType, category: UsageCategory | "all"): Promise<Quota | null>;
|
|
500
|
+
listQuotas(tenantId: string): Promise<Quota[]>;
|
|
501
|
+
checkQuota(tenantId: string, type: QuotaType, category: UsageCategory | "all"): Promise<QuotaStatus>;
|
|
502
|
+
checkAllQuotas(tenantId: string): Promise<QuotaStatus[]>;
|
|
503
|
+
deleteQuota(quotaId: string): Promise<void>;
|
|
504
|
+
resetQuota(quotaId: string): Promise<Quota>;
|
|
505
|
+
setBudget(budget: Omit<Budget, "id" | "spent" | "periodStart" | "periodEnd">): Promise<Budget>;
|
|
506
|
+
getBudget(budgetId: string): Promise<Budget | null>;
|
|
507
|
+
listBudgets(tenantId: string): Promise<Budget[]>;
|
|
508
|
+
checkBudget(budgetId: string): Promise<BudgetStatus>;
|
|
509
|
+
checkAllBudgets(tenantId: string): Promise<BudgetStatus[]>;
|
|
510
|
+
deleteBudget(budgetId: string): Promise<void>;
|
|
511
|
+
getSummary(tenantId: string, period: UsageInterval, date?: Date): Promise<UsageSummary>;
|
|
512
|
+
getTrends(tenantId: string, period: UsageInterval, dataPoints?: number): Promise<UsageTrend>;
|
|
513
|
+
getCostBreakdown(tenantId: string, startDate: Date, endDate: Date): Promise<CostBreakdown>;
|
|
514
|
+
comparePeriods(tenantId: string, period1Start: Date, period1End: Date, period2Start: Date, period2End: Date): Promise<{
|
|
515
|
+
period1: UsageSummary;
|
|
516
|
+
period2: UsageSummary;
|
|
517
|
+
changes: {
|
|
518
|
+
tokens: number;
|
|
519
|
+
requests: number;
|
|
520
|
+
cost: number;
|
|
521
|
+
latency: number;
|
|
522
|
+
};
|
|
523
|
+
}>;
|
|
524
|
+
generateInvoice(tenantId: string, periodStart: Date, periodEnd: Date): Promise<UsageInvoice>;
|
|
525
|
+
getInvoice(invoiceId: string): Promise<UsageInvoice | null>;
|
|
526
|
+
listInvoices(tenantId: string, options?: {
|
|
527
|
+
status?: UsageInvoice["status"];
|
|
528
|
+
limit?: number;
|
|
529
|
+
offset?: number;
|
|
530
|
+
}): Promise<{
|
|
531
|
+
invoices: UsageInvoice[];
|
|
532
|
+
total: number;
|
|
533
|
+
}>;
|
|
534
|
+
markInvoicePaid(invoiceId: string): Promise<UsageInvoice>;
|
|
535
|
+
getAlerts(tenantId: string, options?: {
|
|
536
|
+
type?: AlertType;
|
|
537
|
+
acknowledged?: boolean;
|
|
538
|
+
limit?: number;
|
|
539
|
+
}): Promise<UsageAlert[]>;
|
|
540
|
+
acknowledgeAlert(alertId: string, acknowledgedBy?: string): Promise<void>;
|
|
541
|
+
acknowledgeAllAlerts(tenantId: string, acknowledgedBy?: string): Promise<number>;
|
|
542
|
+
estimateCost(provider: string, model: string, inputTokens: number, outputTokens: number): Promise<number>;
|
|
543
|
+
getPricing(): Promise<Record<string, Record<string, {
|
|
544
|
+
inputPer1K: number;
|
|
545
|
+
outputPer1K: number;
|
|
546
|
+
}>>>;
|
|
547
|
+
projectUsage(tenantId: string, period: UsageInterval): Promise<{
|
|
548
|
+
projected: {
|
|
549
|
+
tokens: number;
|
|
550
|
+
cost: number;
|
|
551
|
+
requests: number;
|
|
552
|
+
};
|
|
553
|
+
confidence: number;
|
|
554
|
+
}>;
|
|
555
|
+
private updateQuotaUsage;
|
|
556
|
+
private updateBudgetSpend;
|
|
557
|
+
private createAlert;
|
|
558
|
+
private getPeriodBounds;
|
|
559
|
+
private getIntervalMs;
|
|
560
|
+
private getSummaryForPeriod;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Agent Loop — Multi-turn tool-calling orchestration
|
|
565
|
+
*
|
|
566
|
+
* Runs an IAI chat → tool execution → repeat loop until the AI stops,
|
|
567
|
+
* a budget is hit, or the caller aborts.
|
|
568
|
+
*/
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Function that executes a tool call and returns a string result.
|
|
572
|
+
* Receives the parsed arguments (from JSON) and the raw tool call.
|
|
573
|
+
*/
|
|
574
|
+
type ToolExecutor = (args: Record<string, unknown>, toolCall: AIToolCall) => Promise<string>;
|
|
575
|
+
/**
|
|
576
|
+
* Tool definition paired with its executor.
|
|
577
|
+
*/
|
|
578
|
+
interface AgentTool {
|
|
579
|
+
/** The AI tool definition (JSON Schema for the function) */
|
|
580
|
+
definition: AITool;
|
|
581
|
+
/** The function that executes this tool */
|
|
582
|
+
execute: ToolExecutor;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Result of a single tool call execution.
|
|
586
|
+
*/
|
|
587
|
+
interface AgentToolResult {
|
|
588
|
+
/** The original tool call from the AI */
|
|
589
|
+
toolCall: AIToolCall;
|
|
590
|
+
/** The string result returned by the executor */
|
|
591
|
+
result: string;
|
|
592
|
+
/** Whether the tool execution succeeded */
|
|
593
|
+
success: boolean;
|
|
594
|
+
/** Error message if the tool failed */
|
|
595
|
+
error?: string;
|
|
596
|
+
/** Execution duration in ms */
|
|
597
|
+
durationMs: number;
|
|
598
|
+
/** Whether the result came from cache */
|
|
599
|
+
cached: boolean;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Cumulative usage across all iterations.
|
|
603
|
+
*/
|
|
604
|
+
interface AgentCumulativeUsage {
|
|
605
|
+
promptTokens: number;
|
|
606
|
+
completionTokens: number;
|
|
607
|
+
totalTokens: number;
|
|
608
|
+
estimatedCostUsd: number;
|
|
609
|
+
iterations: number;
|
|
610
|
+
toolCallCount: number;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Event emitted after each iteration of the agent loop.
|
|
614
|
+
*/
|
|
615
|
+
interface AgentIterationEvent {
|
|
616
|
+
/** 1-based iteration number */
|
|
617
|
+
iteration: number;
|
|
618
|
+
/** The AI response for this iteration */
|
|
619
|
+
response: AIChatResponse;
|
|
620
|
+
/** Tool calls made in this iteration (empty if no tool calls) */
|
|
621
|
+
toolCalls: AgentToolResult[];
|
|
622
|
+
/** Cumulative usage across all iterations */
|
|
623
|
+
cumulativeUsage: AgentCumulativeUsage;
|
|
624
|
+
/** Full conversation so far */
|
|
625
|
+
messages: AIMessage[];
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Callback invoked after each iteration.
|
|
629
|
+
* Return `false` to abort the loop.
|
|
630
|
+
*/
|
|
631
|
+
type AgentIterationCallback = (event: AgentIterationEvent) => void | false | Promise<void | false>;
|
|
632
|
+
/**
|
|
633
|
+
* Why the agent loop stopped.
|
|
634
|
+
*/
|
|
635
|
+
type AgentStopReason = "stop" | "max_iterations" | "max_tokens" | "max_cost" | "aborted" | "callback_abort" | "length" | "content_filter" | "error";
|
|
636
|
+
/**
|
|
637
|
+
* Options for runAgentLoop.
|
|
638
|
+
*/
|
|
639
|
+
interface AgentLoopOptions {
|
|
640
|
+
/** The IAI instance to call */
|
|
641
|
+
ai: IAI;
|
|
642
|
+
/** Initial messages (system + user prompt) */
|
|
643
|
+
messages: AIMessage[];
|
|
644
|
+
/** Tool definitions with executors */
|
|
645
|
+
tools: AgentTool[];
|
|
646
|
+
/** Maximum iterations before forced stop @default 10 */
|
|
647
|
+
maxIterations: number;
|
|
648
|
+
/** Maximum cumulative total tokens @default Infinity */
|
|
649
|
+
maxTokens: number;
|
|
650
|
+
/** Maximum cumulative cost in USD @default Infinity */
|
|
651
|
+
maxCostUsd: number;
|
|
652
|
+
/** Optional cache for tool results */
|
|
653
|
+
cache?: ICache;
|
|
654
|
+
/** Cache TTL in seconds for tool results @default 300 */
|
|
655
|
+
cacheTtlSeconds: number;
|
|
656
|
+
/** Cache key prefix @default "agent:tool:" */
|
|
657
|
+
cacheKeyPrefix: string;
|
|
658
|
+
/** Callback after each iteration */
|
|
659
|
+
onIteration?: AgentIterationCallback;
|
|
660
|
+
/** AbortSignal for cancellation */
|
|
661
|
+
signal?: AbortSignal;
|
|
662
|
+
/** Logger for observability */
|
|
663
|
+
logger?: ILogger;
|
|
664
|
+
/** Additional fields for AIChatRequest (model, temperature, etc.) */
|
|
665
|
+
chatRequestOverrides?: Partial<Omit<AIChatRequest, "messages" | "tools">>;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Result of a completed agent loop.
|
|
669
|
+
*/
|
|
670
|
+
interface AgentLoopResult {
|
|
671
|
+
/** Final AI response */
|
|
672
|
+
response: AIChatResponse;
|
|
673
|
+
/** Complete conversation history including all tool messages */
|
|
674
|
+
messages: AIMessage[];
|
|
675
|
+
/** Why the loop stopped */
|
|
676
|
+
stopReason: AgentStopReason;
|
|
677
|
+
/** Per-iteration details */
|
|
678
|
+
iterations: AgentIterationEvent[];
|
|
679
|
+
/** Cumulative usage summary */
|
|
680
|
+
usage: AgentCumulativeUsage;
|
|
681
|
+
}
|
|
682
|
+
declare const DEFAULT_AGENT_LOOP_OPTIONS: Pick<AgentLoopOptions, "maxIterations" | "maxTokens" | "maxCostUsd" | "cacheTtlSeconds" | "cacheKeyPrefix">;
|
|
683
|
+
/**
|
|
684
|
+
* Run a multi-turn tool-calling agent loop.
|
|
685
|
+
*
|
|
686
|
+
* @example
|
|
687
|
+
* ```typescript
|
|
688
|
+
* const result = await runAgentLoop({
|
|
689
|
+
* ai: platform.ai,
|
|
690
|
+
* messages: [
|
|
691
|
+
* { role: 'system', content: 'You are a helpful assistant.' },
|
|
692
|
+
* { role: 'user', content: 'What is the weather in London?' },
|
|
693
|
+
* ],
|
|
694
|
+
* tools: [{
|
|
695
|
+
* definition: {
|
|
696
|
+
* type: 'function',
|
|
697
|
+
* function: {
|
|
698
|
+
* name: 'get_weather',
|
|
699
|
+
* description: 'Get the weather for a city',
|
|
700
|
+
* parameters: { type: 'object', properties: { city: { type: 'string' } } },
|
|
701
|
+
* },
|
|
702
|
+
* },
|
|
703
|
+
* execute: async (args) => {
|
|
704
|
+
* const weather = await fetchWeather(args.city as string);
|
|
705
|
+
* return JSON.stringify(weather);
|
|
706
|
+
* },
|
|
707
|
+
* }],
|
|
708
|
+
* });
|
|
709
|
+
*
|
|
710
|
+
* console.log(result.stopReason); // "stop"
|
|
711
|
+
* console.log(result.usage.totalTokens); // cumulative tokens
|
|
712
|
+
* ```
|
|
713
|
+
*/
|
|
714
|
+
declare function runAgentLoop(options: Partial<AgentLoopOptions> & Pick<AgentLoopOptions, "ai" | "messages" | "tools">): Promise<AgentLoopResult>;
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Agent Tracer — OTEL span helpers for agent observability
|
|
718
|
+
*
|
|
719
|
+
* Wraps ITracing with standardized agent-specific span attributes
|
|
720
|
+
* following OpenTelemetry semantic conventions.
|
|
721
|
+
*/
|
|
722
|
+
|
|
723
|
+
interface AgentTracerOptions {
|
|
724
|
+
/** The ITracing instance */
|
|
725
|
+
tracing: ITracing;
|
|
726
|
+
/** Agent identifier for span attributes */
|
|
727
|
+
agentId: string;
|
|
728
|
+
}
|
|
729
|
+
interface AgentTracer {
|
|
730
|
+
/**
|
|
731
|
+
* Wrap an entire agent loop execution in a span.
|
|
732
|
+
* Sets `agent.id` on the span.
|
|
733
|
+
*/
|
|
734
|
+
traceLoop<T>(fn: (span: ISpan) => Promise<T>): Promise<T>;
|
|
735
|
+
/**
|
|
736
|
+
* Wrap a single iteration in a span.
|
|
737
|
+
* Sets `agent.iteration` on the span.
|
|
738
|
+
*/
|
|
739
|
+
traceIteration(iteration: number, fn: (span: ISpan) => Promise<void>): Promise<void>;
|
|
740
|
+
/**
|
|
741
|
+
* Wrap a single tool call execution in a span.
|
|
742
|
+
* Sets `agent.tool.name`, `agent.tool.duration_ms`, `agent.tool.success`, `agent.tool.cached`.
|
|
743
|
+
*/
|
|
744
|
+
traceToolCall(toolName: string, fn: (span: ISpan) => Promise<AgentToolResult>): Promise<AgentToolResult>;
|
|
745
|
+
/**
|
|
746
|
+
* Record a decision event on the current span.
|
|
747
|
+
*/
|
|
748
|
+
traceDecision(span: ISpan, attrs: {
|
|
749
|
+
finishReason: string;
|
|
750
|
+
toolCallCount: number;
|
|
751
|
+
cumulativeUsage: AgentCumulativeUsage;
|
|
752
|
+
}): void;
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Create an agent tracer with standardized OTEL attributes.
|
|
756
|
+
*
|
|
757
|
+
* @example
|
|
758
|
+
* ```typescript
|
|
759
|
+
* const tracer = createAgentTracer({ tracing: platform.tracing, agentId: 'weather-agent' });
|
|
760
|
+
*
|
|
761
|
+
* const result = await tracer.traceLoop(async (span) => {
|
|
762
|
+
* return await runAgentLoop({ ... });
|
|
763
|
+
* });
|
|
764
|
+
* ```
|
|
765
|
+
*/
|
|
766
|
+
declare function createAgentTracer(options: AgentTracerOptions): AgentTracer;
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Agent Usage Tracker — Per-agent cost tracking via IAIUsage
|
|
770
|
+
*
|
|
771
|
+
* Tags usage records with agentId in metadata for per-agent attribution.
|
|
772
|
+
* No changes to IAIUsage interface required.
|
|
773
|
+
*/
|
|
774
|
+
|
|
775
|
+
interface AgentUsageTrackerOptions {
|
|
776
|
+
/** The IAIUsage instance */
|
|
777
|
+
usage: IAIUsage;
|
|
778
|
+
/** Agent identifier to tag on all records */
|
|
779
|
+
agentId: string;
|
|
780
|
+
/** Tenant ID for usage records */
|
|
781
|
+
tenantId: string;
|
|
782
|
+
/** Optional user ID */
|
|
783
|
+
userId?: string;
|
|
784
|
+
}
|
|
785
|
+
interface AgentUsageRecordParams {
|
|
786
|
+
/** AI provider name */
|
|
787
|
+
provider: string;
|
|
788
|
+
/** Model used */
|
|
789
|
+
model: string;
|
|
790
|
+
/** Token usage info from the AI response */
|
|
791
|
+
usage: AIUsageInfo;
|
|
792
|
+
/** Usage category @default "chat" */
|
|
793
|
+
category?: UsageCategory;
|
|
794
|
+
/** Whether the request succeeded @default true */
|
|
795
|
+
success?: boolean;
|
|
796
|
+
/** Request latency in ms */
|
|
797
|
+
latencyMs?: number;
|
|
798
|
+
/** Error message if failed */
|
|
799
|
+
error?: string;
|
|
800
|
+
}
|
|
801
|
+
interface AgentBudget {
|
|
802
|
+
/** Maximum cumulative cost in USD */
|
|
803
|
+
maxCostUsd?: number;
|
|
804
|
+
/** Maximum cumulative tokens */
|
|
805
|
+
maxTokens?: number;
|
|
806
|
+
}
|
|
807
|
+
interface AgentUsageTracker {
|
|
808
|
+
/**
|
|
809
|
+
* Record a single AI call's usage, tagged with agentId in metadata.
|
|
810
|
+
*/
|
|
811
|
+
recordIteration(params: AgentUsageRecordParams): Promise<UsageRecord>;
|
|
812
|
+
/**
|
|
813
|
+
* Returns an AgentIterationCallback suitable for runAgentLoop's onIteration.
|
|
814
|
+
* Records usage for each iteration and returns false when budget is exceeded.
|
|
815
|
+
*/
|
|
816
|
+
createBudgetCallback(budget?: AgentBudget): AgentIterationCallback;
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Create a usage tracker that tags all records with an agent ID.
|
|
820
|
+
*
|
|
821
|
+
* @example
|
|
822
|
+
* ```typescript
|
|
823
|
+
* const tracker = createAgentUsageTracker({
|
|
824
|
+
* usage: platform.aiUsage,
|
|
825
|
+
* agentId: 'weather-agent',
|
|
826
|
+
* tenantId: 'tenant_123',
|
|
827
|
+
* });
|
|
828
|
+
*
|
|
829
|
+
* const result = await runAgentLoop({
|
|
830
|
+
* ai, messages, tools,
|
|
831
|
+
* onIteration: tracker.createBudgetCallback({ maxCostUsd: 0.50 }),
|
|
832
|
+
* });
|
|
833
|
+
* ```
|
|
834
|
+
*/
|
|
835
|
+
declare function createAgentUsageTracker(options: AgentUsageTrackerOptions): AgentUsageTracker;
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Traced AI — Auto-instrument any IAI with OTEL spans
|
|
839
|
+
*
|
|
840
|
+
* Wraps an IAI instance so that every chat() call is automatically
|
|
841
|
+
* wrapped in an OTEL span capturing provider, model, tokens, cost,
|
|
842
|
+
* latency, and finish reason.
|
|
843
|
+
*/
|
|
844
|
+
|
|
845
|
+
interface TracedAIOptions {
|
|
846
|
+
/** The IAI instance to wrap */
|
|
847
|
+
ai: IAI;
|
|
848
|
+
/** The ITracing instance */
|
|
849
|
+
tracing: ITracing;
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Wraps an IAI instance with automatic OTEL tracing on chat operations.
|
|
853
|
+
*
|
|
854
|
+
* @example
|
|
855
|
+
* ```typescript
|
|
856
|
+
* const tracedAI = createTracedAI({ ai: platform.ai, tracing: platform.tracing });
|
|
857
|
+
*
|
|
858
|
+
* // Every chat() call now creates an OTEL span with ai.* attributes
|
|
859
|
+
* const response = await tracedAI.chat({ messages: [...] });
|
|
860
|
+
* ```
|
|
861
|
+
*/
|
|
862
|
+
declare function createTracedAI(options: TracedAIOptions): IAI;
|
|
863
|
+
|
|
864
|
+
export { type AIUsageConfig as A, type Budget as B, type CostBreakdown as C, DEFAULT_AGENT_LOOP_OPTIONS as D, type AgentUsageRecordParams as E, type AgentBudget as F, type AgentUsageTracker as G, createAgentUsageTracker as H, type IAIUsage as I, type TracedAIOptions as J, createTracedAI as K, MemoryAIUsage as M, type Quota as Q, type ToolExecutor as T, type UsageRecord as U, type UsageQuery as a, type UsageQueryResult as b, type QuotaType as c, type UsageCategory as d, type QuotaStatus as e, type BudgetStatus as f, type UsageInterval as g, type UsageSummary as h, type UsageTrend as i, type UsageInvoice as j, type AlertType as k, type UsageAlert as l, type UsageInvoiceItem as m, type AgentTool as n, type AgentToolResult as o, type AgentCumulativeUsage as p, type AgentIterationEvent as q, type AgentIterationCallback as r, type AgentStopReason as s, type AgentLoopOptions as t, type AgentLoopResult as u, runAgentLoop as v, type AgentTracerOptions as w, type AgentTracer as x, createAgentTracer as y, type AgentUsageTrackerOptions as z };
|