@aigne/core 1.72.0-beta.2 → 1.72.0-beta.23
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 +261 -0
- package/lib/cjs/agents/agent.d.ts +42 -11
- package/lib/cjs/agents/agent.js +34 -8
- package/lib/cjs/agents/ai-agent.d.ts +63 -4
- package/lib/cjs/agents/ai-agent.js +154 -20
- package/lib/cjs/agents/chat-model.d.ts +157 -0
- package/lib/cjs/agents/chat-model.js +71 -6
- package/lib/cjs/agents/image-agent.d.ts +17 -1
- package/lib/cjs/agents/image-agent.js +16 -0
- package/lib/cjs/agents/image-model.d.ts +12 -2
- package/lib/cjs/agents/image-model.js +1 -1
- package/lib/cjs/agents/mcp-agent.d.ts +17 -0
- package/lib/cjs/agents/mcp-agent.js +18 -0
- package/lib/cjs/agents/model.d.ts +3 -3
- package/lib/cjs/agents/model.js +2 -2
- package/lib/cjs/agents/team-agent.d.ts +55 -0
- package/lib/cjs/agents/team-agent.js +31 -0
- package/lib/cjs/agents/transform-agent.d.ts +12 -0
- package/lib/cjs/agents/transform-agent.js +13 -0
- package/lib/cjs/agents/video-model.d.ts +10 -0
- package/lib/cjs/agents/video-model.js +1 -1
- package/lib/cjs/aigne/context.js +1 -3
- package/lib/cjs/aigne/usage.d.ts +4 -0
- package/lib/cjs/aigne/usage.js +6 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/loader/agent-yaml.d.ts +5 -63
- package/lib/cjs/loader/agent-yaml.js +4 -129
- package/lib/cjs/loader/agents.d.ts +4 -0
- package/lib/cjs/loader/agents.js +17 -0
- package/lib/cjs/loader/index.d.ts +16 -12
- package/lib/cjs/loader/index.js +20 -81
- package/lib/cjs/loader/schema.d.ts +21 -6
- package/lib/cjs/loader/schema.js +60 -1
- package/lib/cjs/memory/recorder.d.ts +4 -4
- package/lib/cjs/memory/retriever.d.ts +4 -4
- package/lib/cjs/prompt/agent-session.d.ts +163 -0
- package/lib/cjs/prompt/agent-session.js +1008 -0
- package/lib/cjs/prompt/compact/compactor.d.ts +7 -0
- package/lib/cjs/prompt/compact/compactor.js +52 -0
- package/lib/cjs/prompt/compact/session-memory-extractor.d.ts +7 -0
- package/lib/cjs/prompt/compact/session-memory-extractor.js +143 -0
- package/lib/cjs/prompt/compact/types.d.ts +336 -0
- package/lib/cjs/prompt/compact/types.js +53 -0
- package/lib/cjs/prompt/compact/user-memory-extractor.d.ts +7 -0
- package/lib/cjs/prompt/compact/user-memory-extractor.js +124 -0
- package/lib/cjs/prompt/context/afs/history.d.ts +5 -1
- package/lib/cjs/prompt/context/afs/history.js +3 -2
- package/lib/cjs/prompt/context/afs/index.js +8 -1
- package/lib/cjs/prompt/prompt-builder.d.ts +11 -9
- package/lib/cjs/prompt/prompt-builder.js +79 -120
- package/lib/cjs/prompt/skills/afs/agent-skill/agent-skill.d.ts +19 -0
- package/lib/cjs/prompt/skills/afs/agent-skill/agent-skill.js +69 -0
- package/lib/cjs/prompt/skills/afs/agent-skill/skill-loader.d.ts +12 -0
- package/lib/cjs/prompt/skills/afs/agent-skill/skill-loader.js +50 -0
- package/lib/cjs/prompt/skills/afs/delete.js +15 -3
- package/lib/cjs/prompt/skills/afs/edit.d.ts +6 -9
- package/lib/cjs/prompt/skills/afs/edit.js +85 -59
- package/lib/cjs/prompt/skills/afs/exec.js +17 -6
- package/lib/cjs/prompt/skills/afs/index.js +4 -1
- package/lib/cjs/prompt/skills/afs/list.d.ts +2 -0
- package/lib/cjs/prompt/skills/afs/list.js +35 -11
- package/lib/cjs/prompt/skills/afs/read.d.ts +9 -3
- package/lib/cjs/prompt/skills/afs/read.js +67 -15
- package/lib/cjs/prompt/skills/afs/rename.js +18 -4
- package/lib/cjs/prompt/skills/afs/search.js +21 -5
- package/lib/cjs/prompt/skills/afs/write.js +20 -6
- package/lib/cjs/prompt/template.d.ts +84 -9
- package/lib/cjs/prompt/template.js +46 -17
- package/lib/cjs/utils/mcp-utils.js +1 -1
- package/lib/cjs/utils/token-estimator.js +1 -1
- package/lib/dts/agents/agent.d.ts +42 -11
- package/lib/dts/agents/ai-agent.d.ts +63 -4
- package/lib/dts/agents/chat-model.d.ts +157 -0
- package/lib/dts/agents/image-agent.d.ts +17 -1
- package/lib/dts/agents/image-model.d.ts +12 -2
- package/lib/dts/agents/mcp-agent.d.ts +17 -0
- package/lib/dts/agents/model.d.ts +3 -3
- package/lib/dts/agents/team-agent.d.ts +55 -0
- package/lib/dts/agents/transform-agent.d.ts +12 -0
- package/lib/dts/agents/video-model.d.ts +10 -0
- package/lib/dts/aigne/context.d.ts +2 -2
- package/lib/dts/aigne/usage.d.ts +4 -0
- package/lib/dts/index.d.ts +1 -0
- package/lib/dts/loader/agent-yaml.d.ts +5 -63
- package/lib/dts/loader/agents.d.ts +4 -0
- package/lib/dts/loader/index.d.ts +16 -12
- package/lib/dts/loader/schema.d.ts +21 -6
- package/lib/dts/memory/recorder.d.ts +4 -4
- package/lib/dts/memory/retriever.d.ts +4 -4
- package/lib/dts/prompt/agent-session.d.ts +163 -0
- package/lib/dts/prompt/compact/compactor.d.ts +7 -0
- package/lib/dts/prompt/compact/session-memory-extractor.d.ts +7 -0
- package/lib/dts/prompt/compact/types.d.ts +336 -0
- package/lib/dts/prompt/compact/user-memory-extractor.d.ts +7 -0
- package/lib/dts/prompt/context/afs/history.d.ts +5 -1
- package/lib/dts/prompt/prompt-builder.d.ts +11 -9
- package/lib/dts/prompt/skills/afs/agent-skill/agent-skill.d.ts +19 -0
- package/lib/dts/prompt/skills/afs/agent-skill/skill-loader.d.ts +12 -0
- package/lib/dts/prompt/skills/afs/edit.d.ts +6 -9
- package/lib/dts/prompt/skills/afs/list.d.ts +2 -0
- package/lib/dts/prompt/skills/afs/read.d.ts +9 -3
- package/lib/dts/prompt/template.d.ts +84 -9
- package/lib/esm/agents/agent.d.ts +42 -11
- package/lib/esm/agents/agent.js +34 -8
- package/lib/esm/agents/ai-agent.d.ts +63 -4
- package/lib/esm/agents/ai-agent.js +154 -20
- package/lib/esm/agents/chat-model.d.ts +157 -0
- package/lib/esm/agents/chat-model.js +70 -5
- package/lib/esm/agents/image-agent.d.ts +17 -1
- package/lib/esm/agents/image-agent.js +16 -0
- package/lib/esm/agents/image-model.d.ts +12 -2
- package/lib/esm/agents/image-model.js +1 -1
- package/lib/esm/agents/mcp-agent.d.ts +17 -0
- package/lib/esm/agents/mcp-agent.js +18 -0
- package/lib/esm/agents/model.d.ts +3 -3
- package/lib/esm/agents/model.js +2 -2
- package/lib/esm/agents/team-agent.d.ts +55 -0
- package/lib/esm/agents/team-agent.js +31 -0
- package/lib/esm/agents/transform-agent.d.ts +12 -0
- package/lib/esm/agents/transform-agent.js +13 -0
- package/lib/esm/agents/video-model.d.ts +10 -0
- package/lib/esm/agents/video-model.js +1 -1
- package/lib/esm/aigne/context.d.ts +2 -2
- package/lib/esm/aigne/context.js +2 -4
- package/lib/esm/aigne/usage.d.ts +4 -0
- package/lib/esm/aigne/usage.js +6 -0
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/loader/agent-yaml.d.ts +5 -63
- package/lib/esm/loader/agent-yaml.js +4 -128
- package/lib/esm/loader/agents.d.ts +4 -0
- package/lib/esm/loader/agents.js +14 -0
- package/lib/esm/loader/index.d.ts +16 -12
- package/lib/esm/loader/index.js +21 -81
- package/lib/esm/loader/schema.d.ts +21 -6
- package/lib/esm/loader/schema.js +57 -0
- package/lib/esm/memory/recorder.d.ts +4 -4
- package/lib/esm/memory/retriever.d.ts +4 -4
- package/lib/esm/prompt/agent-session.d.ts +163 -0
- package/lib/esm/prompt/agent-session.js +968 -0
- package/lib/esm/prompt/compact/compactor.d.ts +7 -0
- package/lib/esm/prompt/compact/compactor.js +48 -0
- package/lib/esm/prompt/compact/session-memory-extractor.d.ts +7 -0
- package/lib/esm/prompt/compact/session-memory-extractor.js +139 -0
- package/lib/esm/prompt/compact/types.d.ts +336 -0
- package/lib/esm/prompt/compact/types.js +50 -0
- package/lib/esm/prompt/compact/user-memory-extractor.d.ts +7 -0
- package/lib/esm/prompt/compact/user-memory-extractor.js +120 -0
- package/lib/esm/prompt/context/afs/history.d.ts +5 -1
- package/lib/esm/prompt/context/afs/history.js +3 -2
- package/lib/esm/prompt/context/afs/index.js +8 -1
- package/lib/esm/prompt/prompt-builder.d.ts +11 -9
- package/lib/esm/prompt/prompt-builder.js +80 -121
- package/lib/esm/prompt/skills/afs/agent-skill/agent-skill.d.ts +19 -0
- package/lib/esm/prompt/skills/afs/agent-skill/agent-skill.js +65 -0
- package/lib/esm/prompt/skills/afs/agent-skill/skill-loader.d.ts +12 -0
- package/lib/esm/prompt/skills/afs/agent-skill/skill-loader.js +43 -0
- package/lib/esm/prompt/skills/afs/delete.js +15 -3
- package/lib/esm/prompt/skills/afs/edit.d.ts +6 -9
- package/lib/esm/prompt/skills/afs/edit.js +85 -59
- package/lib/esm/prompt/skills/afs/exec.js +17 -6
- package/lib/esm/prompt/skills/afs/index.js +4 -1
- package/lib/esm/prompt/skills/afs/list.d.ts +2 -0
- package/lib/esm/prompt/skills/afs/list.js +35 -11
- package/lib/esm/prompt/skills/afs/read.d.ts +9 -3
- package/lib/esm/prompt/skills/afs/read.js +67 -15
- package/lib/esm/prompt/skills/afs/rename.js +18 -4
- package/lib/esm/prompt/skills/afs/search.js +21 -5
- package/lib/esm/prompt/skills/afs/write.js +20 -6
- package/lib/esm/prompt/template.d.ts +84 -9
- package/lib/esm/prompt/template.js +46 -17
- package/lib/esm/utils/mcp-utils.js +1 -1
- package/lib/esm/utils/token-estimator.js +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AIUserMemoryExtractor = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const ai_agent_js_1 = require("../../agents/ai-agent.js");
|
|
6
|
+
const type_utils_js_1 = require("../../utils/type-utils.js");
|
|
7
|
+
const EXTRACTOR_INSTRUCTIONS = `\
|
|
8
|
+
You are a user memory extractor. Your task is to extract long-term user memory facts from session memory that represent verified, persistent user characteristics.
|
|
9
|
+
|
|
10
|
+
## Session Memory Facts (from current session)
|
|
11
|
+
|
|
12
|
+
${"```"}yaml alt="session-facts"
|
|
13
|
+
{{ sessionFacts | yaml.stringify }}
|
|
14
|
+
${"```"}
|
|
15
|
+
|
|
16
|
+
## Existing User Memory Facts
|
|
17
|
+
|
|
18
|
+
${"```"}yaml alt="existing-user-facts"
|
|
19
|
+
{{ existingUserFacts | yaml.stringify }}
|
|
20
|
+
${"```"}
|
|
21
|
+
|
|
22
|
+
## Guidelines
|
|
23
|
+
|
|
24
|
+
1. **Extract session facts into long-term user memory**:
|
|
25
|
+
- Promote facts that represent lasting user characteristics (preferences, skills, working style)
|
|
26
|
+
- Filter out temporary or session-specific information
|
|
27
|
+
- Aggregate patterns observed across multiple sessions
|
|
28
|
+
- Verify consistency with existing user memory
|
|
29
|
+
|
|
30
|
+
2. **User memory should focus on USER characteristics**:
|
|
31
|
+
- **Preferences**: Lasting tool/framework/language preferences the user likes to use
|
|
32
|
+
- **Skills**: Confirmed technical expertise and proficiency levels of the user
|
|
33
|
+
- **Working style**: User's communication preferences, workflow patterns, coding standards
|
|
34
|
+
- **Personal context**: Stable personal context (timezone, team structure, role, work hours)
|
|
35
|
+
- **Project basic info**: What projects the user is working on and their role in them
|
|
36
|
+
- Example: "User is building an AI Agent framework called aigne-framework"
|
|
37
|
+
- Example: "User is the tech lead on a React e-commerce project"
|
|
38
|
+
- DO NOT include project technical details, architecture, or implementation specifics
|
|
39
|
+
|
|
40
|
+
3. **DO NOT include in user memory**:
|
|
41
|
+
- Session-specific tasks or temporary goals
|
|
42
|
+
- Bugs or issues being debugged in a specific session
|
|
43
|
+
- One-time decisions or experimental choices
|
|
44
|
+
- Unverified assumptions or single-instance observations
|
|
45
|
+
- **Project technical details**: architecture decisions, tech stack specifics, implementation details
|
|
46
|
+
- **Project problems**: current bugs, issues, technical debt, or temporary blockers
|
|
47
|
+
- Information about the codebase structure or specific files/modules
|
|
48
|
+
|
|
49
|
+
4. **Output only changes (CRITICAL)**:
|
|
50
|
+
- Only output facts that need to be added or updated
|
|
51
|
+
- DO NOT output facts that already exist and don't need changes
|
|
52
|
+
- Each label in newFacts must be unique
|
|
53
|
+
- When a label already exists in user memory:
|
|
54
|
+
- Include it in newFacts ONLY if session provides new information to update it
|
|
55
|
+
- Omit it from newFacts if it doesn't need changes
|
|
56
|
+
- Use the same label format as session memory: "pref-*", "skill-*", "proj-*", "ctx-*"
|
|
57
|
+
|
|
58
|
+
5. **When to output a fact in newFacts**:
|
|
59
|
+
- **New fact**: Extracting a brand new user characteristic not in existing user memory
|
|
60
|
+
- **Updated fact**: Session provides new information that enhances an existing fact
|
|
61
|
+
- **Refined fact**: Multiple sessions show patterns that refine existing facts
|
|
62
|
+
- DO NOT output if: The fact already exists and session doesn't add new information
|
|
63
|
+
|
|
64
|
+
6. **When to remove facts** (add labels to removeFacts):
|
|
65
|
+
- Facts are proven to be outdated or incorrect
|
|
66
|
+
- User explicitly changed their approach permanently
|
|
67
|
+
- Facts are redundant with newer, better facts
|
|
68
|
+
|
|
69
|
+
7. **Confidence scoring**:
|
|
70
|
+
- Higher confidence (0.8-1.0): Verified across multiple sessions or explicitly stated
|
|
71
|
+
- Medium confidence (0.5-0.7): Observed patterns but limited data
|
|
72
|
+
- Lower confidence (0.3-0.4): Tentative patterns, may need more verification
|
|
73
|
+
- Below 0.3: Don't extract into user memory yet
|
|
74
|
+
|
|
75
|
+
8. **Extraction criteria**:
|
|
76
|
+
- Only extract facts that are clearly valuable long-term
|
|
77
|
+
- Prefer quality over quantity - fewer high-confidence facts are better
|
|
78
|
+
- When in doubt, wait for more sessions to verify the pattern
|
|
79
|
+
|
|
80
|
+
Output the extracted user memory facts and any facts to remove.`;
|
|
81
|
+
class AIUserMemoryExtractor extends ai_agent_js_1.AIAgent {
|
|
82
|
+
constructor(options) {
|
|
83
|
+
super({
|
|
84
|
+
name: "UserMemoryExtractor",
|
|
85
|
+
description: "Extracts long-term user memory facts from session memory",
|
|
86
|
+
inputSchema: zod_1.z.object({
|
|
87
|
+
sessionFacts: zod_1.z
|
|
88
|
+
.array(zod_1.z.object({
|
|
89
|
+
label: zod_1.z.string(),
|
|
90
|
+
fact: zod_1.z.string(),
|
|
91
|
+
confidence: (0, zod_1.optional)(zod_1.z.number()),
|
|
92
|
+
tags: (0, zod_1.optional)(zod_1.z.array(zod_1.z.string())),
|
|
93
|
+
}))
|
|
94
|
+
.describe("Session memory facts to extract from"),
|
|
95
|
+
existingUserFacts: (0, zod_1.optional)(zod_1.z
|
|
96
|
+
.array(zod_1.z.object({
|
|
97
|
+
label: zod_1.z.string(),
|
|
98
|
+
fact: zod_1.z.string(),
|
|
99
|
+
confidence: (0, zod_1.optional)(zod_1.z.number()),
|
|
100
|
+
tags: (0, zod_1.optional)(zod_1.z.array(zod_1.z.string())),
|
|
101
|
+
}))
|
|
102
|
+
.describe("Existing user memory facts for context and deduplication")),
|
|
103
|
+
}),
|
|
104
|
+
outputSchema: zod_1.z.object({
|
|
105
|
+
newFacts: zod_1.z
|
|
106
|
+
.array(zod_1.z.object({
|
|
107
|
+
label: zod_1.z.string().describe("Short, semantic label for the fact (must be unique)"),
|
|
108
|
+
fact: zod_1.z.string().describe("The extracted fact content"),
|
|
109
|
+
confidence: (0, zod_1.optional)(zod_1.z.number().min(0).max(1).describe("Confidence score (0-1)")),
|
|
110
|
+
tags: (0, zod_1.optional)(zod_1.z.array(zod_1.z.string()).describe("Classification tags")),
|
|
111
|
+
}))
|
|
112
|
+
.describe("Facts to add or update in user memory. Only include facts that are new or need updates. Do not include unchanged facts."),
|
|
113
|
+
removeFacts: (0, zod_1.optional)(zod_1.z.array(zod_1.z.string()).describe("Labels of facts to remove from user memory")),
|
|
114
|
+
}),
|
|
115
|
+
instructions: EXTRACTOR_INSTRUCTIONS,
|
|
116
|
+
taskRenderMode: "hide",
|
|
117
|
+
...(0, type_utils_js_1.omitBy)(options ?? {}, (v) => (0, type_utils_js_1.isNil)(v)),
|
|
118
|
+
session: {
|
|
119
|
+
mode: "disabled",
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.AIUserMemoryExtractor = AIUserMemoryExtractor;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { AFSListOptions } from "@aigne/afs";
|
|
1
2
|
import type { Agent } from "../../../agents/agent.js";
|
|
2
|
-
export declare function getHistories(agent
|
|
3
|
+
export declare function getHistories({ filter, agent, }: {
|
|
4
|
+
filter: AFSListOptions["filter"];
|
|
5
|
+
agent: Agent;
|
|
6
|
+
}): Promise<{
|
|
3
7
|
role: "user" | "agent";
|
|
4
8
|
content: unknown;
|
|
5
9
|
}[]>;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getHistories = getHistories;
|
|
4
4
|
const afs_history_1 = require("@aigne/afs-history");
|
|
5
5
|
const type_utils_js_1 = require("../../../utils/type-utils.js");
|
|
6
|
-
async function getHistories(agent) {
|
|
6
|
+
async function getHistories({ filter, agent, }) {
|
|
7
7
|
const afs = agent?.afs;
|
|
8
8
|
if (!afs)
|
|
9
9
|
return [];
|
|
@@ -11,7 +11,8 @@ async function getHistories(agent) {
|
|
|
11
11
|
if (!historyModule)
|
|
12
12
|
return [];
|
|
13
13
|
const history = (await afs.list(historyModule.path, {
|
|
14
|
-
|
|
14
|
+
filter,
|
|
15
|
+
limit: 10,
|
|
15
16
|
orderBy: [["createdAt", "desc"]],
|
|
16
17
|
})).data;
|
|
17
18
|
return history
|
|
@@ -20,7 +20,14 @@ function createAFSContext(agent, context) {
|
|
|
20
20
|
get histories() {
|
|
21
21
|
if (!agent)
|
|
22
22
|
return Promise.resolve([]);
|
|
23
|
-
return (0, history_js_1.getHistories)(
|
|
23
|
+
return (0, history_js_1.getHistories)({
|
|
24
|
+
agent,
|
|
25
|
+
filter: {
|
|
26
|
+
agentId: agent.name,
|
|
27
|
+
userId: context?.userContext.userId,
|
|
28
|
+
sessionId: context?.userContext.sessionId,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
24
31
|
},
|
|
25
32
|
get skills() {
|
|
26
33
|
const afs = agent?.afs;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import type { GetPromptResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
-
import { Agent, type
|
|
2
|
+
import { Agent, type Message } from "../agents/agent.js";
|
|
3
3
|
import { type AIAgent } from "../agents/ai-agent.js";
|
|
4
|
-
import type { ChatModel, ChatModelInput } from "../agents/chat-model.js";
|
|
4
|
+
import type { ChatModel, ChatModelInput, ChatModelInputMessage } from "../agents/chat-model.js";
|
|
5
5
|
import { type FileUnionContent } from "../agents/model.js";
|
|
6
|
+
import type { Context } from "../aigne/context.js";
|
|
7
|
+
import { AgentSession } from "./agent-session.js";
|
|
6
8
|
import { ChatMessagesTemplate } from "./template.js";
|
|
7
9
|
export interface PromptBuilderOptions {
|
|
8
10
|
instructions?: string | ChatMessagesTemplate;
|
|
9
11
|
workingDir?: string;
|
|
10
12
|
}
|
|
11
|
-
export interface PromptBuildOptions
|
|
13
|
+
export interface PromptBuildOptions {
|
|
14
|
+
context?: Context;
|
|
12
15
|
agent?: AIAgent;
|
|
13
16
|
input?: Message;
|
|
14
17
|
model?: ChatModel;
|
|
@@ -26,7 +29,9 @@ export declare class PromptBuilder {
|
|
|
26
29
|
instructions?: string | ChatMessagesTemplate;
|
|
27
30
|
workingDir?: string;
|
|
28
31
|
copy(): PromptBuilder;
|
|
29
|
-
build(options: PromptBuildOptions): Promise<ChatModelInput & {
|
|
32
|
+
build(options: PromptBuildOptions): Promise<Omit<ChatModelInput, "messages"> & {
|
|
33
|
+
session: AgentSession;
|
|
34
|
+
userMessage: ChatModelInputMessage;
|
|
30
35
|
toolAgents?: Agent[];
|
|
31
36
|
}>;
|
|
32
37
|
buildPrompt(options: Pick<PromptBuildOptions, "input" | "context"> & {
|
|
@@ -37,11 +42,8 @@ export declare class PromptBuilder {
|
|
|
37
42
|
}>;
|
|
38
43
|
private getTemplateVariables;
|
|
39
44
|
private buildMessages;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
content: unknown;
|
|
43
|
-
}[]>;
|
|
44
|
-
private refineMessages;
|
|
45
|
+
private mergeMessages;
|
|
46
|
+
protected deprecatedMemories(message: string | undefined, options: PromptBuildOptions): Promise<ChatModelInputMessage[]>;
|
|
45
47
|
private convertMemoriesToMessages;
|
|
46
48
|
private buildResponseFormat;
|
|
47
49
|
private buildTools;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PromptBuilder = void 0;
|
|
4
|
-
const afs_history_1 = require("@aigne/afs-history");
|
|
5
4
|
const index_js_1 = require("@aigne/platform-helpers/nodejs/index.js");
|
|
5
|
+
const uuid_1 = require("@aigne/uuid");
|
|
6
6
|
const yaml_1 = require("yaml");
|
|
7
7
|
const zod_1 = require("zod");
|
|
8
8
|
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
@@ -12,8 +12,8 @@ const model_js_1 = require("../agents/model.js");
|
|
|
12
12
|
const schema_js_1 = require("../loader/schema.js");
|
|
13
13
|
const json_schema_js_1 = require("../utils/json-schema.js");
|
|
14
14
|
const type_utils_js_1 = require("../utils/type-utils.js");
|
|
15
|
+
const agent_session_js_1 = require("./agent-session.js");
|
|
15
16
|
const index_js_2 = require("./context/index.js");
|
|
16
|
-
const afs_builtin_prompt_js_1 = require("./prompts/afs-builtin-prompt.js");
|
|
17
17
|
const memory_message_template_js_1 = require("./prompts/memory-message-template.js");
|
|
18
18
|
const structured_stream_instructions_js_1 = require("./prompts/structured-stream-instructions.js");
|
|
19
19
|
const index_js_3 = require("./skills/afs/index.js");
|
|
@@ -40,10 +40,10 @@ class PromptBuilder {
|
|
|
40
40
|
content = i.content.text;
|
|
41
41
|
else if (i.content.type === "resource") {
|
|
42
42
|
const { resource } = i.content;
|
|
43
|
-
if (typeof resource.text === "string") {
|
|
43
|
+
if ("text" in resource && typeof resource.text === "string") {
|
|
44
44
|
content = resource.text;
|
|
45
45
|
}
|
|
46
|
-
else if (typeof resource.blob === "string") {
|
|
46
|
+
else if ("blob" in resource && typeof resource.blob === "string") {
|
|
47
47
|
content = [{ type: "url", url: resource.blob }];
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -73,13 +73,28 @@ class PromptBuilder {
|
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
async build(options) {
|
|
76
|
+
let { userId, sessionId } = options.context?.userContext || {};
|
|
77
|
+
const agentId = options.agent?.name;
|
|
78
|
+
const afs = options.agent?.afs;
|
|
79
|
+
sessionId ||= (0, uuid_1.v7)();
|
|
80
|
+
const session = new agent_session_js_1.AgentSession({
|
|
81
|
+
agentId,
|
|
82
|
+
userId,
|
|
83
|
+
sessionId,
|
|
84
|
+
afs,
|
|
85
|
+
...options.agent?.session,
|
|
86
|
+
});
|
|
87
|
+
const { systemMessage, userMessage } = await this.buildMessages(options);
|
|
88
|
+
if (systemMessage)
|
|
89
|
+
await session.setSystemMessages(systemMessage);
|
|
76
90
|
return {
|
|
77
|
-
|
|
91
|
+
userMessage,
|
|
78
92
|
responseFormat: options.agent?.structuredStreamMode
|
|
79
93
|
? undefined
|
|
80
94
|
: this.buildResponseFormat(options),
|
|
81
95
|
outputFileType: options.agent?.outputFileType,
|
|
82
96
|
...(await this.buildTools(options)),
|
|
97
|
+
session,
|
|
83
98
|
};
|
|
84
99
|
}
|
|
85
100
|
async buildPrompt(options) {
|
|
@@ -102,85 +117,41 @@ class PromptBuilder {
|
|
|
102
117
|
const { input } = options;
|
|
103
118
|
const inputKey = options.agent?.inputKey;
|
|
104
119
|
const message = inputKey && typeof input?.[inputKey] === "string" ? input[inputKey] : undefined;
|
|
105
|
-
const
|
|
120
|
+
const template = typeof this.instructions === "string"
|
|
106
121
|
? template_js_1.ChatMessagesTemplate.from([template_js_1.SystemMessageTemplate.from(this.instructions)])
|
|
107
|
-
: this.instructions
|
|
122
|
+
: this.instructions;
|
|
123
|
+
const [systemMessages, userMessages] = (0, type_utils_js_1.partition)((await template?.format(this.getTemplateVariables(options), {
|
|
124
|
+
workingDir: this.workingDir,
|
|
125
|
+
})) ?? [], (i) => i.role === "system");
|
|
108
126
|
const inputFileKey = options.agent?.inputFileKey;
|
|
109
127
|
const files = (0, type_utils_js_1.flat)(inputFileKey
|
|
110
128
|
? (0, type_utils_js_1.checkArguments)("Check input files", (0, schema_js_1.optionalize)(model_js_1.fileUnionContentsSchema), input?.[inputFileKey])
|
|
111
129
|
: null);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (options.agent?.useMemoriesFromContext && options.context?.memories?.length) {
|
|
117
|
-
memories.push(...options.context.memories);
|
|
118
|
-
}
|
|
119
|
-
const afs = options.agent?.afs;
|
|
120
|
-
if (afs && options.agent?.historyConfig?.disabled !== true) {
|
|
121
|
-
const historyModule = (await afs.listModules()).find((m) => m.module instanceof afs_history_1.AFSHistory);
|
|
122
|
-
messages.push(await template_js_1.SystemMessageTemplate.from(await (0, afs_builtin_prompt_js_1.getAFSSystemPrompt)(afs)).format({}));
|
|
123
|
-
if (historyModule) {
|
|
124
|
-
const history = await afs.list(historyModule.path, {
|
|
125
|
-
limit: options.agent?.maxRetrieveMemoryCount || 10,
|
|
126
|
-
orderBy: [["createdAt", "desc"]],
|
|
127
|
-
});
|
|
128
|
-
memories.push(...history.data
|
|
129
|
-
.reverse()
|
|
130
|
-
.filter((i) => (0, type_utils_js_1.isNonNullable)(i.content)));
|
|
131
|
-
if (message) {
|
|
132
|
-
const result = (await afs.search("/", message)).data;
|
|
133
|
-
const ms = result
|
|
134
|
-
.map((entry) => {
|
|
135
|
-
if (entry.metadata?.execute)
|
|
136
|
-
return null;
|
|
137
|
-
const content = entry.content || entry.summary;
|
|
138
|
-
if (!content)
|
|
139
|
-
return null;
|
|
140
|
-
return {
|
|
141
|
-
content,
|
|
142
|
-
description: entry.description,
|
|
143
|
-
};
|
|
144
|
-
})
|
|
145
|
-
.filter(type_utils_js_1.isNonNullable);
|
|
146
|
-
memories.push(...ms);
|
|
147
|
-
const executable = result.filter((i) => !!i.metadata?.execute);
|
|
148
|
-
if (executable.length) {
|
|
149
|
-
messages.push({
|
|
150
|
-
role: "system",
|
|
151
|
-
content: await template_js_1.PromptTemplate.from(afs_builtin_prompt_js_1.AFS_EXECUTABLE_TOOLS_PROMPT_TEMPLATE).format({
|
|
152
|
-
tools: executable.map((entry) => ({
|
|
153
|
-
path: entry.path,
|
|
154
|
-
name: entry.metadata.execute.name,
|
|
155
|
-
description: entry.metadata.execute.description,
|
|
156
|
-
inputSchema: entry.metadata.execute.inputSchema,
|
|
157
|
-
outputSchema: entry.metadata.execute.outputSchema,
|
|
158
|
-
})),
|
|
159
|
-
}),
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
130
|
+
if (options.agent?.memories.length || options.context?.memories.length) {
|
|
131
|
+
const deprecatedMemories = await this.deprecatedMemories(message, options);
|
|
132
|
+
if (deprecatedMemories.length)
|
|
133
|
+
systemMessages.push(...deprecatedMemories);
|
|
164
134
|
}
|
|
165
|
-
if (memories.length)
|
|
166
|
-
messages.push(...(await this.convertMemoriesToMessages(memories, options)));
|
|
167
135
|
// if the agent is using structured stream mode, add the instructions
|
|
168
136
|
const { structuredStreamMode, outputSchema } = options.agent || {};
|
|
169
137
|
if (structuredStreamMode && outputSchema) {
|
|
170
138
|
const instructions = options.agent?.customStructuredStreamInstructions?.instructions ||
|
|
171
139
|
PromptBuilder.from(structured_stream_instructions_js_1.STRUCTURED_STREAM_INSTRUCTIONS.instructions);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
140
|
+
systemMessages.push({
|
|
141
|
+
role: "system",
|
|
142
|
+
content: (await instructions.buildPrompt({
|
|
143
|
+
input: {
|
|
144
|
+
...input,
|
|
145
|
+
outputJsonSchema: (0, zod_to_json_schema_1.zodToJsonSchema)(outputSchema),
|
|
146
|
+
},
|
|
147
|
+
})).prompt,
|
|
148
|
+
});
|
|
178
149
|
}
|
|
179
150
|
if (message || files.length) {
|
|
180
151
|
const content = [];
|
|
181
152
|
if (message &&
|
|
182
|
-
// avoid duplicate user messages: developer may have already included the message in the
|
|
183
|
-
!
|
|
153
|
+
// avoid duplicate user messages: developer may have already included the message in the messages
|
|
154
|
+
!userMessages.some((i) => i.role === "user" &&
|
|
184
155
|
(typeof i.content === "string"
|
|
185
156
|
? i.content.includes(message)
|
|
186
157
|
: i.content?.some((c) => c.type === "text" && c.text.includes(message))))) {
|
|
@@ -189,63 +160,51 @@ class PromptBuilder {
|
|
|
189
160
|
if (files.length)
|
|
190
161
|
content.push(...files);
|
|
191
162
|
if (content.length) {
|
|
192
|
-
|
|
163
|
+
userMessages.push({ role: "user", content });
|
|
193
164
|
}
|
|
194
165
|
}
|
|
195
|
-
|
|
196
|
-
|
|
166
|
+
let systemMessage = this.mergeMessages(systemMessages, "system");
|
|
167
|
+
if (!systemMessage.content?.length)
|
|
168
|
+
systemMessage = undefined;
|
|
169
|
+
let userMessage = this.mergeMessages(userMessages, "user");
|
|
170
|
+
if (!userMessage.content?.length) {
|
|
171
|
+
userMessage = { role: "user", content: systemMessage?.content };
|
|
172
|
+
systemMessage = undefined;
|
|
173
|
+
}
|
|
174
|
+
if (!userMessage.content?.length)
|
|
175
|
+
throw new Error("User message cannot be empty.");
|
|
176
|
+
return {
|
|
177
|
+
systemMessage,
|
|
178
|
+
userMessage,
|
|
179
|
+
};
|
|
197
180
|
}
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
.map((i) => {
|
|
213
|
-
if (!i.content)
|
|
214
|
-
return;
|
|
215
|
-
const { input, output } = i.content;
|
|
216
|
-
if (!input || !output)
|
|
217
|
-
return;
|
|
218
|
-
return [
|
|
219
|
-
{ role: "user", content: input },
|
|
220
|
-
{ role: "agent", content: output },
|
|
221
|
-
];
|
|
222
|
-
})
|
|
223
|
-
.filter(type_utils_js_1.isNonNullable)
|
|
224
|
-
.flat();
|
|
181
|
+
mergeMessages(messages, role) {
|
|
182
|
+
const content = [];
|
|
183
|
+
for (const message of messages) {
|
|
184
|
+
if (typeof message.content === "string") {
|
|
185
|
+
content.push({ type: "text", text: message.content });
|
|
186
|
+
}
|
|
187
|
+
else if (Array.isArray(message.content)) {
|
|
188
|
+
content.push(...message.content);
|
|
189
|
+
}
|
|
190
|
+
else if (message.content) {
|
|
191
|
+
throw new Error(`Unsupported message content type: ${typeof message.content}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return { role, content };
|
|
225
195
|
}
|
|
226
|
-
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (!autoMergeSystemMessages) {
|
|
232
|
-
return systemMessages.concat(otherMessages);
|
|
196
|
+
async deprecatedMemories(message, options) {
|
|
197
|
+
const messages = [];
|
|
198
|
+
const memories = [];
|
|
199
|
+
if (options.agent && options.context) {
|
|
200
|
+
memories.push(...(await options.agent.retrieveMemories({ search: message }, { context: options.context })));
|
|
233
201
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
result.push({
|
|
237
|
-
role: "system",
|
|
238
|
-
content: systemMessages
|
|
239
|
-
.map((i) => typeof i.content === "string"
|
|
240
|
-
? i.content
|
|
241
|
-
: i.content
|
|
242
|
-
?.map((c) => (c.type === "text" ? c.text : null))
|
|
243
|
-
.filter(type_utils_js_1.isNonNullable)
|
|
244
|
-
.join("\n"))
|
|
245
|
-
.join("\n"),
|
|
246
|
-
});
|
|
202
|
+
if (options.agent?.useMemoriesFromContext && options.context?.memories?.length) {
|
|
203
|
+
memories.push(...options.context.memories);
|
|
247
204
|
}
|
|
248
|
-
|
|
205
|
+
if (memories.length)
|
|
206
|
+
messages.push(...(await this.convertMemoriesToMessages(memories, options)));
|
|
207
|
+
return messages;
|
|
249
208
|
}
|
|
250
209
|
async convertMemoriesToMessages(memories, options) {
|
|
251
210
|
const messages = [];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Agent, type AgentOptions, type Message } from "../../../../agents/agent.js";
|
|
2
|
+
import type { PromiseOrValue } from "../../../../utils/type-utils.js";
|
|
3
|
+
import type { Skill } from "./skill-loader.js";
|
|
4
|
+
export interface SkillToolInput extends Message {
|
|
5
|
+
skill: string;
|
|
6
|
+
args?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SkillToolOutput extends Message {
|
|
9
|
+
result: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SkillToolOptions extends AgentOptions<SkillToolInput, SkillToolOutput> {
|
|
12
|
+
agentSkills: Skill[];
|
|
13
|
+
}
|
|
14
|
+
export declare class AgentSkill extends Agent<SkillToolInput, SkillToolOutput> {
|
|
15
|
+
formatOutput(output: SkillToolOutput | Message): PromiseOrValue<string>;
|
|
16
|
+
constructor(options: SkillToolOptions);
|
|
17
|
+
private agentSkills;
|
|
18
|
+
process(input: SkillToolInput): Promise<SkillToolOutput>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgentSkill = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const agent_js_1 = require("../../../../agents/agent.js");
|
|
6
|
+
const skillToolInputSchema = zod_1.z.object({
|
|
7
|
+
skill: zod_1.z.string().describe("The name of the skill agent to invoke."),
|
|
8
|
+
args: zod_1.z.string().optional().describe("The arguments to pass to the skill."),
|
|
9
|
+
});
|
|
10
|
+
class AgentSkill extends agent_js_1.Agent {
|
|
11
|
+
formatOutput(output) {
|
|
12
|
+
if ("result" in output && typeof output.result === "string") {
|
|
13
|
+
return output.result;
|
|
14
|
+
}
|
|
15
|
+
return super.formatOutput(output);
|
|
16
|
+
}
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super({
|
|
19
|
+
name: "Skill",
|
|
20
|
+
taskTitle: "Invoke {{skill}}: {{args}}",
|
|
21
|
+
...options,
|
|
22
|
+
description: `\
|
|
23
|
+
Execute a skill within the main conversation
|
|
24
|
+
|
|
25
|
+
<skills_instructions>
|
|
26
|
+
When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
|
|
27
|
+
|
|
28
|
+
When users ask you to run a "slash command" or reference "/" (e.g., "/commit", "/review-pr"), they are referring to a skill. Use this tool to invoke the corresponding skill.
|
|
29
|
+
|
|
30
|
+
User: "run /commit" Assistant: [Calls Skill tool with skill: "commit"]
|
|
31
|
+
How to invoke:
|
|
32
|
+
|
|
33
|
+
Use this tool with the skill name and optional arguments
|
|
34
|
+
|
|
35
|
+
Important:
|
|
36
|
+
|
|
37
|
+
When a skill is relevant, you must invoke this tool IMMEDIATELY as your first action
|
|
38
|
+
NEVER just announce or mention a skill in your text response without actually calling this tool
|
|
39
|
+
This is a BLOCKING REQUIREMENT: invoke the relevant Skill tool BEFORE generating any other response about the task
|
|
40
|
+
Only use skills listed in <available_skills> below
|
|
41
|
+
Do not invoke a skill that is already running
|
|
42
|
+
Do not use this tool for built-in CLI commands (like /help, /clear, etc.)
|
|
43
|
+
</skills_instructions>
|
|
44
|
+
|
|
45
|
+
<available_skills>
|
|
46
|
+
${options.agentSkills.map((s) => `${s.name}: ${s.description}`).join("\n\n")}
|
|
47
|
+
</available_skills>
|
|
48
|
+
`,
|
|
49
|
+
inputSchema: skillToolInputSchema,
|
|
50
|
+
});
|
|
51
|
+
this.agentSkills = options.agentSkills;
|
|
52
|
+
}
|
|
53
|
+
agentSkills;
|
|
54
|
+
async process(input) {
|
|
55
|
+
const skill = this.agentSkills.find((s) => s.name === input.skill);
|
|
56
|
+
if (!skill)
|
|
57
|
+
throw new Error(`Skill not found: ${input.skill}`);
|
|
58
|
+
return {
|
|
59
|
+
result: `\
|
|
60
|
+
Base directory for this skill: ${skill.path}
|
|
61
|
+
|
|
62
|
+
${skill.content}
|
|
63
|
+
|
|
64
|
+
${input.args ? `ARGUMENTS: ${input.args ?? "None"}` : ""}
|
|
65
|
+
`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.AgentSkill = AgentSkill;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AFS } from "@aigne/afs";
|
|
2
|
+
import { AgentSkill } from "./agent-skill.js";
|
|
3
|
+
export interface Skill {
|
|
4
|
+
path: string;
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
content: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function discoverSkillsFromAFS(afs: AFS): Promise<Skill[]>;
|
|
10
|
+
export declare function loadAgentSkillFromAFS({ afs, }: {
|
|
11
|
+
afs: AFS;
|
|
12
|
+
}): Promise<AgentSkill | undefined>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.discoverSkillsFromAFS = discoverSkillsFromAFS;
|
|
7
|
+
exports.loadAgentSkillFromAFS = loadAgentSkillFromAFS;
|
|
8
|
+
const front_matter_1 = __importDefault(require("front-matter"));
|
|
9
|
+
const agent_skill_js_1 = require("./agent-skill.js");
|
|
10
|
+
function parseSkill(content, path) {
|
|
11
|
+
const meta = (0, front_matter_1.default)(content);
|
|
12
|
+
return {
|
|
13
|
+
path,
|
|
14
|
+
name: meta.attributes.name,
|
|
15
|
+
description: meta.attributes.description,
|
|
16
|
+
content: meta.body,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async function discoverSkillsFromAFS(afs) {
|
|
20
|
+
const modules = await afs.listModules();
|
|
21
|
+
const filtered = modules.filter(({ module: m }) => m.agentSkills === true);
|
|
22
|
+
if (!filtered.length)
|
|
23
|
+
return [];
|
|
24
|
+
const skills = [];
|
|
25
|
+
for (const module of filtered) {
|
|
26
|
+
const data = (await afs
|
|
27
|
+
.list(module.path, {
|
|
28
|
+
pattern: "**/SKILL.md",
|
|
29
|
+
maxDepth: 10,
|
|
30
|
+
})
|
|
31
|
+
.catch(() => ({ data: [] }))).data;
|
|
32
|
+
for (const entry of data) {
|
|
33
|
+
const { data: file } = await afs.read(entry.path);
|
|
34
|
+
if (typeof file?.content !== "string")
|
|
35
|
+
continue;
|
|
36
|
+
const dirname = entry.path.split("/").slice(0, -1).join("/");
|
|
37
|
+
const skill = parseSkill(file.content, dirname);
|
|
38
|
+
skills.push(skill);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return skills;
|
|
42
|
+
}
|
|
43
|
+
async function loadAgentSkillFromAFS({ afs, }) {
|
|
44
|
+
const skills = await discoverSkillsFromAFS(afs);
|
|
45
|
+
if (!skills.length)
|
|
46
|
+
return;
|
|
47
|
+
return new agent_skill_js_1.AgentSkill({
|
|
48
|
+
agentSkills: skills,
|
|
49
|
+
});
|
|
50
|
+
}
|