@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.
- package/README.md +267 -0
- package/dist/base-provider-C3mFLNiN.d.cts +1236 -0
- package/dist/base-provider-C3mFLNiN.d.ts +1236 -0
- package/dist/index.cjs +3188 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1502 -0
- package/dist/index.d.ts +1502 -0
- package/dist/index.js +3082 -0
- package/dist/index.js.map +1 -0
- package/dist/testing/index.cjs +2144 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +516 -0
- package/dist/testing/index.d.ts +516 -0
- package/dist/testing/index.js +2098 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +82 -0
package/dist/index.d.ts
ADDED
|
@@ -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.js';
|
|
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.js';
|
|
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 };
|