akemon 0.3.4 → 0.3.6

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/dist/server.js CHANGED
@@ -2,6 +2,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
2
2
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
3
  import { exec } from "child_process";
4
4
  import { scanAndKillOrphans } from "./orphan-scan.js";
5
+ import { timingSafeEqual } from "node:crypto";
5
6
  import { createServer } from "http";
6
7
  import { createInterface } from "readline";
7
8
  import { mkdir } from "fs/promises";
@@ -86,8 +87,35 @@ function bearerToken(req) {
86
87
  }
87
88
  function isOwnerRequest(req, options) {
88
89
  const token = bearerToken(req);
89
- const validTokens = [options.secretKey, options.key].filter(Boolean);
90
- return !!token && validTokens.includes(token);
90
+ const validTokens = [options.secretKey, options.key]
91
+ .filter((validToken) => typeof validToken === "string" && validToken.length > 0);
92
+ return !!token && validTokens.some((validToken) => constantTimeTokenEqual(token, validToken));
93
+ }
94
+ function constantTimeTokenEqual(left, right) {
95
+ const leftBuffer = Buffer.from(left);
96
+ const rightBuffer = Buffer.from(right);
97
+ const length = Math.max(leftBuffer.length, rightBuffer.length, 1);
98
+ const leftPadded = Buffer.alloc(length);
99
+ const rightPadded = Buffer.alloc(length);
100
+ leftBuffer.copy(leftPadded);
101
+ rightBuffer.copy(rightPadded);
102
+ return timingSafeEqual(leftPadded, rightPadded) && leftBuffer.length === rightBuffer.length;
103
+ }
104
+ function writeJsonResponse(res, statusCode, body, pretty = false) {
105
+ res.writeHead(statusCode, { "Content-Type": "application/json" })
106
+ .end(JSON.stringify(body, null, pretty ? 2 : 0));
107
+ }
108
+ function requireOwnerRequest(req, res, options) {
109
+ if (isOwnerRequest(req, options))
110
+ return true;
111
+ writeJsonResponse(res, 401, { error: "Owner token required" });
112
+ return false;
113
+ }
114
+ function requireSoftwareAgent(res, softwareAgent) {
115
+ if (softwareAgent)
116
+ return softwareAgent;
117
+ writeJsonResponse(res, 503, { error: "Software agent peripheral not ready" });
118
+ return null;
91
119
  }
92
120
  function readJsonBody(req, maxBytes = 256 * 1024) {
93
121
  return new Promise((resolve, reject) => {
@@ -118,87 +146,67 @@ function readJsonBody(req, maxBytes = 256 * 1024) {
118
146
  req.on("error", reject);
119
147
  });
120
148
  }
121
- export async function handleSoftwareAgentRunHttp(req, res, deps) {
122
- if (!isOwnerRequest(req, deps.options)) {
123
- res.writeHead(401, { "Content-Type": "application/json" })
124
- .end(JSON.stringify({ error: "Owner token required" }));
125
- return;
126
- }
127
- if (!deps.softwareAgent) {
128
- res.writeHead(503, { "Content-Type": "application/json" })
129
- .end(JSON.stringify({ error: "Software agent peripheral not ready" }));
130
- return;
131
- }
149
+ async function readOwnerSoftwareAgentEnvelope(req, res, deps) {
132
150
  let body;
133
151
  try {
134
152
  body = await readJsonBody(req);
135
153
  }
136
154
  catch (err) {
137
- res.writeHead(400, { "Content-Type": "application/json" })
138
- .end(JSON.stringify({ error: err.message || "Invalid request body" }));
139
- return;
155
+ writeJsonResponse(res, 400, { error: err.message || "Invalid request body" });
156
+ return null;
140
157
  }
141
- let envelope;
142
158
  try {
143
- envelope = createOwnerTaskEnvelope(body, deps.workdir);
159
+ const envelope = createOwnerTaskEnvelope(body, deps.workdir);
144
160
  envelope.memorySummary = await buildSoftwareAgentMemorySummary({
145
161
  workdir: deps.workdir,
146
162
  agentName: deps.agentName,
147
163
  envelope,
148
164
  request: body,
149
165
  });
166
+ if (readOptionalBooleanBody(body?.includeWorkMemoryContext, "includeWorkMemoryContext")) {
167
+ const workContext = await buildWorkMemoryContext({
168
+ workdir: deps.workdir,
169
+ agentName: deps.agentName,
170
+ purpose: `software-agent task: ${envelope.goal}`,
171
+ budget: readOptionalPositiveIntBody(body?.workMemoryContextBudget, "workMemoryContextBudget"),
172
+ });
173
+ envelope.workMemoryDir = workContext.workMemoryDir;
174
+ envelope.workMemoryContext = workContext.text;
175
+ }
176
+ return envelope;
150
177
  }
151
178
  catch (err) {
152
- res.writeHead(400, { "Content-Type": "application/json" })
153
- .end(JSON.stringify({ error: err.message || "Invalid software-agent envelope" }));
154
- return;
179
+ writeJsonResponse(res, 400, { error: err.message || "Invalid software-agent envelope" });
180
+ return null;
155
181
  }
182
+ }
183
+ export async function handleSoftwareAgentRunHttp(req, res, deps) {
184
+ if (!requireOwnerRequest(req, res, deps.options))
185
+ return;
186
+ const softwareAgent = requireSoftwareAgent(res, deps.softwareAgent);
187
+ if (!softwareAgent)
188
+ return;
189
+ const envelope = await readOwnerSoftwareAgentEnvelope(req, res, deps);
190
+ if (!envelope)
191
+ return;
156
192
  try {
157
- const result = await deps.softwareAgent.sendTask(envelope);
158
- res.writeHead(result.success ? 200 : 500, { "Content-Type": "application/json" })
159
- .end(JSON.stringify(result, null, 2));
193
+ const result = await softwareAgent.sendTask(envelope);
194
+ writeJsonResponse(res, 200, redactSecrets(result), true);
160
195
  }
161
196
  catch (err) {
162
197
  const busy = String(err.message || "").includes("busy");
163
- res.writeHead(busy ? 409 : 500, { "Content-Type": "application/json" })
164
- .end(JSON.stringify({ error: err.message || String(err) }));
198
+ writeJsonResponse(res, busy ? 409 : 500, { error: err.message || String(err) });
165
199
  }
166
200
  }
167
201
  export async function handleSoftwareAgentRunStreamHttp(req, res, deps) {
168
- if (!isOwnerRequest(req, deps.options)) {
169
- res.writeHead(401, { "Content-Type": "application/json" })
170
- .end(JSON.stringify({ error: "Owner token required" }));
171
- return;
172
- }
173
- if (!deps.softwareAgent) {
174
- res.writeHead(503, { "Content-Type": "application/json" })
175
- .end(JSON.stringify({ error: "Software agent peripheral not ready" }));
202
+ if (!requireOwnerRequest(req, res, deps.options))
176
203
  return;
177
- }
178
- let body;
179
- try {
180
- body = await readJsonBody(req);
181
- }
182
- catch (err) {
183
- res.writeHead(400, { "Content-Type": "application/json" })
184
- .end(JSON.stringify({ error: err.message || "Invalid request body" }));
204
+ const softwareAgent = requireSoftwareAgent(res, deps.softwareAgent);
205
+ if (!softwareAgent)
185
206
  return;
186
- }
187
- let envelope;
188
- try {
189
- envelope = createOwnerTaskEnvelope(body, deps.workdir);
190
- envelope.memorySummary = await buildSoftwareAgentMemorySummary({
191
- workdir: deps.workdir,
192
- agentName: deps.agentName,
193
- envelope,
194
- request: body,
195
- });
196
- }
197
- catch (err) {
198
- res.writeHead(400, { "Content-Type": "application/json" })
199
- .end(JSON.stringify({ error: err.message || "Invalid software-agent envelope" }));
207
+ const envelope = await readOwnerSoftwareAgentEnvelope(req, res, deps);
208
+ if (!envelope)
200
209
  return;
201
- }
202
210
  const abortController = new AbortController();
203
211
  let responseFinished = false;
204
212
  let streamStarted = false;
@@ -218,7 +226,7 @@ export async function handleSoftwareAgentRunStreamHttp(req, res, deps) {
218
226
  res.flushHeaders?.();
219
227
  };
220
228
  try {
221
- await deps.softwareAgent.sendTask(envelope, {
229
+ await softwareAgent.sendTask(envelope, {
222
230
  signal: abortController.signal,
223
231
  observer: {
224
232
  onStart(event) {
@@ -227,6 +235,9 @@ export async function handleSoftwareAgentRunStreamHttp(req, res, deps) {
227
235
  type: "start",
228
236
  taskId: event.taskId,
229
237
  commandLine: event.commandLine,
238
+ contextSessionId: event.contextSessionId,
239
+ contextPacketPath: event.contextPacketPath,
240
+ workMemoryDir: event.workMemoryDir,
230
241
  });
231
242
  },
232
243
  onStream(event) {
@@ -242,7 +253,12 @@ export async function handleSoftwareAgentRunStreamHttp(req, res, deps) {
242
253
  writeSoftwareAgentStreamEvent(res, {
243
254
  type: "end",
244
255
  taskId: event.taskId,
256
+ exitCode: event.exitCode,
257
+ durationMs: event.durationMs,
245
258
  result: event.result,
259
+ contextSessionId: event.contextSessionId,
260
+ contextPacketPath: event.contextPacketPath,
261
+ workMemoryDir: event.workMemoryDir,
246
262
  });
247
263
  },
248
264
  },
@@ -251,8 +267,7 @@ export async function handleSoftwareAgentRunStreamHttp(req, res, deps) {
251
267
  catch (err) {
252
268
  if (!streamStarted) {
253
269
  const busy = String(err.message || "").includes("busy");
254
- res.writeHead(busy ? 409 : 500, { "Content-Type": "application/json" })
255
- .end(JSON.stringify({ error: err.message || String(err) }));
270
+ writeJsonResponse(res, busy ? 409 : 500, { error: err.message || String(err) });
256
271
  responseFinished = true;
257
272
  return;
258
273
  }
@@ -268,58 +283,95 @@ export async function handleSoftwareAgentRunStreamHttp(req, res, deps) {
268
283
  }
269
284
  }
270
285
  export async function handleSoftwareAgentStatusHttp(req, res, deps) {
271
- if (!isOwnerRequest(req, deps.options)) {
272
- res.writeHead(401, { "Content-Type": "application/json" })
273
- .end(JSON.stringify({ error: "Owner token required" }));
286
+ if (!requireOwnerRequest(req, res, deps.options))
274
287
  return;
275
- }
276
- if (!deps.softwareAgent) {
277
- res.writeHead(503, { "Content-Type": "application/json" })
278
- .end(JSON.stringify({ error: "Software agent peripheral not ready" }));
288
+ const softwareAgent = requireSoftwareAgent(res, deps.softwareAgent);
289
+ if (!softwareAgent)
279
290
  return;
280
- }
281
- res.writeHead(200, { "Content-Type": "application/json" })
282
- .end(JSON.stringify(deps.softwareAgent.getState(), null, 2));
291
+ writeJsonResponse(res, 200, softwareAgent.getState(), true);
283
292
  }
284
293
  export async function handleSoftwareAgentTasksHttp(req, res, deps) {
285
- if (!isOwnerRequest(req, deps.options)) {
286
- res.writeHead(401, { "Content-Type": "application/json" })
287
- .end(JSON.stringify({ error: "Owner token required" }));
294
+ if (!requireOwnerRequest(req, res, deps.options))
288
295
  return;
289
- }
290
296
  const url = new URL(req.url || "/", "http://127.0.0.1");
291
297
  const basePath = "/self/software-agent/tasks";
292
298
  const taskLedgerDir = softwareAgentTaskLedgerDir(deps.workdir, deps.agentName);
293
299
  if (url.pathname === basePath) {
294
300
  const limit = readPositiveIntQuery(url.searchParams.get("limit"), 20, 100);
295
- const tasks = listSoftwareAgentTaskRecords(taskLedgerDir, limit);
296
- res.writeHead(200, { "Content-Type": "application/json" })
297
- .end(JSON.stringify({ tasks }, null, 2));
301
+ const tasks = listSoftwareAgentTaskRecords(taskLedgerDir, limit, {
302
+ contextSessionId: url.searchParams.get("session") || undefined,
303
+ });
304
+ writeJsonResponse(res, 200, { tasks }, true);
298
305
  return;
299
306
  }
300
307
  if (url.pathname.startsWith(`${basePath}/`)) {
301
308
  const taskId = decodeURIComponent(url.pathname.slice(basePath.length + 1));
302
309
  if (!taskId || taskId.includes("/")) {
303
- res.writeHead(400, { "Content-Type": "application/json" })
304
- .end(JSON.stringify({ error: "Invalid software-agent task id" }));
310
+ writeJsonResponse(res, 400, { error: "Invalid software-agent task id" });
305
311
  return;
306
312
  }
307
313
  const task = readSoftwareAgentTaskRecord(taskLedgerDir, taskId);
308
314
  if (!task) {
309
- res.writeHead(404, { "Content-Type": "application/json" })
310
- .end(JSON.stringify({ error: "Software-agent task not found" }));
315
+ writeJsonResponse(res, 404, { error: "Software-agent task not found" });
316
+ return;
317
+ }
318
+ let contextSession;
319
+ if (readBooleanQuery(url.searchParams.get("includeContext")) && task.contextSession?.sessionId) {
320
+ try {
321
+ contextSession = readSoftwareAgentContextSession(softwareAgentContextSessionDir(deps.workdir, deps.agentName), task.contextSession.sessionId, { includeContextPacket: true });
322
+ }
323
+ catch {
324
+ contextSession = null;
325
+ }
326
+ }
327
+ writeJsonResponse(res, 200, { task, ...(contextSession ? { contextSession } : {}) }, true);
328
+ return;
329
+ }
330
+ writeJsonResponse(res, 404, { error: "Software-agent task endpoint not found" });
331
+ }
332
+ export async function handleSoftwareAgentContextSessionsHttp(req, res, deps) {
333
+ if (!requireOwnerRequest(req, res, deps.options))
334
+ return;
335
+ const url = new URL(req.url || "/", "http://127.0.0.1");
336
+ const basePath = "/self/software-agent/sessions";
337
+ const contextSessionDir = softwareAgentContextSessionDir(deps.workdir, deps.agentName);
338
+ if (url.pathname === basePath) {
339
+ const limit = readPositiveIntQuery(url.searchParams.get("limit"), 20, 100);
340
+ const sessions = listSoftwareAgentContextSessions(contextSessionDir, limit);
341
+ writeJsonResponse(res, 200, { sessions }, true);
342
+ return;
343
+ }
344
+ if (url.pathname.startsWith(`${basePath}/`)) {
345
+ const sessionId = decodeURIComponent(url.pathname.slice(basePath.length + 1));
346
+ if (!sessionId || sessionId.includes("/")) {
347
+ writeJsonResponse(res, 400, { error: "Invalid software-agent context session id" });
348
+ return;
349
+ }
350
+ let session;
351
+ try {
352
+ session = readSoftwareAgentContextSession(contextSessionDir, sessionId, {
353
+ includeContextPacket: readBooleanQuery(url.searchParams.get("includeContext")),
354
+ });
355
+ }
356
+ catch (err) {
357
+ writeJsonResponse(res, 400, { error: err.message || "Invalid software-agent context session id" });
358
+ return;
359
+ }
360
+ if (!session) {
361
+ writeJsonResponse(res, 404, { error: "Software-agent context session not found" });
311
362
  return;
312
363
  }
313
- res.writeHead(200, { "Content-Type": "application/json" })
314
- .end(JSON.stringify({ task }, null, 2));
364
+ writeJsonResponse(res, 200, { session }, true);
315
365
  return;
316
366
  }
317
- res.writeHead(404, { "Content-Type": "application/json" })
318
- .end(JSON.stringify({ error: "Software-agent task endpoint not found" }));
367
+ writeJsonResponse(res, 404, { error: "Software-agent context session endpoint not found" });
319
368
  }
320
369
  function softwareAgentTaskLedgerDir(workdir, agentName) {
321
370
  return join(workdir, ".akemon", "agents", agentName, "software-agent", "tasks");
322
371
  }
372
+ function softwareAgentContextSessionDir(workdir, agentName) {
373
+ return join(workdir, ".akemon", "agents", agentName, "software-agent", "sessions");
374
+ }
323
375
  function readPositiveIntQuery(value, fallback, max) {
324
376
  if (!value)
325
377
  return fallback;
@@ -328,30 +380,41 @@ function readPositiveIntQuery(value, fallback, max) {
328
380
  return fallback;
329
381
  return Math.min(parsed, max);
330
382
  }
383
+ function readBooleanQuery(value) {
384
+ return value === "1" || value === "true" || value === "yes";
385
+ }
386
+ function readOptionalBooleanBody(value, field) {
387
+ if (value === undefined || value === null)
388
+ return false;
389
+ if (typeof value !== "boolean")
390
+ throw new Error(`Invalid ${field}: expected boolean`);
391
+ return value;
392
+ }
393
+ function readOptionalPositiveIntBody(value, field) {
394
+ if (value === undefined || value === null)
395
+ return undefined;
396
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
397
+ throw new Error(`Invalid ${field}: expected positive integer`);
398
+ }
399
+ return value;
400
+ }
331
401
  function writeSoftwareAgentStreamEvent(res, event) {
332
402
  if (res.destroyed)
333
403
  return;
334
- res.write(`${JSON.stringify(event)}\n`);
404
+ res.write(`${JSON.stringify(redactSecrets(event))}\n`);
335
405
  }
336
406
  export async function handleSoftwareAgentResetHttp(req, res, deps) {
337
- if (!isOwnerRequest(req, deps.options)) {
338
- res.writeHead(401, { "Content-Type": "application/json" })
339
- .end(JSON.stringify({ error: "Owner token required" }));
407
+ if (!requireOwnerRequest(req, res, deps.options))
340
408
  return;
341
- }
342
- if (!deps.softwareAgent) {
343
- res.writeHead(503, { "Content-Type": "application/json" })
344
- .end(JSON.stringify({ error: "Software agent peripheral not ready" }));
409
+ const softwareAgent = requireSoftwareAgent(res, deps.softwareAgent);
410
+ if (!softwareAgent)
345
411
  return;
346
- }
347
412
  try {
348
- await deps.softwareAgent.resetSession();
349
- res.writeHead(200, { "Content-Type": "application/json" })
350
- .end(JSON.stringify({ ok: true, state: deps.softwareAgent.getState() }, null, 2));
413
+ await softwareAgent.resetSession();
414
+ writeJsonResponse(res, 200, { ok: true, state: softwareAgent.getState() }, true);
351
415
  }
352
416
  catch (err) {
353
- res.writeHead(500, { "Content-Type": "application/json" })
354
- .end(JSON.stringify({ error: err.message || String(err) }));
417
+ writeJsonResponse(res, 500, { error: err.message || String(err) });
355
418
  }
356
419
  }
357
420
  import { RelayPeripheral } from "./relay-peripheral.js";
@@ -366,10 +429,12 @@ import { LongTermModule } from "./longterm-module.js";
366
429
  import { ReflectionModule } from "./reflection-module.js";
367
430
  import { ScriptModule } from "./script-module.js";
368
431
  import { FileEventLog, PersistentEventBus } from "./event-bus.js";
369
- import { CodexSoftwareAgentPeripheral, createOwnerTaskEnvelope, listSoftwareAgentTaskRecords, readSoftwareAgentTaskRecord, } from "./software-agent-peripheral.js";
432
+ import { CodexSoftwareAgentPeripheral, createOwnerTaskEnvelope, listSoftwareAgentContextSessions, listSoftwareAgentTaskRecords, readSoftwareAgentContextSession, readSoftwareAgentTaskRecord, } from "./software-agent-peripheral.js";
370
433
  import { buildSoftwareAgentMemorySummary } from "./software-agent-memory.js";
434
+ import { buildWorkMemoryContext, workMemoryDir } from "./work-memory.js";
371
435
  import { SIG, sig } from "./types.js";
372
436
  import { loadConversation, listConversations, buildLLMContext } from "./context.js";
437
+ import { redactSecrets } from "./redaction.js";
373
438
  import { createMcpServer, initMcpProxy, createMcpProxyServer } from "./mcp-server.js";
374
439
  import { autoRoute, runCollaborativeQuery } from "./agent-utils.js";
375
440
  // createMcpServer, initMcpProxy, createMcpProxyServer → see mcp-server.ts
@@ -378,11 +443,11 @@ const LLM_ENGINES = LLM_ENGINES_SET;
378
443
  // Engine execution — delegates to EnginePeripheral (V2 Step 3)
379
444
  // ---------------------------------------------------------------------------
380
445
  /** Unified engine runner — delegates to EnginePeripheral */
381
- function runEngine(engine, model, allowAll, task, workdir, extraAllowedTools, relay, signal, origin, routing, taskId) {
446
+ function runEngine(engine, model, allowAll, task, workdir, extraAllowedTools, relay, signal, origin, routing, taskId, routeRequest) {
382
447
  if (!_engineP) {
383
448
  throw new Error("Engine peripheral not initialized");
384
449
  }
385
- const result = _engineP.runEngine(task, allowAll, extraAllowedTools, signal, origin, routing, taskId);
450
+ const result = _engineP.runEngine(task, allowAll, extraAllowedTools, signal, origin, routing, taskId, routeRequest);
386
451
  // Sync trace back to module-level for reporting
387
452
  result.then(() => { lastEngineTrace = _engineP.lastTrace; }).catch(() => { lastEngineTrace = _engineP.lastTrace; });
388
453
  return result;
@@ -476,6 +541,15 @@ export async function serve(options) {
476
541
  return;
477
542
  }
478
543
  const requestPath = req.url?.split("?")[0] || "";
544
+ if (req.method === "GET"
545
+ && (requestPath === "/self/software-agent/sessions" || requestPath.startsWith("/self/software-agent/sessions/"))) {
546
+ await handleSoftwareAgentContextSessionsHttp(req, res, {
547
+ options,
548
+ workdir,
549
+ agentName: options.agentName,
550
+ });
551
+ return;
552
+ }
479
553
  if (req.method === "GET"
480
554
  && (requestPath === "/self/software-agent/tasks" || requestPath.startsWith("/self/software-agent/tasks/"))) {
481
555
  await handleSoftwareAgentTasksHttp(req, res, {
@@ -681,6 +755,10 @@ export async function serve(options) {
681
755
  model: process.env.AKEMON_CODEX_MODEL,
682
756
  sandbox: "workspace-write",
683
757
  taskLedgerDir: softwareAgentTaskLedgerDir(workdir, options.agentName),
758
+ contextSessionDir: softwareAgentContextSessionDir(workdir, options.agentName),
759
+ workMemoryDir: workMemoryDir(workdir, options.agentName),
760
+ envPolicy: options.softwareAgentEnvPolicy,
761
+ envAllowlist: options.softwareAgentEnvAllowlist,
684
762
  });
685
763
  // Peripheral registry — Core routes by capability
686
764
  const peripherals = [relay, engineP, codexSoftwareAgent];
@@ -718,7 +796,7 @@ export async function serve(options) {
718
796
  const abortController = new AbortController();
719
797
  const timer = setTimeout(() => abortController.abort(), ENGINE_EXEC_TIMEOUT_MS);
720
798
  try {
721
- const response = await runEngine(options.engine || "claude", options.model, options.allowAll, prompt, workdir, req.tools, req.relay, abortController.signal, req.origin, routing, req.taskId);
799
+ const response = await runEngine(options.engine || "claude", options.model, options.allowAll, prompt, workdir, req.tools, req.relay, abortController.signal, req.origin, routing, req.taskId, req.engineHints);
722
800
  emitTokenUsage(prompt.length, response.length);
723
801
  return { success: true, response };
724
802
  }
@@ -1,6 +1,14 @@
1
1
  import { buildLLMContext, loadConversation } from "./context.js";
2
2
  import { buildRoleContext, loadRoles, resolveRoles } from "./role-module.js";
3
3
  const DEFAULT_CONTEXT_BUDGET = 6000;
4
+ const OWNER_MEMORY_EXCLUDE_TERMS = [
5
+ "owner",
6
+ "private",
7
+ "personal",
8
+ "note",
9
+ "diary",
10
+ "bio",
11
+ ];
4
12
  export async function buildSoftwareAgentMemorySummary(opts) {
5
13
  const budget = opts.contextBudget ?? DEFAULT_CONTEXT_BUDGET;
6
14
  const parts = [
@@ -103,17 +111,7 @@ async function resolveRoleMemoryPolicy(workdir, agentName, roleTrigger) {
103
111
  function roleExcludesOwnerMemory(policy) {
104
112
  return policy.exclude.some((item) => {
105
113
  const normalized = item.toLowerCase();
106
- return normalized.includes("owner")
107
- || normalized.includes("private")
108
- || normalized.includes("personal")
109
- || normalized.includes("note")
110
- || normalized.includes("diary")
111
- || normalized.includes("bio")
112
- || normalized.includes("全部记忆")
113
- || normalized.includes("个人")
114
- || normalized.includes("笔记")
115
- || normalized.includes("日记")
116
- || normalized.includes("状态");
114
+ return OWNER_MEMORY_EXCLUDE_TERMS.some((term) => normalized.includes(term));
117
115
  });
118
116
  }
119
117
  function normalizeRequest(value) {