@falai/agent 0.3.30 → 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/dist/cjs/core/Agent.d.ts +1 -0
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +62 -2
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/ConditionEvaluator.d.ts +72 -0
- package/dist/cjs/core/ConditionEvaluator.d.ts.map +1 -0
- package/dist/cjs/core/ConditionEvaluator.js +272 -0
- package/dist/cjs/core/ConditionEvaluator.js.map +1 -0
- package/dist/cjs/core/PreparationEngine.d.ts +116 -0
- package/dist/cjs/core/PreparationEngine.d.ts.map +1 -0
- package/dist/cjs/core/PreparationEngine.js +353 -0
- package/dist/cjs/core/PreparationEngine.js.map +1 -0
- package/dist/cjs/core/Route.d.ts +6 -0
- package/dist/cjs/core/Route.d.ts.map +1 -1
- package/dist/cjs/core/Route.js +9 -0
- package/dist/cjs/core/Route.js.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.d.ts +3 -3
- package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts +3 -3
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +43 -18
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.d.ts +3 -3
- package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts +3 -3
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +3 -0
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/ai.d.ts +6 -6
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/core/Agent.d.ts +1 -0
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +62 -2
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/ConditionEvaluator.d.ts +72 -0
- package/dist/core/ConditionEvaluator.d.ts.map +1 -0
- package/dist/core/ConditionEvaluator.js +268 -0
- package/dist/core/ConditionEvaluator.js.map +1 -0
- package/dist/core/PreparationEngine.d.ts +116 -0
- package/dist/core/PreparationEngine.d.ts.map +1 -0
- package/dist/core/PreparationEngine.js +349 -0
- package/dist/core/PreparationEngine.js.map +1 -0
- package/dist/core/Route.d.ts +6 -0
- package/dist/core/Route.d.ts.map +1 -1
- package/dist/core/Route.js +9 -0
- package/dist/core/Route.js.map +1 -1
- package/dist/providers/AnthropicProvider.d.ts +3 -3
- package/dist/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts +3 -3
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +43 -18
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/OpenAIProvider.d.ts +3 -3
- package/dist/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/OpenAIProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts +3 -3
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/types/agent.d.ts +3 -0
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/ai.d.ts +6 -6
- package/dist/types/ai.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/Agent.ts +86 -2
- package/src/core/ConditionEvaluator.ts +381 -0
- package/src/core/PreparationEngine.ts +561 -0
- package/src/core/Route.ts +10 -0
- package/src/providers/AnthropicProvider.ts +51 -21
- package/src/providers/GeminiProvider.ts +86 -40
- package/src/providers/OpenAIProvider.ts +48 -21
- package/src/providers/OpenRouterProvider.ts +36 -18
- package/src/types/agent.ts +3 -0
- package/src/types/ai.ts +13 -8
|
@@ -149,24 +149,36 @@ export class AnthropicProvider implements AiProvider {
|
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
async generateMessage<
|
|
152
|
+
async generateMessage<
|
|
153
|
+
TContext = unknown,
|
|
154
|
+
TStructured = AgentStructuredResponse
|
|
155
|
+
>(
|
|
153
156
|
input: GenerateMessageInput<TContext>
|
|
154
|
-
): Promise<GenerateMessageOutput
|
|
155
|
-
return this.generateWithBackup(input);
|
|
157
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
158
|
+
return this.generateWithBackup<TContext, TStructured>(input);
|
|
156
159
|
}
|
|
157
160
|
|
|
158
|
-
async *generateMessageStream<
|
|
161
|
+
async *generateMessageStream<
|
|
162
|
+
TContext = unknown,
|
|
163
|
+
TStructured = AgentStructuredResponse
|
|
164
|
+
>(
|
|
159
165
|
input: GenerateMessageInput<TContext>
|
|
160
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
161
|
-
yield* this.generateStreamWithBackup(input);
|
|
166
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
167
|
+
yield* this.generateStreamWithBackup<TContext, TStructured>(input);
|
|
162
168
|
}
|
|
163
169
|
|
|
164
|
-
private async generateWithBackup<
|
|
170
|
+
private async generateWithBackup<
|
|
171
|
+
TContext = unknown,
|
|
172
|
+
TStructured = AgentStructuredResponse
|
|
173
|
+
>(
|
|
165
174
|
input: GenerateMessageInput<TContext>
|
|
166
|
-
): Promise<GenerateMessageOutput
|
|
175
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
167
176
|
// Try primary model first
|
|
168
177
|
try {
|
|
169
|
-
return await this.generateWithModel
|
|
178
|
+
return await this.generateWithModel<TContext, TStructured>(
|
|
179
|
+
this.primaryModel,
|
|
180
|
+
input
|
|
181
|
+
);
|
|
170
182
|
} catch (primaryError: unknown) {
|
|
171
183
|
const primaryErrMsg = getErrorMessage(primaryError);
|
|
172
184
|
console.warn(
|
|
@@ -190,7 +202,10 @@ export class AnthropicProvider implements AiProvider {
|
|
|
190
202
|
);
|
|
191
203
|
|
|
192
204
|
try {
|
|
193
|
-
const result = await this.generateWithModel
|
|
205
|
+
const result = await this.generateWithModel<TContext, TStructured>(
|
|
206
|
+
backupModel,
|
|
207
|
+
input
|
|
208
|
+
);
|
|
194
209
|
console.log(`[ANTHROPIC] Backup model ${backupModel} succeeded`);
|
|
195
210
|
return result;
|
|
196
211
|
} catch (backupError: unknown) {
|
|
@@ -220,10 +235,13 @@ export class AnthropicProvider implements AiProvider {
|
|
|
220
235
|
}
|
|
221
236
|
}
|
|
222
237
|
|
|
223
|
-
private async generateWithModel<
|
|
238
|
+
private async generateWithModel<
|
|
239
|
+
TContext = unknown,
|
|
240
|
+
TStructured = AgentStructuredResponse
|
|
241
|
+
>(
|
|
224
242
|
model: string,
|
|
225
243
|
input: GenerateMessageInput<TContext>
|
|
226
|
-
): Promise<GenerateMessageOutput
|
|
244
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
227
245
|
const operation = async (): Promise<GenerateMessageOutput> => {
|
|
228
246
|
// Anthropic requires max_tokens to be specified
|
|
229
247
|
const maxTokens = input.parameters?.maxOutputTokens || 4096;
|
|
@@ -306,15 +324,21 @@ export class AnthropicProvider implements AiProvider {
|
|
|
306
324
|
this.retryConfig.timeout,
|
|
307
325
|
this.retryConfig.retries,
|
|
308
326
|
`Anthropic ${model}`
|
|
309
|
-
)
|
|
327
|
+
) as Promise<GenerateMessageOutput<TStructured>>;
|
|
310
328
|
}
|
|
311
329
|
|
|
312
|
-
private async *generateStreamWithBackup<
|
|
330
|
+
private async *generateStreamWithBackup<
|
|
331
|
+
TContext = unknown,
|
|
332
|
+
TStructured = AgentStructuredResponse
|
|
333
|
+
>(
|
|
313
334
|
input: GenerateMessageInput<TContext>
|
|
314
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
335
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
315
336
|
// Try primary model first
|
|
316
337
|
try {
|
|
317
|
-
yield* this.generateStreamWithModel
|
|
338
|
+
yield* this.generateStreamWithModel<TContext, TStructured>(
|
|
339
|
+
this.primaryModel,
|
|
340
|
+
input
|
|
341
|
+
);
|
|
318
342
|
} catch (primaryError: unknown) {
|
|
319
343
|
const primaryErrMsg = getErrorMessage(primaryError);
|
|
320
344
|
console.warn(
|
|
@@ -338,7 +362,10 @@ export class AnthropicProvider implements AiProvider {
|
|
|
338
362
|
);
|
|
339
363
|
|
|
340
364
|
try {
|
|
341
|
-
yield* this.generateStreamWithModel
|
|
365
|
+
yield* this.generateStreamWithModel<TContext, TStructured>(
|
|
366
|
+
backupModel,
|
|
367
|
+
input
|
|
368
|
+
);
|
|
342
369
|
console.log(`[ANTHROPIC] Backup model ${backupModel} succeeded`);
|
|
343
370
|
return;
|
|
344
371
|
} catch (backupError: unknown) {
|
|
@@ -368,10 +395,13 @@ export class AnthropicProvider implements AiProvider {
|
|
|
368
395
|
}
|
|
369
396
|
}
|
|
370
397
|
|
|
371
|
-
private async *generateStreamWithModel<
|
|
398
|
+
private async *generateStreamWithModel<
|
|
399
|
+
TContext = unknown,
|
|
400
|
+
TStructured = AgentStructuredResponse
|
|
401
|
+
>(
|
|
372
402
|
model: string,
|
|
373
403
|
input: GenerateMessageInput<TContext>
|
|
374
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
404
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
375
405
|
// Anthropic requires max_tokens to be specified
|
|
376
406
|
const maxTokens = input.parameters?.maxOutputTokens || 4096;
|
|
377
407
|
|
|
@@ -428,7 +458,7 @@ export class AnthropicProvider implements AiProvider {
|
|
|
428
458
|
delta,
|
|
429
459
|
accumulated,
|
|
430
460
|
done: false,
|
|
431
|
-
}
|
|
461
|
+
} as GenerateMessageStreamChunk<TStructured>;
|
|
432
462
|
}
|
|
433
463
|
} else if (chunk.type === "message_delta") {
|
|
434
464
|
stopReason = chunk.delta.stop_reason || undefined;
|
|
@@ -462,6 +492,6 @@ export class AnthropicProvider implements AiProvider {
|
|
|
462
492
|
completionTokens: outputTokens,
|
|
463
493
|
},
|
|
464
494
|
structured,
|
|
465
|
-
}
|
|
495
|
+
} as GenerateMessageStreamChunk<TStructured>;
|
|
466
496
|
}
|
|
467
497
|
}
|
|
@@ -48,39 +48,67 @@ export interface GeminiProviderOptions {
|
|
|
48
48
|
*/
|
|
49
49
|
interface ErrorWithStatus {
|
|
50
50
|
status?: number;
|
|
51
|
-
code?:
|
|
51
|
+
code?: string;
|
|
52
52
|
message?: string;
|
|
53
|
+
type?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Type guard to check if error is ErrorWithStatus
|
|
58
|
+
*/
|
|
59
|
+
function isErrorWithStatus(error: unknown): error is ErrorWithStatus {
|
|
60
|
+
return (
|
|
61
|
+
typeof error === "object" &&
|
|
62
|
+
error !== null &&
|
|
63
|
+
("status" in error || "code" in error || "message" in error)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Safely extract error message
|
|
69
|
+
*/
|
|
70
|
+
function getErrorMessage(error: unknown): string {
|
|
71
|
+
if (error instanceof Error) {
|
|
72
|
+
return error.message;
|
|
73
|
+
}
|
|
74
|
+
if (isErrorWithStatus(error) && error.message) {
|
|
75
|
+
return error.message;
|
|
76
|
+
}
|
|
77
|
+
return String(error);
|
|
53
78
|
}
|
|
54
79
|
|
|
55
80
|
/**
|
|
56
81
|
* Determines if an error should trigger backup model usage
|
|
57
82
|
*/
|
|
58
83
|
const shouldUseBackupModel = (error: unknown): boolean => {
|
|
59
|
-
|
|
84
|
+
if (!isErrorWithStatus(error)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
60
87
|
|
|
61
|
-
|
|
88
|
+
// Server errors
|
|
89
|
+
if (error.status === 500 || error.status === 503) {
|
|
62
90
|
return true;
|
|
63
91
|
}
|
|
64
92
|
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
message.includes("internal error") ||
|
|
68
|
-
message.includes("Internal error") ||
|
|
69
|
-
message.includes("INTERNAL")
|
|
70
|
-
) {
|
|
93
|
+
// Rate limiting
|
|
94
|
+
if (error.status === 429) {
|
|
71
95
|
return true;
|
|
72
96
|
}
|
|
73
97
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
err?.code === 429 ||
|
|
77
|
-
err?.status === 503 ||
|
|
78
|
-
err?.code === 503
|
|
79
|
-
) {
|
|
98
|
+
// Model overloaded or unavailable
|
|
99
|
+
if (error.code === "overloaded") {
|
|
80
100
|
return true;
|
|
81
101
|
}
|
|
82
102
|
|
|
83
|
-
|
|
103
|
+
const message = getErrorMessage(error);
|
|
104
|
+
if (
|
|
105
|
+
message.includes("overloaded") ||
|
|
106
|
+
message.includes("unavailable") ||
|
|
107
|
+
message.includes("not available") ||
|
|
108
|
+
message.includes("internal error") ||
|
|
109
|
+
message.includes("Internal error") ||
|
|
110
|
+
message.includes("INTERNAL")
|
|
111
|
+
) {
|
|
84
112
|
return true;
|
|
85
113
|
}
|
|
86
114
|
|
|
@@ -119,26 +147,35 @@ export class GeminiProvider implements AiProvider {
|
|
|
119
147
|
};
|
|
120
148
|
}
|
|
121
149
|
|
|
122
|
-
async generateMessage<
|
|
150
|
+
async generateMessage<
|
|
151
|
+
TContext = unknown,
|
|
152
|
+
TStructured = AgentStructuredResponse
|
|
153
|
+
>(
|
|
123
154
|
input: GenerateMessageInput<TContext>
|
|
124
|
-
): Promise<GenerateMessageOutput
|
|
125
|
-
return this.generateWithBackup(input);
|
|
155
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
156
|
+
return this.generateWithBackup<TContext, TStructured>(input);
|
|
126
157
|
}
|
|
127
158
|
|
|
128
|
-
async *generateMessageStream<
|
|
159
|
+
async *generateMessageStream<
|
|
160
|
+
TContext = unknown,
|
|
161
|
+
TStructured = AgentStructuredResponse
|
|
162
|
+
>(
|
|
129
163
|
input: GenerateMessageInput<TContext>
|
|
130
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
131
|
-
yield* this.generateStreamWithBackup(input);
|
|
164
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
165
|
+
yield* this.generateStreamWithBackup<TContext, TStructured>(input);
|
|
132
166
|
}
|
|
133
167
|
|
|
134
|
-
private async generateWithBackup<
|
|
168
|
+
private async generateWithBackup<
|
|
169
|
+
TContext = unknown,
|
|
170
|
+
TStructured = AgentStructuredResponse
|
|
171
|
+
>(
|
|
135
172
|
input: GenerateMessageInput<TContext>
|
|
136
|
-
): Promise<GenerateMessageOutput
|
|
173
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
137
174
|
// Try primary model first
|
|
138
175
|
try {
|
|
139
176
|
return await this.generateWithModel(this.primaryModel, input);
|
|
140
177
|
} catch (primaryError: unknown) {
|
|
141
|
-
const primaryErrMsg =
|
|
178
|
+
const primaryErrMsg = getErrorMessage(primaryError);
|
|
142
179
|
console.warn(
|
|
143
180
|
`[GEMINI] Primary model ${this.primaryModel} failed: ${primaryErrMsg}`
|
|
144
181
|
);
|
|
@@ -162,9 +199,9 @@ export class GeminiProvider implements AiProvider {
|
|
|
162
199
|
try {
|
|
163
200
|
const result = await this.generateWithModel(backupModel, input);
|
|
164
201
|
console.log(`[GEMINI] Backup model ${backupModel} succeeded`);
|
|
165
|
-
return result
|
|
202
|
+
return result as GenerateMessageOutput<TStructured>;
|
|
166
203
|
} catch (backupError: unknown) {
|
|
167
|
-
const backupErrMsg =
|
|
204
|
+
const backupErrMsg = getErrorMessage(backupError);
|
|
168
205
|
console.warn(
|
|
169
206
|
`[GEMINI] Backup model ${backupModel} failed: ${backupErrMsg}`
|
|
170
207
|
);
|
|
@@ -182,7 +219,7 @@ export class GeminiProvider implements AiProvider {
|
|
|
182
219
|
}
|
|
183
220
|
}
|
|
184
221
|
|
|
185
|
-
const lastBackupErrMsg =
|
|
222
|
+
const lastBackupErrMsg = getErrorMessage(lastBackupError);
|
|
186
223
|
console.error(
|
|
187
224
|
`[GEMINI] All models failed. Primary: ${primaryErrMsg}, Last backup: ${lastBackupErrMsg}`
|
|
188
225
|
);
|
|
@@ -190,10 +227,13 @@ export class GeminiProvider implements AiProvider {
|
|
|
190
227
|
}
|
|
191
228
|
}
|
|
192
229
|
|
|
193
|
-
private async generateWithModel<
|
|
230
|
+
private async generateWithModel<
|
|
231
|
+
TContext = unknown,
|
|
232
|
+
TStructured = AgentStructuredResponse
|
|
233
|
+
>(
|
|
194
234
|
model: string,
|
|
195
235
|
input: GenerateMessageInput<TContext>
|
|
196
|
-
): Promise<GenerateMessageOutput
|
|
236
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
197
237
|
const operation = async (): Promise<GenerateMessageOutput> => {
|
|
198
238
|
// Enable JSON mode if requested
|
|
199
239
|
const configOverride: Partial<GenerateContentConfig> = { ...this.config };
|
|
@@ -214,7 +254,7 @@ export class GeminiProvider implements AiProvider {
|
|
|
214
254
|
}
|
|
215
255
|
|
|
216
256
|
// Parse JSON response if JSON mode was enabled
|
|
217
|
-
let structured;
|
|
257
|
+
let structured: AgentStructuredResponse | undefined;
|
|
218
258
|
if (input.parameters?.jsonMode) {
|
|
219
259
|
try {
|
|
220
260
|
structured = JSON.parse(message) as AgentStructuredResponse;
|
|
@@ -241,17 +281,20 @@ export class GeminiProvider implements AiProvider {
|
|
|
241
281
|
this.retryConfig.timeout,
|
|
242
282
|
this.retryConfig.retries,
|
|
243
283
|
`Gemini ${model}`
|
|
244
|
-
)
|
|
284
|
+
) as Promise<GenerateMessageOutput<TStructured>>;
|
|
245
285
|
}
|
|
246
286
|
|
|
247
|
-
private async *generateStreamWithBackup<
|
|
287
|
+
private async *generateStreamWithBackup<
|
|
288
|
+
TContext = unknown,
|
|
289
|
+
TStructured = AgentStructuredResponse
|
|
290
|
+
>(
|
|
248
291
|
input: GenerateMessageInput<TContext>
|
|
249
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
292
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
250
293
|
// Try primary model first
|
|
251
294
|
try {
|
|
252
295
|
yield* this.generateStreamWithModel(this.primaryModel, input);
|
|
253
296
|
} catch (primaryError: unknown) {
|
|
254
|
-
const primaryErrMsg =
|
|
297
|
+
const primaryErrMsg = getErrorMessage(primaryError);
|
|
255
298
|
console.warn(
|
|
256
299
|
`[GEMINI] Primary model ${this.primaryModel} failed: ${primaryErrMsg}`
|
|
257
300
|
);
|
|
@@ -277,7 +320,7 @@ export class GeminiProvider implements AiProvider {
|
|
|
277
320
|
console.log(`[GEMINI] Backup model ${backupModel} succeeded`);
|
|
278
321
|
return;
|
|
279
322
|
} catch (backupError: unknown) {
|
|
280
|
-
const backupErrMsg =
|
|
323
|
+
const backupErrMsg = getErrorMessage(backupError);
|
|
281
324
|
console.warn(
|
|
282
325
|
`[GEMINI] Backup model ${backupModel} failed: ${backupErrMsg}`
|
|
283
326
|
);
|
|
@@ -295,7 +338,7 @@ export class GeminiProvider implements AiProvider {
|
|
|
295
338
|
}
|
|
296
339
|
}
|
|
297
340
|
|
|
298
|
-
const lastBackupErrMsg =
|
|
341
|
+
const lastBackupErrMsg = getErrorMessage(lastBackupError);
|
|
299
342
|
console.error(
|
|
300
343
|
`[GEMINI] All models failed. Primary: ${primaryErrMsg}, Last backup: ${lastBackupErrMsg}`
|
|
301
344
|
);
|
|
@@ -303,10 +346,13 @@ export class GeminiProvider implements AiProvider {
|
|
|
303
346
|
}
|
|
304
347
|
}
|
|
305
348
|
|
|
306
|
-
private async *generateStreamWithModel<
|
|
349
|
+
private async *generateStreamWithModel<
|
|
350
|
+
TContext = unknown,
|
|
351
|
+
TStructured = AgentStructuredResponse
|
|
352
|
+
>(
|
|
307
353
|
model: string,
|
|
308
354
|
input: GenerateMessageInput<TContext>
|
|
309
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
355
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
310
356
|
// Enable JSON mode if requested
|
|
311
357
|
const configOverride: Partial<GenerateContentConfig> = { ...this.config };
|
|
312
358
|
if (input.parameters?.jsonMode) {
|
|
@@ -368,7 +414,7 @@ export class GeminiProvider implements AiProvider {
|
|
|
368
414
|
promptTokens: promptTokenCount,
|
|
369
415
|
completionTokens: candidatesTokenCount,
|
|
370
416
|
},
|
|
371
|
-
structured,
|
|
417
|
+
structured: structured as TStructured | undefined,
|
|
372
418
|
};
|
|
373
419
|
}
|
|
374
420
|
}
|
|
@@ -159,24 +159,36 @@ export class OpenAIProvider implements AiProvider {
|
|
|
159
159
|
};
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
async generateMessage<
|
|
162
|
+
async generateMessage<
|
|
163
|
+
TContext = unknown,
|
|
164
|
+
TStructured = AgentStructuredResponse
|
|
165
|
+
>(
|
|
163
166
|
input: GenerateMessageInput<TContext>
|
|
164
|
-
): Promise<GenerateMessageOutput
|
|
165
|
-
return this.generateWithBackup(input);
|
|
167
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
168
|
+
return this.generateWithBackup<TContext, TStructured>(input);
|
|
166
169
|
}
|
|
167
170
|
|
|
168
|
-
async *generateMessageStream<
|
|
171
|
+
async *generateMessageStream<
|
|
172
|
+
TContext = unknown,
|
|
173
|
+
TStructured = AgentStructuredResponse
|
|
174
|
+
>(
|
|
169
175
|
input: GenerateMessageInput<TContext>
|
|
170
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
171
|
-
yield* this.generateStreamWithBackup(input);
|
|
176
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
177
|
+
yield* this.generateStreamWithBackup<TContext, TStructured>(input);
|
|
172
178
|
}
|
|
173
179
|
|
|
174
|
-
private async generateWithBackup<
|
|
180
|
+
private async generateWithBackup<
|
|
181
|
+
TContext = unknown,
|
|
182
|
+
TStructured = AgentStructuredResponse
|
|
183
|
+
>(
|
|
175
184
|
input: GenerateMessageInput<TContext>
|
|
176
|
-
): Promise<GenerateMessageOutput
|
|
185
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
177
186
|
// Try primary model first
|
|
178
187
|
try {
|
|
179
|
-
return await this.generateWithModel
|
|
188
|
+
return await this.generateWithModel<TContext, TStructured>(
|
|
189
|
+
this.primaryModel,
|
|
190
|
+
input
|
|
191
|
+
);
|
|
180
192
|
} catch (primaryError: unknown) {
|
|
181
193
|
const primaryErrMsg = getErrorMessage(primaryError);
|
|
182
194
|
console.warn(
|
|
@@ -202,7 +214,7 @@ export class OpenAIProvider implements AiProvider {
|
|
|
202
214
|
try {
|
|
203
215
|
const result = await this.generateWithModel(backupModel, input);
|
|
204
216
|
console.log(`[OPENAI] Backup model ${backupModel} succeeded`);
|
|
205
|
-
return result
|
|
217
|
+
return result as GenerateMessageOutput<TStructured>;
|
|
206
218
|
} catch (backupError: unknown) {
|
|
207
219
|
const backupErrMsg = getErrorMessage(backupError);
|
|
208
220
|
console.warn(
|
|
@@ -230,10 +242,13 @@ export class OpenAIProvider implements AiProvider {
|
|
|
230
242
|
}
|
|
231
243
|
}
|
|
232
244
|
|
|
233
|
-
private async generateWithModel<
|
|
245
|
+
private async generateWithModel<
|
|
246
|
+
TContext = unknown,
|
|
247
|
+
TStructured = AgentStructuredResponse
|
|
248
|
+
>(
|
|
234
249
|
model: string,
|
|
235
250
|
input: GenerateMessageInput<TContext>
|
|
236
|
-
): Promise<GenerateMessageOutput
|
|
251
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
237
252
|
const operation = async (): Promise<GenerateMessageOutput> => {
|
|
238
253
|
const params: ChatCompletionCreateParamsNonStreaming = {
|
|
239
254
|
model,
|
|
@@ -358,15 +373,21 @@ export class OpenAIProvider implements AiProvider {
|
|
|
358
373
|
this.retryConfig.timeout,
|
|
359
374
|
this.retryConfig.retries,
|
|
360
375
|
`OpenAI ${model}`
|
|
361
|
-
)
|
|
376
|
+
) as Promise<GenerateMessageOutput<TStructured>>;
|
|
362
377
|
}
|
|
363
378
|
|
|
364
|
-
private async *generateStreamWithBackup<
|
|
379
|
+
private async *generateStreamWithBackup<
|
|
380
|
+
TContext = unknown,
|
|
381
|
+
TStructured = AgentStructuredResponse
|
|
382
|
+
>(
|
|
365
383
|
input: GenerateMessageInput<TContext>
|
|
366
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
384
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
367
385
|
// Try primary model first
|
|
368
386
|
try {
|
|
369
|
-
yield* this.generateStreamWithModel
|
|
387
|
+
yield* this.generateStreamWithModel<TContext, TStructured>(
|
|
388
|
+
this.primaryModel,
|
|
389
|
+
input
|
|
390
|
+
);
|
|
370
391
|
} catch (primaryError: unknown) {
|
|
371
392
|
const primaryErrMsg = getErrorMessage(primaryError);
|
|
372
393
|
console.warn(
|
|
@@ -390,7 +411,10 @@ export class OpenAIProvider implements AiProvider {
|
|
|
390
411
|
);
|
|
391
412
|
|
|
392
413
|
try {
|
|
393
|
-
yield* this.generateStreamWithModel
|
|
414
|
+
yield* this.generateStreamWithModel<TContext, TStructured>(
|
|
415
|
+
backupModel,
|
|
416
|
+
input
|
|
417
|
+
);
|
|
394
418
|
console.log(`[OPENAI] Backup model ${backupModel} succeeded`);
|
|
395
419
|
return;
|
|
396
420
|
} catch (backupError: unknown) {
|
|
@@ -420,10 +444,13 @@ export class OpenAIProvider implements AiProvider {
|
|
|
420
444
|
}
|
|
421
445
|
}
|
|
422
446
|
|
|
423
|
-
private async *generateStreamWithModel<
|
|
447
|
+
private async *generateStreamWithModel<
|
|
448
|
+
TContext = unknown,
|
|
449
|
+
TStructured = AgentStructuredResponse
|
|
450
|
+
>(
|
|
424
451
|
model: string,
|
|
425
452
|
input: GenerateMessageInput<TContext>
|
|
426
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
453
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
427
454
|
const params = {
|
|
428
455
|
...this.config,
|
|
429
456
|
model,
|
|
@@ -483,10 +510,10 @@ export class OpenAIProvider implements AiProvider {
|
|
|
483
510
|
}
|
|
484
511
|
|
|
485
512
|
// Parse JSON response if JSON mode was enabled
|
|
486
|
-
let structured:
|
|
513
|
+
let structured: TStructured | undefined;
|
|
487
514
|
if (input.parameters?.jsonMode && accumulated) {
|
|
488
515
|
try {
|
|
489
|
-
structured = JSON.parse(accumulated) as
|
|
516
|
+
structured = JSON.parse(accumulated) as TStructured;
|
|
490
517
|
} catch (error) {
|
|
491
518
|
console.warn(
|
|
492
519
|
"[OPENAI] Failed to parse JSON response in stream:",
|
|
@@ -169,21 +169,30 @@ export class OpenRouterProvider implements AiProvider {
|
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
async generateMessage<
|
|
172
|
+
async generateMessage<
|
|
173
|
+
TContext = unknown,
|
|
174
|
+
TStructured = AgentStructuredResponse
|
|
175
|
+
>(
|
|
173
176
|
input: GenerateMessageInput<TContext>
|
|
174
|
-
): Promise<GenerateMessageOutput
|
|
175
|
-
return this.generateWithBackup(input);
|
|
177
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
178
|
+
return this.generateWithBackup<TContext, TStructured>(input);
|
|
176
179
|
}
|
|
177
180
|
|
|
178
|
-
async *generateMessageStream<
|
|
181
|
+
async *generateMessageStream<
|
|
182
|
+
TContext = unknown,
|
|
183
|
+
TStructured = AgentStructuredResponse
|
|
184
|
+
>(
|
|
179
185
|
input: GenerateMessageInput<TContext>
|
|
180
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
181
|
-
yield* this.generateStreamWithBackup(input);
|
|
186
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
187
|
+
yield* this.generateStreamWithBackup<TContext, TStructured>(input);
|
|
182
188
|
}
|
|
183
189
|
|
|
184
|
-
private async generateWithBackup<
|
|
190
|
+
private async generateWithBackup<
|
|
191
|
+
TContext = unknown,
|
|
192
|
+
TStructured = AgentStructuredResponse
|
|
193
|
+
>(
|
|
185
194
|
input: GenerateMessageInput<TContext>
|
|
186
|
-
): Promise<GenerateMessageOutput
|
|
195
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
187
196
|
// Try primary model first
|
|
188
197
|
try {
|
|
189
198
|
return await this.generateWithModel(this.primaryModel, input);
|
|
@@ -212,7 +221,7 @@ export class OpenRouterProvider implements AiProvider {
|
|
|
212
221
|
try {
|
|
213
222
|
const result = await this.generateWithModel(backupModel, input);
|
|
214
223
|
console.log(`[OPENROUTER] Backup model ${backupModel} succeeded`);
|
|
215
|
-
return result
|
|
224
|
+
return result as GenerateMessageOutput<TStructured>;
|
|
216
225
|
} catch (backupError: unknown) {
|
|
217
226
|
const backupErrMsg = getErrorMessage(backupError);
|
|
218
227
|
console.warn(
|
|
@@ -240,10 +249,13 @@ export class OpenRouterProvider implements AiProvider {
|
|
|
240
249
|
}
|
|
241
250
|
}
|
|
242
251
|
|
|
243
|
-
private async generateWithModel<
|
|
252
|
+
private async generateWithModel<
|
|
253
|
+
TContext = unknown,
|
|
254
|
+
TStructured = AgentStructuredResponse
|
|
255
|
+
>(
|
|
244
256
|
model: string,
|
|
245
257
|
input: GenerateMessageInput<TContext>
|
|
246
|
-
): Promise<GenerateMessageOutput
|
|
258
|
+
): Promise<GenerateMessageOutput<TStructured>> {
|
|
247
259
|
const operation = async (): Promise<GenerateMessageOutput> => {
|
|
248
260
|
const params: ChatCompletionCreateParamsNonStreaming = {
|
|
249
261
|
model,
|
|
@@ -368,12 +380,15 @@ export class OpenRouterProvider implements AiProvider {
|
|
|
368
380
|
this.retryConfig.timeout,
|
|
369
381
|
this.retryConfig.retries,
|
|
370
382
|
`OpenRouter ${model}`
|
|
371
|
-
)
|
|
383
|
+
) as Promise<GenerateMessageOutput<TStructured>>;
|
|
372
384
|
}
|
|
373
385
|
|
|
374
|
-
private async *generateStreamWithBackup<
|
|
386
|
+
private async *generateStreamWithBackup<
|
|
387
|
+
TContext = unknown,
|
|
388
|
+
TStructured = AgentStructuredResponse
|
|
389
|
+
>(
|
|
375
390
|
input: GenerateMessageInput<TContext>
|
|
376
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
391
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
377
392
|
// Try primary model first
|
|
378
393
|
try {
|
|
379
394
|
yield* this.generateStreamWithModel(this.primaryModel, input);
|
|
@@ -430,10 +445,13 @@ export class OpenRouterProvider implements AiProvider {
|
|
|
430
445
|
}
|
|
431
446
|
}
|
|
432
447
|
|
|
433
|
-
private async *generateStreamWithModel<
|
|
448
|
+
private async *generateStreamWithModel<
|
|
449
|
+
TContext = unknown,
|
|
450
|
+
TStructured = AgentStructuredResponse
|
|
451
|
+
>(
|
|
434
452
|
model: string,
|
|
435
453
|
input: GenerateMessageInput<TContext>
|
|
436
|
-
): AsyncGenerator<GenerateMessageStreamChunk
|
|
454
|
+
): AsyncGenerator<GenerateMessageStreamChunk<TStructured>> {
|
|
437
455
|
const params = {
|
|
438
456
|
...this.config,
|
|
439
457
|
model,
|
|
@@ -493,10 +511,10 @@ export class OpenRouterProvider implements AiProvider {
|
|
|
493
511
|
}
|
|
494
512
|
|
|
495
513
|
// Parse JSON response if JSON mode was enabled
|
|
496
|
-
let structured:
|
|
514
|
+
let structured: TStructured | undefined;
|
|
497
515
|
if (input.parameters?.jsonMode && accumulated) {
|
|
498
516
|
try {
|
|
499
|
-
structured = JSON.parse(accumulated) as
|
|
517
|
+
structured = JSON.parse(accumulated) as TStructured;
|
|
500
518
|
} catch (error) {
|
|
501
519
|
console.warn(
|
|
502
520
|
"[OPENROUTER] Failed to parse JSON response in stream:",
|
package/src/types/agent.ts
CHANGED
|
@@ -25,6 +25,7 @@ export enum CompositionMode {
|
|
|
25
25
|
* Forward declare observation types
|
|
26
26
|
*/
|
|
27
27
|
import type { ObservationOptions } from "./observation";
|
|
28
|
+
import { PreparationEngineOptions } from "@core/PreparationEngine";
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* Context lifecycle hooks for managing state persistence
|
|
@@ -74,6 +75,8 @@ export interface AgentOptions<TContext = unknown> {
|
|
|
74
75
|
ai: AiProvider;
|
|
75
76
|
/** Maximum number of processing iterations per request */
|
|
76
77
|
maxEngineIterations?: number;
|
|
78
|
+
/** Optional parallelism controls for preparation engine */
|
|
79
|
+
preparation?: PreparationEngineOptions;
|
|
77
80
|
/** Composition mode for response generation */
|
|
78
81
|
compositionMode?: CompositionMode;
|
|
79
82
|
/** Initial terms for domain glossary */
|