@agtlantis/core 0.4.1

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,1502 @@
1
+ import { P as ProviderType, a as PricingConfig, M as ModelPricing, b as ProviderPricing, C as CalculateCostParams, c as CostResult, S as StreamingExecution, d as StreamingSession, e as SessionStreamGeneratorFn, f as SessionEvent, E as ErrorEvent, g as StreamingResult, h as ExtractResult, i as SimpleExecution, j as SimpleSession, k as SimpleResult, l as ExecutionStatus, m as CompletionEvent, n as StreamTextParams, B as BaseProvider, F as FileSource, o as FileCache, U as UploadedFile, p as FileManager, L as Logger, q as FileManagerOptions } from './base-provider-C3mFLNiN.cjs';
2
+ export { ag as AdditionalCost, a4 as CreateStreamingSessionOptions, a7 as DefaultOutput, D as DistributiveOmit, ak as DoneMetadata, v as EmittableEventInput, w as EventMetrics, r as Execution, J as ExecutionDoneEvent, I as ExecutionEmitEvent, K as ExecutionErrorEvent, x as ExecutionMetadata, s as ExecutionOptions, t as ExecutionResult, aj as ExecutionSession, H as ExecutionStartEvent, W as FileSourceBase64, V as FileSourceData, T as FileSourcePath, X as FileSourceUrl, ac as GenerateObjectParams, ab as GenerateTextParams, a9 as GenerateTextResultTyped, a8 as InferOutputComplete, G as LLMCallEndEvent, z as LLMCallLogType, af as LLMCallRecord, A as LLMCallStartEvent, ae as LLMCallType, y as LogLevel, a6 as OutputSpec, Q as Provider, R as ReservedEventType, u as SessionEventInput, ah as SessionSummary, ai as SessionSummaryJSON, a1 as SimpleSessionOptions, aa as StreamTextResultTyped, a5 as StreamingSessionInternal, a3 as StreamingSessionOptions, ad as ToolCallSummary, O as createLogger, a2 as createStreamingSession, Y as isFileSource, $ as isFileSourceBase64, _ as isFileSourceData, Z as isFileSourcePath, a0 as isFileSourceUrl, N as noopLogger } from './base-provider-C3mFLNiN.cjs';
3
+ import { LanguageModelUsage, ToolSet, StopCondition } from 'ai';
4
+ export { GenerateTextResult, LanguageModelUsage, StreamTextResult, ToolSet } from 'ai';
5
+ import { z } from 'zod';
6
+ import { GoogleGenerativeAIProviderOptions } from '@ai-sdk/google';
7
+ export { GoogleGenerativeAIProviderOptions } from '@ai-sdk/google';
8
+ import { OpenAIChatLanguageModelOptions } from '@ai-sdk/openai';
9
+ export { OpenAIChatLanguageModelOptions } from '@ai-sdk/openai';
10
+
11
+ declare enum ExecutionErrorCode {
12
+ EXECUTION_ERROR = "EXECUTION_ERROR",
13
+ STREAM_ERROR = "STREAM_ERROR",
14
+ RESULT_EXTRACTION_ERROR = "RESULT_EXTRACTION_ERROR",
15
+ CANCELLED = "CANCELLED",
16
+ VALIDATION_ERROR = "VALIDATION_ERROR"
17
+ }
18
+ declare enum ConfigurationErrorCode {
19
+ CONFIG_ERROR = "CONFIG_ERROR",
20
+ MISSING_API_KEY = "MISSING_API_KEY",
21
+ INVALID_CONFIG = "INVALID_CONFIG",
22
+ MISSING_REQUIRED = "MISSING_REQUIRED"
23
+ }
24
+ declare enum FileErrorCode {
25
+ FILE_ERROR = "FILE_ERROR",
26
+ UPLOAD_ERROR = "UPLOAD_ERROR",
27
+ DELETE_ERROR = "DELETE_ERROR",
28
+ NOT_FOUND = "NOT_FOUND",
29
+ TOO_LARGE = "TOO_LARGE",
30
+ UNSUPPORTED_TYPE = "UNSUPPORTED_TYPE"
31
+ }
32
+ type AgtlantisErrorCode = ExecutionErrorCode | ConfigurationErrorCode | FileErrorCode;
33
+ interface AgtlantisErrorOptions<TCode extends AgtlantisErrorCode = AgtlantisErrorCode> {
34
+ code: TCode;
35
+ cause?: Error;
36
+ context?: Record<string, unknown>;
37
+ }
38
+ interface ErrorOptions<TCode extends AgtlantisErrorCode> {
39
+ code?: TCode;
40
+ cause?: Error;
41
+ context?: Record<string, unknown>;
42
+ }
43
+ type ExecutionErrorOptions = ErrorOptions<ExecutionErrorCode>;
44
+ type ConfigurationErrorOptions = ErrorOptions<ConfigurationErrorCode>;
45
+ type FileErrorOptions = ErrorOptions<FileErrorCode>;
46
+ /**
47
+ * Base error class for all Agtlantis errors.
48
+ * Provides structured error information including error code and optional context.
49
+ */
50
+ declare class AgtlantisError<TCode extends AgtlantisErrorCode = AgtlantisErrorCode> extends Error {
51
+ readonly code: TCode;
52
+ readonly cause?: Error;
53
+ readonly context?: Record<string, unknown>;
54
+ constructor(message: string, options: AgtlantisErrorOptions<TCode>);
55
+ get isRetryable(): boolean;
56
+ toJSON(): Record<string, unknown>;
57
+ }
58
+ /**
59
+ * Error thrown during agent execution (streaming failures, result extraction, cancellation).
60
+ */
61
+ declare class ExecutionError extends AgtlantisError<ExecutionErrorCode> {
62
+ constructor(message: string, options?: ExecutionErrorOptions);
63
+ static from(error: unknown, code?: ExecutionErrorCode, context?: Record<string, unknown>): ExecutionError;
64
+ }
65
+ /**
66
+ * Error thrown when configuration is invalid or missing (API keys, model names).
67
+ */
68
+ declare class ConfigurationError extends AgtlantisError<ConfigurationErrorCode> {
69
+ constructor(message: string, options?: ConfigurationErrorOptions);
70
+ static from(error: unknown, code?: ConfigurationErrorCode, context?: Record<string, unknown>): ConfigurationError;
71
+ }
72
+ /**
73
+ * Error thrown during file operations (upload, delete, not found, size limits).
74
+ */
75
+ declare class FileError extends AgtlantisError<FileErrorCode> {
76
+ constructor(message: string, options?: FileErrorOptions);
77
+ static from(error: unknown, code?: FileErrorCode, context?: Record<string, unknown>): FileError;
78
+ }
79
+
80
+ declare function mergeUsages(usages: LanguageModelUsage[]): LanguageModelUsage;
81
+ declare function createZeroUsage(): LanguageModelUsage;
82
+ declare function detectProviderType(modelId: string): ProviderType | undefined;
83
+
84
+ /**
85
+ * Global pricing configuration.
86
+ *
87
+ * Priority order (highest to lowest):
88
+ * 1. Provider.withPricing() - per-provider override
89
+ * 2. configurePricing() - global override
90
+ * 3. Built-in defaults (defaults.ts)
91
+ * 4. Fallback pricing
92
+ *
93
+ * @module pricing/config
94
+ */
95
+
96
+ /**
97
+ * Configure global pricing overrides.
98
+ *
99
+ * WARNING: This uses global mutable state and is not thread-safe.
100
+ * For multi-tenant scenarios or concurrent requests with different pricing,
101
+ * use `Provider.withPricing()` instead for proper isolation.
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * configurePricing({
106
+ * providers: {
107
+ * google: {
108
+ * 'gemini-2.5-flash': { inputPricePerMillion: 0.5, outputPricePerMillion: 3.0 },
109
+ * },
110
+ * },
111
+ * });
112
+ *
113
+ * // Reset to built-in defaults
114
+ * configurePricing(undefined);
115
+ * ```
116
+ */
117
+ declare function configurePricing(config: PricingConfig | undefined): void;
118
+ declare function getPricingConfig(): PricingConfig | undefined;
119
+ /**
120
+ * Reset global pricing configuration.
121
+ * Useful for testing to ensure clean state between tests.
122
+ */
123
+ declare function resetPricingConfig(): void;
124
+ type PricingSource = 'global' | 'default' | 'fallback';
125
+ interface EffectivePricingResult {
126
+ pricing: ModelPricing;
127
+ source: PricingSource;
128
+ }
129
+ /**
130
+ * Get effective pricing for a model with source information.
131
+ * Useful for debugging to understand which pricing layer is applied.
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const result = getEffectivePricing('gemini-2.5-flash', 'google');
136
+ * console.log(result.source); // 'default' (using built-in pricing)
137
+ *
138
+ * configurePricing({ providers: { google: { 'gemini-2.5-flash': {...} } } });
139
+ * const result2 = getEffectivePricing('gemini-2.5-flash', 'google');
140
+ * console.log(result2.source); // 'global' (using configured override)
141
+ * ```
142
+ */
143
+ declare function getEffectivePricing(model: string, provider: ProviderType): EffectivePricingResult;
144
+
145
+ /**
146
+ * Pricing validation utilities.
147
+ *
148
+ * Provides fail-fast validation for pricing configuration to catch
149
+ * invalid values (negative, NaN, Infinity) at configuration time.
150
+ *
151
+ * @module pricing/validator
152
+ */
153
+
154
+ /**
155
+ * Validates a ModelPricing object.
156
+ * Ensures all price values are non-negative and finite.
157
+ *
158
+ * @throws {Error} If any price value is invalid
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * validateModelPricing(
163
+ * { inputPricePerMillion: 2.5, outputPricePerMillion: 10.0 },
164
+ * 'openai/gpt-4o'
165
+ * );
166
+ * ```
167
+ */
168
+ declare function validateModelPricing(pricing: ModelPricing, context: string): void;
169
+ /**
170
+ * Validates a ProviderPricing object.
171
+ *
172
+ * @throws {Error} If any model pricing is invalid
173
+ *
174
+ * @example
175
+ * ```typescript
176
+ * validateProviderPricing({
177
+ * 'gemini-2.5-flash': { inputPricePerMillion: 0.3, outputPricePerMillion: 2.5 },
178
+ * 'gemini-2.5-pro': { inputPricePerMillion: 1.25, outputPricePerMillion: 10.0 },
179
+ * }, 'google');
180
+ * ```
181
+ */
182
+ declare function validateProviderPricing(pricing: ProviderPricing, providerContext?: string): void;
183
+ /**
184
+ * Validates a PricingConfig object.
185
+ *
186
+ * @throws {Error} If any pricing configuration is invalid
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * validatePricingConfig({
191
+ * providers: {
192
+ * google: { 'gemini-2.5-flash': { inputPricePerMillion: 0.3, outputPricePerMillion: 2.5 } },
193
+ * },
194
+ * fallback: { inputPricePerMillion: 1.0, outputPricePerMillion: 5.0 },
195
+ * });
196
+ * ```
197
+ */
198
+ declare function validatePricingConfig(config: PricingConfig): void;
199
+
200
+ /**
201
+ * Cost calculation functions.
202
+ *
203
+ * @module pricing/calculator
204
+ *
205
+ * NOTE: Cost calculations use standard JavaScript floating-point arithmetic.
206
+ * For high-volume usage tracking, accumulated totals may have minor precision drift.
207
+ * For financial reporting, consider rounding results to appropriate decimal places
208
+ * (e.g., `Math.round(cost * 100) / 100` for cents).
209
+ */
210
+
211
+ /**
212
+ * Get pricing for a specific model.
213
+ *
214
+ * Resolution order:
215
+ * 1. Provider-level config (providerPricing param)
216
+ * 2. Global config (configurePricing)
217
+ * 3. Built-in defaults
218
+ * 4. Fallback pricing
219
+ */
220
+ declare function getModelPricing(model: string, provider: ProviderType, providerPricing?: ProviderPricing): ModelPricing;
221
+ /**
222
+ * Calculate cost from token counts.
223
+ *
224
+ * @throws Error if token counts are negative, non-finite, or if cachedInputTokens > inputTokens
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * const cost = calculateCost({
229
+ * inputTokens: 1000,
230
+ * outputTokens: 500,
231
+ * cachedInputTokens: 200,
232
+ * model: 'gemini-2.5-flash',
233
+ * provider: 'google',
234
+ * });
235
+ * console.log(cost.total); // 0.000315
236
+ * ```
237
+ */
238
+ declare function calculateCost(params: CalculateCostParams, providerPricing?: ProviderPricing): CostResult;
239
+ /**
240
+ * Calculate cost from AI SDK LanguageModelUsage.
241
+ *
242
+ * Convenience function that extracts token counts from the
243
+ * AI SDK's LanguageModelUsage type and calculates the cost.
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * const usage = await result.usage;
248
+ * const cost = calculateCostFromUsage(usage, 'gemini-2.5-flash', 'google');
249
+ * ```
250
+ */
251
+ declare function calculateCostFromUsage(usage: LanguageModelUsage, model: string, provider: ProviderType, providerPricing?: ProviderPricing): CostResult;
252
+ /**
253
+ * Calculate total cost for multiple LLM calls.
254
+ *
255
+ * Aggregates costs from multiple calls, grouping by model.
256
+ *
257
+ * @returns Object with:
258
+ * - `totalCost`: Sum of all call costs in USD
259
+ * - `costByModel`: Map where key format is `${provider}/${model}`
260
+ */
261
+ declare function calculateTotalCost(calls: Array<{
262
+ usage: LanguageModelUsage;
263
+ model: string;
264
+ provider: ProviderType;
265
+ }>, providerPricing?: ProviderPricing): {
266
+ totalCost: number;
267
+ costByModel: Record<string, number>;
268
+ };
269
+
270
+ /**
271
+ * Built-in pricing tables (USD per million tokens).
272
+ *
273
+ * These are the default prices for common models. They can be overridden
274
+ * using `configurePricing()` (global) or `Provider.withPricing()` (per-provider).
275
+ *
276
+ * Last updated: January 2025
277
+ *
278
+ * @module pricing/defaults
279
+ */
280
+
281
+ /**
282
+ * OpenAI model pricing.
283
+ * @see https://openai.com/pricing
284
+ */
285
+ declare const OPENAI_PRICING: ProviderPricing;
286
+ /**
287
+ * Google Gemini model pricing.
288
+ * @see https://ai.google.dev/gemini-api/docs/pricing
289
+ */
290
+ declare const GOOGLE_PRICING: ProviderPricing;
291
+ /**
292
+ * Anthropic Claude model pricing.
293
+ * @see https://www.anthropic.com/pricing
294
+ */
295
+ declare const ANTHROPIC_PRICING: ProviderPricing;
296
+ declare const DEFAULT_PRICING_CONFIG: Required<PricingConfig>;
297
+ declare const DEFAULT_FALLBACK_PRICING: ModelPricing;
298
+
299
+ /**
300
+ * Streaming execution host that uses StreamingSession.
301
+ * Starts execution eagerly on construction - events are buffered automatically.
302
+ *
303
+ * @typeParam TEvent - User's pure domain event type with required `type` field (metrics added automatically)
304
+ *
305
+ * @example
306
+ * ```typescript
307
+ * const execution = new StreamingExecutionHost(
308
+ * () => new StreamingSession({
309
+ * defaultLanguageModel: provider.model,
310
+ * fileManager: new GoogleFileManager(apiKey),
311
+ * }),
312
+ * async function* (session) {
313
+ * session.onDone(() => session.fileManager.clear());
314
+ * const result = await session.generateText({ prompt: 'Hello' });
315
+ * yield session.emit({ type: 'progress', message: 'Working...' });
316
+ * return session.done(result.text);
317
+ * }
318
+ * );
319
+ * // ↑ Execution already started, events being buffered
320
+ *
321
+ * // Option 1: Stream events (buffered + real-time)
322
+ * for await (const event of execution.stream()) {
323
+ * console.log(event.type, event.metrics.elapsedMs);
324
+ * }
325
+ * const result = await execution.result();
326
+ *
327
+ * // Option 2: Skip streaming, events available in result
328
+ * const result = await execution.result();
329
+ * console.log(`Received ${result.events.length} events`);
330
+ *
331
+ * if (result.status === 'succeeded') {
332
+ * console.log(result.value);
333
+ * }
334
+ * ```
335
+ */
336
+ declare class StreamingExecutionHost<TEvent extends {
337
+ type: string;
338
+ }> implements StreamingExecution<TEvent> {
339
+ private readonly createSession;
340
+ private readonly generator;
341
+ private readonly abortController;
342
+ private readonly effectiveSignal;
343
+ private readonly consumerPromise;
344
+ private readonly eventBuffer;
345
+ private readonly subscribers;
346
+ private completed;
347
+ private cleaned;
348
+ private hookRunner;
349
+ private cancelRequested;
350
+ private extractedOutcome;
351
+ private extractedSummary;
352
+ constructor(createSession: (signal?: AbortSignal) => StreamingSession<TEvent>, generator: SessionStreamGeneratorFn<TEvent>, userSignal?: AbortSignal);
353
+ private hasDataField;
354
+ private hasSummaryField;
355
+ private hasErrorField;
356
+ private extractResultAndMetadata;
357
+ private notifySubscribers;
358
+ private startConsuming;
359
+ private buildResult;
360
+ /**
361
+ * Get the event stream.
362
+ * Returns buffered events first, then real-time events.
363
+ * Can be called multiple times - replays buffer each time.
364
+ */
365
+ stream(): AsyncIterable<SessionEvent<TEvent | ErrorEvent>>;
366
+ cancel(): void;
367
+ cleanup(): Promise<void>;
368
+ [Symbol.asyncDispose](): Promise<void>;
369
+ /**
370
+ * Get the execution result with status, summary, and all events.
371
+ * Never throws - returns a discriminated union with status.
372
+ */
373
+ result(): Promise<StreamingResult<SessionEvent<TEvent | ErrorEvent>, ExtractResult<TEvent>>>;
374
+ }
375
+
376
+ /**
377
+ * SimpleExecutionHost implements the SimpleExecution interface for eager execution.
378
+ *
379
+ * Execution starts immediately on construction (eager evaluation).
380
+ * Use result() to get the execution outcome with status and summary.
381
+ *
382
+ * Signal combination:
383
+ * - If userSignal is provided, it's combined with internal AbortController
384
+ * - Both cancel() and userSignal abort will trigger cancellation
385
+ * - The combined signal is passed to SimpleSession for AI SDK calls
386
+ *
387
+ * @example
388
+ * ```typescript
389
+ * const execution = new SimpleExecutionHost(createSession, async (session) => {
390
+ * return await session.generateText({ prompt: 'Hello' });
391
+ * });
392
+ *
393
+ * const result = await execution.result();
394
+ *
395
+ * if (result.status === 'succeeded') {
396
+ * console.log(result.value);
397
+ * }
398
+ * console.log(`Cost: $${result.summary.totalCost}`);
399
+ * ```
400
+ */
401
+ declare class SimpleExecutionHost<TResult> implements SimpleExecution<TResult> {
402
+ private readonly abortController;
403
+ private readonly effectiveSignal;
404
+ private readonly consumerPromise;
405
+ private cachedSession?;
406
+ private readonly startTime;
407
+ private cancelRequested;
408
+ constructor(createSession: (signal?: AbortSignal) => SimpleSession, fn: (session: SimpleSession) => Promise<TResult>, userSignal?: AbortSignal);
409
+ private execute;
410
+ /**
411
+ * Request cancellation of the execution.
412
+ * Aborts the current LLM call if in progress.
413
+ * No-op if execution already completed.
414
+ */
415
+ cancel(): void;
416
+ /**
417
+ * Get the execution result with status and summary.
418
+ * Never throws - returns a discriminated union with status.
419
+ */
420
+ result(): Promise<SimpleResult<TResult>>;
421
+ /**
422
+ * Cleanup resources.
423
+ * For SimpleExecution, hooks are already run during execution,
424
+ * so this is intentionally a no-op.
425
+ */
426
+ cleanup(): Promise<void>;
427
+ [Symbol.asyncDispose](): Promise<void>;
428
+ }
429
+
430
+ declare const ERRORS: {
431
+ readonly ALREADY_CONSUMED: "Execution already consumed";
432
+ readonly METADATA_NOT_AVAILABLE: "Metadata not available yet. Consume the execution first.";
433
+ readonly NO_RESULT: "No result available";
434
+ readonly UNKNOWN_ERROR: "Execution failed with unknown error";
435
+ };
436
+
437
+ /**
438
+ * Calculate duration from start time in milliseconds.
439
+ *
440
+ * @param startTime - The start timestamp from Date.now()
441
+ * @returns Duration in milliseconds
442
+ */
443
+ declare function getDuration(startTime: number): number;
444
+ /**
445
+ * Combine multiple AbortSignals into a single signal.
446
+ * The combined signal aborts when ANY of the source signals abort.
447
+ *
448
+ * Node 18 compatible - doesn't use AbortSignal.any() which is Node 20+.
449
+ *
450
+ * @param signals - AbortSignals to combine
451
+ * @returns A new AbortSignal that aborts when any input signal aborts
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * const userController = new AbortController();
456
+ * const timeoutController = new AbortController();
457
+ *
458
+ * const combined = combineSignals(userController.signal, timeoutController.signal);
459
+ *
460
+ * // Either abort triggers the combined signal
461
+ * userController.abort(); // combined.aborted === true
462
+ * ```
463
+ */
464
+ declare function combineSignals(...signals: AbortSignal[]): AbortSignal;
465
+
466
+ /**
467
+ * Shared utilities for execution hosts.
468
+ *
469
+ * These functions extract common patterns from SimpleExecutionHost and
470
+ * StreamingExecutionHost to reduce code duplication and ensure consistent
471
+ * behavior across both implementations.
472
+ */
473
+ /**
474
+ * Checks if an error is an abort-related error.
475
+ *
476
+ * An error is considered abort-related if either:
477
+ * - The error has the name 'AbortError' (standard for AbortController)
478
+ * - The signal has been aborted (covers edge cases where error name differs)
479
+ *
480
+ * @param error - The error to check
481
+ * @param signal - The AbortSignal associated with the execution
482
+ * @returns true if this is an abort-related error
483
+ */
484
+ declare function isAbortError(error: unknown, signal: AbortSignal): boolean;
485
+ /**
486
+ * Normalizes an unknown error to an Error instance.
487
+ *
488
+ * If the error is already an Error instance, it's returned as-is.
489
+ * Otherwise, it's converted to a string and wrapped in a new Error.
490
+ *
491
+ * @param error - The unknown error to normalize
492
+ * @returns A proper Error instance
493
+ */
494
+ declare function normalizeError(error: unknown): Error;
495
+ /**
496
+ * Determines the execution status based on the execution state.
497
+ *
498
+ * Status determination priority:
499
+ * 1. If user called cancel() OR the operation was aborted → 'canceled'
500
+ * 2. If there's an error → 'failed'
501
+ * 3. Otherwise → 'succeeded'
502
+ *
503
+ * Note: The 'aborted' flag takes precedence over 'hasError' because
504
+ * AbortError is treated as a normal cancellation, not a failure.
505
+ *
506
+ * @param cancelRequested - Whether cancel() was explicitly called
507
+ * @param aborted - Whether the signal was aborted (includes external abort)
508
+ * @param hasError - Whether the execution ended with an error
509
+ * @returns The appropriate execution status
510
+ */
511
+ declare function determineResultStatus(cancelRequested: boolean, aborted: boolean, hasError: boolean): ExecutionStatus;
512
+ /**
513
+ * Return type for createHookRunner utility.
514
+ */
515
+ type HookRunner = {
516
+ /**
517
+ * Ensures hooks run exactly once.
518
+ * Safe to call multiple times - only executes on first call.
519
+ */
520
+ ensureRun: () => Promise<void>;
521
+ /**
522
+ * Check if hooks have already been run.
523
+ */
524
+ hasRun: () => boolean;
525
+ };
526
+ /**
527
+ * Creates a hook runner that ensures hooks run exactly once.
528
+ *
529
+ * This utility encapsulates the common pattern of running cleanup hooks
530
+ * with a guard flag to prevent double execution. Both SimpleExecutionHost
531
+ * and StreamingExecutionHost use this pattern for onDone hooks.
532
+ *
533
+ * @param runHooks - The async function to run hooks
534
+ * @returns Object with ensureRun() and hasRun() methods
535
+ *
536
+ * @example
537
+ * ```typescript
538
+ * const hookRunner = createHookRunner(async () => {
539
+ * await session.runOnDoneHooks();
540
+ * });
541
+ *
542
+ * // In finally block or cleanup:
543
+ * await hookRunner.ensureRun();
544
+ *
545
+ * // Safe to call multiple times - only executes once
546
+ * await hookRunner.ensureRun(); // no-op
547
+ * ```
548
+ */
549
+ declare function createHookRunner(runHooks: () => Promise<void>): HookRunner;
550
+
551
+ type ReplaceResult<TEvent extends {
552
+ type: string;
553
+ }, U> = Exclude<TEvent, {
554
+ type: 'complete';
555
+ }> | CompletionEvent<U>;
556
+ declare function mapExecution<TEvent extends {
557
+ type: string;
558
+ }, UEvent extends {
559
+ type: string;
560
+ }>(execution: StreamingExecution<TEvent>, fn: (event: TEvent) => UEvent | Promise<UEvent>): StreamingExecution<UEvent>;
561
+ declare function mapExecution<A, B>(execution: SimpleExecution<A>, fn: (result: A) => B | Promise<B>): SimpleExecution<B>;
562
+ declare function mapExecutionResult<TEvent extends {
563
+ type: string;
564
+ }, U>(execution: StreamingExecution<TEvent>, fn: (result: ExtractResult<TEvent>) => U | Promise<U>): StreamingExecution<ReplaceResult<TEvent, U>>;
565
+ declare function mapExecutionResult<A, B>(execution: SimpleExecution<A>, fn: (result: A) => B | Promise<B>): SimpleExecution<B>;
566
+
567
+ type ProgressiveStreamOptions<TUserTools extends ToolSet = {}> = Omit<StreamTextParams<TUserTools>, 'tools' | 'toolChoice' | 'stopWhen'> & {
568
+ tools?: TUserTools;
569
+ /**
570
+ * Additional stop conditions. Will be combined with the default
571
+ * `hasToolCall('submitResult')`.
572
+ */
573
+ stopWhen?: StopCondition<ToolSet> | StopCondition<ToolSet>[];
574
+ /**
575
+ * Custom protocol instructions appended to the system prompt.
576
+ * If not provided, uses the default TOOL_CALLING_PROTOCOL.
577
+ */
578
+ protocol?: string;
579
+ };
580
+ /**
581
+ * Progress event - pure domain event without metrics.
582
+ * Framework automatically wraps with SessionEvent at runtime.
583
+ */
584
+ interface ProgressEvent<TProgress> {
585
+ type: 'progress';
586
+ data: TProgress;
587
+ }
588
+ /**
589
+ * Complete event - pure domain event without metrics.
590
+ * Framework automatically wraps with SessionEvent at runtime.
591
+ */
592
+ interface CompleteEvent<TResult> {
593
+ type: 'complete';
594
+ data: TResult;
595
+ summary: unknown;
596
+ }
597
+ declare const TOOL_CALLING_PROTOCOL = "## CRITICAL INSTRUCTION - READ CAREFULLY\n\nYou have 2 tools available:\n1. reportProgress - [OPTIONAL] Show intermediate work (multiple times)\n2. submitResult - [REQUIRED] Submit your final answer\n\n\u26A0\uFE0F IMPORTANT RULES:\n- You may call reportProgress 0-3 times to show progress\n- You MUST call submitResult exactly once to complete the task\n- After calling reportProgress, you MUST call submitResult in your NEXT response\n- If you call reportProgress more than 3 times without submitResult, the task FAILS\n- The task is NOT complete until submitResult is called\n\nCORRECT SEQUENCE:\n1. [Optional] reportProgress\n2. [Required] submitResult (exactly once)\n\n\u274C WRONG: reportProgress \u2192 reportProgress \u2192 reportProgress \u2192 reportProgress (no submitResult = FAIL)\n\u2705 CORRECT: reportProgress \u2192 submitResult (SUCCESS)";
598
+ /**
599
+ * Creates a progressive pattern for streaming LLM responses with intermediate progress updates.
600
+ *
601
+ * The pattern automatically:
602
+ * - Injects `reportProgress` and `submitResult` tools
603
+ * - Stops when `submitResult` is called (via `hasToolCall('submitResult')`)
604
+ * - Appends protocol instructions to the system prompt
605
+ *
606
+ * @example Basic usage
607
+ * ```typescript
608
+ * const pattern = defineProgressivePattern({
609
+ * progressSchema: z.object({ stage: z.string(), message: z.string() }),
610
+ * resultSchema: z.object({ summary: z.string(), score: z.number() }),
611
+ * });
612
+ *
613
+ * for await (const event of pattern.run(provider, {
614
+ * system: 'You are an analyzer.',
615
+ * prompt: 'Analyze this...',
616
+ * })) {
617
+ * console.log(event.type, event.data);
618
+ * }
619
+ * ```
620
+ *
621
+ * @example With custom stopWhen (add step limit)
622
+ * ```typescript
623
+ * import { stepCountIs } from 'ai';
624
+ *
625
+ * for await (const event of pattern.run(provider, {
626
+ * prompt: 'Analyze...',
627
+ * stopWhen: stepCountIs(10), // Stop at submitResult OR after 10 steps
628
+ * })) { ... }
629
+ * ```
630
+ *
631
+ * @example With custom protocol
632
+ * ```typescript
633
+ * for await (const event of pattern.run(provider, {
634
+ * prompt: 'Analyze...',
635
+ * protocol: 'Call reportProgress for each step, then submitResult.',
636
+ * })) { ... }
637
+ * ```
638
+ *
639
+ * @example Composable (within a session)
640
+ * ```typescript
641
+ * provider.streamingExecution(async function*(session) {
642
+ * yield* pattern.runInSession(session, {
643
+ * system: 'You are an analyzer.',
644
+ * messages: [...],
645
+ * });
646
+ * });
647
+ * ```
648
+ */
649
+ declare function defineProgressivePattern<TProgressSchema extends z.ZodType, TResultSchema extends z.ZodType>(config: {
650
+ progressSchema: TProgressSchema;
651
+ resultSchema: TResultSchema;
652
+ }): ProgressivePattern<TProgressSchema, TResultSchema, z.core.output<TProgressSchema>, z.core.output<TResultSchema>, {
653
+ type: string;
654
+ }>;
655
+ declare class ProgressivePattern<TProgressSchema extends z.ZodType, TResultSchema extends z.ZodType, TProgress = z.infer<TProgressSchema>, TResult = z.infer<TResultSchema>, TEvent extends {
656
+ type: string;
657
+ } = {
658
+ type: string;
659
+ }> {
660
+ readonly progressSchema: TProgressSchema;
661
+ readonly resultSchema: TResultSchema;
662
+ constructor(progressSchema: TProgressSchema, resultSchema: TResultSchema);
663
+ private lastParseError;
664
+ /**
665
+ * Runs the pattern within an existing session. Use this for composing
666
+ * multiple patterns or when you need fine-grained control over the session.
667
+ *
668
+ * @param session - The streaming session to run within
669
+ * @param options - Stream options including:
670
+ * - `stopWhen` - Additional stop conditions (combined with default `hasToolCall('submitResult')`)
671
+ * - `protocol` - Custom protocol instructions (replaces default `TOOL_CALLING_PROTOCOL`)
672
+ * - All other `streamText` options except `tools`, `toolChoice`, `stopWhen`
673
+ *
674
+ * @example Basic usage
675
+ * ```typescript
676
+ * provider.streamingExecution(async function*(session) {
677
+ * yield* pattern.runInSession(session, {
678
+ * system: 'You are an analyzer.',
679
+ * messages: [{ role: 'user', content: 'Analyze...' }],
680
+ * });
681
+ * });
682
+ * ```
683
+ *
684
+ * @example With custom stopWhen
685
+ * ```typescript
686
+ * yield* pattern.runInSession(session, {
687
+ * prompt: 'Analyze...',
688
+ * stopWhen: stepCountIs(5), // Combined: submitResult OR 5 steps
689
+ * });
690
+ * ```
691
+ */
692
+ runInSession<TUserTools extends ToolSet = {}>(session: StreamingSession<TEvent>, options: ProgressiveStreamOptions<TUserTools>): AsyncGenerator<SessionEvent<TEvent>, SessionEvent<TEvent>, undefined>;
693
+ /**
694
+ * Standalone execution that creates a new session internally.
695
+ * Use this for simple, single-pattern executions.
696
+ *
697
+ * @param provider - The AI provider to use
698
+ * @param options - Stream options including:
699
+ * - `stopWhen` - Additional stop conditions (combined with default `hasToolCall('submitResult')`)
700
+ * - `protocol` - Custom protocol instructions (replaces default `TOOL_CALLING_PROTOCOL`)
701
+ *
702
+ * @example Basic usage
703
+ * ```typescript
704
+ * for await (const event of pattern.run(provider, {
705
+ * system: 'You are an analyzer.',
706
+ * prompt: 'Analyze this document...',
707
+ * })) {
708
+ * if (event.type === 'progress') {
709
+ * console.log('Progress:', event.data);
710
+ * } else if (event.type === 'complete') {
711
+ * console.log('Result:', event.data);
712
+ * }
713
+ * }
714
+ * ```
715
+ *
716
+ * @example With step limit
717
+ * ```typescript
718
+ * import { stepCountIs } from 'ai';
719
+ *
720
+ * for await (const event of pattern.run(provider, {
721
+ * prompt: 'Analyze...',
722
+ * stopWhen: stepCountIs(10),
723
+ * })) { ... }
724
+ * ```
725
+ */
726
+ run<TUserTools extends ToolSet = {}>(provider: BaseProvider, options: ProgressiveStreamOptions<TUserTools>): AsyncIterable<SessionEvent<TEvent | ErrorEvent>>;
727
+ private createTools;
728
+ private parseJsonWrapper;
729
+ private parseProgressInput;
730
+ private parseResultInput;
731
+ private combineStopConditions;
732
+ private renderSystemPrompt;
733
+ }
734
+
735
+ /**
736
+ * Prompt module types for @agtlantis/core.
737
+ *
738
+ * Provides structured prompt management with versioning, templating, and repository abstraction.
739
+ */
740
+ /**
741
+ * Raw prompt template data as stored in the repository.
742
+ * This is the serialized form before template compilation.
743
+ *
744
+ * @example
745
+ * ```typescript
746
+ * const data: PromptTemplateData = {
747
+ * id: 'greeting',
748
+ * version: '1.0.0',
749
+ * system: 'You are a helpful assistant.',
750
+ * userTemplate: 'Hello, {{name}}!',
751
+ * };
752
+ * ```
753
+ */
754
+ interface PromptTemplateData {
755
+ /** Unique identifier for the prompt */
756
+ id: string;
757
+ /** Semantic version string (e.g., '1.0.0') */
758
+ version: string;
759
+ /** System prompt template (Handlebars syntax) */
760
+ system: string;
761
+ /** User prompt template (Handlebars syntax) */
762
+ userTemplate: string;
763
+ }
764
+ /**
765
+ * Compiled prompt renderer with template functions.
766
+ * Created from PromptTemplate.compile() after Handlebars compilation.
767
+ *
768
+ * @typeParam TSystemInput - Type of the input object for system prompt rendering
769
+ * @typeParam TUserInput - Type of the input object for user prompt rendering
770
+ *
771
+ * @example
772
+ * ```typescript
773
+ * interface SessionContext {
774
+ * studentName: string;
775
+ * }
776
+ * interface TurnContext {
777
+ * previousAnswers: string[];
778
+ * }
779
+ *
780
+ * const renderer: PromptRenderer<SessionContext, TurnContext> = template.compile();
781
+ *
782
+ * const systemPrompt = renderer.renderSystemPrompt({ studentName: 'Kim' });
783
+ * const userPrompt = renderer.renderUserPrompt({ previousAnswers: ['A', 'B'] });
784
+ * ```
785
+ */
786
+ interface PromptRenderer<TSystemInput = unknown, TUserInput = unknown> {
787
+ /** Unique identifier for the prompt */
788
+ id: string;
789
+ /** Semantic version string (e.g., '1.0.0') */
790
+ version: string;
791
+ /** Compiled template function that renders the system prompt */
792
+ renderSystemPrompt: (input: TSystemInput) => string;
793
+ /** Compiled template function that renders the user prompt */
794
+ renderUserPrompt: (input: TUserInput) => string;
795
+ }
796
+ /**
797
+ * Repository interface for prompt storage operations.
798
+ * Implementations can use file system, database, or other storage backends.
799
+ *
800
+ * @example
801
+ * ```typescript
802
+ * import { createFilePromptRepository, PromptTemplate } from '@agtlantis/core';
803
+ *
804
+ * const repo = createFilePromptRepository({ directory: './prompts' });
805
+ *
806
+ * // Read latest version
807
+ * const data = await repo.read('greeting');
808
+ * const renderer = PromptTemplate.from(data).compile<SessionCtx, TurnCtx>();
809
+ *
810
+ * // Read specific version
811
+ * const v1Data = await repo.read('greeting', '1.0.0');
812
+ *
813
+ * // Write new prompt
814
+ * await repo.write({
815
+ * id: 'greeting',
816
+ * version: '2.0.0',
817
+ * system: 'You are a friendly assistant.',
818
+ * userTemplate: 'Hi {{name}}! How are you?',
819
+ * });
820
+ * ```
821
+ */
822
+ interface PromptRepository {
823
+ /**
824
+ * Reads raw prompt template data from the repository.
825
+ *
826
+ * @param id - Prompt identifier
827
+ * @param version - Optional specific version. If omitted, returns the latest version.
828
+ * @returns Raw prompt template data
829
+ * @throws {PromptNotFoundError} If prompt with given id (and version) doesn't exist
830
+ * @throws {PromptInvalidFormatError} If prompt file has invalid format
831
+ */
832
+ read(id: string, version?: string): Promise<PromptTemplateData>;
833
+ /**
834
+ * Writes a prompt to the repository.
835
+ *
836
+ * @param content - Raw prompt template data to store
837
+ * @throws {PromptIOError} If write operation fails
838
+ */
839
+ write(content: PromptTemplateData): Promise<void>;
840
+ }
841
+ /**
842
+ * Minimal file system interface for repository operations.
843
+ * Abstracts Node.js fs/promises for easier testing and potential browser compatibility.
844
+ *
845
+ * @example
846
+ * ```typescript
847
+ * // Use default Node.js implementation
848
+ * const repo = createFilePromptRepository({ directory: './prompts' });
849
+ *
850
+ * // Use custom implementation for testing
851
+ * const mockFs: FileSystem = {
852
+ * readFile: async (path) => mockFiles[path],
853
+ * writeFile: async (path, content) => { mockFiles[path] = content; },
854
+ * readdir: async (path) => Object.keys(mockFiles),
855
+ * };
856
+ * const repo = createFilePromptRepository({ directory: './prompts', fs: mockFs });
857
+ * ```
858
+ */
859
+ interface FileSystem {
860
+ /**
861
+ * Reads file content as UTF-8 string.
862
+ * @param path - Absolute or relative file path
863
+ * @returns File content as string
864
+ * @throws If file doesn't exist or read fails
865
+ */
866
+ readFile(path: string): Promise<string>;
867
+ /**
868
+ * Writes content to a file (creates or overwrites).
869
+ * @param path - Absolute or relative file path
870
+ * @param content - Content to write
871
+ * @throws If write operation fails
872
+ */
873
+ writeFile(path: string, content: string): Promise<void>;
874
+ /**
875
+ * Lists files in a directory.
876
+ * @param path - Directory path
877
+ * @returns Array of file/directory names (not full paths)
878
+ * @throws If directory doesn't exist or read fails
879
+ */
880
+ readdir(path: string): Promise<string[]>;
881
+ }
882
+
883
+ /**
884
+ * Prompt template with compilation capabilities.
885
+ *
886
+ * Use `PromptTemplate.from()` to create from raw data, then call `compile()`
887
+ * to get compiled template functions.
888
+ *
889
+ * @example
890
+ * ```typescript
891
+ * // From raw data
892
+ * const template = PromptTemplate.from({
893
+ * id: 'greeting',
894
+ * version: '1.0.0',
895
+ * system: 'You are helping {{studentName}}.',
896
+ * userTemplate: 'Previous answers: {{answers}}',
897
+ * });
898
+ *
899
+ * // Compile to renderer
900
+ * interface SessionCtx { studentName: string }
901
+ * interface TurnCtx { answers: string[] }
902
+ *
903
+ * const renderer = template.compile<SessionCtx, TurnCtx>();
904
+ * const systemPrompt = renderer.renderSystemPrompt({ studentName: 'Kim' });
905
+ * const userPrompt = renderer.renderUserPrompt({ answers: ['A', 'B'] });
906
+ * ```
907
+ */
908
+ declare class PromptTemplate implements PromptTemplateData {
909
+ readonly id: string;
910
+ readonly version: string;
911
+ readonly system: string;
912
+ readonly userTemplate: string;
913
+ private constructor();
914
+ /**
915
+ * Creates a PromptTemplate instance from raw data.
916
+ *
917
+ * @param data - Raw prompt template data
918
+ * @returns PromptTemplate instance
919
+ */
920
+ static from(data: PromptTemplateData): PromptTemplate;
921
+ /**
922
+ * Compiles templates and returns a PromptRenderer.
923
+ *
924
+ * @typeParam TSystemInput - Type of input for system prompt template
925
+ * @typeParam TUserInput - Type of input for user prompt template (defaults to TSystemInput)
926
+ * @returns Compiled prompt renderer with renderSystemPrompt and renderUserPrompt functions
927
+ * @throws {PromptTemplateError} If template compilation fails
928
+ *
929
+ * @example
930
+ * ```typescript
931
+ * // Different input types for system and user prompts
932
+ * const renderer = template.compile<SessionCtx, TurnCtx>();
933
+ *
934
+ * // Same input type for both
935
+ * const simpleRenderer = template.compile<CommonCtx>();
936
+ * ```
937
+ */
938
+ compile<TSystemInput = unknown, TUserInput = TSystemInput>(): PromptRenderer<TSystemInput, TUserInput>;
939
+ /**
940
+ * Returns raw data representation.
941
+ * Useful for serialization or passing to repository.write().
942
+ */
943
+ toData(): PromptTemplateData;
944
+ }
945
+
946
+ /**
947
+ * Prompt module error classes for @agtlantis/core.
948
+ *
949
+ * Each error type has a specific code and context for precise error handling.
950
+ */
951
+
952
+ declare enum PromptErrorCode {
953
+ /** Generic prompt error */
954
+ PROMPT_ERROR = "PROMPT_ERROR",
955
+ /** Prompt not found in repository */
956
+ NOT_FOUND = "PROMPT_NOT_FOUND",
957
+ /** Invalid prompt file format (e.g., malformed YAML) */
958
+ INVALID_FORMAT = "PROMPT_INVALID_FORMAT",
959
+ /** Template compilation failed */
960
+ TEMPLATE_ERROR = "PROMPT_TEMPLATE_ERROR",
961
+ /** File I/O operation failed */
962
+ IO_ERROR = "PROMPT_IO_ERROR"
963
+ }
964
+ declare module '../errors' {
965
+ interface AgtlantisErrorCodeMap {
966
+ prompt: PromptErrorCode;
967
+ }
968
+ }
969
+ interface PromptErrorOptions {
970
+ code?: PromptErrorCode;
971
+ cause?: Error;
972
+ context?: Record<string, unknown>;
973
+ }
974
+ /**
975
+ * Base error class for prompt operations.
976
+ * Use specific error subclasses for more precise error handling.
977
+ *
978
+ * @example
979
+ * ```typescript
980
+ * throw new PromptError('Something went wrong', {
981
+ * code: PromptErrorCode.PROMPT_ERROR,
982
+ * context: { promptId: 'greeting' }
983
+ * });
984
+ * ```
985
+ */
986
+ declare class PromptError extends AgtlantisError<PromptErrorCode & AgtlantisErrorCode> {
987
+ constructor(message: string, options?: PromptErrorOptions);
988
+ /**
989
+ * Creates a PromptError from an unknown error.
990
+ */
991
+ static from(error: unknown, code?: PromptErrorCode, context?: Record<string, unknown>): PromptError;
992
+ }
993
+ /**
994
+ * Error thrown when a prompt is not found in the repository.
995
+ *
996
+ * @example
997
+ * ```typescript
998
+ * throw new PromptNotFoundError('greeting', '1.0.0');
999
+ * // Error: Prompt 'greeting' version '1.0.0' not found
1000
+ *
1001
+ * throw new PromptNotFoundError('greeting');
1002
+ * // Error: Prompt 'greeting' not found
1003
+ * ```
1004
+ */
1005
+ declare class PromptNotFoundError extends PromptError {
1006
+ readonly promptId: string;
1007
+ readonly version?: string;
1008
+ constructor(promptId: string, version?: string, options?: Omit<PromptErrorOptions, 'code'>);
1009
+ }
1010
+ /**
1011
+ * Error thrown when a prompt file has invalid format.
1012
+ * Examples: malformed YAML, missing required fields, invalid schema.
1013
+ *
1014
+ * @example
1015
+ * ```typescript
1016
+ * throw new PromptInvalidFormatError('greeting', 'Missing required field: system');
1017
+ * // Error: Invalid format for prompt 'greeting': Missing required field: system
1018
+ * ```
1019
+ */
1020
+ declare class PromptInvalidFormatError extends PromptError {
1021
+ readonly promptId: string;
1022
+ readonly details: string;
1023
+ constructor(promptId: string, details: string, options?: Omit<PromptErrorOptions, 'code'>);
1024
+ }
1025
+ /**
1026
+ * Error thrown when template compilation fails.
1027
+ * Examples: invalid Handlebars syntax, missing helper.
1028
+ *
1029
+ * @example
1030
+ * ```typescript
1031
+ * throw new PromptTemplateError('greeting', 'Unexpected token {{/if}}');
1032
+ * // Error: Template compilation failed for prompt 'greeting': Unexpected token {{/if}}
1033
+ * ```
1034
+ */
1035
+ declare class PromptTemplateError extends PromptError {
1036
+ readonly promptId: string;
1037
+ readonly details: string;
1038
+ constructor(promptId: string, details: string, options?: Omit<PromptErrorOptions, 'code'>);
1039
+ }
1040
+ /**
1041
+ * Error thrown when file I/O operations fail.
1042
+ * Examples: read failure, write failure, directory access denied.
1043
+ *
1044
+ * @example
1045
+ * ```typescript
1046
+ * throw new PromptIOError('read', '/path/to/prompt.yaml', {
1047
+ * cause: originalError
1048
+ * });
1049
+ * // Error: Failed to read prompt file: /path/to/prompt.yaml
1050
+ * ```
1051
+ */
1052
+ declare class PromptIOError extends PromptError {
1053
+ readonly operation: 'read' | 'write' | 'list';
1054
+ readonly path: string;
1055
+ constructor(operation: 'read' | 'write' | 'list', path: string, options?: Omit<PromptErrorOptions, 'code'>);
1056
+ }
1057
+
1058
+ /**
1059
+ * Template engine for prompt compilation.
1060
+ *
1061
+ * Uses Handlebars for template rendering with custom helpers.
1062
+ */
1063
+ /**
1064
+ * Compiles a Handlebars template string into a render function.
1065
+ *
1066
+ * @typeParam TInput - Type of the input object for template rendering
1067
+ * @param template - Handlebars template string
1068
+ * @param promptId - Prompt ID for error context
1069
+ * @returns Compiled template function
1070
+ * @throws {PromptTemplateError} If template compilation fails
1071
+ *
1072
+ * @example
1073
+ * ```typescript
1074
+ * const render = compileTemplate<{ name: string }>('Hello, {{name}}!', 'greeting');
1075
+ * const result = render({ name: 'World' });
1076
+ * // => 'Hello, World!'
1077
+ * ```
1078
+ */
1079
+ declare function compileTemplate<TInput>(template: string, promptId: string): (input: TInput) => string;
1080
+
1081
+ /**
1082
+ * File-based prompt repository implementation.
1083
+ *
1084
+ * Stores prompts as YAML files with naming convention: {id}-{version}.yaml
1085
+ */
1086
+
1087
+ interface FilePromptRepositoryOptions {
1088
+ /** Directory path where prompt files are stored */
1089
+ directory: string;
1090
+ /** Optional custom file system implementation (defaults to Node.js fs) */
1091
+ fs?: FileSystem;
1092
+ /** Enable in-memory caching for read operations (defaults to true) */
1093
+ cache?: boolean;
1094
+ }
1095
+ /**
1096
+ * File-based prompt repository.
1097
+ *
1098
+ * Prompts are stored as YAML files with naming convention: {id}-{version}.yaml
1099
+ *
1100
+ * Can be subclassed to customize parsing/serialization (e.g., JSON instead of YAML).
1101
+ *
1102
+ * @example
1103
+ * ```typescript
1104
+ * const repo = new FilePromptRepository({ directory: './prompts' });
1105
+ *
1106
+ * // Read latest version
1107
+ * const prompt = await repo.read<GreetingInput>('greeting');
1108
+ *
1109
+ * // Subclass to use JSON format
1110
+ * class JsonPromptRepository extends FilePromptRepository {
1111
+ * protected parseContent(content: string, promptId: string): PromptTemplateData {
1112
+ * return JSON.parse(content);
1113
+ * }
1114
+ * protected serializeContent(content: PromptTemplateData): string {
1115
+ * return JSON.stringify(content, null, 2);
1116
+ * }
1117
+ * }
1118
+ * ```
1119
+ */
1120
+ declare class FilePromptRepository implements PromptRepository {
1121
+ protected readonly directory: string;
1122
+ protected readonly fileSystem: FileSystem;
1123
+ protected readonly cacheEnabled: boolean;
1124
+ private readonly contentCache;
1125
+ constructor(options: FilePromptRepositoryOptions);
1126
+ /**
1127
+ * Generates file name from prompt id and version.
1128
+ * Override this along with `parseFileName` to change file naming convention.
1129
+ */
1130
+ protected getFileName(id: string, version: string): string;
1131
+ /**
1132
+ * Parses file name into id and version.
1133
+ * Override this along with `getFileName` to change file naming convention.
1134
+ */
1135
+ protected parseFileName(fileName: string): {
1136
+ id: string;
1137
+ version: string;
1138
+ } | null;
1139
+ /**
1140
+ * Parses raw file content into PromptTemplateData.
1141
+ * Override this to support different file formats (e.g., JSON, TOML).
1142
+ */
1143
+ protected parseContent(content: string, promptId: string): PromptTemplateData;
1144
+ /**
1145
+ * Serializes PromptTemplateData to file content string.
1146
+ * Override this to support different file formats (e.g., JSON, TOML).
1147
+ */
1148
+ protected serializeContent(content: PromptTemplateData): string;
1149
+ private getCacheKey;
1150
+ read(id: string, version?: string): Promise<PromptTemplateData>;
1151
+ write(content: PromptTemplateData): Promise<void>;
1152
+ }
1153
+ /**
1154
+ * Creates a file-based prompt repository.
1155
+ *
1156
+ * This is a convenience factory function. For subclassing, use `FilePromptRepository` class directly.
1157
+ *
1158
+ * @example
1159
+ * ```typescript
1160
+ * const repo = createFilePromptRepository({ directory: './prompts' });
1161
+ * const prompt = await repo.read<GreetingInput>('greeting');
1162
+ * ```
1163
+ */
1164
+ declare function createFilePromptRepository(options: FilePromptRepositoryOptions): PromptRepository;
1165
+
1166
+ declare function computeFileSourceHash(source: FileSource): Promise<string>;
1167
+
1168
+ interface InMemoryFileCacheOptions {
1169
+ defaultTTL?: number;
1170
+ }
1171
+ declare class InMemoryFileCache implements FileCache {
1172
+ private readonly cache;
1173
+ private readonly defaultTTL;
1174
+ constructor(options?: InMemoryFileCacheOptions);
1175
+ get(hash: string): UploadedFile | null;
1176
+ set(hash: string, file: UploadedFile, ttl?: number): void;
1177
+ delete(hash: string): void;
1178
+ clear(): void;
1179
+ }
1180
+
1181
+ /** FileManager for providers without file upload support (throws on upload/delete) */
1182
+ declare class NoOpFileManager implements FileManager {
1183
+ upload(_files: FileSource[]): Promise<UploadedFile[]>;
1184
+ delete(_fileId: string): Promise<void>;
1185
+ clear(): Promise<void>;
1186
+ getUploadedFiles(): UploadedFile[];
1187
+ }
1188
+
1189
+ declare const EXTENSION_TO_MIME: Record<string, string>;
1190
+ /** Infers MIME type from file extension (case-insensitive) */
1191
+ declare function inferMediaType(filePath: string): string | undefined;
1192
+ interface FoundFileSource {
1193
+ part: FileSource;
1194
+ path: (string | number)[];
1195
+ }
1196
+ /** Recursively scans an input for FileSources and returns them with their JSON paths */
1197
+ declare function scanForFileSources(input: unknown, currentPath?: (string | number)[]): FoundFileSource[];
1198
+ interface ResolveOptions {
1199
+ basePath?: string;
1200
+ maxSize?: number;
1201
+ }
1202
+ declare const DEFAULT_MAX_SIZE: number;
1203
+ /**
1204
+ * Resolves a FileSource to AI SDK compatible format.
1205
+ * Path-based parts are read into Buffer; others returned unchanged.
1206
+ */
1207
+ declare function resolveFileSource(part: FileSource, options?: ResolveOptions): Promise<FileSource>;
1208
+ /** Resolves all FileSources in an input (returns new object, original unchanged) */
1209
+ declare function resolveFileSourcesInInput<T>(input: T, options?: ResolveOptions): Promise<T>;
1210
+ interface FileSourceDisplayInfo {
1211
+ source: FileSource['source'];
1212
+ description: string;
1213
+ mediaType: string;
1214
+ filename?: string;
1215
+ }
1216
+ /** Extracts display info from a FileSource for reporting (excludes raw data) */
1217
+ declare function getFileSourceDisplayInfo(part: FileSource): FileSourceDisplayInfo;
1218
+ declare function getFileSourcesDisplayInfo(input: unknown): FileSourceDisplayInfo[];
1219
+
1220
+ type HarmCategory = 'HARM_CATEGORY_HATE_SPEECH' | 'HARM_CATEGORY_SEXUALLY_EXPLICIT' | 'HARM_CATEGORY_DANGEROUS_CONTENT' | 'HARM_CATEGORY_HARASSMENT' | 'HARM_CATEGORY_CIVIC_INTEGRITY';
1221
+ type HarmBlockThreshold = 'BLOCK_NONE' | 'BLOCK_ONLY_HIGH' | 'BLOCK_MEDIUM_AND_ABOVE' | 'BLOCK_LOW_AND_ABOVE' | 'OFF';
1222
+ interface SafetySetting {
1223
+ category: HarmCategory;
1224
+ threshold: HarmBlockThreshold;
1225
+ }
1226
+ interface GoogleProviderConfig {
1227
+ apiKey: string;
1228
+ safetySettings?: SafetySetting[];
1229
+ }
1230
+ declare class GoogleProvider extends BaseProvider {
1231
+ private readonly apiKey;
1232
+ private readonly defaultModelId;
1233
+ private readonly logger;
1234
+ private readonly safetySettings?;
1235
+ private readonly pricingConfig?;
1236
+ private readonly defaultOptions?;
1237
+ private readonly searchEnabled;
1238
+ private readonly urlContextEnabled;
1239
+ private readonly fileCache?;
1240
+ private readonly google;
1241
+ constructor(apiKey: string, defaultModelId: string | null, logger: Logger, safetySettings?: SafetySetting[] | undefined, pricingConfig?: ProviderPricing | undefined, defaultOptions?: GoogleGenerativeAIProviderOptions | undefined, searchEnabled?: boolean, urlContextEnabled?: boolean, fileCache?: FileCache | undefined);
1242
+ withDefaultModel(modelId: string): GoogleProvider;
1243
+ withLogger(newLogger: Logger): GoogleProvider;
1244
+ withPricing(pricing: ProviderPricing): GoogleProvider;
1245
+ /**
1246
+ * Set default provider-specific options for all LLM calls.
1247
+ * These options will be deep-merged with per-call providerOptions.
1248
+ *
1249
+ * @example
1250
+ * ```typescript
1251
+ * createGoogleProvider({ apiKey: 'xxx' })
1252
+ * .withDefaultModel('gemini-2.0-flash-thinking-exp')
1253
+ * .withDefaultOptions({
1254
+ * thinkingConfig: { includeThoughts: true, thinkingLevel: 'low' }
1255
+ * })
1256
+ * ```
1257
+ */
1258
+ withDefaultOptions(options: GoogleGenerativeAIProviderOptions): GoogleProvider;
1259
+ /**
1260
+ * Enable Google Search grounding for all LLM calls.
1261
+ * Allows the model to access real-time web information.
1262
+ *
1263
+ * @example
1264
+ * ```typescript
1265
+ * createGoogleProvider({ apiKey: 'xxx' })
1266
+ * .withDefaultModel('gemini-2.5-flash')
1267
+ * .withSearchEnabled()
1268
+ * ```
1269
+ */
1270
+ withSearchEnabled(): GoogleProvider;
1271
+ /**
1272
+ * Enable URL Context grounding for all LLM calls.
1273
+ * Allows the model to retrieve and use content from URLs in the prompt.
1274
+ *
1275
+ * @example
1276
+ * ```typescript
1277
+ * createGoogleProvider({ apiKey: 'xxx' })
1278
+ * .withDefaultModel('gemini-2.5-flash')
1279
+ * .withUrlContextEnabled()
1280
+ * ```
1281
+ */
1282
+ withUrlContextEnabled(): GoogleProvider;
1283
+ /**
1284
+ * Set a file cache for reusing uploaded files across sessions.
1285
+ * If no cache is provided, creates a new InMemoryFileCache.
1286
+ *
1287
+ * @example
1288
+ * ```typescript
1289
+ * // Use default InMemoryFileCache
1290
+ * createGoogleProvider({ apiKey: 'xxx' })
1291
+ * .withFileCache()
1292
+ *
1293
+ * // Use custom cache with TTL
1294
+ * const cache = new InMemoryFileCache({ defaultTTL: 3600000 });
1295
+ * createGoogleProvider({ apiKey: 'xxx' })
1296
+ * .withFileCache(cache)
1297
+ * ```
1298
+ */
1299
+ withFileCache(cache?: FileCache): GoogleProvider;
1300
+ private getSessionConfig;
1301
+ protected createStreamingSession<TEvent extends {
1302
+ type: string;
1303
+ }>(signal?: AbortSignal): StreamingSession<TEvent>;
1304
+ protected createSimpleSession(signal?: AbortSignal): SimpleSession;
1305
+ /**
1306
+ * Type assertion needed because @ai-sdk/google's type signature doesn't
1307
+ * include the second parameter, but it's supported at runtime.
1308
+ */
1309
+ private createModel;
1310
+ }
1311
+ declare function createGoogleProvider(config: GoogleProviderConfig): GoogleProvider;
1312
+
1313
+ /** Google GenAI File API implementation with automatic session cleanup */
1314
+ declare class GoogleFileManager implements FileManager {
1315
+ private uploadedFiles;
1316
+ private client;
1317
+ private cache;
1318
+ constructor(apiKey: string, options?: FileManagerOptions);
1319
+ private uploadOne;
1320
+ upload(files: FileSource[]): Promise<UploadedFile[]>;
1321
+ delete(fileId: string): Promise<void>;
1322
+ clear(): Promise<void>;
1323
+ getUploadedFiles(): UploadedFile[];
1324
+ }
1325
+
1326
+ interface OpenAIProviderConfig {
1327
+ apiKey: string;
1328
+ baseURL?: string;
1329
+ organization?: string;
1330
+ }
1331
+ declare class OpenAIProvider extends BaseProvider {
1332
+ private readonly apiKey;
1333
+ private readonly defaultModelId;
1334
+ private readonly logger;
1335
+ private readonly baseURL?;
1336
+ private readonly organization?;
1337
+ private readonly pricingConfig?;
1338
+ private readonly defaultOptions?;
1339
+ private readonly fileCache?;
1340
+ private readonly openai;
1341
+ constructor(apiKey: string, defaultModelId: string | null, logger: Logger, baseURL?: string | undefined, organization?: string | undefined, pricingConfig?: ProviderPricing | undefined, defaultOptions?: OpenAIChatLanguageModelOptions | undefined, fileCache?: FileCache | undefined);
1342
+ withDefaultModel(modelId: string): OpenAIProvider;
1343
+ withLogger(newLogger: Logger): OpenAIProvider;
1344
+ withPricing(pricing: ProviderPricing): OpenAIProvider;
1345
+ /**
1346
+ * Set default provider-specific options for all LLM calls.
1347
+ * These options will be deep-merged with per-call providerOptions.
1348
+ *
1349
+ * @example
1350
+ * ```typescript
1351
+ * createOpenAIProvider({ apiKey: 'xxx' })
1352
+ * .withDefaultModel('gpt-4o')
1353
+ * .withDefaultOptions({
1354
+ * reasoningEffort: 'high',
1355
+ * parallelToolCalls: true,
1356
+ * })
1357
+ * ```
1358
+ */
1359
+ withDefaultOptions(options: OpenAIChatLanguageModelOptions): OpenAIProvider;
1360
+ /**
1361
+ * Set a file cache for API consistency with GoogleProvider.
1362
+ * Note: OpenAI does not support file caching, so this is a no-op.
1363
+ *
1364
+ * @example
1365
+ * ```typescript
1366
+ * createOpenAIProvider({ apiKey: 'xxx' })
1367
+ * .withFileCache()
1368
+ * ```
1369
+ */
1370
+ withFileCache(cache?: FileCache): OpenAIProvider;
1371
+ private getSessionConfig;
1372
+ protected createStreamingSession<TEvent extends {
1373
+ type: string;
1374
+ }>(signal?: AbortSignal): StreamingSession<TEvent>;
1375
+ protected createSimpleSession(signal?: AbortSignal): SimpleSession;
1376
+ }
1377
+ declare function createOpenAIProvider(config: OpenAIProviderConfig): OpenAIProvider;
1378
+
1379
+ interface ValidationResult {
1380
+ valid: boolean;
1381
+ reason?: string;
1382
+ }
1383
+ interface ValidationAttempt<TResult> extends ValidationResult {
1384
+ result: TResult;
1385
+ attempt: number;
1386
+ }
1387
+ interface ReadonlyValidationHistory<TResult> {
1388
+ /** 1-based attempt number for the next attempt. */
1389
+ readonly nextAttempt: number;
1390
+ /** Last validation attempt, or undefined if no attempts yet. */
1391
+ readonly last: ValidationAttempt<TResult> | undefined;
1392
+ /** All validation attempts as a readonly array. */
1393
+ readonly all: readonly ValidationAttempt<TResult>[];
1394
+ /** Reasons from all failed attempts. */
1395
+ readonly failureReasons: string[];
1396
+ /** True if at least one previous attempt exists. */
1397
+ readonly isRetry: boolean;
1398
+ }
1399
+ interface ValidationOptions<TResult> {
1400
+ /**
1401
+ * Validation function that checks the result.
1402
+ * Can access history to compare with previous attempts.
1403
+ */
1404
+ validate: (result: TResult, history: ReadonlyValidationHistory<TResult>) => ValidationResult | Promise<ValidationResult>;
1405
+ /**
1406
+ * Maximum number of attempts before throwing ValidationExhaustedError.
1407
+ * @default 3
1408
+ * @minimum 1
1409
+ */
1410
+ maxAttempts?: number;
1411
+ /**
1412
+ * AbortSignal for cancellation support.
1413
+ * When aborted, throws the abort reason before the next attempt.
1414
+ */
1415
+ signal?: AbortSignal;
1416
+ /**
1417
+ * Delay between retry attempts in milliseconds.
1418
+ * Only applied when there will be another attempt after a failure.
1419
+ */
1420
+ retryDelay?: number;
1421
+ /**
1422
+ * Callback invoked after each attempt (success or failure).
1423
+ * Useful for logging or progress tracking.
1424
+ */
1425
+ onAttempt?: (attempt: ValidationAttempt<TResult>) => void;
1426
+ }
1427
+
1428
+ declare class ValidationHistory<TResult> implements ReadonlyValidationHistory<TResult> {
1429
+ private attempts;
1430
+ get nextAttempt(): number;
1431
+ get last(): ValidationAttempt<TResult> | undefined;
1432
+ get all(): readonly ValidationAttempt<TResult>[];
1433
+ get failureReasons(): string[];
1434
+ get isRetry(): boolean;
1435
+ /** Internal use only - not exposed via ReadonlyValidationHistory. */
1436
+ add(result: TResult, validation: ValidationResult): void;
1437
+ }
1438
+
1439
+ declare enum ValidationErrorCode {
1440
+ VALIDATION_EXHAUSTED = "VALIDATION_EXHAUSTED"
1441
+ }
1442
+ /**
1443
+ * Error thrown when validation fails after all attempts are exhausted.
1444
+ * Contains the full validation history for debugging and partial result recovery.
1445
+ *
1446
+ * @example
1447
+ * ```typescript
1448
+ * try {
1449
+ * const result = await withValidation(execute, options);
1450
+ * } catch (e) {
1451
+ * if (e instanceof ValidationExhaustedError) {
1452
+ * console.log(`Failed after ${e.history.all.length} attempts`);
1453
+ * console.log('Last result:', e.history.last?.result);
1454
+ * console.log('All failures:', e.history.failureReasons);
1455
+ * console.log('Error code:', e.code); // 'VALIDATION_EXHAUSTED'
1456
+ * }
1457
+ * }
1458
+ * ```
1459
+ */
1460
+ declare class ValidationExhaustedError<TResult> extends AgtlantisError<ValidationErrorCode & AgtlantisErrorCode> {
1461
+ readonly history: ReadonlyValidationHistory<TResult>;
1462
+ constructor(message: string, history: ReadonlyValidationHistory<TResult>);
1463
+ }
1464
+
1465
+ /**
1466
+ * Wraps an async operation with validation and retry logic.
1467
+ *
1468
+ * Executes the function and validates the result. If validation fails,
1469
+ * retries up to maxAttempts times, passing the history to the execute
1470
+ * function so it can adjust its approach based on previous failures.
1471
+ *
1472
+ * @param execute - Function to execute. Receives history for retry context.
1473
+ * @param options - Validation options including the validate function.
1474
+ * @returns The first result that passes validation.
1475
+ * @throws {ValidationExhaustedError} If all attempts fail validation.
1476
+ *
1477
+ * @example
1478
+ * ```typescript
1479
+ * const result = await withValidation(
1480
+ * (history) => session.generateText({
1481
+ * messages: [
1482
+ * { role: 'user', content: prompt },
1483
+ * ...(history.isRetry ? [{
1484
+ * role: 'user' as const,
1485
+ * content: `Fix: ${history.last!.reason}`,
1486
+ * }] : []),
1487
+ * ],
1488
+ * schema,
1489
+ * }),
1490
+ * {
1491
+ * validate: (result) => ({
1492
+ * valid: result.confidence > 0.8,
1493
+ * reason: `Confidence ${result.confidence} below 0.8`,
1494
+ * }),
1495
+ * maxAttempts: 3,
1496
+ * }
1497
+ * );
1498
+ * ```
1499
+ */
1500
+ declare function withValidation<TResult>(execute: (history: ReadonlyValidationHistory<NoInfer<TResult>>) => Promise<TResult>, options: ValidationOptions<NoInfer<TResult>>): Promise<TResult>;
1501
+
1502
+ export { ANTHROPIC_PRICING, AgtlantisError, type AgtlantisErrorCode, type AgtlantisErrorOptions, BaseProvider, CalculateCostParams, type CompleteEvent, CompletionEvent, ConfigurationError, ConfigurationErrorCode, type ConfigurationErrorOptions, CostResult, DEFAULT_FALLBACK_PRICING, DEFAULT_MAX_SIZE, DEFAULT_PRICING_CONFIG, ERRORS, EXTENSION_TO_MIME, type EffectivePricingResult, ErrorEvent, ExecutionError, ExecutionErrorCode, type ExecutionErrorOptions, ExecutionStatus, ExtractResult, FileCache, FileError, FileErrorCode, type FileErrorOptions, FileManager, FileManagerOptions, FilePromptRepository, type FilePromptRepositoryOptions, FileSource, type FileSourceDisplayInfo, type FileSystem, type FoundFileSource, GOOGLE_PRICING, GoogleFileManager, GoogleProvider, type GoogleProviderConfig, type HarmBlockThreshold, type HarmCategory, type HookRunner, InMemoryFileCache, type InMemoryFileCacheOptions, Logger, ModelPricing, NoOpFileManager, OPENAI_PRICING, type OpenAIProviderConfig, PricingConfig, type PricingSource, type ProgressEvent, ProgressivePattern, type ProgressiveStreamOptions, PromptError, PromptErrorCode, type PromptErrorOptions, PromptIOError, PromptInvalidFormatError, PromptNotFoundError, type PromptRenderer, type PromptRepository, PromptTemplate, type PromptTemplateData, PromptTemplateError, ProviderPricing, ProviderType, type ReadonlyValidationHistory, type ReplaceResult, type ResolveOptions, type SafetySetting, SessionEvent, SessionStreamGeneratorFn, SimpleExecution, SimpleExecutionHost, SimpleResult, SimpleSession, StreamTextParams, StreamingExecution, StreamingExecutionHost, StreamingResult, StreamingSession, TOOL_CALLING_PROTOCOL, UploadedFile, type ValidationAttempt, ValidationErrorCode, ValidationExhaustedError, ValidationHistory, type ValidationOptions, type ValidationResult, calculateCost, calculateCostFromUsage, calculateTotalCost, combineSignals, compileTemplate, computeFileSourceHash, configurePricing, createFilePromptRepository, createGoogleProvider, createHookRunner, createOpenAIProvider, createZeroUsage, defineProgressivePattern, detectProviderType, determineResultStatus, getDuration, getEffectivePricing, getFileSourceDisplayInfo, getFileSourcesDisplayInfo, getModelPricing, getPricingConfig, inferMediaType, isAbortError, mapExecution, mapExecutionResult, mergeUsages, normalizeError, resetPricingConfig, resolveFileSource, resolveFileSourcesInInput, scanForFileSources, validateModelPricing, validatePricingConfig, validateProviderPricing, withValidation };