@yandy0725/pi-memory 1.0.0 → 1.1.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/README.md +7 -1
- package/README.zh.md +7 -1
- package/index.ts +13 -3
- package/package.json +1 -1
- package/src/config.ts +8 -2
- package/src/dream.ts +3 -1
- package/src/extract.ts +5 -2
- package/src/inject.ts +4 -1
package/README.md
CHANGED
|
@@ -47,7 +47,8 @@ Create `memory.json` in the agent directory (`~/.pi/agent/memory.json`) or the p
|
|
|
47
47
|
"dream": {
|
|
48
48
|
"nudgeAfterSessions": 5,
|
|
49
49
|
"nudgeAfterHours": 24,
|
|
50
|
-
"model": "auto"
|
|
50
|
+
"model": "auto",
|
|
51
|
+
"thinkLevel": "high"
|
|
51
52
|
},
|
|
52
53
|
"sessionSearch": {
|
|
53
54
|
"maxSessions": 10,
|
|
@@ -56,6 +57,7 @@ Create `memory.json` in the agent directory (`~/.pi/agent/memory.json`) or the p
|
|
|
56
57
|
"autoSurfacing": {
|
|
57
58
|
"enabled": true,
|
|
58
59
|
"model": "auto",
|
|
60
|
+
"thinkLevel": "off",
|
|
59
61
|
"maxFiles": 5,
|
|
60
62
|
"maxTopicBytes": 4096,
|
|
61
63
|
"maxInjectionBytes": 20480
|
|
@@ -63,6 +65,7 @@ Create `memory.json` in the agent directory (`~/.pi/agent/memory.json`) or the p
|
|
|
63
65
|
"extractMemories": {
|
|
64
66
|
"enabled": true,
|
|
65
67
|
"model": "auto",
|
|
68
|
+
"thinkLevel": "high",
|
|
66
69
|
"maxContextTokens": 2000
|
|
67
70
|
}
|
|
68
71
|
}
|
|
@@ -77,15 +80,18 @@ Create `memory.json` in the agent directory (`~/.pi/agent/memory.json`) or the p
|
|
|
77
80
|
| `dream.nudgeAfterSessions` | `5` | Sessions since last dream before nudge is shown |
|
|
78
81
|
| `dream.nudgeAfterHours` | `24` | Hours since last dream before nudge is shown |
|
|
79
82
|
| `dream.model` | `"auto"` | Model for dream consolidation (`"auto"` = same as current, or `"provider/id"`) |
|
|
83
|
+
| `dream.thinkLevel` | `"high"` | Thinking effort for dream subagent: `"off"`, `"minimal"`, `"low"`, `"medium"`, `"high"`, `"xhigh"` |
|
|
80
84
|
| `sessionSearch.maxSessions` | `10` | Max sessions to scan when searching history |
|
|
81
85
|
| `sessionSearch.maxMatches` | `5` | Max matches to return from history search |
|
|
82
86
|
| `autoSurfacing.enabled` | `true` | ⭐ Enable per-turn topic file auto-injection |
|
|
83
87
|
| `autoSurfacing.model` | `"auto"` | ⭐ Model for side-query relevance selection |
|
|
88
|
+
| `autoSurfacing.thinkLevel` | `"off"` | ⭐ Thinking effort for side-query (recommended: `"off"` for lightweight selection) |
|
|
84
89
|
| `autoSurfacing.maxFiles` | `5` | ⭐ Max topic files to inject per turn |
|
|
85
90
|
| `autoSurfacing.maxTopicBytes` | `4096` | ⭐ Max bytes per injected topic file (truncated) |
|
|
86
91
|
| `autoSurfacing.maxInjectionBytes` | `20480` | ⭐ Max total bytes of injected content per turn |
|
|
87
92
|
| `extractMemories.enabled` | `true` | ⭐ Enable per-turn memory extraction |
|
|
88
93
|
| `extractMemories.model` | `"auto"` | ⭐ Model for the extraction subagent |
|
|
94
|
+
| `extractMemories.thinkLevel` | `"high"` | ⭐ Thinking effort for extraction: `"off"` / `"minimal"` / `"low"` / `"medium"` / `"high"` / `"xhigh"` |
|
|
89
95
|
| `extractMemories.maxContextTokens` | `2000` | ⭐ Max tokens of conversation to analyze |
|
|
90
96
|
|
|
91
97
|
Project-level config (`.pi/memory.json`) is only loaded when the project is trusted.
|
package/README.zh.md
CHANGED
|
@@ -47,7 +47,8 @@ pi install npm:@yandy0725/pi-memory
|
|
|
47
47
|
"dream": {
|
|
48
48
|
"nudgeAfterSessions": 5,
|
|
49
49
|
"nudgeAfterHours": 24,
|
|
50
|
-
"model": "auto"
|
|
50
|
+
"model": "auto",
|
|
51
|
+
"thinkLevel": "high"
|
|
51
52
|
},
|
|
52
53
|
"sessionSearch": {
|
|
53
54
|
"maxSessions": 10,
|
|
@@ -56,6 +57,7 @@ pi install npm:@yandy0725/pi-memory
|
|
|
56
57
|
"autoSurfacing": {
|
|
57
58
|
"enabled": true,
|
|
58
59
|
"model": "auto",
|
|
60
|
+
"thinkLevel": "off",
|
|
59
61
|
"maxFiles": 5,
|
|
60
62
|
"maxTopicBytes": 4096,
|
|
61
63
|
"maxInjectionBytes": 20480
|
|
@@ -63,6 +65,7 @@ pi install npm:@yandy0725/pi-memory
|
|
|
63
65
|
"extractMemories": {
|
|
64
66
|
"enabled": true,
|
|
65
67
|
"model": "auto",
|
|
68
|
+
"thinkLevel": "high",
|
|
66
69
|
"maxContextTokens": 2000
|
|
67
70
|
}
|
|
68
71
|
}
|
|
@@ -77,15 +80,18 @@ pi install npm:@yandy0725/pi-memory
|
|
|
77
80
|
| `dream.nudgeAfterSessions` | `5` | 触发提醒需经过的会话数 |
|
|
78
81
|
| `dream.nudgeAfterHours` | `24` | 触发提醒需经过的小时数 |
|
|
79
82
|
| `dream.model` | `"auto"` | 整理使用的模型(`"auto"` = 当前模型,或 `"provider/id"`) |
|
|
83
|
+
| `dream.thinkLevel` | `"high"` | 整理子 agent 的思考深度:`"off"` / `"minimal"` / `"low"` / `"medium"` / `"high"` / `"xhigh"` |
|
|
80
84
|
| `sessionSearch.maxSessions` | `10` | 搜索历史时最多扫描的会话数 |
|
|
81
85
|
| `sessionSearch.maxMatches` | `5` | 历史搜索最多返回的匹配数 |
|
|
82
86
|
| `autoSurfacing.enabled` | `true` | ⭐ 启用 per-turn topic 文件自动注入 |
|
|
83
87
|
| `autoSurfacing.model` | `"auto"` | ⭐ side-query 相关性选择模型 |
|
|
88
|
+
| `autoSurfacing.thinkLevel` | `"off"` | ⭐ side-query 思考深度(推荐 `"off"`,轻量选择任务) |
|
|
84
89
|
| `autoSurfacing.maxFiles` | `5` | ⭐ 每轮最多注入的 topic 文件数 |
|
|
85
90
|
| `autoSurfacing.maxTopicBytes` | `4096` | ⭐ 单个注入 topic 文件最大字节数(截断) |
|
|
86
91
|
| `autoSurfacing.maxInjectionBytes` | `20480` | ⭐ 每轮注入内容总字节数上限 |
|
|
87
92
|
| `extractMemories.enabled` | `true` | ⭐ 启用 per-turn 记忆自动提取 |
|
|
88
93
|
| `extractMemories.model` | `"auto"` | ⭐ 提取子 agent 使用的模型 |
|
|
94
|
+
| `extractMemories.thinkLevel` | `"high"` | ⭐ 提取的思考深度:`"off"` / `"minimal"` / `"low"` / `"medium"` / `"high"` / `"xhigh"` |
|
|
89
95
|
| `extractMemories.maxContextTokens` | `2000` | ⭐ 分析对话的最大 token 数 |
|
|
90
96
|
|
|
91
97
|
项目级配置(`.pi/memory.json`)仅在项目受信任时加载。
|
package/index.ts
CHANGED
|
@@ -61,12 +61,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
61
61
|
// session_start handlers (including pi-subagents') have completed.
|
|
62
62
|
// Does not block session_start.
|
|
63
63
|
const dreamModel = config.dream.model;
|
|
64
|
+
const dreamThinkLevel = config.dream.thinkLevel;
|
|
64
65
|
const dir = memoryDir;
|
|
65
66
|
ctx.ui.setStatus("dream", "Consolidating memory...");
|
|
66
67
|
setTimeout(async () => {
|
|
67
68
|
try {
|
|
68
69
|
const summary = await runDream({
|
|
69
70
|
model: dreamModel,
|
|
71
|
+
thinkLevel: dreamThinkLevel,
|
|
70
72
|
memoryDir: dir,
|
|
71
73
|
events: pi.events,
|
|
72
74
|
});
|
|
@@ -87,17 +89,23 @@ export default function (pi: ExtensionAPI) {
|
|
|
87
89
|
pi.on("before_agent_start", async (event, ctx) => {
|
|
88
90
|
if (!config?.enabled || !indexSnapshot || !memoryDir) return;
|
|
89
91
|
|
|
90
|
-
// Auto-surfacing: select relevant topic files via LLM side-query and inject as message
|
|
92
|
+
// Auto-surfacing: select relevant topic files via LLM side-query and inject as message.
|
|
93
|
+
// Skip for subagents: pi-subagents strips "subagent" from all children's
|
|
94
|
+
// tool sets, so its absence reliably identifies subagents. Without this guard,
|
|
95
|
+
// runSideQuery's subagent spawn → before_agent_start → re-enter here → OOM.
|
|
96
|
+
const agentTools = event.systemPromptOptions?.selectedTools;
|
|
97
|
+
const isSubagent = agentTools && !agentTools.includes("subagent");
|
|
98
|
+
|
|
91
99
|
const autoSurfacing = config.autoSurfacing;
|
|
92
100
|
// biome-ignore lint/suspicious/noExplicitAny: message injection result
|
|
93
101
|
let injectedMessage: any;
|
|
94
|
-
if (autoSurfacing?.enabled && event.prompt) {
|
|
102
|
+
if (autoSurfacing?.enabled && event.prompt && !isSubagent) {
|
|
95
103
|
try {
|
|
96
104
|
if (ctx.hasUI) ctx.ui.setStatus("surfacing", "Searching relevant memories…");
|
|
97
105
|
const manifest = await scanTopics(memoryDir);
|
|
98
106
|
if (manifest.length > 0) {
|
|
99
107
|
const queryPrompt = buildSurfacingPrompt(manifest, event.prompt.slice(0, 4000), injectedTopics);
|
|
100
|
-
const selected = await runSideQuery(queryPrompt, manifest, autoSurfacing.maxFiles, pi.events);
|
|
108
|
+
const selected = await runSideQuery(queryPrompt, manifest, autoSurfacing.maxFiles, autoSurfacing.thinkLevel, pi.events);
|
|
101
109
|
if (selected.length > 0) {
|
|
102
110
|
const content = await injectSurfacedContent(
|
|
103
111
|
memoryDir,
|
|
@@ -135,6 +143,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
135
143
|
// Fire-and-forget: extract memories in background
|
|
136
144
|
runExtract({
|
|
137
145
|
model: extractConfig.model,
|
|
146
|
+
thinkLevel: extractConfig.thinkLevel,
|
|
138
147
|
memoryDir,
|
|
139
148
|
messages: event.messages.map((m) => ({
|
|
140
149
|
// biome-ignore lint/suspicious/noExplicitAny: pi event message union type
|
|
@@ -197,6 +206,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
197
206
|
try {
|
|
198
207
|
const summary = await runDream({
|
|
199
208
|
model: config.dream.model,
|
|
209
|
+
thinkLevel: config.dream.thinkLevel,
|
|
200
210
|
memoryDir,
|
|
201
211
|
signal: ctx.signal,
|
|
202
212
|
events: pi.events,
|
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -3,9 +3,12 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { CONFIG_DIR_NAME, getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
5
5
|
|
|
6
|
+
export type ThinkLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
7
|
+
|
|
6
8
|
export interface AutoSurfacingConfig {
|
|
7
9
|
enabled: boolean;
|
|
8
10
|
model: string;
|
|
11
|
+
thinkLevel: ThinkLevel;
|
|
9
12
|
maxFiles: number;
|
|
10
13
|
maxTopicBytes: number;
|
|
11
14
|
maxInjectionBytes: number;
|
|
@@ -14,6 +17,7 @@ export interface AutoSurfacingConfig {
|
|
|
14
17
|
export interface ExtractMemoriesConfig {
|
|
15
18
|
enabled: boolean;
|
|
16
19
|
model: string;
|
|
20
|
+
thinkLevel: ThinkLevel;
|
|
17
21
|
maxContextTokens: number;
|
|
18
22
|
}
|
|
19
23
|
|
|
@@ -22,7 +26,7 @@ export interface MemoryConfig {
|
|
|
22
26
|
memoryDir: string;
|
|
23
27
|
memIndexMaxLines: number;
|
|
24
28
|
memIndexMaxBytes: number;
|
|
25
|
-
dream: { nudgeAfterSessions: number; nudgeAfterHours: number; model: string };
|
|
29
|
+
dream: { nudgeAfterSessions: number; nudgeAfterHours: number; model: string; thinkLevel: ThinkLevel };
|
|
26
30
|
sessionSearch: { maxSessions: number; maxMatches: number };
|
|
27
31
|
autoSurfacing: AutoSurfacingConfig;
|
|
28
32
|
extractMemories: ExtractMemoriesConfig;
|
|
@@ -33,11 +37,12 @@ export const DEFAULT_CONFIG: MemoryConfig = {
|
|
|
33
37
|
memoryDir: join(homedir(), CONFIG_DIR_NAME, "memory"),
|
|
34
38
|
memIndexMaxLines: 200,
|
|
35
39
|
memIndexMaxBytes: 25600,
|
|
36
|
-
dream: { nudgeAfterSessions: 5, nudgeAfterHours: 24, model: "auto" },
|
|
40
|
+
dream: { nudgeAfterSessions: 5, nudgeAfterHours: 24, model: "auto", thinkLevel: "high" },
|
|
37
41
|
sessionSearch: { maxSessions: 10, maxMatches: 5 },
|
|
38
42
|
autoSurfacing: {
|
|
39
43
|
enabled: true,
|
|
40
44
|
model: "auto",
|
|
45
|
+
thinkLevel: "off",
|
|
41
46
|
maxFiles: 5,
|
|
42
47
|
maxTopicBytes: 4096,
|
|
43
48
|
maxInjectionBytes: 20480,
|
|
@@ -45,6 +50,7 @@ export const DEFAULT_CONFIG: MemoryConfig = {
|
|
|
45
50
|
extractMemories: {
|
|
46
51
|
enabled: true,
|
|
47
52
|
model: "auto",
|
|
53
|
+
thinkLevel: "high",
|
|
48
54
|
maxContextTokens: 2000,
|
|
49
55
|
},
|
|
50
56
|
};
|
package/src/dream.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { access } from "node:fs/promises";
|
|
2
|
+
import type { ThinkLevel } from "./config";
|
|
2
3
|
import { getSubagentsService, type SubagentsService, type WorkspaceProvider } from "@yandy0725/pi-subagents";
|
|
3
4
|
|
|
4
5
|
/** Build dream consolidation task.
|
|
@@ -53,6 +54,7 @@ CRITICAL for hooks and descriptions:
|
|
|
53
54
|
|
|
54
55
|
export interface RunDreamOpts {
|
|
55
56
|
model: string;
|
|
57
|
+
thinkLevel: ThinkLevel;
|
|
56
58
|
memoryDir: string;
|
|
57
59
|
signal?: AbortSignal;
|
|
58
60
|
// biome-ignore lint/suspicious/noExplicitAny: pi events API handler
|
|
@@ -88,7 +90,7 @@ export async function runDream(opts: RunDreamOpts): Promise<string> {
|
|
|
88
90
|
const agentId = service.spawn(
|
|
89
91
|
"memory-agent",
|
|
90
92
|
task,
|
|
91
|
-
model ? { model, thinkingLevel:
|
|
93
|
+
model ? { model, thinkingLevel: opts.thinkLevel } : { thinkingLevel: opts.thinkLevel },
|
|
92
94
|
);
|
|
93
95
|
|
|
94
96
|
// Wait for completion/failure via pi-subagents events (abort-while-queued
|
package/src/extract.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { access } from "node:fs/promises";
|
|
2
|
+
import type { ThinkLevel } from "./config";
|
|
2
3
|
import { getSubagentsService, type SubagentsService, type WorkspaceProvider } from "@yandy0725/pi-subagents";
|
|
3
4
|
|
|
4
5
|
export interface RunExtractOpts {
|
|
5
6
|
model: string;
|
|
7
|
+
thinkLevel: ThinkLevel;
|
|
6
8
|
memoryDir: string;
|
|
7
9
|
messages: Array<{ role: string; content: string }>;
|
|
8
10
|
maxContextTokens: number;
|
|
@@ -84,6 +86,7 @@ export async function runExtract(opts: RunExtractOpts): Promise<void> {
|
|
|
84
86
|
if (!service) return; // silently skip if no subagent service
|
|
85
87
|
|
|
86
88
|
const model = opts.model === "auto" ? undefined : opts.model;
|
|
89
|
+
const thinkLevel = opts.thinkLevel;
|
|
87
90
|
const task = buildExtractTask(opts.memoryDir, opts.messages, opts.maxContextTokens);
|
|
88
91
|
|
|
89
92
|
const provider: WorkspaceProvider = {
|
|
@@ -104,7 +107,7 @@ export async function runExtract(opts: RunExtractOpts): Promise<void> {
|
|
|
104
107
|
"memory-agent",
|
|
105
108
|
task,
|
|
106
109
|
model
|
|
107
|
-
? { model, inheritContext: false, maxTurns: 5, thinkingLevel:
|
|
108
|
-
: { inheritContext: false, maxTurns: 5, thinkingLevel:
|
|
110
|
+
? { model, inheritContext: false, maxTurns: 5, thinkingLevel: thinkLevel }
|
|
111
|
+
: { inheritContext: false, maxTurns: 5, thinkingLevel: thinkLevel },
|
|
109
112
|
);
|
|
110
113
|
}
|
package/src/inject.ts
CHANGED
|
@@ -117,10 +117,13 @@ export async function injectSurfacedContent(
|
|
|
117
117
|
/** Run a lightweight LLM side-query to select relevant topic files.
|
|
118
118
|
* Uses pi-subagents spawn + Promise pattern (same as dream.ts).
|
|
119
119
|
* Falls back to keyword matching if subagent service is unavailable. */
|
|
120
|
+
import type { ThinkLevel } from "./config";
|
|
121
|
+
|
|
120
122
|
export async function runSideQuery(
|
|
121
123
|
prompt: string,
|
|
122
124
|
manifest: TopicManifest[],
|
|
123
125
|
maxFiles: number,
|
|
126
|
+
thinkLevel: ThinkLevel,
|
|
124
127
|
// biome-ignore lint/suspicious/noExplicitAny: pi events API handler
|
|
125
128
|
events?: { on(channel: string, handler: (data: any) => void): () => void },
|
|
126
129
|
): Promise<string[]> {
|
|
@@ -219,7 +222,7 @@ export async function runSideQuery(
|
|
|
219
222
|
const agentId = service.spawn("memory-agent", task, {
|
|
220
223
|
maxTurns: 1,
|
|
221
224
|
inheritContext: false,
|
|
222
|
-
thinkingLevel:
|
|
225
|
+
thinkingLevel: thinkLevel,
|
|
223
226
|
foreground: true,
|
|
224
227
|
bypassQueue: true,
|
|
225
228
|
});
|