@aigne/core 1.63.0-beta.7 → 1.63.0-beta.9
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 +24 -0
- package/lib/cjs/agents/agent.d.ts +2 -1
- package/lib/cjs/agents/agent.js +12 -4
- package/lib/cjs/agents/chat-model.js +1 -1
- package/lib/cjs/prompt/prompt-builder.js +14 -5
- package/lib/dts/agents/agent.d.ts +2 -1
- package/lib/esm/agents/agent.d.ts +2 -1
- package/lib/esm/agents/agent.js +12 -4
- package/lib/esm/agents/chat-model.js +1 -1
- package/lib/esm/prompt/prompt-builder.js +14 -5
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.63.0-beta.9](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0-beta.8...core-v1.63.0-beta.9) (2025-10-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* allow custom user messages and prevent duplicate user content ([#632](https://github.com/AIGNE-io/aigne-framework/issues/632)) ([6c883b2](https://github.com/AIGNE-io/aigne-framework/commit/6c883b2d57a65e9b46232cece91fc6aa1de03aba))
|
|
9
|
+
* **models:** auto retry when got emtpy response from gemini ([#636](https://github.com/AIGNE-io/aigne-framework/issues/636)) ([9367cef](https://github.com/AIGNE-io/aigne-framework/commit/9367cef49ea4c0c87b8a36b454deb2efaee6886f))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Dependencies
|
|
13
|
+
|
|
14
|
+
* The following workspace dependencies were updated
|
|
15
|
+
* dependencies
|
|
16
|
+
* @aigne/observability-api bumped to 0.11.2-beta.4
|
|
17
|
+
|
|
18
|
+
## [1.63.0-beta.8](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0-beta.7...core-v1.63.0-beta.8) (2025-10-16)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Dependencies
|
|
22
|
+
|
|
23
|
+
* The following workspace dependencies were updated
|
|
24
|
+
* dependencies
|
|
25
|
+
* @aigne/observability-api bumped to 0.11.2-beta.3
|
|
26
|
+
|
|
3
27
|
## [1.63.0-beta.7](https://github.com/AIGNE-io/aigne-framework/compare/core-v1.63.0-beta.6...core-v1.63.0-beta.7) (2025-10-15)
|
|
4
28
|
|
|
5
29
|
|
package/lib/cjs/agents/agent.js
CHANGED
|
@@ -451,7 +451,10 @@ class Agent {
|
|
|
451
451
|
(0, stream_utils_js_1.mergeAgentResponseChunk)(output, chunk);
|
|
452
452
|
yield chunk;
|
|
453
453
|
}
|
|
454
|
-
|
|
454
|
+
let result = await this.processAgentOutput(input, output, options);
|
|
455
|
+
if (attempt > 0) {
|
|
456
|
+
result = { ...result, $meta: { ...result.$meta, retries: attempt } };
|
|
457
|
+
}
|
|
455
458
|
if (result && !(0, fast_deep_equal_1.default)(result, output)) {
|
|
456
459
|
yield { delta: { json: result } };
|
|
457
460
|
}
|
|
@@ -461,7 +464,8 @@ class Agent {
|
|
|
461
464
|
catch (error) {
|
|
462
465
|
if (this.retryOnError?.retries) {
|
|
463
466
|
const { retries, minTimeout = DEFAULT_RETRY_MIN_TIMEOUT, factor = DEFAULT_RETRY_FACTOR, randomize = false, shouldRetry, } = this.retryOnError;
|
|
464
|
-
if (attempt
|
|
467
|
+
if (attempt < retries && (!shouldRetry || (await shouldRetry(error)))) {
|
|
468
|
+
attempt++;
|
|
465
469
|
const timeout = minTimeout * factor ** (attempt - 1) * (randomize ? 1 + Math.random() : 1);
|
|
466
470
|
logger_js_1.logger.warn(`Agent ${this.name} attempt ${attempt} of ${retries} failed with error: ${error}. Retrying in ${timeout}ms...`);
|
|
467
471
|
await new Promise((resolve) => setTimeout(resolve, timeout));
|
|
@@ -469,8 +473,12 @@ class Agent {
|
|
|
469
473
|
}
|
|
470
474
|
}
|
|
471
475
|
const res = await this.processAgentError(input, error, options);
|
|
472
|
-
if (!res.retry)
|
|
473
|
-
|
|
476
|
+
if (!res.retry) {
|
|
477
|
+
const e = res.error ?? error;
|
|
478
|
+
if (attempt > 0)
|
|
479
|
+
e.message += ` (after ${attempt} retries)`;
|
|
480
|
+
throw e;
|
|
481
|
+
}
|
|
474
482
|
}
|
|
475
483
|
}
|
|
476
484
|
}
|
|
@@ -42,7 +42,7 @@ const type_utils_js_1 = require("../utils/type-utils.js");
|
|
|
42
42
|
const agent_js_1 = require("./agent.js");
|
|
43
43
|
const model_js_1 = require("./model.js");
|
|
44
44
|
const CHAT_MODEL_DEFAULT_RETRY_OPTIONS = {
|
|
45
|
-
retries:
|
|
45
|
+
retries: 10,
|
|
46
46
|
shouldRetry: async (error) => error instanceof StructuredOutputError || (await Promise.resolve().then(() => __importStar(require("is-network-error")))).default(error),
|
|
47
47
|
};
|
|
48
48
|
class StructuredOutputError extends Error {
|
|
@@ -87,9 +87,9 @@ class PromptBuilder {
|
|
|
87
87
|
const { input } = options;
|
|
88
88
|
const inputKey = options.agent?.inputKey;
|
|
89
89
|
const message = inputKey && typeof input?.[inputKey] === "string" ? input[inputKey] : undefined;
|
|
90
|
-
const messages = (await (typeof this.instructions === "string"
|
|
90
|
+
const [messages, otherCustomMessages] = (0, type_utils_js_1.partition)((await (typeof this.instructions === "string"
|
|
91
91
|
? template_js_1.ChatMessagesTemplate.from([template_js_1.SystemMessageTemplate.from(this.instructions)])
|
|
92
|
-
: this.instructions)?.format(options.input, { workingDir: this.workingDir })) ?? [];
|
|
92
|
+
: this.instructions)?.format(options.input, { workingDir: this.workingDir })) ?? [], (i) => i.role === "system");
|
|
93
93
|
const inputFileKey = options.agent?.inputFileKey;
|
|
94
94
|
const files = (0, type_utils_js_1.flat)(inputFileKey
|
|
95
95
|
? (0, type_utils_js_1.checkArguments)("Check input files", (0, schema_js_1.optionalize)(model_js_1.fileUnionContentsSchema), input?.[inputFileKey])
|
|
@@ -102,7 +102,7 @@ class PromptBuilder {
|
|
|
102
102
|
memories.push(...options.context.memories);
|
|
103
103
|
}
|
|
104
104
|
if (options.agent?.afs) {
|
|
105
|
-
messages.push(template_js_1.SystemMessageTemplate.from(await (0, afs_builtin_prompt_js_1.getAFSSystemPrompt)(options.agent.afs)));
|
|
105
|
+
messages.push(await template_js_1.SystemMessageTemplate.from(await (0, afs_builtin_prompt_js_1.getAFSSystemPrompt)(options.agent.afs)).format({}));
|
|
106
106
|
if (options.agent.afsConfig?.injectHistory) {
|
|
107
107
|
const history = await options.agent.afs.list(afs_1.AFSHistory.Path, {
|
|
108
108
|
limit: options.agent.afsConfig.historyWindowSize || 10,
|
|
@@ -132,12 +132,21 @@ class PromptBuilder {
|
|
|
132
132
|
}
|
|
133
133
|
if (message || files.length) {
|
|
134
134
|
const content = [];
|
|
135
|
-
if (message
|
|
135
|
+
if (message &&
|
|
136
|
+
// avoid duplicate user messages: developer may have already included the message in the custom user messages
|
|
137
|
+
!otherCustomMessages.some((i) => i.role === "user" &&
|
|
138
|
+
(typeof i.content === "string"
|
|
139
|
+
? i.content.includes(message)
|
|
140
|
+
: i.content?.some((c) => c.type === "text" && c.text.includes(message))))) {
|
|
136
141
|
content.push({ type: "text", text: message });
|
|
142
|
+
}
|
|
137
143
|
if (files.length)
|
|
138
144
|
content.push(...files);
|
|
139
|
-
|
|
145
|
+
if (content.length) {
|
|
146
|
+
messages.push({ role: "user", content });
|
|
147
|
+
}
|
|
140
148
|
}
|
|
149
|
+
messages.push(...otherCustomMessages);
|
|
141
150
|
return this.refineMessages(options, messages);
|
|
142
151
|
}
|
|
143
152
|
refineMessages(options, messages) {
|
package/lib/esm/agents/agent.js
CHANGED
|
@@ -403,7 +403,10 @@ export class Agent {
|
|
|
403
403
|
mergeAgentResponseChunk(output, chunk);
|
|
404
404
|
yield chunk;
|
|
405
405
|
}
|
|
406
|
-
|
|
406
|
+
let result = await this.processAgentOutput(input, output, options);
|
|
407
|
+
if (attempt > 0) {
|
|
408
|
+
result = { ...result, $meta: { ...result.$meta, retries: attempt } };
|
|
409
|
+
}
|
|
407
410
|
if (result && !equal(result, output)) {
|
|
408
411
|
yield { delta: { json: result } };
|
|
409
412
|
}
|
|
@@ -413,7 +416,8 @@ export class Agent {
|
|
|
413
416
|
catch (error) {
|
|
414
417
|
if (this.retryOnError?.retries) {
|
|
415
418
|
const { retries, minTimeout = DEFAULT_RETRY_MIN_TIMEOUT, factor = DEFAULT_RETRY_FACTOR, randomize = false, shouldRetry, } = this.retryOnError;
|
|
416
|
-
if (attempt
|
|
419
|
+
if (attempt < retries && (!shouldRetry || (await shouldRetry(error)))) {
|
|
420
|
+
attempt++;
|
|
417
421
|
const timeout = minTimeout * factor ** (attempt - 1) * (randomize ? 1 + Math.random() : 1);
|
|
418
422
|
logger.warn(`Agent ${this.name} attempt ${attempt} of ${retries} failed with error: ${error}. Retrying in ${timeout}ms...`);
|
|
419
423
|
await new Promise((resolve) => setTimeout(resolve, timeout));
|
|
@@ -421,8 +425,12 @@ export class Agent {
|
|
|
421
425
|
}
|
|
422
426
|
}
|
|
423
427
|
const res = await this.processAgentError(input, error, options);
|
|
424
|
-
if (!res.retry)
|
|
425
|
-
|
|
428
|
+
if (!res.retry) {
|
|
429
|
+
const e = res.error ?? error;
|
|
430
|
+
if (attempt > 0)
|
|
431
|
+
e.message += ` (after ${attempt} retries)`;
|
|
432
|
+
throw e;
|
|
433
|
+
}
|
|
426
434
|
}
|
|
427
435
|
}
|
|
428
436
|
}
|
|
@@ -6,7 +6,7 @@ import { checkArguments, isNil, omitByDeep } from "../utils/type-utils.js";
|
|
|
6
6
|
import { agentOptionsSchema, } from "./agent.js";
|
|
7
7
|
import { fileContentSchema, fileUnionContentSchema, localContentSchema, Model, urlContentSchema, } from "./model.js";
|
|
8
8
|
const CHAT_MODEL_DEFAULT_RETRY_OPTIONS = {
|
|
9
|
-
retries:
|
|
9
|
+
retries: 10,
|
|
10
10
|
shouldRetry: async (error) => error instanceof StructuredOutputError || (await import("is-network-error")).default(error),
|
|
11
11
|
};
|
|
12
12
|
export class StructuredOutputError extends Error {
|
|
@@ -84,9 +84,9 @@ export class PromptBuilder {
|
|
|
84
84
|
const { input } = options;
|
|
85
85
|
const inputKey = options.agent?.inputKey;
|
|
86
86
|
const message = inputKey && typeof input?.[inputKey] === "string" ? input[inputKey] : undefined;
|
|
87
|
-
const messages = (await (typeof this.instructions === "string"
|
|
87
|
+
const [messages, otherCustomMessages] = partition((await (typeof this.instructions === "string"
|
|
88
88
|
? ChatMessagesTemplate.from([SystemMessageTemplate.from(this.instructions)])
|
|
89
|
-
: this.instructions)?.format(options.input, { workingDir: this.workingDir })) ?? [];
|
|
89
|
+
: this.instructions)?.format(options.input, { workingDir: this.workingDir })) ?? [], (i) => i.role === "system");
|
|
90
90
|
const inputFileKey = options.agent?.inputFileKey;
|
|
91
91
|
const files = flat(inputFileKey
|
|
92
92
|
? checkArguments("Check input files", optionalize(fileUnionContentsSchema), input?.[inputFileKey])
|
|
@@ -99,7 +99,7 @@ export class PromptBuilder {
|
|
|
99
99
|
memories.push(...options.context.memories);
|
|
100
100
|
}
|
|
101
101
|
if (options.agent?.afs) {
|
|
102
|
-
messages.push(SystemMessageTemplate.from(await getAFSSystemPrompt(options.agent.afs)));
|
|
102
|
+
messages.push(await SystemMessageTemplate.from(await getAFSSystemPrompt(options.agent.afs)).format({}));
|
|
103
103
|
if (options.agent.afsConfig?.injectHistory) {
|
|
104
104
|
const history = await options.agent.afs.list(AFSHistory.Path, {
|
|
105
105
|
limit: options.agent.afsConfig.historyWindowSize || 10,
|
|
@@ -129,12 +129,21 @@ export class PromptBuilder {
|
|
|
129
129
|
}
|
|
130
130
|
if (message || files.length) {
|
|
131
131
|
const content = [];
|
|
132
|
-
if (message
|
|
132
|
+
if (message &&
|
|
133
|
+
// avoid duplicate user messages: developer may have already included the message in the custom user messages
|
|
134
|
+
!otherCustomMessages.some((i) => i.role === "user" &&
|
|
135
|
+
(typeof i.content === "string"
|
|
136
|
+
? i.content.includes(message)
|
|
137
|
+
: i.content?.some((c) => c.type === "text" && c.text.includes(message))))) {
|
|
133
138
|
content.push({ type: "text", text: message });
|
|
139
|
+
}
|
|
134
140
|
if (files.length)
|
|
135
141
|
content.push(...files);
|
|
136
|
-
|
|
142
|
+
if (content.length) {
|
|
143
|
+
messages.push({ role: "user", content });
|
|
144
|
+
}
|
|
137
145
|
}
|
|
146
|
+
messages.push(...otherCustomMessages);
|
|
138
147
|
return this.refineMessages(options, messages);
|
|
139
148
|
}
|
|
140
149
|
refineMessages(options, messages) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/core",
|
|
3
|
-
"version": "1.63.0-beta.
|
|
3
|
+
"version": "1.63.0-beta.9",
|
|
4
4
|
"description": "The functional core of agentic AI",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -92,8 +92,8 @@
|
|
|
92
92
|
"zod": "^3.25.67",
|
|
93
93
|
"zod-from-json-schema": "^0.0.5",
|
|
94
94
|
"zod-to-json-schema": "^3.24.6",
|
|
95
|
-
"@aigne/observability-api": "^0.11.2-beta.2",
|
|
96
95
|
"@aigne/afs": "^1.1.0-beta",
|
|
96
|
+
"@aigne/observability-api": "^0.11.2-beta.4",
|
|
97
97
|
"@aigne/platform-helpers": "^0.6.3"
|
|
98
98
|
},
|
|
99
99
|
"devDependencies": {
|