@aigne/core 1.72.0-beta.8 → 1.72.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 +349 -0
- package/lib/cjs/agents/agent.d.ts +5 -0
- package/lib/cjs/agents/agent.js +5 -0
- package/lib/cjs/agents/ai-agent.d.ts +41 -5
- package/lib/cjs/agents/ai-agent.js +89 -29
- package/lib/cjs/agents/chat-model.d.ts +3 -0
- package/lib/cjs/agents/chat-model.js +18 -1
- package/lib/cjs/agents/image-model.js +1 -1
- package/lib/cjs/agents/model.d.ts +3 -3
- package/lib/cjs/agents/model.js +2 -2
- package/lib/cjs/agents/video-model.js +1 -1
- package/lib/cjs/aigne/context.js +1 -3
- package/lib/cjs/prompt/agent-session.d.ts +115 -5
- package/lib/cjs/prompt/agent-session.js +752 -85
- package/lib/cjs/prompt/compact/compactor.js +4 -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 +257 -0
- package/lib/cjs/prompt/compact/types.js +35 -1
- 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/prompt-builder.js +3 -3
- package/lib/cjs/prompt/skills/afs/agent-skill/agent-skill.d.ts +2 -0
- package/lib/cjs/prompt/skills/afs/agent-skill/agent-skill.js +6 -0
- package/lib/cjs/prompt/skills/afs/agent-skill/skill-loader.d.ts +1 -2
- package/lib/cjs/prompt/skills/afs/agent-skill/skill-loader.js +15 -26
- package/lib/cjs/prompt/skills/afs/list.d.ts +2 -0
- package/lib/cjs/prompt/skills/afs/list.js +9 -1
- package/lib/cjs/prompt/skills/afs/read.d.ts +3 -1
- package/lib/cjs/prompt/skills/afs/read.js +5 -0
- package/lib/cjs/utils/mcp-utils.js +1 -1
- package/lib/cjs/utils/token-estimator.js +1 -1
- package/lib/cjs/utils/type-utils.js +0 -1
- package/lib/dts/agents/agent.d.ts +5 -0
- package/lib/dts/agents/ai-agent.d.ts +41 -5
- package/lib/dts/agents/chat-model.d.ts +3 -0
- package/lib/dts/agents/model.d.ts +3 -3
- package/lib/dts/prompt/agent-session.d.ts +115 -5
- package/lib/dts/prompt/compact/session-memory-extractor.d.ts +7 -0
- package/lib/dts/prompt/compact/types.d.ts +257 -0
- package/lib/dts/prompt/compact/user-memory-extractor.d.ts +7 -0
- package/lib/dts/prompt/skills/afs/agent-skill/agent-skill.d.ts +2 -0
- package/lib/dts/prompt/skills/afs/agent-skill/skill-loader.d.ts +1 -2
- package/lib/dts/prompt/skills/afs/list.d.ts +2 -0
- package/lib/dts/prompt/skills/afs/read.d.ts +3 -1
- package/lib/esm/agents/agent.d.ts +5 -0
- package/lib/esm/agents/agent.js +5 -0
- package/lib/esm/agents/ai-agent.d.ts +41 -5
- package/lib/esm/agents/ai-agent.js +89 -29
- package/lib/esm/agents/chat-model.d.ts +3 -0
- package/lib/esm/agents/chat-model.js +18 -1
- package/lib/esm/agents/image-model.js +1 -1
- package/lib/esm/agents/model.d.ts +3 -3
- package/lib/esm/agents/model.js +2 -2
- package/lib/esm/agents/video-model.js +1 -1
- package/lib/esm/aigne/context.js +2 -4
- package/lib/esm/prompt/agent-session.d.ts +115 -5
- package/lib/esm/prompt/agent-session.js +750 -86
- package/lib/esm/prompt/compact/compactor.js +4 -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 +257 -0
- package/lib/esm/prompt/compact/types.js +34 -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/prompt-builder.js +3 -3
- package/lib/esm/prompt/skills/afs/agent-skill/agent-skill.d.ts +2 -0
- package/lib/esm/prompt/skills/afs/agent-skill/agent-skill.js +6 -0
- package/lib/esm/prompt/skills/afs/agent-skill/skill-loader.d.ts +1 -2
- package/lib/esm/prompt/skills/afs/agent-skill/skill-loader.js +14 -24
- package/lib/esm/prompt/skills/afs/list.d.ts +2 -0
- package/lib/esm/prompt/skills/afs/list.js +9 -1
- package/lib/esm/prompt/skills/afs/read.d.ts +3 -1
- package/lib/esm/prompt/skills/afs/read.js +5 -0
- package/lib/esm/utils/mcp-utils.js +1 -1
- package/lib/esm/utils/token-estimator.js +1 -1
- package/lib/esm/utils/type-utils.js +0 -1
- package/package.json +6 -6
|
@@ -41,7 +41,11 @@ class AISessionCompactor extends ai_agent_js_1.AIAgent {
|
|
|
41
41
|
summary: zod_1.z.string().describe("A comprehensive summary of the conversation history"),
|
|
42
42
|
}),
|
|
43
43
|
instructions: COMPACTOR_INSTRUCTIONS,
|
|
44
|
+
taskRenderMode: "hide",
|
|
44
45
|
...(0, type_utils_js_1.omitBy)(options ?? {}, (v) => (0, type_utils_js_1.isNil)(v)),
|
|
46
|
+
session: {
|
|
47
|
+
mode: "disabled",
|
|
48
|
+
},
|
|
45
49
|
});
|
|
46
50
|
}
|
|
47
51
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AIAgent, type AIAgentOptions } from "../../agents/ai-agent.js";
|
|
2
|
+
import type { MemoryExtractorInput, MemoryExtractorOutput } from "./types.js";
|
|
3
|
+
export interface CreateSessionMemoryExtractorOptions extends AIAgentOptions<MemoryExtractorInput, MemoryExtractorOutput> {
|
|
4
|
+
}
|
|
5
|
+
export declare class AISessionMemoryExtractor extends AIAgent<MemoryExtractorInput, MemoryExtractorOutput> {
|
|
6
|
+
constructor(options?: CreateSessionMemoryExtractorOptions);
|
|
7
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AISessionMemoryExtractor = 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 session memory fact extractor. Your task is to extract facts that help continue THIS SESSION's work.
|
|
9
|
+
|
|
10
|
+
**Key Principle**: Extract WORK CONTEXT (tasks, decisions, blockers), NOT PROJECT DOCUMENTATION (tech stack, code structure, implementation details).
|
|
11
|
+
|
|
12
|
+
Session memory is for remembering:
|
|
13
|
+
- What we're trying to accomplish
|
|
14
|
+
- Why we made certain choices
|
|
15
|
+
- What problems we encountered
|
|
16
|
+
- Important context for continuing the work
|
|
17
|
+
|
|
18
|
+
Session memory is NOT for documenting:
|
|
19
|
+
- What the code does (visible in code)
|
|
20
|
+
- How the project is structured (can explore directly)
|
|
21
|
+
- What technologies are used (obvious from files)
|
|
22
|
+
|
|
23
|
+
## User Memory Facts (Long-term, cross-session)
|
|
24
|
+
|
|
25
|
+
${"```"}yaml alt="user-memory-facts"
|
|
26
|
+
{{ existingUserFacts | yaml.stringify }}
|
|
27
|
+
${"```"}
|
|
28
|
+
|
|
29
|
+
## Existing Session Memory Facts
|
|
30
|
+
|
|
31
|
+
${"```"}yaml alt="existing-facts"
|
|
32
|
+
{{ existingFacts | yaml.stringify }}
|
|
33
|
+
${"```"}
|
|
34
|
+
|
|
35
|
+
## Recent Conversation
|
|
36
|
+
|
|
37
|
+
${"```"}yaml alt="recent-messages"
|
|
38
|
+
{{ messages | yaml.stringify }}
|
|
39
|
+
${"```"}
|
|
40
|
+
|
|
41
|
+
## Guidelines
|
|
42
|
+
|
|
43
|
+
1. **Avoid duplicating User Memory (CRITICAL)**:
|
|
44
|
+
- User Memory contains long-term, cross-session facts about the user
|
|
45
|
+
- DO NOT extract facts that are already covered in User Memory
|
|
46
|
+
- Focus on session-specific information that User Memory doesn't capture
|
|
47
|
+
- Example: If User Memory has "User prefers TypeScript", don't add "User is using TypeScript" to session memory
|
|
48
|
+
|
|
49
|
+
2. **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 session memory:
|
|
54
|
+
- Include it in newFacts ONLY if conversation provides new information to update it
|
|
55
|
+
- Omit it from newFacts if it doesn't need changes
|
|
56
|
+
|
|
57
|
+
3. **What to extract** (Session context, NOT project documentation):
|
|
58
|
+
- **Current tasks and goals**: What the user is trying to accomplish in this session
|
|
59
|
+
- **Important decisions**: Key choices made and WHY (not just WHAT was chosen)
|
|
60
|
+
- **Session-specific constraints**: Temporary requirements or limitations for this work
|
|
61
|
+
- **Blockers and context**: Issues encountered and relevant background
|
|
62
|
+
- **Session-specific user preferences**: Only if different from User Memory for this session
|
|
63
|
+
|
|
64
|
+
4. **What NOT to extract** (Can be inferred from code or documentation):
|
|
65
|
+
- ❌ Tech stack details (e.g., "Project uses React") - obvious from package.json
|
|
66
|
+
- ❌ Code structure facts (e.g., "Code is in /src") - can be seen directly
|
|
67
|
+
- ❌ Implementation details (e.g., "Function X does Y") - visible in code
|
|
68
|
+
- ❌ Architecture documentation - should be in actual docs, not memory
|
|
69
|
+
- ❌ Generic project facts that don't help with current work
|
|
70
|
+
|
|
71
|
+
5. **When to output a fact in newFacts**:
|
|
72
|
+
- **New fact**: Learning something new about current work context not in existing session memory
|
|
73
|
+
- **Updated fact**: New information about current tasks or decisions
|
|
74
|
+
- **DO NOT output**: Facts already in session memory, facts covered by User Memory, or obvious code facts
|
|
75
|
+
- Example: Extract "User is fixing the memory duplication bug to optimize token usage" ✓
|
|
76
|
+
- Example: Don't extract "Project uses TypeScript" ❌ (obvious from code)
|
|
77
|
+
|
|
78
|
+
6. **Remove outdated facts** by including their labels in removeFacts:
|
|
79
|
+
- Facts that are no longer relevant to current session
|
|
80
|
+
- Facts that have been superseded by new information
|
|
81
|
+
|
|
82
|
+
7. **Label naming conventions**:
|
|
83
|
+
- Use short, descriptive, kebab-case labels
|
|
84
|
+
- Focus on: "task-*" (current tasks), "decision-*" (key decisions), "ctx-*" (context), "blocker-*" (blockers)
|
|
85
|
+
- Examples: "task-fix-memory-bug", "decision-use-incremental-updates", "ctx-working-on-compact-module", "blocker-type-error"
|
|
86
|
+
|
|
87
|
+
8. **Fact content guidelines**:
|
|
88
|
+
- Write concise, actionable facts (1-2 sentences max)
|
|
89
|
+
- Focus on WHY and WHAT (goals, decisions, context), not HOW (implementation details)
|
|
90
|
+
- Information should help continue the work, not document the codebase
|
|
91
|
+
|
|
92
|
+
9. **Extraction criteria**:
|
|
93
|
+
- Only extract if there's clear, explicit information in the conversation
|
|
94
|
+
- The information should be useful for continuing the current work
|
|
95
|
+
- Don't make assumptions or infer beyond what's stated
|
|
96
|
+
- When in doubt about whether something changed, don't output it
|
|
97
|
+
|
|
98
|
+
Output only the new or updated facts in newFacts, and any labels to remove in removeFacts.`;
|
|
99
|
+
class AISessionMemoryExtractor extends ai_agent_js_1.AIAgent {
|
|
100
|
+
constructor(options) {
|
|
101
|
+
super({
|
|
102
|
+
name: "SessionMemoryExtractor",
|
|
103
|
+
description: "Extracts and maintains session memory facts from conversations",
|
|
104
|
+
inputSchema: zod_1.z.object({
|
|
105
|
+
existingUserFacts: (0, zod_1.optional)(zod_1.z
|
|
106
|
+
.array(zod_1.z.object({
|
|
107
|
+
label: zod_1.z.string(),
|
|
108
|
+
fact: zod_1.z.string(),
|
|
109
|
+
confidence: (0, zod_1.optional)(zod_1.z.number()),
|
|
110
|
+
tags: (0, zod_1.optional)(zod_1.z.array(zod_1.z.string())),
|
|
111
|
+
}))
|
|
112
|
+
.describe("User memory facts (long-term, cross-session) to avoid duplication")),
|
|
113
|
+
existingFacts: (0, zod_1.optional)(zod_1.z
|
|
114
|
+
.array(zod_1.z.object({
|
|
115
|
+
label: zod_1.z.string(),
|
|
116
|
+
fact: zod_1.z.string(),
|
|
117
|
+
confidence: (0, zod_1.optional)(zod_1.z.number()),
|
|
118
|
+
tags: (0, zod_1.optional)(zod_1.z.array(zod_1.z.string())),
|
|
119
|
+
}))
|
|
120
|
+
.describe("Existing session memory facts for context and deduplication")),
|
|
121
|
+
messages: zod_1.z.array(zod_1.z.any()).describe("Recent conversation messages"),
|
|
122
|
+
}),
|
|
123
|
+
outputSchema: zod_1.z.object({
|
|
124
|
+
newFacts: zod_1.z
|
|
125
|
+
.array(zod_1.z.object({
|
|
126
|
+
label: zod_1.z.string().describe("Short, semantic label for the fact"),
|
|
127
|
+
fact: zod_1.z.string().describe("The fact content"),
|
|
128
|
+
confidence: (0, zod_1.optional)(zod_1.z.number().min(0).max(1).describe("Confidence score (0-1)")),
|
|
129
|
+
tags: (0, zod_1.optional)(zod_1.z.array(zod_1.z.string()).describe("Classification tags")),
|
|
130
|
+
}))
|
|
131
|
+
.describe("Facts to add or update in session memory. Only include facts that are new or need updates. Do not include unchanged facts."),
|
|
132
|
+
removeFacts: (0, zod_1.optional)(zod_1.z.array(zod_1.z.string()).describe("Labels of facts to remove from memory")),
|
|
133
|
+
}),
|
|
134
|
+
instructions: EXTRACTOR_INSTRUCTIONS,
|
|
135
|
+
taskRenderMode: "hide",
|
|
136
|
+
...(0, type_utils_js_1.omitBy)(options ?? {}, (v) => (0, type_utils_js_1.isNil)(v)),
|
|
137
|
+
session: {
|
|
138
|
+
mode: "disabled",
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.AISessionMemoryExtractor = AISessionMemoryExtractor;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { Agent, Message } from "../../agents/agent.js";
|
|
2
2
|
import type { ChatModelInputMessage } from "../../agents/chat-model.js";
|
|
3
|
+
/**
|
|
4
|
+
* Session mode type
|
|
5
|
+
*/
|
|
6
|
+
export type SessionMode = "auto" | "disabled";
|
|
7
|
+
/**
|
|
8
|
+
* Default session mode
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_SESSION_MODE: SessionMode;
|
|
3
11
|
/**
|
|
4
12
|
* Default compaction mode
|
|
5
13
|
*/
|
|
@@ -29,6 +37,13 @@ export interface EntryContent {
|
|
|
29
37
|
*/
|
|
30
38
|
export interface CompactContent extends Message {
|
|
31
39
|
summary: string;
|
|
40
|
+
/**
|
|
41
|
+
* Last Agent Skill content in the session
|
|
42
|
+
* Preserved across compactions to maintain skill instructions
|
|
43
|
+
*/
|
|
44
|
+
lastAgentSkill?: {
|
|
45
|
+
content: string;
|
|
46
|
+
};
|
|
32
47
|
}
|
|
33
48
|
/**
|
|
34
49
|
* Input structure for the compactor agent
|
|
@@ -77,3 +92,245 @@ export interface CompactConfig {
|
|
|
77
92
|
*/
|
|
78
93
|
compactor?: Compactor;
|
|
79
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Default ratio of maxTokens to allocate for user memory
|
|
97
|
+
*/
|
|
98
|
+
export declare const DEFAULT_MEMORY_RATIO = 0.04;
|
|
99
|
+
/**
|
|
100
|
+
* Default query limit for loading memory facts
|
|
101
|
+
*/
|
|
102
|
+
export declare const DEFAULT_MEMORY_QUERY_LIMIT = 200;
|
|
103
|
+
/**
|
|
104
|
+
* Content structure for a single memory fact
|
|
105
|
+
*
|
|
106
|
+
* Used by both session memory and user memory to store learned facts.
|
|
107
|
+
* Each fact is stored as an individual AFSEntry with metadata at the AFSEntry level.
|
|
108
|
+
*
|
|
109
|
+
* Storage paths:
|
|
110
|
+
* - Session Memory:
|
|
111
|
+
* - List: /by-session/:sessionId/@metadata/memory
|
|
112
|
+
* - Create: /by-session/:sessionId/@metadata/memory/new
|
|
113
|
+
* - Read: /by-session/:sessionId/@metadata/memory/:memoryId
|
|
114
|
+
* - User Memory:
|
|
115
|
+
* - List: /by-user/:userId/@metadata/memory
|
|
116
|
+
* - Create: /by-user/:userId/@metadata/memory/new
|
|
117
|
+
* - Read: /by-user/:userId/@metadata/memory/:memoryId
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* AFSEntry<MemoryFact> {
|
|
121
|
+
* id: "fact-001", // AFSEntry ID (auto-generated)
|
|
122
|
+
* userId: "user-001",
|
|
123
|
+
* agentId: "assistant", // which agent learned this fact
|
|
124
|
+
* sessionId: "session-123", // which session it was learned from (if applicable)
|
|
125
|
+
* createdAt: Date,
|
|
126
|
+
* content: {
|
|
127
|
+
* label: "pref-package-manager", // semantic label for this fact
|
|
128
|
+
* fact: "User prefers using pnpm",
|
|
129
|
+
* confidence: 0.9,
|
|
130
|
+
* tags: ["preference", "tooling"]
|
|
131
|
+
* }
|
|
132
|
+
* }
|
|
133
|
+
*/
|
|
134
|
+
export interface MemoryFact {
|
|
135
|
+
/**
|
|
136
|
+
* Semantic label for this fact (short, human-readable)
|
|
137
|
+
* Used for updates and deletions to uniquely identify facts
|
|
138
|
+
* @example "pref-package-manager", "skill-typescript", "proj-main-language"
|
|
139
|
+
*/
|
|
140
|
+
label: string;
|
|
141
|
+
/**
|
|
142
|
+
* The fact content (text description)
|
|
143
|
+
*/
|
|
144
|
+
fact: string;
|
|
145
|
+
/**
|
|
146
|
+
* Confidence score (0-1)
|
|
147
|
+
* Higher values indicate more certain facts
|
|
148
|
+
* @default 1.0
|
|
149
|
+
*/
|
|
150
|
+
confidence?: number;
|
|
151
|
+
/**
|
|
152
|
+
* Classification tags for the fact
|
|
153
|
+
* @example ['preference', 'technical', 'project-specific']
|
|
154
|
+
*/
|
|
155
|
+
tags?: string[];
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Input structure for the memory extractor agent
|
|
159
|
+
*/
|
|
160
|
+
export interface MemoryExtractorInput extends Message {
|
|
161
|
+
/**
|
|
162
|
+
* User memory facts (long-term, cross-session) to avoid duplication
|
|
163
|
+
*/
|
|
164
|
+
existingUserFacts?: MemoryFact[];
|
|
165
|
+
/**
|
|
166
|
+
* Existing session memory facts (for context and deduplication)
|
|
167
|
+
*/
|
|
168
|
+
existingFacts?: MemoryFact[];
|
|
169
|
+
/**
|
|
170
|
+
* Recent conversation messages to extract facts from
|
|
171
|
+
*/
|
|
172
|
+
messages: ChatModelInputMessage[];
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Output structure from the memory extractor agent
|
|
176
|
+
*/
|
|
177
|
+
export interface MemoryExtractorOutput extends Message {
|
|
178
|
+
/**
|
|
179
|
+
* New or updated facts from the conversation
|
|
180
|
+
* Only include facts that need to be added or updated
|
|
181
|
+
* Do not include unchanged facts that already exist
|
|
182
|
+
*/
|
|
183
|
+
newFacts: MemoryFact[];
|
|
184
|
+
/**
|
|
185
|
+
* Fact labels to remove from existing memory
|
|
186
|
+
* Each string should match a label in existingFacts
|
|
187
|
+
* @example ["pref-package-manager", "skill-old-framework"]
|
|
188
|
+
*/
|
|
189
|
+
removeFacts?: string[];
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Type alias for a memory extractor agent
|
|
193
|
+
*/
|
|
194
|
+
export type MemoryExtractor = Agent<MemoryExtractorInput, MemoryExtractorOutput>;
|
|
195
|
+
/**
|
|
196
|
+
* Default session memory mode
|
|
197
|
+
*/
|
|
198
|
+
export declare const DEFAULT_SESSION_MEMORY_MODE: "auto";
|
|
199
|
+
/**
|
|
200
|
+
* Default async mode for session memory extraction
|
|
201
|
+
*/
|
|
202
|
+
export declare const DEFAULT_SESSION_MEMORY_ASYNC = true;
|
|
203
|
+
/**
|
|
204
|
+
* Metadata for tracking session memory extraction progress
|
|
205
|
+
*
|
|
206
|
+
* This metadata is stored in each memory entry's metadata field.
|
|
207
|
+
* When extracting new facts, the latestEntryId is recorded in the metadata
|
|
208
|
+
* to track which history entries have been processed.
|
|
209
|
+
*/
|
|
210
|
+
export interface SessionMemoryMetadata {
|
|
211
|
+
/**
|
|
212
|
+
* ID of the last extracted history entry
|
|
213
|
+
* Used to determine which entries still need processing
|
|
214
|
+
*/
|
|
215
|
+
latestEntryId?: string;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Default user memory mode
|
|
219
|
+
*/
|
|
220
|
+
export declare const DEFAULT_USER_MEMORY_MODE: "auto";
|
|
221
|
+
/**
|
|
222
|
+
* Default async mode for user memory consolidation
|
|
223
|
+
*/
|
|
224
|
+
export declare const DEFAULT_USER_MEMORY_ASYNC = true;
|
|
225
|
+
/**
|
|
226
|
+
* Input structure for the user memory extractor agent
|
|
227
|
+
*/
|
|
228
|
+
export interface UserMemoryExtractorInput extends Message {
|
|
229
|
+
/**
|
|
230
|
+
* Session memory facts from multiple sessions to consolidate
|
|
231
|
+
*/
|
|
232
|
+
sessionFacts: MemoryFact[];
|
|
233
|
+
/**
|
|
234
|
+
* Existing user memory facts (for context and deduplication)
|
|
235
|
+
*/
|
|
236
|
+
existingUserFacts?: MemoryFact[];
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Output structure from the user memory extractor agent
|
|
240
|
+
*/
|
|
241
|
+
export interface UserMemoryExtractorOutput extends Message {
|
|
242
|
+
/**
|
|
243
|
+
* New or updated facts for user memory
|
|
244
|
+
* Only include facts that need to be added or updated
|
|
245
|
+
* Do not include unchanged facts that already exist
|
|
246
|
+
* Each label should be unique - these will replace old facts with same labels
|
|
247
|
+
*/
|
|
248
|
+
newFacts: MemoryFact[];
|
|
249
|
+
/**
|
|
250
|
+
* Fact labels to remove from user memory
|
|
251
|
+
* Each string should match a label in existingUserFacts
|
|
252
|
+
*/
|
|
253
|
+
removeFacts?: string[];
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Type alias for a user memory extractor agent
|
|
257
|
+
*/
|
|
258
|
+
export type UserMemoryExtractor = Agent<UserMemoryExtractorInput, UserMemoryExtractorOutput>;
|
|
259
|
+
/**
|
|
260
|
+
* Configuration for user memory
|
|
261
|
+
* User memory contains long-term facts consolidated from multiple sessions
|
|
262
|
+
*/
|
|
263
|
+
export interface UserMemoryConfig {
|
|
264
|
+
/**
|
|
265
|
+
* User memory mode
|
|
266
|
+
* - "auto": Enable memory and auto-consolidate at appropriate times
|
|
267
|
+
* - "disabled": Disable user memory completely
|
|
268
|
+
* @default DEFAULT_USER_MEMORY_MODE ("auto")
|
|
269
|
+
*/
|
|
270
|
+
mode?: "auto" | "disabled";
|
|
271
|
+
/**
|
|
272
|
+
* Ratio of maxTokens to allocate for user memory (0-1)
|
|
273
|
+
*
|
|
274
|
+
* Defines what portion of maxTokens budget should be allocated for
|
|
275
|
+
* injecting user memory facts into the prompt.
|
|
276
|
+
*
|
|
277
|
+
* @default DEFAULT_MEMORY_RATIO (0.04 = 4% of maxTokens)
|
|
278
|
+
* @example 0.04 means if maxTokens=80000, allocate 3200 tokens for memory
|
|
279
|
+
*/
|
|
280
|
+
memoryRatio?: number;
|
|
281
|
+
/**
|
|
282
|
+
* Maximum number of fact entries to load from storage
|
|
283
|
+
* @default DEFAULT_MEMORY_QUERY_LIMIT (200)
|
|
284
|
+
*/
|
|
285
|
+
queryLimit?: number;
|
|
286
|
+
/**
|
|
287
|
+
* Whether to perform memory consolidation asynchronously
|
|
288
|
+
* @default DEFAULT_USER_MEMORY_ASYNC (true)
|
|
289
|
+
*/
|
|
290
|
+
async?: boolean;
|
|
291
|
+
/**
|
|
292
|
+
* Agent that extracts user memory facts from session memory
|
|
293
|
+
* Input: { sessionFacts: MemoryFact[], existingUserFacts?: MemoryFact[] }
|
|
294
|
+
* Output: { newFacts: MemoryFact[], removeFacts?: string[] }
|
|
295
|
+
*/
|
|
296
|
+
extractor?: UserMemoryExtractor;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Configuration for session memory
|
|
300
|
+
* Session memory contains facts extracted from the current session's conversation
|
|
301
|
+
*/
|
|
302
|
+
export interface SessionMemoryConfig {
|
|
303
|
+
/**
|
|
304
|
+
* Session memory mode
|
|
305
|
+
* - "auto": Enable memory and auto-update after each conversation turn
|
|
306
|
+
* - "disabled": Disable memory completely
|
|
307
|
+
* @default DEFAULT_SESSION_MEMORY_MODE ("auto")
|
|
308
|
+
*/
|
|
309
|
+
mode?: "auto" | "disabled";
|
|
310
|
+
/**
|
|
311
|
+
* Ratio of maxTokens to allocate for session memory (0-1)
|
|
312
|
+
*
|
|
313
|
+
* Defines what portion of maxTokens budget should be allocated for
|
|
314
|
+
* injecting session memory facts into the prompt.
|
|
315
|
+
*
|
|
316
|
+
* @default DEFAULT_MEMORY_RATIO (0.04 = 4% of maxTokens)
|
|
317
|
+
* @example 0.04 means if maxTokens=80000, allocate 3200 tokens for memory
|
|
318
|
+
*/
|
|
319
|
+
memoryRatio?: number;
|
|
320
|
+
/**
|
|
321
|
+
* Maximum number of fact entries to load from storage
|
|
322
|
+
* @default DEFAULT_MEMORY_QUERY_LIMIT (200)
|
|
323
|
+
*/
|
|
324
|
+
queryLimit?: number;
|
|
325
|
+
/**
|
|
326
|
+
* Whether to perform memory extraction asynchronously
|
|
327
|
+
* @default DEFAULT_SESSION_MEMORY_ASYNC (true)
|
|
328
|
+
*/
|
|
329
|
+
async?: boolean;
|
|
330
|
+
/**
|
|
331
|
+
* Agent that extracts facts from conversation messages
|
|
332
|
+
* Input: { existingUserFacts?: MemoryFact[], existingFacts?: MemoryFact[], messages: ChatModelInputMessage[] }
|
|
333
|
+
* Output: { newFacts: MemoryFact[], removeFacts?: string[] }
|
|
334
|
+
*/
|
|
335
|
+
extractor?: MemoryExtractor;
|
|
336
|
+
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_COMPACT_ASYNC = exports.DEFAULT_KEEP_RECENT_RATIO = exports.DEFAULT_MAX_TOKENS = exports.DEFAULT_COMPACT_MODE = void 0;
|
|
3
|
+
exports.DEFAULT_USER_MEMORY_ASYNC = exports.DEFAULT_USER_MEMORY_MODE = exports.DEFAULT_SESSION_MEMORY_ASYNC = exports.DEFAULT_SESSION_MEMORY_MODE = exports.DEFAULT_MEMORY_QUERY_LIMIT = exports.DEFAULT_MEMORY_RATIO = exports.DEFAULT_COMPACT_ASYNC = exports.DEFAULT_KEEP_RECENT_RATIO = exports.DEFAULT_MAX_TOKENS = exports.DEFAULT_COMPACT_MODE = exports.DEFAULT_SESSION_MODE = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Default session mode
|
|
6
|
+
*/
|
|
7
|
+
exports.DEFAULT_SESSION_MODE = "auto";
|
|
4
8
|
/**
|
|
5
9
|
* Default compaction mode
|
|
6
10
|
*/
|
|
@@ -17,3 +21,33 @@ exports.DEFAULT_KEEP_RECENT_RATIO = 0.5;
|
|
|
17
21
|
* Default async mode for compaction
|
|
18
22
|
*/
|
|
19
23
|
exports.DEFAULT_COMPACT_ASYNC = true;
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// User Memory Types
|
|
26
|
+
// ============================================================================
|
|
27
|
+
/**
|
|
28
|
+
* Default ratio of maxTokens to allocate for user memory
|
|
29
|
+
*/
|
|
30
|
+
exports.DEFAULT_MEMORY_RATIO = 0.04;
|
|
31
|
+
/**
|
|
32
|
+
* Default query limit for loading memory facts
|
|
33
|
+
*/
|
|
34
|
+
exports.DEFAULT_MEMORY_QUERY_LIMIT = 200;
|
|
35
|
+
/**
|
|
36
|
+
* Default session memory mode
|
|
37
|
+
*/
|
|
38
|
+
exports.DEFAULT_SESSION_MEMORY_MODE = "auto";
|
|
39
|
+
/**
|
|
40
|
+
* Default async mode for session memory extraction
|
|
41
|
+
*/
|
|
42
|
+
exports.DEFAULT_SESSION_MEMORY_ASYNC = true;
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// User Memory Types
|
|
45
|
+
// ============================================================================
|
|
46
|
+
/**
|
|
47
|
+
* Default user memory mode
|
|
48
|
+
*/
|
|
49
|
+
exports.DEFAULT_USER_MEMORY_MODE = "auto";
|
|
50
|
+
/**
|
|
51
|
+
* Default async mode for user memory consolidation
|
|
52
|
+
*/
|
|
53
|
+
exports.DEFAULT_USER_MEMORY_ASYNC = true;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AIAgent, type AIAgentOptions } from "../../agents/ai-agent.js";
|
|
2
|
+
import type { UserMemoryExtractorInput, UserMemoryExtractorOutput } from "./types.js";
|
|
3
|
+
export interface CreateUserMemoryExtractorOptions extends AIAgentOptions<UserMemoryExtractorInput, UserMemoryExtractorOutput> {
|
|
4
|
+
}
|
|
5
|
+
export declare class AIUserMemoryExtractor extends AIAgent<UserMemoryExtractorInput, UserMemoryExtractorOutput> {
|
|
6
|
+
constructor(options?: CreateUserMemoryExtractorOptions);
|
|
7
|
+
}
|
|
@@ -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;
|
|
@@ -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
|
}
|
|
@@ -82,7 +82,7 @@ class PromptBuilder {
|
|
|
82
82
|
userId,
|
|
83
83
|
sessionId,
|
|
84
84
|
afs,
|
|
85
|
-
|
|
85
|
+
...options.agent?.session,
|
|
86
86
|
});
|
|
87
87
|
const { systemMessage, userMessage } = await this.buildMessages(options);
|
|
88
88
|
if (systemMessage)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Agent, type AgentOptions, type Message } from "../../../../agents/agent.js";
|
|
2
|
+
import type { PromiseOrValue } from "../../../../utils/type-utils.js";
|
|
2
3
|
import type { Skill } from "./skill-loader.js";
|
|
3
4
|
export interface SkillToolInput extends Message {
|
|
4
5
|
skill: string;
|
|
@@ -11,6 +12,7 @@ export interface SkillToolOptions extends AgentOptions<SkillToolInput, SkillTool
|
|
|
11
12
|
agentSkills: Skill[];
|
|
12
13
|
}
|
|
13
14
|
export declare class AgentSkill extends Agent<SkillToolInput, SkillToolOutput> {
|
|
15
|
+
formatOutput(output: SkillToolOutput | Message): PromiseOrValue<string>;
|
|
14
16
|
constructor(options: SkillToolOptions);
|
|
15
17
|
private agentSkills;
|
|
16
18
|
process(input: SkillToolInput): Promise<SkillToolOutput>;
|
|
@@ -8,6 +8,12 @@ const skillToolInputSchema = zod_1.z.object({
|
|
|
8
8
|
args: zod_1.z.string().optional().describe("The arguments to pass to the skill."),
|
|
9
9
|
});
|
|
10
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
|
+
}
|
|
11
17
|
constructor(options) {
|
|
12
18
|
super({
|
|
13
19
|
name: "Skill",
|
|
@@ -6,8 +6,7 @@ export interface Skill {
|
|
|
6
6
|
description: string;
|
|
7
7
|
content: string;
|
|
8
8
|
}
|
|
9
|
-
export declare function
|
|
10
|
-
export declare function loadSkills(paths: string[]): Promise<Skill[]>;
|
|
9
|
+
export declare function discoverSkillsFromAFS(afs: AFS): Promise<Skill[]>;
|
|
11
10
|
export declare function loadAgentSkillFromAFS({ afs, }: {
|
|
12
11
|
afs: AFS;
|
|
13
12
|
}): Promise<AgentSkill | undefined>;
|