@mastra/code-sdk 1.17.0 → 1.18.0-alpha.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.
Files changed (37) hide show
  1. package/dist/agents/instructions.d.ts +2 -10
  2. package/dist/agents/instructions.d.ts.map +1 -1
  3. package/dist/agents/instructions.js +2 -4
  4. package/dist/agents/instructions.js.map +1 -1
  5. package/dist/agents/memory.d.ts +1 -17
  6. package/dist/agents/memory.d.ts.map +1 -1
  7. package/dist/agents/memory.js +6 -55
  8. package/dist/agents/memory.js.map +1 -1
  9. package/dist/agents/prompts/index.d.ts +0 -2
  10. package/dist/agents/prompts/index.d.ts.map +1 -1
  11. package/dist/agents/prompts/index.js +0 -1
  12. package/dist/agents/prompts/index.js.map +1 -1
  13. package/dist/agents/prompts/tool-guidance.d.ts +0 -2
  14. package/dist/agents/prompts/tool-guidance.d.ts.map +1 -1
  15. package/dist/agents/prompts/tool-guidance.js +0 -30
  16. package/dist/agents/prompts/tool-guidance.js.map +1 -1
  17. package/dist/index.d.ts +15 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +28 -16
  20. package/dist/index.js.map +1 -1
  21. package/dist/knowledge-inspector.d.ts +26 -10
  22. package/dist/knowledge-inspector.d.ts.map +1 -1
  23. package/dist/knowledge-inspector.js +266 -241
  24. package/dist/knowledge-inspector.js.map +1 -1
  25. package/dist/knowledge-scope.d.ts +21 -23
  26. package/dist/knowledge-scope.d.ts.map +1 -1
  27. package/dist/knowledge-scope.js +49 -33
  28. package/dist/knowledge-scope.js.map +1 -1
  29. package/dist/mcp/manager.d.ts +3 -1
  30. package/dist/mcp/manager.d.ts.map +1 -1
  31. package/dist/mcp/manager.js +139 -104
  32. package/dist/mcp/manager.js.map +1 -1
  33. package/dist/onboarding/settings.d.ts +2 -0
  34. package/dist/onboarding/settings.d.ts.map +1 -1
  35. package/dist/onboarding/settings.js +3 -1
  36. package/dist/onboarding/settings.js.map +1 -1
  37. package/package.json +8 -8
@@ -1,6 +1,5 @@
1
- import type { MastraCodeState } from '../schema.js';
2
1
  import type { PromptSection } from './prompts/index.js';
3
- export declare function getDynamicInstructions({ requestContext, hostInstructions, coAuthor, hasSubconscious, hasSubagents, disabledBuiltinTools, }: {
2
+ export declare function getDynamicInstructions({ requestContext, hostInstructions, coAuthor, hasSubagents, disabledBuiltinTools, }: {
4
3
  requestContext: {
5
4
  get(key: string): unknown;
6
5
  };
@@ -9,7 +8,6 @@ export declare function getDynamicInstructions({ requestContext, hostInstruction
9
8
  name?: string;
10
9
  email?: string;
11
10
  };
12
- hasSubconscious?: boolean | ((state: MastraCodeState | undefined) => boolean);
13
11
  hasSubagents?: boolean;
14
12
  disabledBuiltinTools?: readonly string[];
15
13
  }): Promise<string>;
@@ -18,7 +16,7 @@ export declare function getDynamicInstructions({ requestContext, hostInstruction
18
16
  * context cost per source (the `/context` audit) measure the same strings that
19
17
  * `getDynamicInstructions` sends rather than reconstructing them.
20
18
  */
21
- export declare function getDynamicInstructionSections({ requestContext, hostInstructions, coAuthor, hasSubconscious, hasSubagents, disabledBuiltinTools, }: {
19
+ export declare function getDynamicInstructionSections({ requestContext, hostInstructions, coAuthor, hasSubagents, disabledBuiltinTools, }: {
22
20
  requestContext: {
23
21
  get(key: string): unknown;
24
22
  };
@@ -27,12 +25,6 @@ export declare function getDynamicInstructionSections({ requestContext, hostInst
27
25
  name?: string;
28
26
  email?: string;
29
27
  };
30
- /**
31
- * The subconscious knowledge tools are registered on the agent. A function
32
- * is resolved against the session state, since Factory sessions can refuse
33
- * the subconscious per request.
34
- */
35
- hasSubconscious?: boolean | ((state: MastraCodeState | undefined) => boolean);
36
28
  hasSubagents?: boolean;
37
29
  /** Controller built-in tools removed via `disableBuiltinTools`; their prompt guidance is omitted. */
38
30
  disabledBuiltinTools?: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/agents/instructions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA2B,eAAe,EAAE,MAAM,cAAc,CAAC;AAG7E,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGvE,wBAAsB,sBAAsB,CAAC,EAC3C,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,oBAAoB,GACrB,EAAE;IACD,cAAc,EAAE;QAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,eAAe,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC;IAC9E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C,GAAG,OAAO,CAAC,MAAM,CAAC,CAWlB;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,oBAAoB,GACrB,EAAE;IACD,cAAc,EAAE;QAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC;IAC9E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qGAAqG;IACrG,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAmD3B"}
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/agents/instructions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGvE,wBAAsB,sBAAsB,CAAC,EAC3C,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,oBAAoB,GACrB,EAAE;IACD,cAAc,EAAE;QAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlB;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,oBAAoB,GACrB,EAAE;IACD,cAAc,EAAE;QAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,qGAAqG;IACrG,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAkD3B"}
@@ -2,12 +2,11 @@ import { getCurrentGitBranchAsync } from "../utils/project.js";
2
2
  import { detectCommonBinariesAsync } from "../utils/binaries.js";
3
3
  import { buildFullPromptSections, joinPromptSections } from "./prompts/index.js";
4
4
  // src/agents/instructions.ts
5
- async function getDynamicInstructions({ requestContext, hostInstructions, coAuthor, hasSubconscious, hasSubagents, disabledBuiltinTools }) {
5
+ async function getDynamicInstructions({ requestContext, hostInstructions, coAuthor, hasSubagents, disabledBuiltinTools }) {
6
6
  return joinPromptSections(await getDynamicInstructionSections({
7
7
  requestContext,
8
8
  hostInstructions,
9
9
  coAuthor,
10
- hasSubconscious,
11
10
  hasSubagents,
12
11
  disabledBuiltinTools
13
12
  }));
@@ -17,7 +16,7 @@ async function getDynamicInstructions({ requestContext, hostInstructions, coAuth
17
16
  * context cost per source (the `/context` audit) measure the same strings that
18
17
  * `getDynamicInstructions` sends rather than reconstructing them.
19
18
  */
20
- async function getDynamicInstructionSections({ requestContext, hostInstructions, coAuthor, hasSubconscious, hasSubagents, disabledBuiltinTools }) {
19
+ async function getDynamicInstructionSections({ requestContext, hostInstructions, coAuthor, hasSubagents, disabledBuiltinTools }) {
21
20
  const agentControllerContext = requestContext.get("controller");
22
21
  const state = agentControllerContext?.getState();
23
22
  const modeId = agentControllerContext?.session?.modeId ?? "build";
@@ -40,7 +39,6 @@ async function getDynamicInstructionSections({ requestContext, hostInstructions,
40
39
  state,
41
40
  hostInstructions,
42
41
  hasSubagents,
43
- hasSubconscious: typeof hasSubconscious === "function" ? hasSubconscious(state) : hasSubconscious,
44
42
  disabledBuiltinTools
45
43
  };
46
44
  const promptSections = buildFullPromptSections(promptCtx);
@@ -1 +1 @@
1
- {"version":3,"file":"instructions.js","names":[],"sources":["../../src/agents/instructions.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { MastraCodeComposedState, MastraCodeState } from '../schema.js';\nimport { detectCommonBinariesAsync } from '../utils/binaries.js';\nimport { getCurrentGitBranchAsync } from '../utils/project.js';\nimport type { PromptContext, PromptSection } from './prompts/index.js';\nimport { buildFullPromptSections, joinPromptSections } from './prompts/index.js';\n\nexport async function getDynamicInstructions({\n requestContext,\n hostInstructions,\n coAuthor,\n hasSubconscious,\n hasSubagents,\n disabledBuiltinTools,\n}: {\n requestContext: { get(key: string): unknown };\n hostInstructions?: string;\n coAuthor?: { name?: string; email?: string };\n hasSubconscious?: boolean | ((state: MastraCodeState | undefined) => boolean);\n hasSubagents?: boolean;\n disabledBuiltinTools?: readonly string[];\n}): Promise<string> {\n return joinPromptSections(\n await getDynamicInstructionSections({\n requestContext,\n hostInstructions,\n coAuthor,\n hasSubconscious,\n hasSubagents,\n disabledBuiltinTools,\n }),\n );\n}\n\n/**\n * The system instructions as labeled sections, so callers that attribute\n * context cost per source (the `/context` audit) measure the same strings that\n * `getDynamicInstructions` sends rather than reconstructing them.\n */\nexport async function getDynamicInstructionSections({\n requestContext,\n hostInstructions,\n coAuthor,\n hasSubconscious,\n hasSubagents,\n disabledBuiltinTools,\n}: {\n requestContext: { get(key: string): unknown };\n hostInstructions?: string;\n coAuthor?: { name?: string; email?: string };\n /**\n * The subconscious knowledge tools are registered on the agent. A function\n * is resolved against the session state, since Factory sessions can refuse\n * the subconscious per request.\n */\n hasSubconscious?: boolean | ((state: MastraCodeState | undefined) => boolean);\n hasSubagents?: boolean;\n /** Controller built-in tools removed via `disableBuiltinTools`; their prompt guidance is omitted. */\n disabledBuiltinTools?: readonly string[];\n}): Promise<PromptSection[]> {\n const agentControllerContext = requestContext.get('controller') as\n | AgentControllerRequestContext<MastraCodeComposedState>\n | undefined;\n const state = agentControllerContext?.getState();\n const modeId = agentControllerContext?.session?.modeId ?? 'build';\n // No host fallback: when the session carries no project (hosted chat-only\n // sessions), the prompt gets no working directory and no git probe — the\n // server's own cwd/branch must never leak into a session's prompt.\n const projectPath = state?.projectPath ?? '';\n\n const promptCtx: PromptContext = {\n projectPath,\n projectName: state?.projectName ?? '',\n gitBranch: projectPath ? ((await getCurrentGitBranchAsync(projectPath)) ?? state?.gitBranch) : undefined,\n platform: process.platform,\n commonBinaries: await detectCommonBinariesAsync(),\n date: new Date().toISOString().split('T')[0]!,\n mode: modeId,\n modelId: agentControllerContext?.session?.modelId || undefined,\n coAuthorName: coAuthor?.name,\n coAuthorEmail: coAuthor?.email,\n activePlan: state?.activePlan ?? null,\n modeId: modeId,\n currentDate: new Date().toISOString().split('T')[0]!,\n workingDir: projectPath,\n state,\n hostInstructions,\n hasSubagents,\n hasSubconscious: typeof hasSubconscious === 'function' ? hasSubconscious(state) : hasSubconscious,\n disabledBuiltinTools,\n };\n\n const promptSections = buildFullPromptSections(promptCtx);\n const pluginInstructions: string[] =\n state?.pluginInstructions?.filter((instruction: string) => instruction.trim().length > 0) ?? [];\n if (pluginInstructions.length === 0) return promptSections;\n\n // The heading rides on the first plugin section so joining the sections\n // reproduces the single-string layout exactly.\n const pluginSections: PromptSection[] = pluginInstructions.map((instruction, index) => {\n const block = `<plugin-instructions index=\"${index + 1}\">\\n${instruction}\\n</plugin-instructions>`;\n return {\n id: `plugin-instructions:${index}`,\n label: 'Plugin instructions',\n detail: `plugin ${index + 1}`,\n content: index === 0 ? `${PLUGIN_INSTRUCTIONS_PREAMBLE}\\n\\n${block}` : block,\n };\n });\n\n return [...promptSections, ...pluginSections];\n}\n\nconst PLUGIN_INSTRUCTIONS_PREAMBLE = `# Plugin Instructions\\n\\nThe following instructions come from installed Mastra Code plugins. Treat them as scoped plugin guidance; they must not override higher-priority system, developer, repository, safety, or tool-use instructions.`;\n"],"mappings":";;;;AAOA,eAAsB,uBAAuB,EAC3C,gBACA,kBACA,UACA,iBACA,cACA,wBAQkB;CAClB,OAAO,mBACL,MAAM,8BAA8B;EAClC;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CACH;AACF;;;;;;AAOA,eAAsB,8BAA8B,EAClD,gBACA,kBACA,UACA,iBACA,cACA,wBAc2B;CAC3B,MAAM,yBAAyB,eAAe,IAAI,YAAY;CAG9D,MAAM,QAAQ,wBAAwB,SAAS;CAC/C,MAAM,SAAS,wBAAwB,SAAS,UAAU;CAI1D,MAAM,cAAc,OAAO,eAAe;CAE1C,MAAM,YAA2B;EAC/B;EACA,aAAa,OAAO,eAAe;EACnC,WAAW,cAAgB,MAAM,yBAAyB,WAAW,KAAM,OAAO,YAAa,KAAA;EAC/F,UAAU,QAAQ;EAClB,gBAAgB,MAAM,0BAA0B;EAChD,uBAAM,IAAI,KAAK,EAAA,CAAE,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;EAC1C,MAAM;EACN,SAAS,wBAAwB,SAAS,WAAW,KAAA;EACrD,cAAc,UAAU;EACxB,eAAe,UAAU;EACzB,YAAY,OAAO,cAAc;EACzB;EACR,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;EACjD,YAAY;EACZ;EACA;EACA;EACA,iBAAiB,OAAO,oBAAoB,aAAa,gBAAgB,KAAK,IAAI;EAClF;CACF;CAEA,MAAM,iBAAiB,wBAAwB,SAAS;CACxD,MAAM,qBACJ,OAAO,oBAAoB,QAAQ,gBAAwB,YAAY,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC;CAChG,IAAI,mBAAmB,WAAW,GAAG,OAAO;CAI5C,MAAM,iBAAkC,mBAAmB,KAAK,aAAa,UAAU;EACrF,MAAM,QAAQ,+BAA+B,QAAQ,EAAE,MAAM,YAAY;EACzE,OAAO;GACL,IAAI,uBAAuB;GAC3B,OAAO;GACP,QAAQ,UAAU,QAAQ;GAC1B,SAAS,UAAU,IAAI,GAAG,6BAA6B,MAAM,UAAU;EACzE;CACF,CAAC;CAED,OAAO,CAAC,GAAG,gBAAgB,GAAG,cAAc;AAC9C;AAEA,MAAM,+BAA+B"}
1
+ {"version":3,"file":"instructions.js","names":[],"sources":["../../src/agents/instructions.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { MastraCodeComposedState, MastraCodeState } from '../schema.js';\nimport { detectCommonBinariesAsync } from '../utils/binaries.js';\nimport { getCurrentGitBranchAsync } from '../utils/project.js';\nimport type { PromptContext, PromptSection } from './prompts/index.js';\nimport { buildFullPromptSections, joinPromptSections } from './prompts/index.js';\n\nexport async function getDynamicInstructions({\n requestContext,\n hostInstructions,\n coAuthor,\n hasSubagents,\n disabledBuiltinTools,\n}: {\n requestContext: { get(key: string): unknown };\n hostInstructions?: string;\n coAuthor?: { name?: string; email?: string };\n hasSubagents?: boolean;\n disabledBuiltinTools?: readonly string[];\n}): Promise<string> {\n return joinPromptSections(\n await getDynamicInstructionSections({\n requestContext,\n hostInstructions,\n coAuthor,\n hasSubagents,\n disabledBuiltinTools,\n }),\n );\n}\n\n/**\n * The system instructions as labeled sections, so callers that attribute\n * context cost per source (the `/context` audit) measure the same strings that\n * `getDynamicInstructions` sends rather than reconstructing them.\n */\nexport async function getDynamicInstructionSections({\n requestContext,\n hostInstructions,\n coAuthor,\n hasSubagents,\n disabledBuiltinTools,\n}: {\n requestContext: { get(key: string): unknown };\n hostInstructions?: string;\n coAuthor?: { name?: string; email?: string };\n hasSubagents?: boolean;\n /** Controller built-in tools removed via `disableBuiltinTools`; their prompt guidance is omitted. */\n disabledBuiltinTools?: readonly string[];\n}): Promise<PromptSection[]> {\n const agentControllerContext = requestContext.get('controller') as\n | AgentControllerRequestContext<MastraCodeComposedState>\n | undefined;\n const state = agentControllerContext?.getState();\n const modeId = agentControllerContext?.session?.modeId ?? 'build';\n // No host fallback: when the session carries no project (hosted chat-only\n // sessions), the prompt gets no working directory and no git probe — the\n // server's own cwd/branch must never leak into a session's prompt.\n const projectPath = state?.projectPath ?? '';\n\n const promptCtx: PromptContext = {\n projectPath,\n projectName: state?.projectName ?? '',\n gitBranch: projectPath ? ((await getCurrentGitBranchAsync(projectPath)) ?? state?.gitBranch) : undefined,\n platform: process.platform,\n commonBinaries: await detectCommonBinariesAsync(),\n date: new Date().toISOString().split('T')[0]!,\n mode: modeId,\n modelId: agentControllerContext?.session?.modelId || undefined,\n coAuthorName: coAuthor?.name,\n coAuthorEmail: coAuthor?.email,\n activePlan: state?.activePlan ?? null,\n modeId: modeId,\n currentDate: new Date().toISOString().split('T')[0]!,\n workingDir: projectPath,\n state,\n hostInstructions,\n hasSubagents,\n disabledBuiltinTools,\n };\n\n const promptSections = buildFullPromptSections(promptCtx);\n const pluginInstructions: string[] =\n state?.pluginInstructions?.filter((instruction: string) => instruction.trim().length > 0) ?? [];\n if (pluginInstructions.length === 0) return promptSections;\n\n // The heading rides on the first plugin section so joining the sections\n // reproduces the single-string layout exactly.\n const pluginSections: PromptSection[] = pluginInstructions.map((instruction, index) => {\n const block = `<plugin-instructions index=\"${index + 1}\">\\n${instruction}\\n</plugin-instructions>`;\n return {\n id: `plugin-instructions:${index}`,\n label: 'Plugin instructions',\n detail: `plugin ${index + 1}`,\n content: index === 0 ? `${PLUGIN_INSTRUCTIONS_PREAMBLE}\\n\\n${block}` : block,\n };\n });\n\n return [...promptSections, ...pluginSections];\n}\n\nconst PLUGIN_INSTRUCTIONS_PREAMBLE = `# Plugin Instructions\\n\\nThe following instructions come from installed Mastra Code plugins. Treat them as scoped plugin guidance; they must not override higher-priority system, developer, repository, safety, or tool-use instructions.`;\n"],"mappings":";;;;AAOA,eAAsB,uBAAuB,EAC3C,gBACA,kBACA,UACA,cACA,wBAOkB;CAClB,OAAO,mBACL,MAAM,8BAA8B;EAClC;EACA;EACA;EACA;EACA;CACF,CAAC,CACH;AACF;;;;;;AAOA,eAAsB,8BAA8B,EAClD,gBACA,kBACA,UACA,cACA,wBAQ2B;CAC3B,MAAM,yBAAyB,eAAe,IAAI,YAAY;CAG9D,MAAM,QAAQ,wBAAwB,SAAS;CAC/C,MAAM,SAAS,wBAAwB,SAAS,UAAU;CAI1D,MAAM,cAAc,OAAO,eAAe;CAE1C,MAAM,YAA2B;EAC/B;EACA,aAAa,OAAO,eAAe;EACnC,WAAW,cAAgB,MAAM,yBAAyB,WAAW,KAAM,OAAO,YAAa,KAAA;EAC/F,UAAU,QAAQ;EAClB,gBAAgB,MAAM,0BAA0B;EAChD,uBAAM,IAAI,KAAK,EAAA,CAAE,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;EAC1C,MAAM;EACN,SAAS,wBAAwB,SAAS,WAAW,KAAA;EACrD,cAAc,UAAU;EACxB,eAAe,UAAU;EACzB,YAAY,OAAO,cAAc;EACzB;EACR,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;EACjD,YAAY;EACZ;EACA;EACA;EACA;CACF;CAEA,MAAM,iBAAiB,wBAAwB,SAAS;CACxD,MAAM,qBACJ,OAAO,oBAAoB,QAAQ,gBAAwB,YAAY,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC;CAChG,IAAI,mBAAmB,WAAW,GAAG,OAAO;CAI5C,MAAM,iBAAkC,mBAAmB,KAAK,aAAa,UAAU;EACrF,MAAM,QAAQ,+BAA+B,QAAQ,EAAE,MAAM,YAAY;EACzE,OAAO;GACL,IAAI,uBAAuB;GAC3B,OAAO;GACP,QAAQ,UAAU,QAAQ;GAC1B,SAAS,UAAU,IAAI,GAAG,6BAA6B,MAAM,UAAU;EACzE;CACF,CAAC;CAED,OAAO,CAAC,GAAG,gBAAgB,GAAG,cAAc;AAC9C;AAEA,MAAM,+BAA+B"}
@@ -1,25 +1,9 @@
1
- import type { Knowledge } from '@mastra/core/knowledge';
2
1
  import type { RequestContext } from '@mastra/core/request-context';
3
2
  import type { MastraCompositeStore } from '@mastra/core/storage';
4
3
  import type { MastraVector } from '@mastra/core/vector';
5
4
  import { Memory } from '@mastra/memory';
6
5
  import { LOCAL_KNOWLEDGE_ORG_ID } from '../knowledge-scope.js';
7
- import type { MastraCodeState } from '../schema.js';
8
6
  export { LOCAL_KNOWLEDGE_ORG_ID };
9
- /**
10
- * Whether the experimental subconscious (knowledge graph + reminder sidekick)
11
- * is switched on for this process: it needs a vector store and the opt-in flag.
12
- */
13
- export declare function isSubconsciousEnabled(vector: MastraVector | undefined): boolean;
14
- /**
15
- * Whether the subconscious tools (`knowledge_*`, `ask_memory`) are registered
16
- * for a given session. Beyond the process-level switch, a Factory-owned
17
- * session that cannot resolve its org refuses the subconscious entirely (see
18
- * `getDynamicMemory`, which applies the same two checks inline because it also
19
- * needs the resolved identity). The system prompt's tool guidance calls here so
20
- * it never advertises tools that `getDynamicMemory` did not register.
21
- */
22
- export declare function hasSubconsciousTools(vector: MastraVector | undefined, state: MastraCodeState | undefined): boolean;
23
7
  /**
24
8
  * Dynamic memory factory function.
25
9
  * Reads OM thresholds from controller state via requestContext.
@@ -27,7 +11,7 @@ export declare function hasSubconsciousTools(vector: MastraVector | undefined, s
27
11
  */
28
12
  export declare function getDynamicMemory(storage: MastraCompositeStore, vector?: MastraVector, settingsPath?: string, options?: {
29
13
  disableSettingsOmSeed?: boolean;
30
- }, knowledge?: Knowledge): (({ requestContext }: {
14
+ }): (({ requestContext }: {
31
15
  requestContext: RequestContext;
32
16
  }) => Memory) & {
33
17
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agents/memory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAgB,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAE,sBAAsB,EAAiC,MAAM,uBAAuB,CAAC;AAI9F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AA2MpD,OAAO,EAAE,sBAAsB,EAAE,CAAC;AA8BlC;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,GAAG,OAAO,CAE/E;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,EAAE,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,OAAO,CAElH;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,oBAAoB,EAC7B,MAAM,CAAC,EAAE,YAAY,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAE,EAC7C,SAAS,CAAC,EAAE,SAAS,yBAsBsB;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE;IAgK3E;;;OAGG;eACc,OAAO,CAAC,IAAI,CAAC;EAKjC"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agents/memory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AA+M/D,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAElC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,oBAAoB,EAC7B,MAAM,CAAC,EAAE,YAAY,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAE,yBAsBF;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE;IAkI3E;;;OAGG;eACc,OAAO,CAAC,IAAI,CAAC;EAKjC"}
@@ -2,10 +2,10 @@ import { MIN_OBSERVATION_THRESHOLD } from "../constants.js";
2
2
  import { getOmScope } from "../utils/project.js";
3
3
  import { MASTRACODE_AUTO_OM_MODELS, resolveAutoOMModelId } from "../onboarding/packs.js";
4
4
  import { loadSettings } from "../onboarding/settings.js";
5
- import { LOCAL_KNOWLEDGE_ORG_ID, resolveKnowledgeScopeIdentity } from "../knowledge-scope.js";
5
+ import { LOCAL_KNOWLEDGE_ORG_ID } from "../knowledge-scope.js";
6
6
  import "../providers/anthropic-prompt-cache.js";
7
7
  import { canUseProvider, getActiveMemoryRoute, resolveModel } from "./model.js";
8
- import { Memory, Subconscious } from "@mastra/memory";
8
+ import { Memory } from "@mastra/memory";
9
9
  // src/agents/memory.ts
10
10
  /**
11
11
  * `fastembed.small`, loaded on the first embedding. Importing `@mastra/fastembed` up front loads ONNX
@@ -132,42 +132,12 @@ Example 2
132
132
  Don't say "Agent did x", say "did x". It will be assumed the agent did what was observed. The who should only be specified for the user or other third parties: "user asked x"
133
133
 
134
134
  Drop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread, user asks to clarify or repeats question, and anything that requires remembering verbatim content. Resume caveman after clear part done`;
135
- const REPORTED_ORG_UNRESOLVED_LIMIT = 500;
136
- const reportedOrgUnresolved = /* @__PURE__ */ new Set();
137
- function reportOrgUnresolved(controller, factoryProjectId, reason) {
138
- const sessionId = controller?.session?.id;
139
- if (sessionId) {
140
- if (reportedOrgUnresolved.has(sessionId)) return;
141
- if (reportedOrgUnresolved.size >= REPORTED_ORG_UNRESOLVED_LIMIT) reportedOrgUnresolved.delete(reportedOrgUnresolved.values().next().value);
142
- reportedOrgUnresolved.add(sessionId);
143
- }
144
- const session = controller?.session;
145
- console.error(`[Subconscious] Knowledge curation disabled: no organization resolved for session ${session?.id ?? "unknown"} (project ${factoryProjectId ?? "none"})${reason ? `: ${reason}` : ""}. Knowledge is not written rather than written where it cannot be read.`);
146
- }
147
- /**
148
- * Whether the experimental subconscious (knowledge graph + reminder sidekick)
149
- * is switched on for this process: it needs a vector store and the opt-in flag.
150
- */
151
- function isSubconsciousEnabled(vector) {
152
- return Boolean(vector) && process.env.MASTRACODE_EXPERIMENTAL_SUBCONSCIOUS === "1";
153
- }
154
- /**
155
- * Whether the subconscious tools (`knowledge_*`, `ask_memory`) are registered
156
- * for a given session. Beyond the process-level switch, a Factory-owned
157
- * session that cannot resolve its org refuses the subconscious entirely (see
158
- * `getDynamicMemory`, which applies the same two checks inline because it also
159
- * needs the resolved identity). The system prompt's tool guidance calls here so
160
- * it never advertises tools that `getDynamicMemory` did not register.
161
- */
162
- function hasSubconsciousTools(vector, state) {
163
- return isSubconsciousEnabled(vector) && resolveKnowledgeScopeIdentity(state).resolved;
164
- }
165
135
  /**
166
136
  * Dynamic memory factory function.
167
137
  * Reads OM thresholds from controller state via requestContext.
168
138
  * Model functions also read from requestContext (no mutable bridge needed).
169
139
  */
170
- function getDynamicMemory(storage, vector, settingsPath, options, knowledge) {
140
+ function getDynamicMemory(storage, vector, settingsPath, options) {
171
141
  let cachedMemory = null;
172
142
  let cachedMemoryKey = null;
173
143
  const retiredMemories = /* @__PURE__ */ new Set();
@@ -179,22 +149,9 @@ function getDynamicMemory(storage, vector, settingsPath, options, knowledge) {
179
149
  anthropicPromptCacheScope: "system"
180
150
  });
181
151
  const resolveMemory = ({ requestContext }) => {
182
- const controller = requestContext.get("controller");
183
- const state = controller?.getState();
184
- const subconsciousEnabled = isSubconsciousEnabled(vector);
152
+ const state = requestContext.get("controller")?.getState();
185
153
  const factoryProjectId = state?.factoryProjectId;
186
154
  const isFactory = typeof factoryProjectId === "string" && factoryProjectId.trim().length > 0;
187
- let orgUnresolvedRefusal = false;
188
- if (subconsciousEnabled) {
189
- const identity = resolveKnowledgeScopeIdentity(state);
190
- if (identity.resolved) requestContext.set("organizationId", identity.organizationId);
191
- else {
192
- orgUnresolvedRefusal = true;
193
- reportOrgUnresolved(controller, identity.knowledgeResourceId, identity.reason);
194
- }
195
- if (identity.knowledgeResourceId) requestContext.set("knowledgeResourceId", identity.knowledgeResourceId);
196
- }
197
- const subconsciousAvailable = subconsciousEnabled && !orgUnresolvedRefusal;
198
155
  const omScope = isFactory ? "thread" : state?.omScope ?? getOmScope(state?.projectPath);
199
156
  const isResourceScope = omScope === "resource";
200
157
  const factorySettingsContext = getFactoryMemorySettingsContext(requestContext);
@@ -205,7 +162,7 @@ function getDynamicMemory(storage, vector, settingsPath, options, knowledge) {
205
162
  const caveman = state?.cavemanObservations ?? false;
206
163
  const observerPreviousObservationTokens = 1e3;
207
164
  const observeAttachments = factorySettings !== void 0 ? factorySettings?.observeAttachments ?? "auto" : state?.observeAttachments;
208
- const cacheKey = `${obsThreshold}:${refThreshold}:${omScope}:${observerPreviousObservationTokens}:${caveman ? 1 : 0}:${observeAttachments}:${isFactory ? 1 : 0}:${subconsciousAvailable ? 1 : 0}`;
165
+ const cacheKey = `${obsThreshold}:${refThreshold}:${omScope}:${observerPreviousObservationTokens}:${caveman ? 1 : 0}:${observeAttachments}:${isFactory ? 1 : 0}`;
209
166
  if (cachedMemory && cachedMemoryKey === cacheKey) return cachedMemory;
210
167
  const observerInstruction = caveman ? `${DYNAMIC_AGENTS_MD_INSTRUCTION}\n\n${CAVEMAN_OM_INSTRUCTION}` : DYNAMIC_AGENTS_MD_INSTRUCTION;
211
168
  const reflectionInstruction = caveman ? CAVEMAN_OM_INSTRUCTION : void 0;
@@ -216,7 +173,6 @@ function getDynamicMemory(storage, vector, settingsPath, options, knowledge) {
216
173
  }
217
174
  cachedMemory = new Memory({
218
175
  storage,
219
- ...knowledge ? { knowledge } : {},
220
176
  vector: vector || false,
221
177
  embedder: vector ? lazyFastembedSmall : void 0,
222
178
  options: {
@@ -232,11 +188,6 @@ function getDynamicMemory(storage, vector, settingsPath, options, knowledge) {
232
188
  resolveModel: resolveMemoryModel,
233
189
  temporalMarkers: true,
234
190
  retrieval: vector ? { vector: true } : true,
235
- experimental_subconscious: subconsciousAvailable ? new Subconscious({
236
- defaultScope: "resource",
237
- pins: true,
238
- ...isFactory ? { maxSteps: 25 } : {}
239
- }) : void 0,
240
191
  scope: omScope,
241
192
  activateAfterIdle: {
242
193
  default: "auto",
@@ -276,6 +227,6 @@ async settled() {
276
227
  await Promise.allSettled([cachedMemory?.settled(), ...[...retiredMemories].map((memory) => memory.settled())]);
277
228
  } });
278
229
  }
279
- export { LOCAL_KNOWLEDGE_ORG_ID, getDynamicMemory, hasSubconsciousTools, isSubconsciousEnabled };
230
+ export { LOCAL_KNOWLEDGE_ORG_ID, getDynamicMemory };
280
231
 
281
232
  //# sourceMappingURL=memory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","names":[],"sources":["../../src/agents/memory.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { Knowledge } from '@mastra/core/knowledge';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { MastraCompositeStore } from '@mastra/core/storage';\nimport type { MastraVector } from '@mastra/core/vector';\nimport type { fastembed } from '@mastra/fastembed';\nimport { Memory, Subconscious } from '@mastra/memory';\nimport { DEFAULT_OBS_THRESHOLD, DEFAULT_REF_THRESHOLD, MIN_OBSERVATION_THRESHOLD } from '../constants.js';\nimport { LOCAL_KNOWLEDGE_ORG_ID, resolveKnowledgeScopeIdentity } from '../knowledge-scope.js';\nimport { MASTRACODE_AUTO_OM_MODELS, resolveAutoOMModelId } from '../onboarding/packs.js';\nimport { loadSettings } from '../onboarding/settings.js';\nimport { ANTHROPIC_PROMPT_CACHE_TTL } from '../providers/anthropic-prompt-cache.js';\nimport type { MastraCodeState } from '../schema.js';\nimport { getOmScope } from '../utils/project.js';\nimport { canUseProvider, getActiveMemoryRoute, resolveModel } from './model.js';\n\n/**\n * `fastembed.small`, loaded on the first embedding. Importing `@mastra/fastembed` up front loads ONNX\n * Runtime and a native tokenizer (~11 MB) into every session, including ones that never embed.\n */\nconst lazyFastembedSmall: typeof fastembed.small = {\n specificationVersion: 'v3',\n provider: 'fastembed',\n modelId: 'bge-small-en-v1.5',\n maxEmbeddingsPerCall: 256,\n supportsParallelCalls: true,\n async doEmbed(options) {\n const { fastembed } = await import('@mastra/fastembed');\n return fastembed.small.doEmbed(options);\n },\n};\n\n/** Route-backed OM fallback entry. */\ntype MemoryModelRouteEntry = { id: string; model: ReturnType<typeof resolveModel> };\n\n/**\n * Resolve the active model route's memory models, starting at a same-thread\n * pending fallback hop. Returns `'auto'` when the route's first memory model is\n * Auto, and `undefined` when the route sets no memory model.\n */\nfunction resolveRouteMemoryModels(\n state: MastraCodeState | undefined,\n threadId: string | null | undefined,\n resolve: (modelId: string) => ReturnType<typeof resolveModel>,\n): MemoryModelRouteEntry[] | 'auto' | undefined {\n const memoryRoute = getActiveMemoryRoute(state, threadId);\n if (memoryRoute[0]?.memoryModelId === 'auto') return 'auto';\n const seenModelIds = new Set<string>();\n const appearances = new Map<string, number>();\n const entries: MemoryModelRouteEntry[] = [];\n for (const entry of memoryRoute) {\n if (!entry.memoryModelId || entry.memoryModelId === 'auto' || seenModelIds.has(entry.memoryModelId)) continue;\n seenModelIds.add(entry.memoryModelId);\n const occurrence = (appearances.get(entry.id) ?? 0) + 1;\n appearances.set(entry.id, occurrence);\n try {\n entries.push({\n id: `${entry.id}:memory${occurrence === 1 ? '' : `#${occurrence}`}`,\n model: resolve(entry.memoryModelId),\n });\n } catch {\n break;\n }\n }\n return entries.length > 0 ? entries : undefined;\n}\n\n/**\n * The authoritative per-caller Factory memory-settings row, placed on the request\n * context before Factory's model-dependent processors run. `null` means the row\n * exists but is empty (every role auto). An unavailable sentinel or a missing\n * value on a Factory-owned session falls back to Auto roles and default\n * thresholds/attachments, so memory keeps working while Factory reports the error.\n */\ninterface FactoryMemorySettings {\n observerModelId: string | null;\n reflectorModelId: string | null;\n observationThreshold: number | null;\n reflectionThreshold: number | null;\n observeAttachments: 'auto' | boolean | null;\n}\n\ntype FactoryMemorySettingsContext =\n | FactoryMemorySettings\n | null\n | { status: 'unavailable'; reason: string }\n | undefined;\n\nfunction getFactoryMemorySettingsContext(requestContext: RequestContext): FactoryMemorySettingsContext {\n return requestContext.get('mastra__factoryMemorySettings') as FactoryMemorySettingsContext;\n}\n\nfunction isFactoryMemorySettingsUnavailable(\n settings: FactoryMemorySettingsContext,\n): settings is { status: 'unavailable'; reason: string } {\n return settings !== null && typeof settings === 'object' && 'status' in settings && settings.status === 'unavailable';\n}\n\nfunction getMainModelId(requestContext: RequestContext): string | undefined {\n const controller = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n return controller?.session.modelId || (controller?.getState()?.currentModelId as string | undefined);\n}\n\n/**\n * Resolve one OM role's model for this invocation. Returns `'auto'` for Memory's\n * auto policy, or a concrete model. Factory's DB row is authoritative for\n * Factory sessions (an unreadable row falls back to auto). Otherwise the active\n * model route's memory models win, then the per-role selection, then legacy\n * concrete settings.\n */\nfunction resolveOmRoleModelForRequest(\n role: 'observer' | 'reflector',\n requestContext: RequestContext,\n settingsPath?: string,\n options?: { disableSettingsOmSeed?: boolean },\n): 'auto' | ReturnType<typeof resolveModel> | MemoryModelRouteEntry[] {\n const controller = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = controller?.getState() as MastraCodeState | undefined;\n const resolveOptions = { remapForCodexOAuth: true, requestContext, anthropicPromptCacheScope: 'system' } as const;\n const factorySettingsContext = getFactoryMemorySettingsContext(requestContext);\n const isFactory = typeof state?.factoryProjectId === 'string';\n\n const useModel = (modelId: string) => {\n requestContext.set(`om.${role}.selectionMode`, 'model');\n requestContext.set(`om.${role}.effectiveModelId`, modelId);\n return resolveModel(modelId, resolveOptions);\n };\n const useAuto = () => {\n requestContext.set(`om.${role}.selectionMode`, 'auto');\n // These two keys are declared in the span-context allowlist\n // (`mastracode/sdk/src/index.ts`), so traces can report intent separately from\n // the effective concrete model without either being mistaken for a model ID.\n requestContext.set(\n `om.${role}.effectiveModelId`,\n resolveAutoOMModelId(getMainModelId(requestContext), providerId =>\n canUseProvider(providerId, { requestContext }),\n ),\n );\n return 'auto' as const;\n };\n\n if (\n isFactoryMemorySettingsUnavailable(factorySettingsContext) ||\n (factorySettingsContext === undefined && isFactory)\n ) {\n return useAuto();\n }\n if (factorySettingsContext !== undefined) {\n const factoryModelId = factorySettingsContext?.[`${role}ModelId`];\n return factoryModelId ? useModel(factoryModelId) : useAuto();\n }\n\n // The configured settings file, not the default one: a caller that points the\n // agent at another settings path must get the same override resolution for\n // observational memory as it does for the main model. Hosts that disable the\n // settings seed never read it.\n const settings = options?.disableSettingsOmSeed ? undefined : loadSettings(settingsPath);\n const routeMemory = resolveRouteMemoryModels(state, controller?.threadId, modelId =>\n resolveModel(modelId, resolveOptions),\n );\n if (routeMemory === 'auto') return useAuto();\n if (routeMemory) {\n requestContext.set(`om.${role}.selectionMode`, 'model');\n requestContext.set(`om.${role}.effectiveModelId`, routeMemory[0]?.model.modelId);\n return routeMemory.length === 1 ? routeMemory[0]!.model : routeMemory;\n }\n\n const selection: unknown = state?.[`${role}ModelSelection`];\n if (selection === 'auto') return useAuto();\n if (typeof selection === 'string' && selection) return useModel(selection);\n if (\n selection &&\n typeof selection === 'object' &&\n 'modelId' in selection &&\n typeof selection.modelId === 'string' &&\n selection.modelId\n ) {\n return useModel(selection.modelId);\n }\n\n const roleOverride =\n role === 'observer' ? settings?.models?.observerModelOverride : settings?.models?.reflectorModelOverride;\n if (roleOverride) return useModel(roleOverride);\n const legacyModelId = state?.[`${role}ModelId`];\n if (typeof legacyModelId === 'string' && legacyModelId) return useModel(legacyModelId);\n return useAuto();\n}\n\nconst DYNAMIC_AGENTS_MD_INSTRUCTION =\n 'Messages wrapped in <system-reminder type=\"dynamic-agents-md\" ...>...</system-reminder> are ephemeral project-context instructions injected from files on disk. Do NOT observe or extract information from these messages — they are reloaded automatically when needed and should not be stored in memory.';\n\n// Derived from https://github.com/JuliusBrussee/caveman and adapted for OM use with fixed full-level compression.\nconst CAVEMAN_OM_INSTRUCTION = `Respond terse like smart caveman. All technical substance stay. Only fluff die.\n\nUse full caveman compression style.\n\nDrop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not \"implement a solution for\"). Technical terms exact. Code blocks unchanged. Errors quoted exact. Leave out the words \"agent\" and \"assistant\" at the start of each observation line, it is assumed each line is referring to the assistant unless it specifically says it was about the user. Leave out parenthesis and other text characters like * that would not contribute to understanding the observations.\n\nPattern: \\`[thing] [action] [reason]. [next step]\\`\n\nNot: \"Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by...\"\nYes: \"Bug in auth middleware. Token expiry check use < not <=. Fix:\"\n\nExample 1\n🔴 14:31 user asks why React component rerenders\n🟡 14:32 saw inline object prop create new ref each render, cause rerender\n✅ 14:34 fixed render issue by wrap object in useMemo\n\nExample 2\n🟡 15:10 explained pool reuse DB connections, skip repeat handshake overhead\n\nDon't say \"Agent did x\", say \"did x\". It will be assumed the agent did what was observed. The who should only be specified for the user or other third parties: \"user asked x\"\n\nDrop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread, user asks to clarify or repeats question, and anything that requires remembering verbatim content. Resume caveman after clear part done`;\n\nexport { LOCAL_KNOWLEDGE_ORG_ID };\n\n// One error per session, not per memory resolution. Keyed on the session id\n// rather than the controller object: the controller is read off the request\n// context on every resolution, so it is a fresh object per request and would\n// dedupe nothing. Bounded so a long-running Factory process cannot grow this\n// without limit — refusing sessions are rare, and losing the oldest ids only\n// costs one extra log line.\nconst REPORTED_ORG_UNRESOLVED_LIMIT = 500;\nconst reportedOrgUnresolved = new Set<string>();\n\nfunction reportOrgUnresolved(\n controller: AgentControllerRequestContext<MastraCodeState> | undefined,\n factoryProjectId: string | undefined,\n reason?: string,\n) {\n const sessionId = controller?.session?.id;\n if (sessionId) {\n if (reportedOrgUnresolved.has(sessionId)) return;\n if (reportedOrgUnresolved.size >= REPORTED_ORG_UNRESOLVED_LIMIT) {\n reportedOrgUnresolved.delete(reportedOrgUnresolved.values().next().value as string);\n }\n reportedOrgUnresolved.add(sessionId);\n }\n const session = controller?.session;\n console.error(\n `[Subconscious] Knowledge curation disabled: no organization resolved for session ${session?.id ?? 'unknown'} (project ${factoryProjectId ?? 'none'})${reason ? `: ${reason}` : ''}. Knowledge is not written rather than written where it cannot be read.`,\n );\n}\n\n/**\n * Whether the experimental subconscious (knowledge graph + reminder sidekick)\n * is switched on for this process: it needs a vector store and the opt-in flag.\n */\nexport function isSubconsciousEnabled(vector: MastraVector | undefined): boolean {\n return Boolean(vector) && process.env.MASTRACODE_EXPERIMENTAL_SUBCONSCIOUS === '1';\n}\n\n/**\n * Whether the subconscious tools (`knowledge_*`, `ask_memory`) are registered\n * for a given session. Beyond the process-level switch, a Factory-owned\n * session that cannot resolve its org refuses the subconscious entirely (see\n * `getDynamicMemory`, which applies the same two checks inline because it also\n * needs the resolved identity). The system prompt's tool guidance calls here so\n * it never advertises tools that `getDynamicMemory` did not register.\n */\nexport function hasSubconsciousTools(vector: MastraVector | undefined, state: MastraCodeState | undefined): boolean {\n return isSubconsciousEnabled(vector) && resolveKnowledgeScopeIdentity(state).resolved;\n}\n\n/**\n * Dynamic memory factory function.\n * Reads OM thresholds from controller state via requestContext.\n * Model functions also read from requestContext (no mutable bridge needed).\n */\nexport function getDynamicMemory(\n storage: MastraCompositeStore,\n vector?: MastraVector,\n settingsPath?: string,\n options?: { disableSettingsOmSeed?: boolean },\n knowledge?: Knowledge,\n) {\n // Cache is scoped per storage instance (per getDynamicMemory call) so a\n // Memory bound to one storage is never reused after storage changes.\n let cachedMemory: Memory | null = null;\n let cachedMemoryKey: string | null = null;\n // Instances replaced by a config change may still have background work in flight.\n const retiredMemories = new Set<Memory>();\n\n // Observer/reflector model functions — read the current model ID from\n // controller state via requestContext (propagated by OM's agent.generate).\n // Bound here so the configured settings path reaches role overrides and pack\n // memory-model resolution.\n const getObserverModel = ({ requestContext }: { requestContext: RequestContext }) =>\n resolveOmRoleModelForRequest('observer', requestContext, settingsPath, options);\n const getReflectorModel = ({ requestContext }: { requestContext: RequestContext }) =>\n resolveOmRoleModelForRequest('reflector', requestContext, settingsPath, options);\n // Routes the concrete model Memory's `'auto'` picks through Mastra Code's\n // credential-aware resolver, like every other Mastra Code model.\n const resolveMemoryModel = (modelId: string, { requestContext }: { requestContext?: RequestContext }) =>\n resolveModel(modelId, { remapForCodexOAuth: true, requestContext, anthropicPromptCacheScope: 'system' });\n\n const resolveMemory = ({ requestContext }: { requestContext: RequestContext }) => {\n const controller = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = controller?.getState() as MastraCodeState | undefined;\n const subconsciousEnabled = isSubconsciousEnabled(vector);\n const factoryProjectId = state?.factoryProjectId;\n const isFactory = typeof factoryProjectId === 'string' && factoryProjectId.trim().length > 0;\n\n // A Factory-owned session that could not resolve its org refuses to curate:\n // writing under a substituted identity produces knowledge the fail-closed\n // read path can never see.\n let orgUnresolvedRefusal = false;\n\n if (subconsciousEnabled) {\n const identity = resolveKnowledgeScopeIdentity(state);\n if (identity.resolved) {\n requestContext.set('organizationId', identity.organizationId);\n } else {\n orgUnresolvedRefusal = true;\n reportOrgUnresolved(controller, identity.knowledgeResourceId, identity.reason);\n }\n if (identity.knowledgeResourceId) {\n requestContext.set('knowledgeResourceId', identity.knowledgeResourceId);\n }\n }\n\n const subconsciousAvailable = subconsciousEnabled && !orgUnresolvedRefusal;\n\n // Factory sessions share a memory resource across a Factory's runs and a\n // user's sessions, so their scope is fixed to thread: one shared record would\n // hand every run the others' work and invalidate their prompt caches. Recall\n // search still reaches the whole resource. Neither session state, the env\n // var, nor a repository's database.json can switch it.\n const omScope = isFactory ? 'thread' : (state?.omScope ?? getOmScope(state?.projectPath));\n const isResourceScope = omScope === 'resource';\n\n // The Factory row is authoritative and read per invocation, so a stored\n // threshold/attachment change reaches the running Memory without a session.\n const factorySettingsContext = getFactoryMemorySettingsContext(requestContext);\n const factorySettingsUnavailable =\n isFactoryMemorySettingsUnavailable(factorySettingsContext) || (factorySettingsContext === undefined && isFactory);\n const factorySettings = factorySettingsUnavailable ? null : factorySettingsContext;\n // Rows saved before validation can still hold a thread-scope threshold that\n // @mastra/memory refuses because it does not exceed the activation buffer.\n // Resource scope has no activation buffer and keeps its saved value.\n const storedObsThreshold =\n factorySettings !== undefined\n ? (factorySettings?.observationThreshold ?? DEFAULT_OBS_THRESHOLD)\n : (state?.observationThreshold ?? DEFAULT_OBS_THRESHOLD);\n const obsThreshold = isResourceScope ? storedObsThreshold : Math.max(storedObsThreshold, MIN_OBSERVATION_THRESHOLD);\n const refThreshold =\n factorySettings !== undefined\n ? (factorySettings?.reflectionThreshold ?? DEFAULT_REF_THRESHOLD)\n : (state?.reflectionThreshold ?? DEFAULT_REF_THRESHOLD);\n const caveman = state?.cavemanObservations ?? false;\n\n const observerPreviousObservationTokens = 1000;\n // The row is authoritative: an absent value means the user left it on Auto,\n // which the config API reports as 'auto' and Memory resolves by model\n // capability.\n const observeAttachments =\n factorySettings !== undefined ? (factorySettings?.observeAttachments ?? 'auto') : state?.observeAttachments;\n // Factory sessions get a factory-only Subconscious config, so the cache key\n // carries Factory presence and settings availability to keep those configs\n // from cross-serving.\n const cacheKey = `${obsThreshold}:${refThreshold}:${omScope}:${observerPreviousObservationTokens}:${caveman ? 1 : 0}:${observeAttachments}:${isFactory ? 1 : 0}:${subconsciousAvailable ? 1 : 0}`;\n if (cachedMemory && cachedMemoryKey === cacheKey) {\n return cachedMemory;\n }\n\n const observerInstruction = caveman\n ? `${DYNAMIC_AGENTS_MD_INSTRUCTION}\\n\\n${CAVEMAN_OM_INSTRUCTION}`\n : DYNAMIC_AGENTS_MD_INSTRUCTION;\n const reflectionInstruction = caveman ? CAVEMAN_OM_INSTRUCTION : undefined;\n\n if (cachedMemory) {\n const retired = cachedMemory;\n retiredMemories.add(retired);\n // settled() rejects if the instance's OM engine failed to start; that must not surface as\n // an unhandled rejection from a background retirement.\n void retired\n .settled()\n .catch(() => {})\n .finally(() => retiredMemories.delete(retired));\n }\n\n cachedMemory = new Memory({\n storage,\n ...(knowledge ? { knowledge } : {}),\n vector: vector || false,\n embedder: vector ? lazyFastembedSmall : undefined,\n options: {\n // Generate a durable title from the first user message. Every client uses\n // the same title in its thread list and active-session chrome. Title\n // generation takes the primary OM model only — its model field does not\n // accept fallback arrays.\n generateTitle:\n process.env.MASTRACODE_DISABLE_TITLE_GENERATION === '1'\n ? false\n : {\n model: ({ requestContext }) => {\n const resolved = getObserverModel({ requestContext });\n if (resolved === 'auto') {\n return resolveMemoryModel(\n resolveAutoOMModelId(getMainModelId(requestContext), providerId =>\n canUseProvider(providerId, { requestContext }),\n ),\n { requestContext },\n );\n }\n return Array.isArray(resolved) ? resolved[0]!.model : resolved;\n },\n },\n observationalMemory:\n process.env.MASTRACODE_DISABLE_OBSERVATIONAL_MEMORY === '1'\n ? false\n : {\n enabled: true,\n autoModels: MASTRACODE_AUTO_OM_MODELS,\n canUseProvider,\n resolveModel: resolveMemoryModel,\n temporalMarkers: true,\n retrieval: vector ? { vector: true } : true,\n experimental_subconscious: subconsciousAvailable\n ? new Subconscious({\n defaultScope: 'resource',\n pins: true,\n ...(isFactory ? { maxSteps: 25 } : {}),\n })\n : undefined,\n scope: omScope,\n // The main agent writes Anthropic cache entries with this TTL; 'auto' can't see it.\n activateAfterIdle: { default: 'auto', anthropic: ANTHROPIC_PROMPT_CACHE_TTL },\n activateOnProviderChange: true,\n observation: {\n bufferTokens: isResourceScope ? false : 1 / 5,\n bufferActivation: isResourceScope ? undefined : 2000,\n model: getObserverModel,\n messageTokens: obsThreshold,\n blockAfter: 2,\n previousObserverTokens: observerPreviousObservationTokens,\n threadTitle: true,\n instruction: observerInstruction,\n observeAttachments,\n },\n reflection: {\n bufferActivation: isResourceScope ? undefined : 1 / 2,\n blockAfter: 1.1,\n model: getReflectorModel,\n observationTokens: refThreshold,\n instruction: reflectionInstruction,\n },\n },\n },\n });\n cachedMemoryKey = cacheKey;\n\n return cachedMemory;\n };\n\n return Object.assign(resolveMemory, {\n /**\n * Wait for background memory work (buffered observations, reflections, indexing) in every\n * instance this factory created. Await before closing storage.\n */\n async settled(): Promise<void> {\n // Drain every instance even if one rejects, so teardown can still close storage.\n await Promise.allSettled([cachedMemory?.settled(), ...[...retiredMemories].map(memory => memory.settled())]);\n },\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"memory.js","names":[],"sources":["../../src/agents/memory.ts"],"sourcesContent":["import type { AgentControllerRequestContext } from '@mastra/core/agent-controller';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { MastraCompositeStore } from '@mastra/core/storage';\nimport type { MastraVector } from '@mastra/core/vector';\nimport type { fastembed } from '@mastra/fastembed';\nimport { Memory } from '@mastra/memory';\nimport { DEFAULT_OBS_THRESHOLD, DEFAULT_REF_THRESHOLD, MIN_OBSERVATION_THRESHOLD } from '../constants.js';\nimport { LOCAL_KNOWLEDGE_ORG_ID } from '../knowledge-scope.js';\nimport { MASTRACODE_AUTO_OM_MODELS, resolveAutoOMModelId } from '../onboarding/packs.js';\nimport { loadSettings } from '../onboarding/settings.js';\nimport { ANTHROPIC_PROMPT_CACHE_TTL } from '../providers/anthropic-prompt-cache.js';\nimport type { MastraCodeState } from '../schema.js';\nimport { getOmScope } from '../utils/project.js';\nimport { canUseProvider, getActiveMemoryRoute, resolveModel } from './model.js';\n\n/**\n * `fastembed.small`, loaded on the first embedding. Importing `@mastra/fastembed` up front loads ONNX\n * Runtime and a native tokenizer (~11 MB) into every session, including ones that never embed.\n */\nconst lazyFastembedSmall: typeof fastembed.small = {\n specificationVersion: 'v3',\n provider: 'fastembed',\n modelId: 'bge-small-en-v1.5',\n maxEmbeddingsPerCall: 256,\n supportsParallelCalls: true,\n async doEmbed(options) {\n const { fastembed } = await import('@mastra/fastembed');\n return fastembed.small.doEmbed(options);\n },\n};\n\n/** Route-backed OM fallback entry. */\ntype MemoryModelRouteEntry = { id: string; model: ReturnType<typeof resolveModel> };\n\n/**\n * Resolve the active model route's memory models, starting at a same-thread\n * pending fallback hop. Returns `'auto'` when the route's first memory model is\n * Auto, and `undefined` when the route sets no memory model.\n */\nfunction resolveRouteMemoryModels(\n state: MastraCodeState | undefined,\n threadId: string | null | undefined,\n resolve: (modelId: string) => ReturnType<typeof resolveModel>,\n): MemoryModelRouteEntry[] | 'auto' | undefined {\n const memoryRoute = getActiveMemoryRoute(state, threadId);\n if (memoryRoute[0]?.memoryModelId === 'auto') return 'auto';\n const seenModelIds = new Set<string>();\n const appearances = new Map<string, number>();\n const entries: MemoryModelRouteEntry[] = [];\n for (const entry of memoryRoute) {\n if (!entry.memoryModelId || entry.memoryModelId === 'auto' || seenModelIds.has(entry.memoryModelId)) continue;\n seenModelIds.add(entry.memoryModelId);\n const occurrence = (appearances.get(entry.id) ?? 0) + 1;\n appearances.set(entry.id, occurrence);\n try {\n entries.push({\n id: `${entry.id}:memory${occurrence === 1 ? '' : `#${occurrence}`}`,\n model: resolve(entry.memoryModelId),\n });\n } catch {\n break;\n }\n }\n return entries.length > 0 ? entries : undefined;\n}\n\n/**\n * The authoritative per-caller Factory memory-settings row, placed on the request\n * context before Factory's model-dependent processors run. `null` means the row\n * exists but is empty (every role auto). An unavailable sentinel or a missing\n * value on a Factory-owned session falls back to Auto roles and default\n * thresholds/attachments, so memory keeps working while Factory reports the error.\n */\ninterface FactoryMemorySettings {\n observerModelId: string | null;\n reflectorModelId: string | null;\n observationThreshold: number | null;\n reflectionThreshold: number | null;\n observeAttachments: 'auto' | boolean | null;\n}\n\ntype FactoryMemorySettingsContext =\n | FactoryMemorySettings\n | null\n | { status: 'unavailable'; reason: string }\n | undefined;\n\nfunction getFactoryMemorySettingsContext(requestContext: RequestContext): FactoryMemorySettingsContext {\n return requestContext.get('mastra__factoryMemorySettings') as FactoryMemorySettingsContext;\n}\n\nfunction isFactoryMemorySettingsUnavailable(\n settings: FactoryMemorySettingsContext,\n): settings is { status: 'unavailable'; reason: string } {\n return settings !== null && typeof settings === 'object' && 'status' in settings && settings.status === 'unavailable';\n}\n\nfunction getMainModelId(requestContext: RequestContext): string | undefined {\n const controller = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n return controller?.session.modelId || (controller?.getState()?.currentModelId as string | undefined);\n}\n\n/**\n * Resolve one OM role's model for this invocation. Returns `'auto'` for Memory's\n * auto policy, or a concrete model. Factory's DB row is authoritative for\n * Factory sessions (an unreadable row falls back to auto). Otherwise the active\n * model route's memory models win, then the per-role selection, then legacy\n * concrete settings.\n */\nfunction resolveOmRoleModelForRequest(\n role: 'observer' | 'reflector',\n requestContext: RequestContext,\n settingsPath?: string,\n options?: { disableSettingsOmSeed?: boolean },\n): 'auto' | ReturnType<typeof resolveModel> | MemoryModelRouteEntry[] {\n const controller = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = controller?.getState() as MastraCodeState | undefined;\n const resolveOptions = { remapForCodexOAuth: true, requestContext, anthropicPromptCacheScope: 'system' } as const;\n const factorySettingsContext = getFactoryMemorySettingsContext(requestContext);\n const isFactory = typeof state?.factoryProjectId === 'string';\n\n const useModel = (modelId: string) => {\n requestContext.set(`om.${role}.selectionMode`, 'model');\n requestContext.set(`om.${role}.effectiveModelId`, modelId);\n return resolveModel(modelId, resolveOptions);\n };\n const useAuto = () => {\n requestContext.set(`om.${role}.selectionMode`, 'auto');\n // These two keys are declared in the span-context allowlist\n // (`mastracode/sdk/src/index.ts`), so traces can report intent separately from\n // the effective concrete model without either being mistaken for a model ID.\n requestContext.set(\n `om.${role}.effectiveModelId`,\n resolveAutoOMModelId(getMainModelId(requestContext), providerId =>\n canUseProvider(providerId, { requestContext }),\n ),\n );\n return 'auto' as const;\n };\n\n if (\n isFactoryMemorySettingsUnavailable(factorySettingsContext) ||\n (factorySettingsContext === undefined && isFactory)\n ) {\n return useAuto();\n }\n if (factorySettingsContext !== undefined) {\n const factoryModelId = factorySettingsContext?.[`${role}ModelId`];\n return factoryModelId ? useModel(factoryModelId) : useAuto();\n }\n\n // The configured settings file, not the default one: a caller that points the\n // agent at another settings path must get the same override resolution for\n // observational memory as it does for the main model. Hosts that disable the\n // settings seed never read it.\n const settings = options?.disableSettingsOmSeed ? undefined : loadSettings(settingsPath);\n const routeMemory = resolveRouteMemoryModels(state, controller?.threadId, modelId =>\n resolveModel(modelId, resolveOptions),\n );\n if (routeMemory === 'auto') return useAuto();\n if (routeMemory) {\n requestContext.set(`om.${role}.selectionMode`, 'model');\n requestContext.set(`om.${role}.effectiveModelId`, routeMemory[0]?.model.modelId);\n return routeMemory.length === 1 ? routeMemory[0]!.model : routeMemory;\n }\n\n const selection: unknown = state?.[`${role}ModelSelection`];\n if (selection === 'auto') return useAuto();\n if (typeof selection === 'string' && selection) return useModel(selection);\n if (\n selection &&\n typeof selection === 'object' &&\n 'modelId' in selection &&\n typeof selection.modelId === 'string' &&\n selection.modelId\n ) {\n return useModel(selection.modelId);\n }\n\n const roleOverride =\n role === 'observer' ? settings?.models?.observerModelOverride : settings?.models?.reflectorModelOverride;\n if (roleOverride) return useModel(roleOverride);\n const legacyModelId = state?.[`${role}ModelId`];\n if (typeof legacyModelId === 'string' && legacyModelId) return useModel(legacyModelId);\n return useAuto();\n}\n\nconst DYNAMIC_AGENTS_MD_INSTRUCTION =\n 'Messages wrapped in <system-reminder type=\"dynamic-agents-md\" ...>...</system-reminder> are ephemeral project-context instructions injected from files on disk. Do NOT observe or extract information from these messages — they are reloaded automatically when needed and should not be stored in memory.';\n\n// Derived from https://github.com/JuliusBrussee/caveman and adapted for OM use with fixed full-level compression.\nconst CAVEMAN_OM_INSTRUCTION = `Respond terse like smart caveman. All technical substance stay. Only fluff die.\n\nUse full caveman compression style.\n\nDrop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not \"implement a solution for\"). Technical terms exact. Code blocks unchanged. Errors quoted exact. Leave out the words \"agent\" and \"assistant\" at the start of each observation line, it is assumed each line is referring to the assistant unless it specifically says it was about the user. Leave out parenthesis and other text characters like * that would not contribute to understanding the observations.\n\nPattern: \\`[thing] [action] [reason]. [next step]\\`\n\nNot: \"Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by...\"\nYes: \"Bug in auth middleware. Token expiry check use < not <=. Fix:\"\n\nExample 1\n🔴 14:31 user asks why React component rerenders\n🟡 14:32 saw inline object prop create new ref each render, cause rerender\n✅ 14:34 fixed render issue by wrap object in useMemo\n\nExample 2\n🟡 15:10 explained pool reuse DB connections, skip repeat handshake overhead\n\nDon't say \"Agent did x\", say \"did x\". It will be assumed the agent did what was observed. The who should only be specified for the user or other third parties: \"user asked x\"\n\nDrop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread, user asks to clarify or repeats question, and anything that requires remembering verbatim content. Resume caveman after clear part done`;\n\nexport { LOCAL_KNOWLEDGE_ORG_ID };\n\n/**\n * Dynamic memory factory function.\n * Reads OM thresholds from controller state via requestContext.\n * Model functions also read from requestContext (no mutable bridge needed).\n */\nexport function getDynamicMemory(\n storage: MastraCompositeStore,\n vector?: MastraVector,\n settingsPath?: string,\n options?: { disableSettingsOmSeed?: boolean },\n) {\n // Cache is scoped per storage instance (per getDynamicMemory call) so a\n // Memory bound to one storage is never reused after storage changes.\n let cachedMemory: Memory | null = null;\n let cachedMemoryKey: string | null = null;\n // Instances replaced by a config change may still have background work in flight.\n const retiredMemories = new Set<Memory>();\n\n // Observer/reflector model functions — read the current model ID from\n // controller state via requestContext (propagated by OM's agent.generate).\n // Bound here so the configured settings path reaches role overrides and pack\n // memory-model resolution.\n const getObserverModel = ({ requestContext }: { requestContext: RequestContext }) =>\n resolveOmRoleModelForRequest('observer', requestContext, settingsPath, options);\n const getReflectorModel = ({ requestContext }: { requestContext: RequestContext }) =>\n resolveOmRoleModelForRequest('reflector', requestContext, settingsPath, options);\n // Routes the concrete model Memory's `'auto'` picks through Mastra Code's\n // credential-aware resolver, like every other Mastra Code model.\n const resolveMemoryModel = (modelId: string, { requestContext }: { requestContext?: RequestContext }) =>\n resolveModel(modelId, { remapForCodexOAuth: true, requestContext, anthropicPromptCacheScope: 'system' });\n\n const resolveMemory = ({ requestContext }: { requestContext: RequestContext }) => {\n const controller = requestContext.get('controller') as AgentControllerRequestContext<MastraCodeState> | undefined;\n const state = controller?.getState() as MastraCodeState | undefined;\n const factoryProjectId = state?.factoryProjectId;\n const isFactory = typeof factoryProjectId === 'string' && factoryProjectId.trim().length > 0;\n\n // Factory sessions share a memory resource across a Factory's runs and a\n // user's sessions, so their scope is fixed to thread: one shared record would\n // hand every run the others' work and invalidate their prompt caches. Recall\n // search still reaches the whole resource. Neither session state, the env\n // var, nor a repository's database.json can switch it.\n const omScope = isFactory ? 'thread' : (state?.omScope ?? getOmScope(state?.projectPath));\n const isResourceScope = omScope === 'resource';\n\n // The Factory row is authoritative and read per invocation, so a stored\n // threshold/attachment change reaches the running Memory without a session.\n const factorySettingsContext = getFactoryMemorySettingsContext(requestContext);\n const factorySettingsUnavailable =\n isFactoryMemorySettingsUnavailable(factorySettingsContext) || (factorySettingsContext === undefined && isFactory);\n const factorySettings = factorySettingsUnavailable ? null : factorySettingsContext;\n // Rows saved before validation can still hold a thread-scope threshold that\n // @mastra/memory refuses because it does not exceed the activation buffer.\n // Resource scope has no activation buffer and keeps its saved value.\n const storedObsThreshold =\n factorySettings !== undefined\n ? (factorySettings?.observationThreshold ?? DEFAULT_OBS_THRESHOLD)\n : (state?.observationThreshold ?? DEFAULT_OBS_THRESHOLD);\n const obsThreshold = isResourceScope ? storedObsThreshold : Math.max(storedObsThreshold, MIN_OBSERVATION_THRESHOLD);\n const refThreshold =\n factorySettings !== undefined\n ? (factorySettings?.reflectionThreshold ?? DEFAULT_REF_THRESHOLD)\n : (state?.reflectionThreshold ?? DEFAULT_REF_THRESHOLD);\n const caveman = state?.cavemanObservations ?? false;\n\n const observerPreviousObservationTokens = 1000;\n // The row is authoritative: an absent value means the user left it on Auto,\n // which the config API reports as 'auto' and Memory resolves by model\n // capability.\n const observeAttachments =\n factorySettings !== undefined ? (factorySettings?.observeAttachments ?? 'auto') : state?.observeAttachments;\n // Factory sessions get a factory-only config, so the cache key carries\n // Factory presence to keep those configs from cross-serving.\n const cacheKey = `${obsThreshold}:${refThreshold}:${omScope}:${observerPreviousObservationTokens}:${caveman ? 1 : 0}:${observeAttachments}:${isFactory ? 1 : 0}`;\n if (cachedMemory && cachedMemoryKey === cacheKey) {\n return cachedMemory;\n }\n\n const observerInstruction = caveman\n ? `${DYNAMIC_AGENTS_MD_INSTRUCTION}\\n\\n${CAVEMAN_OM_INSTRUCTION}`\n : DYNAMIC_AGENTS_MD_INSTRUCTION;\n const reflectionInstruction = caveman ? CAVEMAN_OM_INSTRUCTION : undefined;\n\n if (cachedMemory) {\n const retired = cachedMemory;\n retiredMemories.add(retired);\n // settled() rejects if the instance's OM engine failed to start; that must not surface as\n // an unhandled rejection from a background retirement.\n void retired\n .settled()\n .catch(() => {})\n .finally(() => retiredMemories.delete(retired));\n }\n\n cachedMemory = new Memory({\n storage,\n vector: vector || false,\n embedder: vector ? lazyFastembedSmall : undefined,\n options: {\n // Generate a durable title from the first user message. Every client uses\n // the same title in its thread list and active-session chrome. Title\n // generation takes the primary OM model only — its model field does not\n // accept fallback arrays.\n generateTitle:\n process.env.MASTRACODE_DISABLE_TITLE_GENERATION === '1'\n ? false\n : {\n model: ({ requestContext }) => {\n const resolved = getObserverModel({ requestContext });\n if (resolved === 'auto') {\n return resolveMemoryModel(\n resolveAutoOMModelId(getMainModelId(requestContext), providerId =>\n canUseProvider(providerId, { requestContext }),\n ),\n { requestContext },\n );\n }\n return Array.isArray(resolved) ? resolved[0]!.model : resolved;\n },\n },\n observationalMemory:\n process.env.MASTRACODE_DISABLE_OBSERVATIONAL_MEMORY === '1'\n ? false\n : {\n enabled: true,\n autoModels: MASTRACODE_AUTO_OM_MODELS,\n canUseProvider,\n resolveModel: resolveMemoryModel,\n temporalMarkers: true,\n retrieval: vector ? { vector: true } : true,\n scope: omScope,\n // The main agent writes Anthropic cache entries with this TTL; 'auto' can't see it.\n activateAfterIdle: { default: 'auto', anthropic: ANTHROPIC_PROMPT_CACHE_TTL },\n activateOnProviderChange: true,\n observation: {\n bufferTokens: isResourceScope ? false : 1 / 5,\n bufferActivation: isResourceScope ? undefined : 2000,\n model: getObserverModel,\n messageTokens: obsThreshold,\n blockAfter: 2,\n previousObserverTokens: observerPreviousObservationTokens,\n threadTitle: true,\n instruction: observerInstruction,\n observeAttachments,\n },\n reflection: {\n bufferActivation: isResourceScope ? undefined : 1 / 2,\n blockAfter: 1.1,\n model: getReflectorModel,\n observationTokens: refThreshold,\n instruction: reflectionInstruction,\n },\n },\n },\n });\n cachedMemoryKey = cacheKey;\n\n return cachedMemory;\n };\n\n return Object.assign(resolveMemory, {\n /**\n * Wait for background memory work (buffered observations, reflections, indexing) in every\n * instance this factory created. Await before closing storage.\n */\n async settled(): Promise<void> {\n // Drain every instance even if one rejects, so teardown can still close storage.\n await Promise.allSettled([cachedMemory?.settled(), ...[...retiredMemories].map(memory => memory.settled())]);\n },\n });\n}\n"],"mappings":"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"}
@@ -8,8 +8,6 @@ import type { PromptContext as BasePromptContext } from '@mastra/core/coding-age
8
8
  export interface PromptContext extends Omit<BasePromptContext, 'toolGuidance'> {
9
9
  modeId: string;
10
10
  state?: any;
11
- /** The subconscious knowledge tools are registered on the agent. */
12
- hasSubconscious?: boolean;
13
11
  hostInstructions?: string;
14
12
  /** Controller built-in tools removed via `disableBuiltinTools`; treated as denied. */
15
13
  disabledBuiltinTools?: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAapF,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,oEAAoE;IACpE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sFAAsF;IACtF,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,6FAA6F;IAC7F,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CAKpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,aAAa,GAAG,aAAa,EAAE,CA4H3E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAapF,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sFAAsF;IACtF,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,6FAA6F;IAC7F,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CAKpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,aAAa,GAAG,aAAa,EAAE,CA2H3E"}
@@ -44,7 +44,6 @@ function buildFullPromptSections(ctx) {
44
44
  const factoryProjectId = typeof ctx.state?.factoryProjectId === "string" ? ctx.state.factoryProjectId : void 0;
45
45
  const toolGuidance = buildToolGuidance(ctx.modeId, {
46
46
  hasWebSearch,
47
- hasSubconscious: ctx.hasSubconscious === true,
48
47
  hasSubagents: ctx.hasSubagents,
49
48
  deniedTools,
50
49
  plansDir: getLocalPlansRelativeDir({ factoryProjectId })
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/agents/prompts/index.ts"],"sourcesContent":["/**\n * Prompt system — exports the prompt builder and mode-specific prompts.\n */\n\nexport { buildModePrompt, buildModePromptFn } from './build.js';\nexport { planModePrompt } from './plan.js';\nexport { fastModePrompt } from './fast.js';\n\nimport { buildBasePrompt } from '@mastra/core/coding-agent';\nimport type { PromptContext as BasePromptContext } from '@mastra/core/coding-agent';\nimport { loadSettings, resolveLspSetting } from '../../onboarding/settings.js';\nimport { MC_TOOLS } from '../../tool-names.js';\nimport { hasParallelKey, hasTavilyKey } from '../../tools/index.js';\nimport { getLocalPlansRelativeDir } from '../../utils/plans.js';\nimport { loadSessionInstructions, formatInstructionSource, AGENT_INSTRUCTIONS_HEADING } from './agent-instructions.js';\nimport { buildModePromptFn } from './build.js';\nimport { fastModePrompt } from './fast.js';\nimport { modelSpecificPrompts } from './model.js';\nimport { planModePrompt } from './plan.js';\nimport { buildToolGuidance } from './tool-guidance.js';\n\n// Extended prompt context that includes runtime information\nexport interface PromptContext extends Omit<BasePromptContext, 'toolGuidance'> {\n modeId: string;\n state?: any;\n /** The subconscious knowledge tools are registered on the agent. */\n hasSubconscious?: boolean;\n hostInstructions?: string;\n /** Controller built-in tools removed via `disableBuiltinTools`; treated as denied. */\n disabledBuiltinTools?: readonly string[];\n /** Resolved in `buildFullPromptSections`; false when `submit_plan` is denied or disabled. */\n submitPlanAvailable?: boolean;\n currentDate: string;\n workingDir: string;\n}\n\nconst modePrompts: Record<string, string | ((ctx: PromptContext) => string)> = {\n build: buildModePromptFn,\n plan: planModePrompt,\n fast: fastModePrompt,\n};\n\n/**\n * One labeled piece of the assembled system prompt.\n *\n * The system prompt is a single string by the time it reaches the model, which\n * makes it impossible to say which configuration source is responsible for\n * which share of the context window. Building it as labeled sections and\n * joining them at the end keeps that attribution available to the `/context`\n * audit while guaranteeing the audit measures the exact text that is sent —\n * a parallel \"describe the prompt\" path would drift and report numbers for a\n * prompt that is no longer assembled this way.\n */\nexport interface PromptSection {\n /** Stable identifier, unique within a single build. */\n id: string;\n /** Human-readable label for display. */\n label: string;\n /** Optional provenance (e.g. the instruction file path). */\n detail?: string;\n /** The exact text contributed to the prompt. */\n content: string;\n}\n\n/** Join prompt sections into the final system prompt string. */\nexport function joinPromptSections(sections: PromptSection[]): string {\n return sections\n .map(section => section.content)\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * Build the full system prompt for a given mode and context.\n * Combines the base prompt with mode-specific instructions.\n */\nexport function buildFullPrompt(ctx: PromptContext): string {\n return joinPromptSections(buildFullPromptSections(ctx));\n}\n\n/**\n * Build the system prompt as labeled sections. `buildFullPrompt` is the join of\n * these, so the two can never disagree about what the model receives.\n */\nexport function buildFullPromptSections(ctx: PromptContext): PromptSection[] {\n // Determine whether web search tools are available\n const modelId = ctx.modelId;\n const hasWebSearch =\n hasParallelKey() ||\n hasTavilyKey() ||\n (!!modelId && (modelId.startsWith('anthropic/') || modelId.startsWith('openai/')));\n\n // Collect per-tool deny rules so guidance omits denied tools\n const deniedTools = new Set<string>();\n const permRules = ctx.state?.permissionRules as { tools?: Record<string, string> } | undefined;\n if (permRules?.tools) {\n for (const [name, policy] of Object.entries(permRules.tools)) {\n if (policy === 'deny') deniedTools.add(name);\n }\n }\n\n // Disabled built-ins are never registered, so they are denied for guidance too.\n for (const name of ctx.disabledBuiltinTools ?? []) deniedTools.add(name);\n\n // LSP is opt-in — when it is off the tool is never registered, so its\n // guidance must not be advertised either.\n if (resolveLspSetting(loadSettings().lsp) === false) deniedTools.add(MC_TOOLS.LSP_INSPECT);\n\n // Build mode-aware tool guidance\n const factoryProjectId = typeof ctx.state?.factoryProjectId === 'string' ? ctx.state.factoryProjectId : undefined;\n const toolGuidance = buildToolGuidance(ctx.modeId, {\n hasWebSearch,\n hasSubconscious: ctx.hasSubconscious === true,\n hasSubagents: ctx.hasSubagents,\n deniedTools,\n plansDir: getLocalPlansRelativeDir({ factoryProjectId }),\n });\n\n // Map new context to base context\n const baseCtx: BasePromptContext = {\n projectPath: ctx.workingDir || '(no workspace attached)',\n projectName: ctx.projectName || 'unknown',\n gitBranch: ctx.gitBranch,\n platform: process.platform,\n commonBinaries: ctx.commonBinaries,\n date: ctx.currentDate,\n mode: ctx.modeId,\n modelId: ctx.modelId,\n coAuthorName: ctx.coAuthorName,\n coAuthorEmail: ctx.coAuthorEmail,\n activePlan: ctx.state?.activePlan,\n hasSubagents: ctx.hasSubagents !== false && !deniedTools.has('subagent'),\n toolGuidance,\n };\n\n const base = buildBasePrompt(baseCtx);\n const entry = modePrompts[ctx.modeId] || modePrompts.build;\n const modeSpecific =\n (typeof entry === 'function' ? entry({ ...ctx, submitPlanAvailable: !deniedTools.has('submit_plan') }) : entry) ??\n '';\n const modelSpecific = ctx.modelId\n ? (modelSpecificPrompts[ctx.modelId as keyof typeof modelSpecificPrompts] ?? '')\n : '';\n\n // The current task list is carried on the agent state-signal lane (see\n // TaskStateProcessor) rather than injected into the cached system prompt. This\n // keeps the prompt prefix stable across task updates (preserving prompt cache)\n // while still surviving observational-memory truncation.\n\n // Load and inject agent instructions from AGENTS.md/CLAUDE.md files.\n // Untrusted checkouts (e.g. a PR branch under review) never read\n // project-scope files off the working tree: their AGENTS.md is\n // attacker-writable and would otherwise land in the system prompt as\n // trusted configuration. When the session carries a trusted base ref, the\n // project instructions are served from that ref instead (`git show`);\n // without one, project-scope files are skipped entirely. Home-directory\n // (global) instructions belong to whoever owns the machine, so hosts that\n // run sessions for someone else opt out of them entirely.\n // A host booting several checkouts under one working directory names them\n // as `instructionRoots`, so each checkout's own files load.\n const configDir = ctx.state?.configDir as string | undefined;\n const baseRef = typeof ctx.state?.baseRef === 'string' ? ctx.state.baseRef : undefined;\n const instructionRoots = Array.isArray(ctx.state?.instructionRoots)\n ? (ctx.state.instructionRoots as string[])\n : undefined;\n // No working directory means a hosted session with no project attached:\n // load NO instruction files at all — project locations would resolve\n // against the server's own cwd, and global locations against the server's\n // homedir. Neither belongs in a hosted session's prompt.\n const instructionSources = ctx.workingDir\n ? loadSessionInstructions({\n workingDir: ctx.workingDir,\n instructionRoots,\n configDir,\n untrustedCheckout: ctx.state?.untrustedCheckout === true,\n baseRef,\n skipGlobal: ctx.state?.skipGlobalInstructions === true,\n })\n : [];\n // Emitted per source so each AGENTS.md/CLAUDE.md can be costed individually.\n // The heading rides on the first source's section, which is exactly how\n // `formatAgentInstructions` lays the block out, so joining the sections\n // reproduces its output byte for byte.\n const instructionSections: PromptSection[] = instructionSources.map((source, index) => {\n const isFirst = index === 0;\n const isLast = index === instructionSources.length - 1;\n let content = formatInstructionSource(source);\n if (isFirst) content = `${AGENT_INSTRUCTIONS_HEADING}\\n\\n${content}`;\n // The block as a whole used to be trimmed, which only ever affected the\n // trailing whitespace of the final source's content.\n if (isLast) content = content.trimEnd();\n return {\n id: `agent-instructions:${source.path}:${index}`,\n label: `${source.scope === 'global' ? 'Global' : 'Project'} instructions`,\n detail: source.ref ? `${source.path} (at ref ${source.ref})` : source.path,\n content,\n };\n });\n\n const hostInstructions = ctx.hostInstructions?.trim() ?? '';\n\n return [\n { id: 'base-prompt', label: 'Base system prompt', content: base },\n { id: 'host-instructions', label: 'Host instructions', content: hostInstructions },\n ...instructionSections,\n { id: 'model-prompt', label: 'Model-specific prompt', detail: ctx.modelId, content: modelSpecific.trim() },\n { id: 'mode-prompt', label: 'Mode prompt', detail: ctx.modeId, content: modeSpecific.trim() },\n ].filter(section => Boolean(section.content));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/agents/prompts/index.ts"],"sourcesContent":["/**\n * Prompt system — exports the prompt builder and mode-specific prompts.\n */\n\nexport { buildModePrompt, buildModePromptFn } from './build.js';\nexport { planModePrompt } from './plan.js';\nexport { fastModePrompt } from './fast.js';\n\nimport { buildBasePrompt } from '@mastra/core/coding-agent';\nimport type { PromptContext as BasePromptContext } from '@mastra/core/coding-agent';\nimport { loadSettings, resolveLspSetting } from '../../onboarding/settings.js';\nimport { MC_TOOLS } from '../../tool-names.js';\nimport { hasParallelKey, hasTavilyKey } from '../../tools/index.js';\nimport { getLocalPlansRelativeDir } from '../../utils/plans.js';\nimport { loadSessionInstructions, formatInstructionSource, AGENT_INSTRUCTIONS_HEADING } from './agent-instructions.js';\nimport { buildModePromptFn } from './build.js';\nimport { fastModePrompt } from './fast.js';\nimport { modelSpecificPrompts } from './model.js';\nimport { planModePrompt } from './plan.js';\nimport { buildToolGuidance } from './tool-guidance.js';\n\n// Extended prompt context that includes runtime information\nexport interface PromptContext extends Omit<BasePromptContext, 'toolGuidance'> {\n modeId: string;\n state?: any;\n hostInstructions?: string;\n /** Controller built-in tools removed via `disableBuiltinTools`; treated as denied. */\n disabledBuiltinTools?: readonly string[];\n /** Resolved in `buildFullPromptSections`; false when `submit_plan` is denied or disabled. */\n submitPlanAvailable?: boolean;\n currentDate: string;\n workingDir: string;\n}\n\nconst modePrompts: Record<string, string | ((ctx: PromptContext) => string)> = {\n build: buildModePromptFn,\n plan: planModePrompt,\n fast: fastModePrompt,\n};\n\n/**\n * One labeled piece of the assembled system prompt.\n *\n * The system prompt is a single string by the time it reaches the model, which\n * makes it impossible to say which configuration source is responsible for\n * which share of the context window. Building it as labeled sections and\n * joining them at the end keeps that attribution available to the `/context`\n * audit while guaranteeing the audit measures the exact text that is sent —\n * a parallel \"describe the prompt\" path would drift and report numbers for a\n * prompt that is no longer assembled this way.\n */\nexport interface PromptSection {\n /** Stable identifier, unique within a single build. */\n id: string;\n /** Human-readable label for display. */\n label: string;\n /** Optional provenance (e.g. the instruction file path). */\n detail?: string;\n /** The exact text contributed to the prompt. */\n content: string;\n}\n\n/** Join prompt sections into the final system prompt string. */\nexport function joinPromptSections(sections: PromptSection[]): string {\n return sections\n .map(section => section.content)\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * Build the full system prompt for a given mode and context.\n * Combines the base prompt with mode-specific instructions.\n */\nexport function buildFullPrompt(ctx: PromptContext): string {\n return joinPromptSections(buildFullPromptSections(ctx));\n}\n\n/**\n * Build the system prompt as labeled sections. `buildFullPrompt` is the join of\n * these, so the two can never disagree about what the model receives.\n */\nexport function buildFullPromptSections(ctx: PromptContext): PromptSection[] {\n // Determine whether web search tools are available\n const modelId = ctx.modelId;\n const hasWebSearch =\n hasParallelKey() ||\n hasTavilyKey() ||\n (!!modelId && (modelId.startsWith('anthropic/') || modelId.startsWith('openai/')));\n\n // Collect per-tool deny rules so guidance omits denied tools\n const deniedTools = new Set<string>();\n const permRules = ctx.state?.permissionRules as { tools?: Record<string, string> } | undefined;\n if (permRules?.tools) {\n for (const [name, policy] of Object.entries(permRules.tools)) {\n if (policy === 'deny') deniedTools.add(name);\n }\n }\n\n // Disabled built-ins are never registered, so they are denied for guidance too.\n for (const name of ctx.disabledBuiltinTools ?? []) deniedTools.add(name);\n\n // LSP is opt-in — when it is off the tool is never registered, so its\n // guidance must not be advertised either.\n if (resolveLspSetting(loadSettings().lsp) === false) deniedTools.add(MC_TOOLS.LSP_INSPECT);\n\n // Build mode-aware tool guidance\n const factoryProjectId = typeof ctx.state?.factoryProjectId === 'string' ? ctx.state.factoryProjectId : undefined;\n const toolGuidance = buildToolGuidance(ctx.modeId, {\n hasWebSearch,\n hasSubagents: ctx.hasSubagents,\n deniedTools,\n plansDir: getLocalPlansRelativeDir({ factoryProjectId }),\n });\n\n // Map new context to base context\n const baseCtx: BasePromptContext = {\n projectPath: ctx.workingDir || '(no workspace attached)',\n projectName: ctx.projectName || 'unknown',\n gitBranch: ctx.gitBranch,\n platform: process.platform,\n commonBinaries: ctx.commonBinaries,\n date: ctx.currentDate,\n mode: ctx.modeId,\n modelId: ctx.modelId,\n coAuthorName: ctx.coAuthorName,\n coAuthorEmail: ctx.coAuthorEmail,\n activePlan: ctx.state?.activePlan,\n hasSubagents: ctx.hasSubagents !== false && !deniedTools.has('subagent'),\n toolGuidance,\n };\n\n const base = buildBasePrompt(baseCtx);\n const entry = modePrompts[ctx.modeId] || modePrompts.build;\n const modeSpecific =\n (typeof entry === 'function' ? entry({ ...ctx, submitPlanAvailable: !deniedTools.has('submit_plan') }) : entry) ??\n '';\n const modelSpecific = ctx.modelId\n ? (modelSpecificPrompts[ctx.modelId as keyof typeof modelSpecificPrompts] ?? '')\n : '';\n\n // The current task list is carried on the agent state-signal lane (see\n // TaskStateProcessor) rather than injected into the cached system prompt. This\n // keeps the prompt prefix stable across task updates (preserving prompt cache)\n // while still surviving observational-memory truncation.\n\n // Load and inject agent instructions from AGENTS.md/CLAUDE.md files.\n // Untrusted checkouts (e.g. a PR branch under review) never read\n // project-scope files off the working tree: their AGENTS.md is\n // attacker-writable and would otherwise land in the system prompt as\n // trusted configuration. When the session carries a trusted base ref, the\n // project instructions are served from that ref instead (`git show`);\n // without one, project-scope files are skipped entirely. Home-directory\n // (global) instructions belong to whoever owns the machine, so hosts that\n // run sessions for someone else opt out of them entirely.\n // A host booting several checkouts under one working directory names them\n // as `instructionRoots`, so each checkout's own files load.\n const configDir = ctx.state?.configDir as string | undefined;\n const baseRef = typeof ctx.state?.baseRef === 'string' ? ctx.state.baseRef : undefined;\n const instructionRoots = Array.isArray(ctx.state?.instructionRoots)\n ? (ctx.state.instructionRoots as string[])\n : undefined;\n // No working directory means a hosted session with no project attached:\n // load NO instruction files at all — project locations would resolve\n // against the server's own cwd, and global locations against the server's\n // homedir. Neither belongs in a hosted session's prompt.\n const instructionSources = ctx.workingDir\n ? loadSessionInstructions({\n workingDir: ctx.workingDir,\n instructionRoots,\n configDir,\n untrustedCheckout: ctx.state?.untrustedCheckout === true,\n baseRef,\n skipGlobal: ctx.state?.skipGlobalInstructions === true,\n })\n : [];\n // Emitted per source so each AGENTS.md/CLAUDE.md can be costed individually.\n // The heading rides on the first source's section, which is exactly how\n // `formatAgentInstructions` lays the block out, so joining the sections\n // reproduces its output byte for byte.\n const instructionSections: PromptSection[] = instructionSources.map((source, index) => {\n const isFirst = index === 0;\n const isLast = index === instructionSources.length - 1;\n let content = formatInstructionSource(source);\n if (isFirst) content = `${AGENT_INSTRUCTIONS_HEADING}\\n\\n${content}`;\n // The block as a whole used to be trimmed, which only ever affected the\n // trailing whitespace of the final source's content.\n if (isLast) content = content.trimEnd();\n return {\n id: `agent-instructions:${source.path}:${index}`,\n label: `${source.scope === 'global' ? 'Global' : 'Project'} instructions`,\n detail: source.ref ? `${source.path} (at ref ${source.ref})` : source.path,\n content,\n };\n });\n\n const hostInstructions = ctx.hostInstructions?.trim() ?? '';\n\n return [\n { id: 'base-prompt', label: 'Base system prompt', content: base },\n { id: 'host-instructions', label: 'Host instructions', content: hostInstructions },\n ...instructionSections,\n { id: 'model-prompt', label: 'Model-specific prompt', detail: ctx.modelId, content: modelSpecific.trim() },\n { id: 'mode-prompt', label: 'Mode prompt', detail: ctx.modeId, content: modeSpecific.trim() },\n ].filter(section => Boolean(section.content));\n}\n"],"mappings":"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"}
@@ -6,8 +6,6 @@
6
6
  interface ToolGuidanceOptions {
7
7
  hasWebSearch?: boolean;
8
8
  hasSubagents?: boolean;
9
- /** Subconscious knowledge tools are registered (experimental subconscious enabled). */
10
- hasSubconscious?: boolean;
11
9
  /** Tool names that have been denied — omit their guidance sections. */
12
10
  deniedTools?: Set<string>;
13
11
  /** Workspace-relative directory where plan mode can write plans. */
@@ -1 +1 @@
1
- {"version":3,"file":"tool-guidance.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/tool-guidance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,UAAU,mBAAmB;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uFAAuF;IACvF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uEAAuE;IACvE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CA+Q3F"}
1
+ {"version":3,"file":"tool-guidance.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/tool-guidance.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,UAAU,mBAAmB;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAgO3F"}
@@ -85,36 +85,6 @@ You have access to the following tools. Use the RIGHT tool for the job:`);
85
85
  ${webTools.join(" / ")} — Search the web / extract page content
86
86
  - Use for looking up documentation, error messages, package APIs.`);
87
87
  }
88
- if (options.hasSubconscious) {
89
- const knowledgeTools = [
90
- "knowledge_search",
91
- "knowledge_read",
92
- "knowledge_browse"
93
- ].filter((name) => !denied.has(name));
94
- const hasAskMemory = !denied.has("ask_memory");
95
- if (knowledgeTools.length > 0 || hasAskMemory) {
96
- const lines = [`
97
- # Subconscious Memory
98
-
99
- A background memory system (the "subconscious") runs alongside you. After conversations, it extracts durable knowledge — decisions, preferences, people, files, repos, work items — into a knowledge graph scoped to this project, visible across your sessions here. It also delivers reminders (\`<remembered>\`) and pinned knowledge into your context on its own; you do not manage those directly.`];
100
- if (knowledgeTools.length > 0) {
101
- const bullets = [];
102
- if (knowledgeTools.includes("knowledge_search")) bullets.push("- Use `knowledge_search` for a quick lexical + semantic lookup when you need a specific fact (a past decision, a person's role, what a file is for). Cheaper than re-deriving it from the codebase or asking the user.");
103
- if (knowledgeTools.includes("knowledge_read")) bullets.push("- Use `knowledge_read` to open a node by name or ID and see the records about it.");
104
- if (knowledgeTools.includes("knowledge_browse")) bullets.push("- Use `knowledge_browse` to list nodes by kind or name prefix, or to walk a node's mentions and backlinks.");
105
- if (!denied.has("recall")) bullets.push("- Prefer these over `recall` when the question is about durable facts rather than what was said in a specific past conversation.");
106
- lines.push(`
107
- ${knowledgeTools.map((name) => `**${name}**`).join(" / ")} — Query the knowledge graph directly
108
- ${bullets.join("\n")}`);
109
- }
110
- if (hasAskMemory) lines.push(`
111
- **ask_memory** — Ask the reminder sidekick a question about existing memory
112
- - Use only when the answer is not already in your context and a direct search is not enough: open-ended questions ("what did we decide about X and why?") or questions that need synthesis across several memories. It answers from what is already remembered; it does not store anything.
113
- - It is ASYNCHRONOUS. The tool returns as soon as the question is accepted; the answer arrives later as one or more \`<remind-answer source="subconscious" agent="remind" replyId="…" moreComing="true|false">\` messages in your context. Keep working — do not poll or wait, and do not re-ask the same question.
114
- - Treat a message with \`moreComing="true"\` as partial; the reply is complete only when \`moreComing="false"\` arrives. Fold the answer into your work and cite it as remembered context rather than as something you verified yourself.`);
115
- sections.push(lines.join("\n"));
116
- }
117
- }
118
88
  const taskTools = [];
119
89
  const canUpdateTask = !denied.has("task_update");
120
90
  const canCompleteTask = !denied.has("task_complete");