minimal-agent 0.11.0 → 0.12.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/package.json +4 -1
- package/plugins/workflow-runner/plugin.js +27 -15
- package/plugins/workflow-runner/plugin.ts +34 -20
- package/plugins/workflow-runner/src/agentCommon.js +13 -12
- package/plugins/workflow-runner/src/agentCommon.ts +22 -13
- package/plugins/workflow-runner/src/index.js +5 -3
- package/plugins/workflow-runner/src/index.ts +31 -13
- package/plugins/workflow-runner/src/multimodal.js +2 -1
- package/plugins/workflow-runner/src/multimodal.ts +2 -1
- package/plugins/workflow-runner/src/stepExecutors/skill.js +5 -6
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +12 -7
- package/plugins/workflow-runner/src/stepExecutors/tool.js +68 -57
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +88 -66
- package/plugins/workflow-runner/src/toolRuntime.js +48 -0
- package/plugins/workflow-runner/src/toolRuntime.ts +64 -0
- package/plugins/workflow-runner/src/types.ts +26 -7
- package/plugins/workflow-runner/test/context-files.test.ts +47 -16
- package/plugins/workflow-runner/test/hostCapability.test.ts +9 -3
- package/plugins/workflow-runner/test/multimodal.test.ts +61 -10
- package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +168 -0
- package/src/cli/print.js +19 -4
- package/src/cli/print.ts +17 -4
- package/src/cli/streamJson.js +19 -4
- package/src/cli/streamJson.ts +17 -4
- package/src/config/configDefaults.js +25 -0
- package/src/config/configDefaults.ts +33 -0
- package/src/config/configFile.js +2 -21
- package/src/config/configFile.ts +11 -24
- package/src/config/configManagement.js +1 -1
- package/src/config/configManagement.ts +2 -2
- package/src/context/compact.js +4 -0
- package/src/context/compact.ts +4 -0
- package/src/context/contextBundle.js +38 -13
- package/src/context/contextBundle.ts +47 -13
- package/src/harness/stallGuard.js +19 -4
- package/src/harness/stallGuard.ts +30 -7
- package/src/loop.js +95 -11
- package/src/loop.ts +125 -16
- package/src/main.js +8 -1
- package/src/main.tsx +7 -1
- package/src/memory/constants.js +10 -0
- package/src/memory/constants.ts +13 -0
- package/src/memory/episodicMemory.js +274 -2
- package/src/memory/episodicMemory.ts +306 -1
- package/src/memory/fileStore.js +24 -4
- package/src/memory/fileStore.ts +22 -2
- package/src/memory/memoryService.js +79 -12
- package/src/memory/memoryService.ts +108 -9
- package/src/memory/repository.js +415 -85
- package/src/memory/repository.ts +437 -86
- package/src/memory/turnJournal.js +95 -0
- package/src/memory/turnJournal.ts +120 -0
- package/src/memory/types.ts +16 -0
- package/src/plugins/pluginApi.ts +30 -6
- package/src/plugins/pluginRunner.js +6 -2
- package/src/plugins/pluginRunner.ts +12 -7
- package/src/prompts/policyRegistry.js +27 -0
- package/src/prompts/policyRegistry.ts +27 -0
- package/src/prompts/promptAssembly.js +39 -7
- package/src/prompts/promptAssembly.ts +145 -59
- package/src/session/runAgentTurn.js +43 -21
- package/src/session/runAgentTurn.ts +68 -26
- package/src/session/runTurn.js +11 -46
- package/src/session/runTurn.ts +12 -46
- package/src/session/runtimeStore.js +149 -0
- package/src/session/runtimeStore.ts +197 -0
- package/src/session/sessionState.js +5 -0
- package/src/session/sessionState.ts +14 -0
- package/src/tools/agent/agent.js +143 -14
- package/src/tools/agent/agent.ts +149 -14
- package/src/tools/agent/agentTaskService.js +60 -0
- package/src/tools/agent/agentTaskService.ts +113 -0
- package/src/tools/agent/agentTypes.js +5 -0
- package/src/tools/agent/agentTypes.ts +5 -0
- package/src/tools/bash/bash.js +31 -11
- package/src/tools/bash/bash.ts +29 -10
- package/src/tools/capabilities.js +5 -0
- package/src/tools/capabilities.ts +11 -1
- package/src/tools/edit/edit.js +7 -4
- package/src/tools/edit/edit.ts +7 -4
- package/src/tools/edit/multi-edit.js +4 -2
- package/src/tools/edit/multi-edit.ts +4 -2
- package/src/tools/glob/glob.js +156 -40
- package/src/tools/glob/glob.ts +185 -46
- package/src/tools/index.js +35 -17
- package/src/tools/index.ts +81 -20
- package/src/tools/lsp/lsp.js +165 -22
- package/src/tools/lsp/lsp.ts +206 -36
- package/src/tools/powershell/powershell.js +116 -26
- package/src/tools/powershell/powershell.ts +155 -30
- package/src/tools/presentresult/presentresult.js +10 -0
- package/src/tools/presentresult/presentresult.ts +10 -0
- package/src/tools/read/read.js +244 -29
- package/src/tools/read/read.ts +391 -59
- package/src/tools/shared/diffSummary.js +44 -0
- package/src/tools/shared/diffSummary.ts +63 -0
- package/src/tools/shared/fileActivity.js +2 -1
- package/src/tools/shared/fileActivity.ts +3 -0
- package/src/tools/shared/permanentDeleteGuard.js +26 -0
- package/src/tools/shared/permanentDeleteGuard.ts +34 -0
- package/src/tools/shared/toolOutputStore.js +97 -0
- package/src/tools/shared/toolOutputStore.ts +110 -0
- package/src/tools/skill/skill.js +86 -0
- package/src/tools/skill/skill.ts +94 -0
- package/src/tools/snip/snip.js +67 -0
- package/src/tools/snip/snip.ts +80 -0
- package/src/tools/tasks/backgroundTaskService.js +79 -28
- package/src/tools/tasks/backgroundTaskService.ts +165 -49
- package/src/tools/tasks/taskManagement.js +163 -0
- package/src/tools/tasks/taskManagement.ts +180 -0
- package/src/tools/tasks/taskOutput.js +64 -14
- package/src/tools/tasks/taskOutput.ts +102 -23
- package/src/tools/tasks/taskStop.js +48 -8
- package/src/tools/tasks/taskStop.ts +69 -9
- package/src/tools/tasks/taskStore.js +46 -0
- package/src/tools/tasks/taskStore.ts +77 -0
- package/src/tools/terminal/terminalCapture.js +167 -0
- package/src/tools/terminal/terminalCapture.ts +179 -0
- package/src/tools/trash/trash.js +233 -0
- package/src/tools/trash/trash.ts +283 -0
- package/src/tools/worktree/sessionWorktree.js +128 -0
- package/src/tools/worktree/sessionWorktree.ts +158 -0
- package/src/tools/write/write.js +6 -2
- package/src/tools/write/write.ts +6 -2
- package/src/types.ts +12 -0
- package/src/ui/hooks/useChat.js +31 -11
- package/src/ui/hooks/useChat.ts +31 -13
- package/src/web/protocol.ts +78 -3
|
@@ -12,8 +12,19 @@ import {
|
|
|
12
12
|
sha256,
|
|
13
13
|
validateMemoryInput,
|
|
14
14
|
} from './codec.js';
|
|
15
|
-
import {
|
|
16
|
-
|
|
15
|
+
import {
|
|
16
|
+
DEFAULT_RETENTION,
|
|
17
|
+
DEFAULT_SETTINGS,
|
|
18
|
+
MEMORY_RETENTION_DAYS_MAX,
|
|
19
|
+
MEMORY_RETENTION_DAYS_MIN,
|
|
20
|
+
MEMORY_RETENTION_MB_MAX,
|
|
21
|
+
MEMORY_RETENTION_MB_MIN,
|
|
22
|
+
PERSONA_MAX_CHARS,
|
|
23
|
+
} from './constants.js';
|
|
24
|
+
import {
|
|
25
|
+
clearConversationEpisodes,
|
|
26
|
+
episodicMemoryService,
|
|
27
|
+
} from './episodicMemory.js';
|
|
17
28
|
import {
|
|
18
29
|
acquireFileLock,
|
|
19
30
|
appendPrivateLine,
|
|
@@ -26,7 +37,9 @@ import {
|
|
|
26
37
|
} from './fileStore.js';
|
|
27
38
|
import { ensureMemoryMigrated } from './migration.js';
|
|
28
39
|
import {
|
|
40
|
+
clearScopeTransactionQuarantine,
|
|
29
41
|
readVersionedMemory,
|
|
42
|
+
refreshTopicView,
|
|
30
43
|
removeVersionedMemory,
|
|
31
44
|
replaceMemoryBatchVersioned,
|
|
32
45
|
replaceVersionedMemory,
|
|
@@ -86,6 +99,7 @@ export { containsForbiddenSecret } from './codec.js';
|
|
|
86
99
|
|
|
87
100
|
function mergeSettings(raw: Partial<MemorySettings>): MemorySettings {
|
|
88
101
|
const review = raw.reviewAfterDays;
|
|
102
|
+
const retention = raw.retention;
|
|
89
103
|
return {
|
|
90
104
|
autoRemember:
|
|
91
105
|
typeof raw.autoRemember === 'boolean'
|
|
@@ -100,16 +114,44 @@ function mergeSettings(raw: Partial<MemorySettings>): MemorySettings {
|
|
|
100
114
|
project: review?.project ?? DEFAULT_SETTINGS.reviewAfterDays!.project,
|
|
101
115
|
decision: review?.decision ?? DEFAULT_SETTINGS.reviewAfterDays!.decision,
|
|
102
116
|
},
|
|
117
|
+
retention: {
|
|
118
|
+
episodeDays: retention?.episodeDays ?? DEFAULT_RETENTION.episodeDays,
|
|
119
|
+
episodeMaxMegabytes:
|
|
120
|
+
retention?.episodeMaxMegabytes ?? DEFAULT_RETENTION.episodeMaxMegabytes,
|
|
121
|
+
},
|
|
103
122
|
};
|
|
104
123
|
}
|
|
105
124
|
|
|
106
125
|
function validateSettingsPatch(patch: Partial<MemorySettings>): void {
|
|
107
|
-
if (patch.reviewAfterDays
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
126
|
+
if (patch.reviewAfterDays !== undefined) {
|
|
127
|
+
for (const [category, days] of Object.entries(patch.reviewAfterDays)) {
|
|
128
|
+
if (!Number.isInteger(days) || days < 7 || days > 3_650) {
|
|
129
|
+
throw new Error(`复核周期 ${category} 必须是 7-3650 之间的整数天`);
|
|
130
|
+
}
|
|
111
131
|
}
|
|
112
132
|
}
|
|
133
|
+
if (patch.retention === undefined) return;
|
|
134
|
+
const { episodeDays, episodeMaxMegabytes } = patch.retention;
|
|
135
|
+
if (
|
|
136
|
+
episodeDays !== undefined
|
|
137
|
+
&& (!Number.isInteger(episodeDays)
|
|
138
|
+
|| episodeDays < MEMORY_RETENTION_DAYS_MIN
|
|
139
|
+
|| episodeDays > MEMORY_RETENTION_DAYS_MAX)
|
|
140
|
+
) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`会话原文保留天数必须是 ${MEMORY_RETENTION_DAYS_MIN}-${MEMORY_RETENTION_DAYS_MAX} 之间的整数`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
if (
|
|
146
|
+
episodeMaxMegabytes !== undefined
|
|
147
|
+
&& (!Number.isInteger(episodeMaxMegabytes)
|
|
148
|
+
|| episodeMaxMegabytes < MEMORY_RETENTION_MB_MIN
|
|
149
|
+
|| episodeMaxMegabytes > MEMORY_RETENTION_MB_MAX)
|
|
150
|
+
) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`会话原文体积上限必须是 ${MEMORY_RETENTION_MB_MIN}-${MEMORY_RETENTION_MB_MAX} 之间的整数 MB`,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
113
155
|
}
|
|
114
156
|
|
|
115
157
|
async function settingsDocument(): Promise<VersionedMemorySettings> {
|
|
@@ -129,6 +171,9 @@ async function settingsDocument(): Promise<VersionedMemorySettings> {
|
|
|
129
171
|
}
|
|
130
172
|
}
|
|
131
173
|
|
|
174
|
+
/** 审计日志单代上限;超限挪成 `.1`,保留最近两代。 */
|
|
175
|
+
const AUDIT_MAX_BYTES = 4 * 1024 * 1024;
|
|
176
|
+
|
|
132
177
|
async function appendAudit(input: {
|
|
133
178
|
action: string;
|
|
134
179
|
record?: MemoryRecord;
|
|
@@ -147,28 +192,69 @@ async function appendAudit(input: {
|
|
|
147
192
|
version: input.version,
|
|
148
193
|
result: input.result,
|
|
149
194
|
}),
|
|
195
|
+
// 审计日志同样是 append-only,必须轮转——它此前是仓库里第二个只增不减的存储。
|
|
196
|
+
{ maxBytes: AUDIT_MAX_BYTES },
|
|
150
197
|
).catch(() => undefined);
|
|
151
198
|
}
|
|
152
199
|
|
|
200
|
+
const EMPTY_SCOPE_SNAPSHOT: MemorySnapshot = Object.freeze({
|
|
201
|
+
records: [],
|
|
202
|
+
versions: {},
|
|
203
|
+
diagnostics: [],
|
|
204
|
+
createdAt: 0,
|
|
205
|
+
}) as MemorySnapshot;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* 合并快照的记忆化。
|
|
209
|
+
*
|
|
210
|
+
* ⚠️ 这不是"顺手加个缓存",是修一个死缓存:`retrieval.ts` 用
|
|
211
|
+
* `WeakMap<MemorySnapshot, Bm25Index>` 按快照对象缓存 BM25 索引,而本函数以前**每次都
|
|
212
|
+
* 返回全新对象字面量** —— 于是 recall / buildContextBundle 这两条热路径上 WeakMap 永远
|
|
213
|
+
* miss,每轮对话都要重建整个索引,`recordSearchIndexCacheHit()` 一次都不会触发(诊断计数
|
|
214
|
+
* 器因此说谎)。单测直接对同一个 snapshot 对象调两次 recallFromSnapshot,机制是对的,
|
|
215
|
+
* 但生产集成从不复用对象,属于"测试通过、生产死代码"。
|
|
216
|
+
*
|
|
217
|
+
* 用底层两个 scope 快照的**对象标识**做键:scanMemoryScope 在缓存命中时返回同一个对象,
|
|
218
|
+
* 有变更时才换新对象——比时间戳更精确,也不怕时钟碰撞。
|
|
219
|
+
*/
|
|
220
|
+
let combinedSnapshotCache: {
|
|
221
|
+
personal: MemorySnapshot;
|
|
222
|
+
workspace: MemorySnapshot;
|
|
223
|
+
workspaceId?: string;
|
|
224
|
+
combined: MemorySnapshot;
|
|
225
|
+
} | null = null;
|
|
226
|
+
|
|
153
227
|
async function combinedSnapshot(workspaceId?: string): Promise<MemorySnapshot> {
|
|
154
228
|
await ensureMemoryMigrated();
|
|
155
229
|
const personal = await scanMemoryScope('personal');
|
|
156
230
|
const workspace = workspaceId
|
|
157
231
|
? await scanMemoryScope('workspace', workspaceId)
|
|
158
|
-
:
|
|
159
|
-
|
|
232
|
+
: EMPTY_SCOPE_SNAPSHOT;
|
|
233
|
+
const cached = combinedSnapshotCache;
|
|
234
|
+
if (
|
|
235
|
+
cached
|
|
236
|
+
&& cached.personal === personal
|
|
237
|
+
&& cached.workspace === workspace
|
|
238
|
+
&& cached.workspaceId === workspaceId
|
|
239
|
+
) {
|
|
240
|
+
return cached.combined;
|
|
241
|
+
}
|
|
242
|
+
const combined: MemorySnapshot = {
|
|
160
243
|
records: [...personal.records, ...workspace.records],
|
|
161
244
|
versions: { ...personal.versions, ...workspace.versions },
|
|
162
245
|
diagnostics: [...personal.diagnostics, ...workspace.diagnostics],
|
|
163
246
|
createdAt: Date.now(),
|
|
164
247
|
};
|
|
248
|
+
combinedSnapshotCache = { personal, workspace, workspaceId, combined };
|
|
249
|
+
return combined;
|
|
165
250
|
}
|
|
166
251
|
|
|
167
252
|
function refreshTopicViewAfterMutation(
|
|
168
253
|
scope: MemoryScope,
|
|
169
254
|
workspaceId?: string,
|
|
170
255
|
): void {
|
|
171
|
-
|
|
256
|
+
combinedSnapshotCache = null;
|
|
257
|
+
void refreshTopicView(scope, workspaceId).catch(() => undefined);
|
|
172
258
|
}
|
|
173
259
|
|
|
174
260
|
function sameTopic(
|
|
@@ -565,6 +651,19 @@ export const memoryService = {
|
|
|
565
651
|
await removeVersionedMemory({ record, version }, version);
|
|
566
652
|
await appendAudit({ action: 'clear', record, version, result: 'ok' });
|
|
567
653
|
}
|
|
654
|
+
// ★ 会话原文日志也要清掉。
|
|
655
|
+
// Desktop「永久清空」以前只删 records,而同一个记忆中心页面还提供
|
|
656
|
+
// ConversationHistorySearch —— 用户"清空记忆"后全部对话原文依然可搜,
|
|
657
|
+
// 与按钮承诺严重不符。工作区范围才有对应的 episodes 文件。
|
|
658
|
+
if (scope === 'workspace' && workspaceId) {
|
|
659
|
+
const removed = await clearConversationEpisodes(workspaceId).catch(() => 0);
|
|
660
|
+
if (removed) {
|
|
661
|
+
await appendAudit({ action: 'clear-episodes', result: 'ok' });
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
// 只有用户明确清空整个 scope 才表示隔离事务的复核现场也不再需要。
|
|
665
|
+
// 普通新增/更新记忆不得清除这类诊断。
|
|
666
|
+
await clearScopeTransactionQuarantine(scope, workspaceId);
|
|
568
667
|
refreshTopicViewAfterMutation(scope, workspaceId);
|
|
569
668
|
});
|
|
570
669
|
},
|