@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.
@@ -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 };