@aigne/core 1.55.0 → 1.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/lib/cjs/agents/agent.d.ts +8 -0
- package/lib/cjs/agents/agent.js +33 -3
- package/lib/cjs/agents/chat-model.d.ts +3 -1
- package/lib/cjs/agents/chat-model.js +33 -1
- package/lib/cjs/agents/team-agent.js +21 -12
- package/lib/cjs/aigne/context.d.ts +0 -4
- package/lib/cjs/aigne/context.js +5 -31
- package/lib/dts/agents/agent.d.ts +8 -0
- package/lib/dts/agents/chat-model.d.ts +3 -1
- package/lib/dts/aigne/context.d.ts +0 -4
- package/lib/esm/agents/agent.d.ts +8 -0
- package/lib/esm/agents/agent.js +33 -3
- package/lib/esm/agents/chat-model.d.ts +3 -1
- package/lib/esm/agents/chat-model.js +29 -1
- package/lib/esm/agents/team-agent.js +21 -12
- package/lib/esm/aigne/context.d.ts +0 -4
- package/lib/esm/aigne/context.js +5 -31
- package/package.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.56.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.55.1...core-v1.56.0) (2025-08-27)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **models:** add retry mechanism for network errors and structured output validation errors ([#418](https://github.com/AIGNE-io/aigne-framework/issues/418)) ([52bc9ee](https://github.com/AIGNE-io/aigne-framework/commit/52bc9eec5f4f4fa3c3f26881c405f4f89dad01c9))
|
|
9
|
+
|
|
10
|
+
## [1.55.1](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.55.0...core-v1.55.1) (2025-08-26)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **cli:** reduce memory usage of AIGNE CLI ([#411](https://github.com/AIGNE-io/aigne-framework/issues/411)) ([9c36969](https://github.com/AIGNE-io/aigne-framework/commit/9c369699d966d37abf2d6a1624eac3d2fda4123b))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Dependencies
|
|
19
|
+
|
|
20
|
+
* The following workspace dependencies were updated
|
|
21
|
+
* dependencies
|
|
22
|
+
* @aigne/observability-api bumped to 0.10.1
|
|
23
|
+
|
|
3
24
|
## [1.55.0](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.54.0...core-v1.55.0) (2025-08-21)
|
|
4
25
|
|
|
5
26
|
|
|
@@ -122,6 +122,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
|
|
|
122
122
|
*/
|
|
123
123
|
maxRetrieveMemoryCount?: number;
|
|
124
124
|
hooks?: AgentHooks<I, O> | AgentHooks<I, O>[];
|
|
125
|
+
retryOnError?: Agent<I, O>["retryOnError"] | boolean;
|
|
125
126
|
}
|
|
126
127
|
export declare const agentOptionsSchema: ZodObject<{
|
|
127
128
|
[key in keyof AgentOptions]: ZodType<AgentOptions[key]>;
|
|
@@ -217,6 +218,13 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
|
|
|
217
218
|
* {@includeCode ../../test/agents/agent.test.ts#example-agent-hooks}
|
|
218
219
|
*/
|
|
219
220
|
readonly hooks: AgentHooks<I, O>[];
|
|
221
|
+
retryOnError?: {
|
|
222
|
+
retries?: number;
|
|
223
|
+
minTimeout?: number;
|
|
224
|
+
factor?: number;
|
|
225
|
+
randomize?: boolean;
|
|
226
|
+
shouldRetry?: (error: Error) => boolean | Promise<boolean>;
|
|
227
|
+
};
|
|
220
228
|
/**
|
|
221
229
|
* List of GuideRail agents applied to this agent
|
|
222
230
|
*
|
package/lib/cjs/agents/agent.js
CHANGED
|
@@ -57,6 +57,9 @@ const type_utils_js_1 = require("../utils/type-utils.js");
|
|
|
57
57
|
const types_js_1 = require("./types.js");
|
|
58
58
|
__exportStar(require("./types.js"), exports);
|
|
59
59
|
exports.DEFAULT_INPUT_ACTION_GET = "$get";
|
|
60
|
+
const DEFAULT_RETRIES = 3;
|
|
61
|
+
const DEFAULT_RETRY_MIN_TIMEOUT = 1000;
|
|
62
|
+
const DEFAULT_RETRY_FACTOR = 2;
|
|
60
63
|
const hooksSchema = zod_1.z.object({
|
|
61
64
|
onStart: zod_1.z.custom().optional(),
|
|
62
65
|
onEnd: zod_1.z.custom().optional(),
|
|
@@ -82,6 +85,18 @@ exports.agentOptionsSchema = zod_1.z.object({
|
|
|
82
85
|
maxRetrieveMemoryCount: zod_1.z.number().optional(),
|
|
83
86
|
hooks: zod_1.z.union([zod_1.z.array(hooksSchema), hooksSchema]).optional(),
|
|
84
87
|
guideRails: zod_1.z.array(zod_1.z.custom()).optional(),
|
|
88
|
+
retryOnError: zod_1.z
|
|
89
|
+
.union([
|
|
90
|
+
zod_1.z.boolean(),
|
|
91
|
+
zod_1.z.object({
|
|
92
|
+
retries: zod_1.z.number().int().min(0),
|
|
93
|
+
minTimeout: zod_1.z.number().min(0).optional(),
|
|
94
|
+
factor: zod_1.z.number().min(1).optional(),
|
|
95
|
+
randomize: zod_1.z.boolean().optional(),
|
|
96
|
+
shouldRetry: zod_1.z.custom().optional(),
|
|
97
|
+
}),
|
|
98
|
+
])
|
|
99
|
+
.optional(),
|
|
85
100
|
});
|
|
86
101
|
/**
|
|
87
102
|
* Agent is the base class for all agents.
|
|
@@ -107,6 +122,7 @@ exports.agentOptionsSchema = zod_1.z.object({
|
|
|
107
122
|
*/
|
|
108
123
|
class Agent {
|
|
109
124
|
constructor(options = {}) {
|
|
125
|
+
(0, type_utils_js_1.checkArguments)("Agent options", exports.agentOptionsSchema, options);
|
|
110
126
|
const { inputSchema, outputSchema } = options;
|
|
111
127
|
this.name = options.name || this.constructor.name;
|
|
112
128
|
this.alias = options.alias;
|
|
@@ -135,6 +151,12 @@ class Agent {
|
|
|
135
151
|
this.asyncMemoryRecord = options.asyncMemoryRecord;
|
|
136
152
|
this.maxRetrieveMemoryCount = options.maxRetrieveMemoryCount;
|
|
137
153
|
this.hooks = (0, type_utils_js_1.flat)(options.hooks);
|
|
154
|
+
this.retryOnError =
|
|
155
|
+
options.retryOnError === false
|
|
156
|
+
? undefined
|
|
157
|
+
: options.retryOnError === true
|
|
158
|
+
? { retries: DEFAULT_RETRIES }
|
|
159
|
+
: options.retryOnError;
|
|
138
160
|
this.guideRails = options.guideRails;
|
|
139
161
|
}
|
|
140
162
|
/**
|
|
@@ -158,6 +180,7 @@ class Agent {
|
|
|
158
180
|
* {@includeCode ../../test/agents/agent.test.ts#example-agent-hooks}
|
|
159
181
|
*/
|
|
160
182
|
hooks;
|
|
183
|
+
retryOnError;
|
|
161
184
|
/**
|
|
162
185
|
* List of GuideRail agents applied to this agent
|
|
163
186
|
*
|
|
@@ -387,6 +410,7 @@ class Agent {
|
|
|
387
410
|
}
|
|
388
411
|
async *processStreamingAndRetry(input, options) {
|
|
389
412
|
let output = {};
|
|
413
|
+
let attempt = 0;
|
|
390
414
|
for (;;) {
|
|
391
415
|
// Reset output to avoid accumulating old data
|
|
392
416
|
const resetOutput = Object.fromEntries(Object.entries(output).map(([key]) => [key, null]));
|
|
@@ -415,6 +439,15 @@ class Agent {
|
|
|
415
439
|
break;
|
|
416
440
|
}
|
|
417
441
|
catch (error) {
|
|
442
|
+
if (this.retryOnError?.retries) {
|
|
443
|
+
const { retries, minTimeout = DEFAULT_RETRY_MIN_TIMEOUT, factor = DEFAULT_RETRY_FACTOR, randomize = false, shouldRetry, } = this.retryOnError;
|
|
444
|
+
if (attempt++ < retries && (!shouldRetry || (await shouldRetry(error)))) {
|
|
445
|
+
const timeout = minTimeout * factor ** (attempt - 1) * (randomize ? 1 + Math.random() : 1);
|
|
446
|
+
logger_js_1.logger.warn(`Agent ${this.name} attempt ${attempt} of ${retries} failed with error: ${error}. Retrying in ${timeout}ms...`);
|
|
447
|
+
await new Promise((resolve) => setTimeout(resolve, timeout));
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
418
451
|
const res = await this.processAgentError(input, error, options);
|
|
419
452
|
if (!res.retry)
|
|
420
453
|
throw res.error ?? error;
|
|
@@ -506,9 +539,6 @@ class Agent {
|
|
|
506
539
|
* @param options Invocation options
|
|
507
540
|
*/
|
|
508
541
|
async processAgentError(input, error, options) {
|
|
509
|
-
if ("$error_has_been_processed" in error && error.$error_has_been_processed)
|
|
510
|
-
return {};
|
|
511
|
-
Object.defineProperty(error, "$error_has_been_processed", { value: true, enumerable: false });
|
|
512
542
|
logger_js_1.logger.error("Invoke agent %s failed with error: %O", this.name, error);
|
|
513
543
|
if (!this.disableEvents)
|
|
514
544
|
options.context.emit("agentFailed", { agent: this, error });
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type
|
|
2
|
+
import { type PromiseOrValue } from "../utils/type-utils.js";
|
|
3
3
|
import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type Message } from "./agent.js";
|
|
4
|
+
export declare class StructuredOutputError extends Error {
|
|
5
|
+
}
|
|
4
6
|
/**
|
|
5
7
|
* ChatModel is an abstract base class for interacting with Large Language Models (LLMs).
|
|
6
8
|
*
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.chatModelOutputUsageSchema = exports.ChatModel = void 0;
|
|
6
|
+
exports.chatModelOutputUsageSchema = exports.ChatModel = exports.StructuredOutputError = void 0;
|
|
7
|
+
const ajv_1 = require("ajv");
|
|
8
|
+
const is_network_error_1 = __importDefault(require("is-network-error"));
|
|
4
9
|
const zod_1 = require("zod");
|
|
10
|
+
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
5
11
|
const agent_js_1 = require("./agent.js");
|
|
12
|
+
const CHAT_MODEL_DEFAULT_RETRY_OPTIONS = {
|
|
13
|
+
retries: 3,
|
|
14
|
+
shouldRetry: (error) => error instanceof StructuredOutputError || (0, is_network_error_1.default)(error),
|
|
15
|
+
};
|
|
16
|
+
class StructuredOutputError extends Error {
|
|
17
|
+
}
|
|
18
|
+
exports.StructuredOutputError = StructuredOutputError;
|
|
6
19
|
/**
|
|
7
20
|
* ChatModel is an abstract base class for interacting with Large Language Models (LLMs).
|
|
8
21
|
*
|
|
@@ -29,10 +42,21 @@ const agent_js_1 = require("./agent.js");
|
|
|
29
42
|
class ChatModel extends agent_js_1.Agent {
|
|
30
43
|
tag = "ChatModelAgent";
|
|
31
44
|
constructor(options) {
|
|
45
|
+
if (options)
|
|
46
|
+
(0, type_utils_js_1.checkArguments)("ChatModel", agent_js_1.agentOptionsSchema, options);
|
|
47
|
+
const retryOnError = options?.retryOnError === false
|
|
48
|
+
? false
|
|
49
|
+
: options?.retryOnError === true
|
|
50
|
+
? CHAT_MODEL_DEFAULT_RETRY_OPTIONS
|
|
51
|
+
: {
|
|
52
|
+
...CHAT_MODEL_DEFAULT_RETRY_OPTIONS,
|
|
53
|
+
...options?.retryOnError,
|
|
54
|
+
};
|
|
32
55
|
super({
|
|
33
56
|
...options,
|
|
34
57
|
inputSchema: chatModelInputSchema,
|
|
35
58
|
outputSchema: chatModelOutputSchema,
|
|
59
|
+
retryOnError,
|
|
36
60
|
});
|
|
37
61
|
}
|
|
38
62
|
get credential() {
|
|
@@ -137,6 +161,14 @@ class ChatModel extends agent_js_1.Agent {
|
|
|
137
161
|
}
|
|
138
162
|
}
|
|
139
163
|
}
|
|
164
|
+
if (input.responseFormat?.type === "json_schema" &&
|
|
165
|
+
// NOTE: Should not validate if there are tool calls
|
|
166
|
+
!output.toolCalls?.length) {
|
|
167
|
+
const ajv = new ajv_1.Ajv();
|
|
168
|
+
if (!ajv.validate(input.responseFormat.jsonSchema.schema, output.json)) {
|
|
169
|
+
throw new StructuredOutputError(`Output JSON does not conform to the provided JSON schema: ${ajv.errorsText()}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
140
172
|
super.postprocess(input, output, options);
|
|
141
173
|
const { usage } = output;
|
|
142
174
|
if (usage) {
|
|
@@ -196,25 +196,34 @@ class TeamAgent extends agent_js_1.Agent {
|
|
|
196
196
|
let arr = input[this.iterateOn];
|
|
197
197
|
arr = Array.isArray(arr) ? [...arr] : (0, type_utils_js_1.isNil)(arr) ? [arr] : [];
|
|
198
198
|
const results = new Array(arr.length);
|
|
199
|
+
let error;
|
|
199
200
|
const queue = fastq_1.default.promise(async ({ item, index }) => {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
201
|
+
try {
|
|
202
|
+
if (!(0, type_utils_js_1.isRecord)(item))
|
|
203
|
+
throw new TypeError(`Expected ${String(key)} to be an object, got ${typeof item}`);
|
|
204
|
+
const o = await (0, agent_js_1.agentProcessResultToObject)(await this._processNonIterator({ ...input, [key]: arr, ...item }, { ...options, streaming: false }));
|
|
205
|
+
const res = (0, type_utils_js_1.omit)(o, key);
|
|
206
|
+
// Merge the item result with the original item used for next iteration
|
|
207
|
+
if (this.iterateWithPreviousOutput) {
|
|
208
|
+
arr = (0, immer_1.produce)(arr, (draft) => {
|
|
209
|
+
const item = draft[index];
|
|
210
|
+
(0, node_assert_1.default)(item);
|
|
211
|
+
Object.assign(item, res);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
results[index] = res;
|
|
215
|
+
}
|
|
216
|
+
catch (e) {
|
|
217
|
+
error = e;
|
|
218
|
+
queue.killAndDrain();
|
|
211
219
|
}
|
|
212
|
-
results[index] = res;
|
|
213
220
|
}, this.concurrency);
|
|
214
221
|
for (let index = 0; index < arr.length; index++) {
|
|
215
222
|
queue.push({ index, item: arr[index] });
|
|
216
223
|
}
|
|
217
224
|
await queue.drained();
|
|
225
|
+
if (error)
|
|
226
|
+
throw error;
|
|
218
227
|
yield { delta: { json: { [key]: results } } };
|
|
219
228
|
}
|
|
220
229
|
_processNonIterator(input, options) {
|
|
@@ -163,7 +163,6 @@ export declare class AIGNEContext implements Context {
|
|
|
163
163
|
get observer(): AIGNEObserver | undefined;
|
|
164
164
|
get limits(): ContextLimits | undefined;
|
|
165
165
|
get status(): "normal" | "timeout";
|
|
166
|
-
get spans(): Span[];
|
|
167
166
|
get usage(): ContextUsage;
|
|
168
167
|
get userContext(): Context["userContext"];
|
|
169
168
|
set userContext(userContext: Context["userContext"]);
|
|
@@ -181,7 +180,6 @@ export declare class AIGNEContext implements Context {
|
|
|
181
180
|
subscribe: Context["subscribe"];
|
|
182
181
|
unsubscribe: Context["unsubscribe"];
|
|
183
182
|
emit<K extends keyof ContextEmitEventMap>(eventName: K, ...args: Args<K, ContextEmitEventMap>): boolean;
|
|
184
|
-
private endAllSpans;
|
|
185
183
|
private trace;
|
|
186
184
|
on<K extends keyof ContextEventMap>(eventName: K, listener: Listener<K, ContextEventMap>): this;
|
|
187
185
|
once<K extends keyof ContextEventMap>(eventName: K, listener: Listener<K, ContextEventMap>): this;
|
|
@@ -189,7 +187,6 @@ export declare class AIGNEContext implements Context {
|
|
|
189
187
|
}
|
|
190
188
|
declare class AIGNEContextShared {
|
|
191
189
|
private readonly parent?;
|
|
192
|
-
spans: Span[];
|
|
193
190
|
constructor(parent?: (Pick<Context, "model" | "imageModel" | "agents" | "skills" | "limits" | "observer"> & {
|
|
194
191
|
messageQueue?: MessageQueue;
|
|
195
192
|
events?: Emitter<any>;
|
|
@@ -202,7 +199,6 @@ declare class AIGNEContextShared {
|
|
|
202
199
|
get agents(): Agent<any, any>[];
|
|
203
200
|
get observer(): AIGNEObserver | undefined;
|
|
204
201
|
get limits(): ContextLimits | undefined;
|
|
205
|
-
addSpan(span: Span): void;
|
|
206
202
|
usage: ContextUsage;
|
|
207
203
|
userContext: Context["userContext"];
|
|
208
204
|
memories: Context["memories"];
|
package/lib/cjs/aigne/context.js
CHANGED
|
@@ -45,9 +45,6 @@ class AIGNEContext {
|
|
|
45
45
|
// 修改了 rootId 是否会之前的有影响?,之前为 this.id
|
|
46
46
|
this.rootId = this.span?.spanContext?.().traceId ?? (0, uuid_1.v7)();
|
|
47
47
|
}
|
|
48
|
-
if (this.span) {
|
|
49
|
-
this.internal.addSpan(this.span);
|
|
50
|
-
}
|
|
51
48
|
this.id = this.span?.spanContext()?.spanId ?? (0, uuid_1.v7)();
|
|
52
49
|
}
|
|
53
50
|
id;
|
|
@@ -79,9 +76,6 @@ class AIGNEContext {
|
|
|
79
76
|
get status() {
|
|
80
77
|
return this.internal.status;
|
|
81
78
|
}
|
|
82
|
-
get spans() {
|
|
83
|
-
return this.internal.spans;
|
|
84
|
-
}
|
|
85
79
|
get usage() {
|
|
86
80
|
return this.internal.usage;
|
|
87
81
|
}
|
|
@@ -122,18 +116,12 @@ class AIGNEContext {
|
|
|
122
116
|
const newContext = options?.newContext === false ? this : this.newContext();
|
|
123
117
|
return Promise.resolve(newContext.internal.invoke(agent, message, newContext, options)).then(async (response) => {
|
|
124
118
|
if (!options?.streaming) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return [output, activeAgent];
|
|
130
|
-
}
|
|
131
|
-
return output;
|
|
132
|
-
}
|
|
133
|
-
catch (error) {
|
|
134
|
-
this.endAllSpans(error);
|
|
135
|
-
throw error;
|
|
119
|
+
let { __activeAgent__: activeAgent, ...output } = await (0, stream_utils_js_1.agentResponseStreamToObject)(response);
|
|
120
|
+
output = await this.onInvocationResult(output, options);
|
|
121
|
+
if (options?.returnActiveAgent) {
|
|
122
|
+
return [output, activeAgent];
|
|
136
123
|
}
|
|
124
|
+
return output;
|
|
137
125
|
}
|
|
138
126
|
const activeAgentPromise = (0, promise_js_1.promiseWithResolvers)();
|
|
139
127
|
const stream = (0, stream_utils_js_1.onAgentResponseStreamEnd)((0, stream_utils_js_1.asyncGeneratorToReadableStream)(response), {
|
|
@@ -152,10 +140,6 @@ class AIGNEContext {
|
|
|
152
140
|
activeAgentPromise.resolve(output.__activeAgent__);
|
|
153
141
|
return await this.onInvocationResult(output, options);
|
|
154
142
|
},
|
|
155
|
-
onError: (error) => {
|
|
156
|
-
this.endAllSpans(error);
|
|
157
|
-
return error;
|
|
158
|
-
},
|
|
159
143
|
});
|
|
160
144
|
const finalStream = !options.returnProgressChunks
|
|
161
145
|
? stream
|
|
@@ -217,12 +201,6 @@ class AIGNEContext {
|
|
|
217
201
|
this.trace(eventName, args, b);
|
|
218
202
|
return this.internal.events.emit(eventName, ...newArgs);
|
|
219
203
|
}
|
|
220
|
-
async endAllSpans(error) {
|
|
221
|
-
this.spans.forEach((span) => {
|
|
222
|
-
span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: error?.message });
|
|
223
|
-
span.end();
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
204
|
async trace(eventName, args, b) {
|
|
227
205
|
const span = this.span;
|
|
228
206
|
if (!span)
|
|
@@ -298,7 +276,6 @@ class AIGNEContext {
|
|
|
298
276
|
exports.AIGNEContext = AIGNEContext;
|
|
299
277
|
class AIGNEContextShared {
|
|
300
278
|
parent;
|
|
301
|
-
spans = [];
|
|
302
279
|
constructor(parent) {
|
|
303
280
|
this.parent = parent;
|
|
304
281
|
this.messageQueue = this.parent?.messageQueue ?? new message_queue_js_1.MessageQueue();
|
|
@@ -324,9 +301,6 @@ class AIGNEContextShared {
|
|
|
324
301
|
get limits() {
|
|
325
302
|
return this.parent?.limits;
|
|
326
303
|
}
|
|
327
|
-
addSpan(span) {
|
|
328
|
-
this.spans.push(span);
|
|
329
|
-
}
|
|
330
304
|
usage = (0, usage_js_1.newEmptyContextUsage)();
|
|
331
305
|
userContext = {};
|
|
332
306
|
memories = [];
|
|
@@ -122,6 +122,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
|
|
|
122
122
|
*/
|
|
123
123
|
maxRetrieveMemoryCount?: number;
|
|
124
124
|
hooks?: AgentHooks<I, O> | AgentHooks<I, O>[];
|
|
125
|
+
retryOnError?: Agent<I, O>["retryOnError"] | boolean;
|
|
125
126
|
}
|
|
126
127
|
export declare const agentOptionsSchema: ZodObject<{
|
|
127
128
|
[key in keyof AgentOptions]: ZodType<AgentOptions[key]>;
|
|
@@ -217,6 +218,13 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
|
|
|
217
218
|
* {@includeCode ../../test/agents/agent.test.ts#example-agent-hooks}
|
|
218
219
|
*/
|
|
219
220
|
readonly hooks: AgentHooks<I, O>[];
|
|
221
|
+
retryOnError?: {
|
|
222
|
+
retries?: number;
|
|
223
|
+
minTimeout?: number;
|
|
224
|
+
factor?: number;
|
|
225
|
+
randomize?: boolean;
|
|
226
|
+
shouldRetry?: (error: Error) => boolean | Promise<boolean>;
|
|
227
|
+
};
|
|
220
228
|
/**
|
|
221
229
|
* List of GuideRail agents applied to this agent
|
|
222
230
|
*
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type
|
|
2
|
+
import { type PromiseOrValue } from "../utils/type-utils.js";
|
|
3
3
|
import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type Message } from "./agent.js";
|
|
4
|
+
export declare class StructuredOutputError extends Error {
|
|
5
|
+
}
|
|
4
6
|
/**
|
|
5
7
|
* ChatModel is an abstract base class for interacting with Large Language Models (LLMs).
|
|
6
8
|
*
|
|
@@ -163,7 +163,6 @@ export declare class AIGNEContext implements Context {
|
|
|
163
163
|
get observer(): AIGNEObserver | undefined;
|
|
164
164
|
get limits(): ContextLimits | undefined;
|
|
165
165
|
get status(): "normal" | "timeout";
|
|
166
|
-
get spans(): Span[];
|
|
167
166
|
get usage(): ContextUsage;
|
|
168
167
|
get userContext(): Context["userContext"];
|
|
169
168
|
set userContext(userContext: Context["userContext"]);
|
|
@@ -181,7 +180,6 @@ export declare class AIGNEContext implements Context {
|
|
|
181
180
|
subscribe: Context["subscribe"];
|
|
182
181
|
unsubscribe: Context["unsubscribe"];
|
|
183
182
|
emit<K extends keyof ContextEmitEventMap>(eventName: K, ...args: Args<K, ContextEmitEventMap>): boolean;
|
|
184
|
-
private endAllSpans;
|
|
185
183
|
private trace;
|
|
186
184
|
on<K extends keyof ContextEventMap>(eventName: K, listener: Listener<K, ContextEventMap>): this;
|
|
187
185
|
once<K extends keyof ContextEventMap>(eventName: K, listener: Listener<K, ContextEventMap>): this;
|
|
@@ -189,7 +187,6 @@ export declare class AIGNEContext implements Context {
|
|
|
189
187
|
}
|
|
190
188
|
declare class AIGNEContextShared {
|
|
191
189
|
private readonly parent?;
|
|
192
|
-
spans: Span[];
|
|
193
190
|
constructor(parent?: (Pick<Context, "model" | "imageModel" | "agents" | "skills" | "limits" | "observer"> & {
|
|
194
191
|
messageQueue?: MessageQueue;
|
|
195
192
|
events?: Emitter<any>;
|
|
@@ -202,7 +199,6 @@ declare class AIGNEContextShared {
|
|
|
202
199
|
get agents(): Agent<any, any>[];
|
|
203
200
|
get observer(): AIGNEObserver | undefined;
|
|
204
201
|
get limits(): ContextLimits | undefined;
|
|
205
|
-
addSpan(span: Span): void;
|
|
206
202
|
usage: ContextUsage;
|
|
207
203
|
userContext: Context["userContext"];
|
|
208
204
|
memories: Context["memories"];
|
|
@@ -122,6 +122,7 @@ export interface AgentOptions<I extends Message = Message, O extends Message = M
|
|
|
122
122
|
*/
|
|
123
123
|
maxRetrieveMemoryCount?: number;
|
|
124
124
|
hooks?: AgentHooks<I, O> | AgentHooks<I, O>[];
|
|
125
|
+
retryOnError?: Agent<I, O>["retryOnError"] | boolean;
|
|
125
126
|
}
|
|
126
127
|
export declare const agentOptionsSchema: ZodObject<{
|
|
127
128
|
[key in keyof AgentOptions]: ZodType<AgentOptions[key]>;
|
|
@@ -217,6 +218,13 @@ export declare abstract class Agent<I extends Message = any, O extends Message =
|
|
|
217
218
|
* {@includeCode ../../test/agents/agent.test.ts#example-agent-hooks}
|
|
218
219
|
*/
|
|
219
220
|
readonly hooks: AgentHooks<I, O>[];
|
|
221
|
+
retryOnError?: {
|
|
222
|
+
retries?: number;
|
|
223
|
+
minTimeout?: number;
|
|
224
|
+
factor?: number;
|
|
225
|
+
randomize?: boolean;
|
|
226
|
+
shouldRetry?: (error: Error) => boolean | Promise<boolean>;
|
|
227
|
+
};
|
|
220
228
|
/**
|
|
221
229
|
* List of GuideRail agents applied to this agent
|
|
222
230
|
*
|
package/lib/esm/agents/agent.js
CHANGED
|
@@ -9,6 +9,9 @@ import { checkArguments, createAccessorArray, flat, isEmpty, isNil, isNonNullabl
|
|
|
9
9
|
import { replaceTransferAgentToName, transferToAgentOutput, } from "./types.js";
|
|
10
10
|
export * from "./types.js";
|
|
11
11
|
export const DEFAULT_INPUT_ACTION_GET = "$get";
|
|
12
|
+
const DEFAULT_RETRIES = 3;
|
|
13
|
+
const DEFAULT_RETRY_MIN_TIMEOUT = 1000;
|
|
14
|
+
const DEFAULT_RETRY_FACTOR = 2;
|
|
12
15
|
const hooksSchema = z.object({
|
|
13
16
|
onStart: z.custom().optional(),
|
|
14
17
|
onEnd: z.custom().optional(),
|
|
@@ -34,6 +37,18 @@ export const agentOptionsSchema = z.object({
|
|
|
34
37
|
maxRetrieveMemoryCount: z.number().optional(),
|
|
35
38
|
hooks: z.union([z.array(hooksSchema), hooksSchema]).optional(),
|
|
36
39
|
guideRails: z.array(z.custom()).optional(),
|
|
40
|
+
retryOnError: z
|
|
41
|
+
.union([
|
|
42
|
+
z.boolean(),
|
|
43
|
+
z.object({
|
|
44
|
+
retries: z.number().int().min(0),
|
|
45
|
+
minTimeout: z.number().min(0).optional(),
|
|
46
|
+
factor: z.number().min(1).optional(),
|
|
47
|
+
randomize: z.boolean().optional(),
|
|
48
|
+
shouldRetry: z.custom().optional(),
|
|
49
|
+
}),
|
|
50
|
+
])
|
|
51
|
+
.optional(),
|
|
37
52
|
});
|
|
38
53
|
/**
|
|
39
54
|
* Agent is the base class for all agents.
|
|
@@ -59,6 +74,7 @@ export const agentOptionsSchema = z.object({
|
|
|
59
74
|
*/
|
|
60
75
|
export class Agent {
|
|
61
76
|
constructor(options = {}) {
|
|
77
|
+
checkArguments("Agent options", agentOptionsSchema, options);
|
|
62
78
|
const { inputSchema, outputSchema } = options;
|
|
63
79
|
this.name = options.name || this.constructor.name;
|
|
64
80
|
this.alias = options.alias;
|
|
@@ -87,6 +103,12 @@ export class Agent {
|
|
|
87
103
|
this.asyncMemoryRecord = options.asyncMemoryRecord;
|
|
88
104
|
this.maxRetrieveMemoryCount = options.maxRetrieveMemoryCount;
|
|
89
105
|
this.hooks = flat(options.hooks);
|
|
106
|
+
this.retryOnError =
|
|
107
|
+
options.retryOnError === false
|
|
108
|
+
? undefined
|
|
109
|
+
: options.retryOnError === true
|
|
110
|
+
? { retries: DEFAULT_RETRIES }
|
|
111
|
+
: options.retryOnError;
|
|
90
112
|
this.guideRails = options.guideRails;
|
|
91
113
|
}
|
|
92
114
|
/**
|
|
@@ -110,6 +132,7 @@ export class Agent {
|
|
|
110
132
|
* {@includeCode ../../test/agents/agent.test.ts#example-agent-hooks}
|
|
111
133
|
*/
|
|
112
134
|
hooks;
|
|
135
|
+
retryOnError;
|
|
113
136
|
/**
|
|
114
137
|
* List of GuideRail agents applied to this agent
|
|
115
138
|
*
|
|
@@ -339,6 +362,7 @@ export class Agent {
|
|
|
339
362
|
}
|
|
340
363
|
async *processStreamingAndRetry(input, options) {
|
|
341
364
|
let output = {};
|
|
365
|
+
let attempt = 0;
|
|
342
366
|
for (;;) {
|
|
343
367
|
// Reset output to avoid accumulating old data
|
|
344
368
|
const resetOutput = Object.fromEntries(Object.entries(output).map(([key]) => [key, null]));
|
|
@@ -367,6 +391,15 @@ export class Agent {
|
|
|
367
391
|
break;
|
|
368
392
|
}
|
|
369
393
|
catch (error) {
|
|
394
|
+
if (this.retryOnError?.retries) {
|
|
395
|
+
const { retries, minTimeout = DEFAULT_RETRY_MIN_TIMEOUT, factor = DEFAULT_RETRY_FACTOR, randomize = false, shouldRetry, } = this.retryOnError;
|
|
396
|
+
if (attempt++ < retries && (!shouldRetry || (await shouldRetry(error)))) {
|
|
397
|
+
const timeout = minTimeout * factor ** (attempt - 1) * (randomize ? 1 + Math.random() : 1);
|
|
398
|
+
logger.warn(`Agent ${this.name} attempt ${attempt} of ${retries} failed with error: ${error}. Retrying in ${timeout}ms...`);
|
|
399
|
+
await new Promise((resolve) => setTimeout(resolve, timeout));
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
370
403
|
const res = await this.processAgentError(input, error, options);
|
|
371
404
|
if (!res.retry)
|
|
372
405
|
throw res.error ?? error;
|
|
@@ -458,9 +491,6 @@ export class Agent {
|
|
|
458
491
|
* @param options Invocation options
|
|
459
492
|
*/
|
|
460
493
|
async processAgentError(input, error, options) {
|
|
461
|
-
if ("$error_has_been_processed" in error && error.$error_has_been_processed)
|
|
462
|
-
return {};
|
|
463
|
-
Object.defineProperty(error, "$error_has_been_processed", { value: true, enumerable: false });
|
|
464
494
|
logger.error("Invoke agent %s failed with error: %O", this.name, error);
|
|
465
495
|
if (!this.disableEvents)
|
|
466
496
|
options.context.emit("agentFailed", { agent: this, error });
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type
|
|
2
|
+
import { type PromiseOrValue } from "../utils/type-utils.js";
|
|
3
3
|
import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type Message } from "./agent.js";
|
|
4
|
+
export declare class StructuredOutputError extends Error {
|
|
5
|
+
}
|
|
4
6
|
/**
|
|
5
7
|
* ChatModel is an abstract base class for interacting with Large Language Models (LLMs).
|
|
6
8
|
*
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import { Ajv } from "ajv";
|
|
2
|
+
import isNetworkError from "is-network-error";
|
|
1
3
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
4
|
+
import { checkArguments } from "../utils/type-utils.js";
|
|
5
|
+
import { Agent, agentOptionsSchema, } from "./agent.js";
|
|
6
|
+
const CHAT_MODEL_DEFAULT_RETRY_OPTIONS = {
|
|
7
|
+
retries: 3,
|
|
8
|
+
shouldRetry: (error) => error instanceof StructuredOutputError || isNetworkError(error),
|
|
9
|
+
};
|
|
10
|
+
export class StructuredOutputError extends Error {
|
|
11
|
+
}
|
|
3
12
|
/**
|
|
4
13
|
* ChatModel is an abstract base class for interacting with Large Language Models (LLMs).
|
|
5
14
|
*
|
|
@@ -26,10 +35,21 @@ import { Agent, } from "./agent.js";
|
|
|
26
35
|
export class ChatModel extends Agent {
|
|
27
36
|
tag = "ChatModelAgent";
|
|
28
37
|
constructor(options) {
|
|
38
|
+
if (options)
|
|
39
|
+
checkArguments("ChatModel", agentOptionsSchema, options);
|
|
40
|
+
const retryOnError = options?.retryOnError === false
|
|
41
|
+
? false
|
|
42
|
+
: options?.retryOnError === true
|
|
43
|
+
? CHAT_MODEL_DEFAULT_RETRY_OPTIONS
|
|
44
|
+
: {
|
|
45
|
+
...CHAT_MODEL_DEFAULT_RETRY_OPTIONS,
|
|
46
|
+
...options?.retryOnError,
|
|
47
|
+
};
|
|
29
48
|
super({
|
|
30
49
|
...options,
|
|
31
50
|
inputSchema: chatModelInputSchema,
|
|
32
51
|
outputSchema: chatModelOutputSchema,
|
|
52
|
+
retryOnError,
|
|
33
53
|
});
|
|
34
54
|
}
|
|
35
55
|
get credential() {
|
|
@@ -134,6 +154,14 @@ export class ChatModel extends Agent {
|
|
|
134
154
|
}
|
|
135
155
|
}
|
|
136
156
|
}
|
|
157
|
+
if (input.responseFormat?.type === "json_schema" &&
|
|
158
|
+
// NOTE: Should not validate if there are tool calls
|
|
159
|
+
!output.toolCalls?.length) {
|
|
160
|
+
const ajv = new Ajv();
|
|
161
|
+
if (!ajv.validate(input.responseFormat.jsonSchema.schema, output.json)) {
|
|
162
|
+
throw new StructuredOutputError(`Output JSON does not conform to the provided JSON schema: ${ajv.errorsText()}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
137
165
|
super.postprocess(input, output, options);
|
|
138
166
|
const { usage } = output;
|
|
139
167
|
if (usage) {
|
|
@@ -190,25 +190,34 @@ export class TeamAgent extends Agent {
|
|
|
190
190
|
let arr = input[this.iterateOn];
|
|
191
191
|
arr = Array.isArray(arr) ? [...arr] : isNil(arr) ? [arr] : [];
|
|
192
192
|
const results = new Array(arr.length);
|
|
193
|
+
let error;
|
|
193
194
|
const queue = fastq.promise(async ({ item, index }) => {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
195
|
+
try {
|
|
196
|
+
if (!isRecord(item))
|
|
197
|
+
throw new TypeError(`Expected ${String(key)} to be an object, got ${typeof item}`);
|
|
198
|
+
const o = await agentProcessResultToObject(await this._processNonIterator({ ...input, [key]: arr, ...item }, { ...options, streaming: false }));
|
|
199
|
+
const res = omit(o, key);
|
|
200
|
+
// Merge the item result with the original item used for next iteration
|
|
201
|
+
if (this.iterateWithPreviousOutput) {
|
|
202
|
+
arr = produce(arr, (draft) => {
|
|
203
|
+
const item = draft[index];
|
|
204
|
+
assert(item);
|
|
205
|
+
Object.assign(item, res);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
results[index] = res;
|
|
209
|
+
}
|
|
210
|
+
catch (e) {
|
|
211
|
+
error = e;
|
|
212
|
+
queue.killAndDrain();
|
|
205
213
|
}
|
|
206
|
-
results[index] = res;
|
|
207
214
|
}, this.concurrency);
|
|
208
215
|
for (let index = 0; index < arr.length; index++) {
|
|
209
216
|
queue.push({ index, item: arr[index] });
|
|
210
217
|
}
|
|
211
218
|
await queue.drained();
|
|
219
|
+
if (error)
|
|
220
|
+
throw error;
|
|
212
221
|
yield { delta: { json: { [key]: results } } };
|
|
213
222
|
}
|
|
214
223
|
_processNonIterator(input, options) {
|
|
@@ -163,7 +163,6 @@ export declare class AIGNEContext implements Context {
|
|
|
163
163
|
get observer(): AIGNEObserver | undefined;
|
|
164
164
|
get limits(): ContextLimits | undefined;
|
|
165
165
|
get status(): "normal" | "timeout";
|
|
166
|
-
get spans(): Span[];
|
|
167
166
|
get usage(): ContextUsage;
|
|
168
167
|
get userContext(): Context["userContext"];
|
|
169
168
|
set userContext(userContext: Context["userContext"]);
|
|
@@ -181,7 +180,6 @@ export declare class AIGNEContext implements Context {
|
|
|
181
180
|
subscribe: Context["subscribe"];
|
|
182
181
|
unsubscribe: Context["unsubscribe"];
|
|
183
182
|
emit<K extends keyof ContextEmitEventMap>(eventName: K, ...args: Args<K, ContextEmitEventMap>): boolean;
|
|
184
|
-
private endAllSpans;
|
|
185
183
|
private trace;
|
|
186
184
|
on<K extends keyof ContextEventMap>(eventName: K, listener: Listener<K, ContextEventMap>): this;
|
|
187
185
|
once<K extends keyof ContextEventMap>(eventName: K, listener: Listener<K, ContextEventMap>): this;
|
|
@@ -189,7 +187,6 @@ export declare class AIGNEContext implements Context {
|
|
|
189
187
|
}
|
|
190
188
|
declare class AIGNEContextShared {
|
|
191
189
|
private readonly parent?;
|
|
192
|
-
spans: Span[];
|
|
193
190
|
constructor(parent?: (Pick<Context, "model" | "imageModel" | "agents" | "skills" | "limits" | "observer"> & {
|
|
194
191
|
messageQueue?: MessageQueue;
|
|
195
192
|
events?: Emitter<any>;
|
|
@@ -202,7 +199,6 @@ declare class AIGNEContextShared {
|
|
|
202
199
|
get agents(): Agent<any, any>[];
|
|
203
200
|
get observer(): AIGNEObserver | undefined;
|
|
204
201
|
get limits(): ContextLimits | undefined;
|
|
205
|
-
addSpan(span: Span): void;
|
|
206
202
|
usage: ContextUsage;
|
|
207
203
|
userContext: Context["userContext"];
|
|
208
204
|
memories: Context["memories"];
|
package/lib/esm/aigne/context.js
CHANGED
|
@@ -39,9 +39,6 @@ export class AIGNEContext {
|
|
|
39
39
|
// 修改了 rootId 是否会之前的有影响?,之前为 this.id
|
|
40
40
|
this.rootId = this.span?.spanContext?.().traceId ?? v7();
|
|
41
41
|
}
|
|
42
|
-
if (this.span) {
|
|
43
|
-
this.internal.addSpan(this.span);
|
|
44
|
-
}
|
|
45
42
|
this.id = this.span?.spanContext()?.spanId ?? v7();
|
|
46
43
|
}
|
|
47
44
|
id;
|
|
@@ -73,9 +70,6 @@ export class AIGNEContext {
|
|
|
73
70
|
get status() {
|
|
74
71
|
return this.internal.status;
|
|
75
72
|
}
|
|
76
|
-
get spans() {
|
|
77
|
-
return this.internal.spans;
|
|
78
|
-
}
|
|
79
73
|
get usage() {
|
|
80
74
|
return this.internal.usage;
|
|
81
75
|
}
|
|
@@ -116,18 +110,12 @@ export class AIGNEContext {
|
|
|
116
110
|
const newContext = options?.newContext === false ? this : this.newContext();
|
|
117
111
|
return Promise.resolve(newContext.internal.invoke(agent, message, newContext, options)).then(async (response) => {
|
|
118
112
|
if (!options?.streaming) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return [output, activeAgent];
|
|
124
|
-
}
|
|
125
|
-
return output;
|
|
126
|
-
}
|
|
127
|
-
catch (error) {
|
|
128
|
-
this.endAllSpans(error);
|
|
129
|
-
throw error;
|
|
113
|
+
let { __activeAgent__: activeAgent, ...output } = await agentResponseStreamToObject(response);
|
|
114
|
+
output = await this.onInvocationResult(output, options);
|
|
115
|
+
if (options?.returnActiveAgent) {
|
|
116
|
+
return [output, activeAgent];
|
|
130
117
|
}
|
|
118
|
+
return output;
|
|
131
119
|
}
|
|
132
120
|
const activeAgentPromise = promiseWithResolvers();
|
|
133
121
|
const stream = onAgentResponseStreamEnd(asyncGeneratorToReadableStream(response), {
|
|
@@ -146,10 +134,6 @@ export class AIGNEContext {
|
|
|
146
134
|
activeAgentPromise.resolve(output.__activeAgent__);
|
|
147
135
|
return await this.onInvocationResult(output, options);
|
|
148
136
|
},
|
|
149
|
-
onError: (error) => {
|
|
150
|
-
this.endAllSpans(error);
|
|
151
|
-
return error;
|
|
152
|
-
},
|
|
153
137
|
});
|
|
154
138
|
const finalStream = !options.returnProgressChunks
|
|
155
139
|
? stream
|
|
@@ -211,12 +195,6 @@ export class AIGNEContext {
|
|
|
211
195
|
this.trace(eventName, args, b);
|
|
212
196
|
return this.internal.events.emit(eventName, ...newArgs);
|
|
213
197
|
}
|
|
214
|
-
async endAllSpans(error) {
|
|
215
|
-
this.spans.forEach((span) => {
|
|
216
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: error?.message });
|
|
217
|
-
span.end();
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
198
|
async trace(eventName, args, b) {
|
|
221
199
|
const span = this.span;
|
|
222
200
|
if (!span)
|
|
@@ -291,7 +269,6 @@ export class AIGNEContext {
|
|
|
291
269
|
}
|
|
292
270
|
class AIGNEContextShared {
|
|
293
271
|
parent;
|
|
294
|
-
spans = [];
|
|
295
272
|
constructor(parent) {
|
|
296
273
|
this.parent = parent;
|
|
297
274
|
this.messageQueue = this.parent?.messageQueue ?? new MessageQueue();
|
|
@@ -317,9 +294,6 @@ class AIGNEContextShared {
|
|
|
317
294
|
get limits() {
|
|
318
295
|
return this.parent?.limits;
|
|
319
296
|
}
|
|
320
|
-
addSpan(span) {
|
|
321
|
-
this.spans.push(span);
|
|
322
|
-
}
|
|
323
297
|
usage = newEmptyContextUsage();
|
|
324
298
|
userContext = {};
|
|
325
299
|
memories = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.56.0",
|
|
4
4
|
"description": "The functional core of agentic AI",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"@opentelemetry/api": "^1.9.0",
|
|
72
72
|
"@opentelemetry/sdk-trace-base": "^2.0.1",
|
|
73
73
|
"@types/debug": "^4.1.12",
|
|
74
|
+
"ajv": "^8.17.1",
|
|
74
75
|
"camelize-ts": "^3.0.0",
|
|
75
76
|
"content-type": "^1.0.5",
|
|
76
77
|
"debug": "^4.4.1",
|
|
@@ -78,6 +79,7 @@
|
|
|
78
79
|
"fast-deep-equal": "^3.1.3",
|
|
79
80
|
"fastq": "^1.19.1",
|
|
80
81
|
"immer": "^10.1.1",
|
|
82
|
+
"is-network-error": "^1.1.0",
|
|
81
83
|
"jaison": "^2.0.2",
|
|
82
84
|
"jsonata": "^2.0.6",
|
|
83
85
|
"nunjucks": "^3.2.4",
|
|
@@ -89,7 +91,7 @@
|
|
|
89
91
|
"yaml": "^2.8.0",
|
|
90
92
|
"zod": "^3.25.67",
|
|
91
93
|
"zod-to-json-schema": "^3.24.6",
|
|
92
|
-
"@aigne/observability-api": "^0.10.
|
|
94
|
+
"@aigne/observability-api": "^0.10.1",
|
|
93
95
|
"@aigne/platform-helpers": "^0.6.2"
|
|
94
96
|
},
|
|
95
97
|
"devDependencies": {
|