@botbotgo/agent-harness 0.0.298 → 0.0.300

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 (166) hide show
  1. package/README.md +78 -38
  2. package/README.zh.md +80 -31
  3. package/dist/acp.d.ts +3 -0
  4. package/dist/acp.js +10 -2
  5. package/dist/api.d.ts +14 -2
  6. package/dist/api.js +19 -3
  7. package/dist/cli.d.ts +18 -1
  8. package/dist/cli.js +1408 -319
  9. package/dist/client/acp.d.ts +9 -3
  10. package/dist/client/acp.js +55 -1
  11. package/dist/client/in-process.d.ts +5 -2
  12. package/dist/client/in-process.js +4 -6
  13. package/dist/client/index.d.ts +1 -1
  14. package/dist/client/types.d.ts +6 -5
  15. package/dist/config/agents/direct.yaml +7 -17
  16. package/dist/config/agents/orchestra.yaml +9 -65
  17. package/dist/config/catalogs/embedding-models.yaml +1 -1
  18. package/dist/config/catalogs/stores.yaml +1 -1
  19. package/dist/config/knowledge/knowledge-runtime.yaml +36 -2
  20. package/dist/config/knowledge/procedural-memory-runtime.yaml +78 -0
  21. package/dist/config/{catalogs/models.yaml → models.yaml} +2 -2
  22. package/dist/config/prompts/direct-system.md +16 -0
  23. package/dist/config/prompts/orchestra-system.md +62 -0
  24. package/dist/config/prompts/routing-system.md +14 -0
  25. package/dist/config/runtime/runtime-memory.yaml +39 -5
  26. package/dist/config/runtime/workspace.yaml +7 -16
  27. package/dist/contracts/runtime.d.ts +242 -1
  28. package/dist/contracts/workspace.d.ts +2 -0
  29. package/dist/index.d.ts +5 -3
  30. package/dist/index.js +2 -1
  31. package/dist/init-project.js +178 -33
  32. package/dist/knowledge/contracts.d.ts +5 -0
  33. package/dist/knowledge/module.d.ts +5 -0
  34. package/dist/knowledge/module.js +340 -18
  35. package/dist/package-version.d.ts +1 -1
  36. package/dist/package-version.js +1 -1
  37. package/dist/persistence/file-store.d.ts +5 -1
  38. package/dist/persistence/file-store.js +16 -0
  39. package/dist/persistence/sqlite-store.d.ts +4 -1
  40. package/dist/persistence/sqlite-store.js +88 -14
  41. package/dist/persistence/types.d.ts +4 -1
  42. package/dist/procedural/config.d.ts +63 -0
  43. package/dist/procedural/config.js +125 -0
  44. package/dist/procedural/index.d.ts +2 -0
  45. package/dist/procedural/index.js +1 -0
  46. package/dist/protocol/ag-ui/http.d.ts +3 -0
  47. package/dist/protocol/ag-ui/http.js +10 -0
  48. package/dist/request-events.d.ts +63 -0
  49. package/dist/request-events.js +400 -0
  50. package/dist/resource/isolation.js +11 -0
  51. package/dist/resource/resource-impl.d.ts +1 -0
  52. package/dist/resource/resource-impl.js +103 -12
  53. package/dist/resources/init-templates/agent-context/deep-research.md +5 -0
  54. package/dist/resources/init-templates/prompts/research-analyst-basic.md +1 -0
  55. package/dist/resources/init-templates/prompts/research-analyst-web-search.md +1 -0
  56. package/dist/resources/init-templates/prompts/research-host-deep-research-basic.md +1 -0
  57. package/dist/resources/init-templates/prompts/research-host-deep-research-web-search.md +1 -0
  58. package/dist/resources/init-templates/prompts/research-host-single-agent-basic.md +1 -0
  59. package/dist/resources/init-templates/prompts/research-host-single-agent-web-search.md +1 -0
  60. package/dist/resources/prompts/runtime/browser-capability-disclaimer-recovery.md +1 -0
  61. package/dist/resources/prompts/runtime/default-subagent.md +2 -0
  62. package/dist/resources/prompts/runtime/durable-memory-context.md +7 -0
  63. package/dist/resources/prompts/runtime/execution-with-tool-evidence-retry.md +1 -0
  64. package/dist/resources/prompts/runtime/execution-with-tool-evidence.md +1 -0
  65. package/dist/resources/prompts/runtime/invalid-tool-selection-recovery.md +1 -0
  66. package/dist/resources/prompts/runtime/memory-manager.md +31 -0
  67. package/dist/resources/prompts/runtime/memory-mutation-reconciliation.md +22 -0
  68. package/dist/resources/prompts/runtime/slash-command-skill.md +6 -0
  69. package/dist/resources/prompts/runtime/strict-tool-json.md +1 -0
  70. package/dist/resources/prompts/runtime/workspace-boundary-guidance.md +3 -0
  71. package/dist/resources/prompts/runtime/workspace-relative-path.md +1 -0
  72. package/dist/resources/prompts/runtime/write-todos-descriptive-content.md +1 -0
  73. package/dist/resources/prompts/runtime/write-todos-full-entry.md +1 -0
  74. package/dist/resources/prompts/runtime/write-todos-non-empty-initial-list.md +1 -0
  75. package/dist/resources/tools/_runtime_tool_helpers.mjs +152 -0
  76. package/dist/resources/tools/cancel_request.mjs +21 -0
  77. package/dist/resources/tools/fetch_url.mjs +23 -0
  78. package/dist/resources/tools/http_request.mjs +30 -0
  79. package/dist/resources/tools/inspect_approvals.mjs +27 -0
  80. package/dist/resources/tools/inspect_artifacts.mjs +21 -0
  81. package/dist/resources/tools/inspect_events.mjs +21 -0
  82. package/dist/resources/tools/inspect_requests.mjs +27 -0
  83. package/dist/resources/tools/inspect_sessions.mjs +21 -0
  84. package/dist/resources/tools/list_files.mjs +27 -0
  85. package/dist/resources/tools/read_artifact.mjs +22 -0
  86. package/dist/resources/tools/request_approval.mjs +27 -0
  87. package/dist/resources/tools/run_command.mjs +21 -0
  88. package/dist/resources/tools/schedule_task.mjs +76 -0
  89. package/dist/resources/tools/search_files.mjs +47 -0
  90. package/dist/resources/tools/send_message.mjs +23 -0
  91. package/dist/runtime/adapter/direct-builtin-utility.d.ts +1 -0
  92. package/dist/runtime/adapter/direct-builtin-utility.js +90 -0
  93. package/dist/runtime/adapter/flow/execution-context.d.ts +1 -1
  94. package/dist/runtime/adapter/flow/execution-context.js +1 -1
  95. package/dist/runtime/adapter/flow/invocation-flow.d.ts +1 -0
  96. package/dist/runtime/adapter/flow/invocation-flow.js +9 -1
  97. package/dist/runtime/adapter/flow/invoke-runtime.d.ts +1 -1
  98. package/dist/runtime/adapter/flow/stream-runtime.d.ts +5 -1
  99. package/dist/runtime/adapter/flow/stream-runtime.js +556 -35
  100. package/dist/runtime/adapter/invocation-result.js +3 -2
  101. package/dist/runtime/adapter/local-tool-invocation.d.ts +1 -1
  102. package/dist/runtime/adapter/local-tool-invocation.js +28 -4
  103. package/dist/runtime/adapter/middleware-assembly.js +3 -1
  104. package/dist/runtime/adapter/model/invocation-request.d.ts +4 -1
  105. package/dist/runtime/adapter/model/invocation-request.js +138 -16
  106. package/dist/runtime/adapter/model/message-assembly.js +2 -6
  107. package/dist/runtime/adapter/model/model-providers.js +103 -5
  108. package/dist/runtime/adapter/resilience.js +17 -2
  109. package/dist/runtime/adapter/runtime-adapter-support.d.ts +11 -7
  110. package/dist/runtime/adapter/runtime-adapter-support.js +39 -5
  111. package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +63 -1
  112. package/dist/runtime/adapter/tool/builtin-middleware-tools.js +193 -21
  113. package/dist/runtime/adapter/tool/tool-arguments.d.ts +3 -1
  114. package/dist/runtime/adapter/tool/tool-arguments.js +52 -17
  115. package/dist/runtime/adapter/tool-resolution.d.ts +1 -0
  116. package/dist/runtime/adapter/tool-resolution.js +4 -2
  117. package/dist/runtime/agent-runtime-adapter.d.ts +27 -0
  118. package/dist/runtime/agent-runtime-adapter.js +163 -11
  119. package/dist/runtime/harness/events/event-bus.d.ts +1 -0
  120. package/dist/runtime/harness/events/event-bus.js +3 -0
  121. package/dist/runtime/harness/events/event-sink.d.ts +3 -0
  122. package/dist/runtime/harness/events/event-sink.js +16 -7
  123. package/dist/runtime/harness/events/streaming.d.ts +18 -1
  124. package/dist/runtime/harness/events/streaming.js +23 -10
  125. package/dist/runtime/harness/run/inspection.js +26 -5
  126. package/dist/runtime/harness/run/stream-run.d.ts +13 -4
  127. package/dist/runtime/harness/run/stream-run.js +448 -4
  128. package/dist/runtime/harness/run/surface-semantics.js +7 -34
  129. package/dist/runtime/harness/system/runtime-memory-manager.d.ts +3 -0
  130. package/dist/runtime/harness/system/runtime-memory-manager.js +384 -69
  131. package/dist/runtime/harness/system/runtime-memory-policy.d.ts +20 -1
  132. package/dist/runtime/harness/system/runtime-memory-policy.js +65 -17
  133. package/dist/runtime/harness/system/runtime-memory-records.js +100 -0
  134. package/dist/runtime/harness/system/runtime-memory-sync.js +2 -2
  135. package/dist/runtime/harness/system/store.d.ts +4 -0
  136. package/dist/runtime/harness/system/store.js +153 -0
  137. package/dist/runtime/harness.d.ts +9 -1
  138. package/dist/runtime/harness.js +141 -7
  139. package/dist/runtime/maintenance/sqlite-checkpoint-saver.d.ts +8 -3
  140. package/dist/runtime/maintenance/sqlite-checkpoint-saver.js +152 -53
  141. package/dist/runtime/parsing/output-parsing.d.ts +10 -2
  142. package/dist/runtime/parsing/output-parsing.js +223 -16
  143. package/dist/runtime/parsing/stream-event-parsing.d.ts +7 -0
  144. package/dist/runtime/parsing/stream-event-parsing.js +51 -1
  145. package/dist/runtime/scheduling/system-schedule-manager.d.ts +41 -0
  146. package/dist/runtime/scheduling/system-schedule-manager.js +532 -0
  147. package/dist/runtime/support/embedding-models.d.ts +1 -1
  148. package/dist/runtime/support/embedding-models.js +5 -2
  149. package/dist/runtime/support/runtime-factories.js +1 -1
  150. package/dist/runtime/support/runtime-layout.d.ts +3 -0
  151. package/dist/runtime/support/runtime-layout.js +10 -1
  152. package/dist/runtime/support/runtime-prompts.d.ts +30 -0
  153. package/dist/runtime/support/runtime-prompts.js +55 -0
  154. package/dist/runtime/support/vector-stores.d.ts +1 -1
  155. package/dist/runtime/support/vector-stores.js +5 -2
  156. package/dist/upstream-events.js +8 -7
  157. package/dist/utils/bundled-text.d.ts +3 -0
  158. package/dist/utils/bundled-text.js +25 -0
  159. package/dist/utils/id.js +3 -2
  160. package/dist/workspace/agent-binding-compiler.js +53 -13
  161. package/dist/workspace/object-loader.js +64 -2
  162. package/dist/workspace/support/workspace-ref-utils.d.ts +2 -1
  163. package/dist/workspace/support/workspace-ref-utils.js +24 -5
  164. package/dist/workspace/yaml-object-reader.d.ts +1 -0
  165. package/dist/workspace/yaml-object-reader.js +95 -17
  166. package/package.json +11 -5
@@ -1,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { writeFile } from "node:fs/promises";
3
3
  import { AGENT_HARNESS_VERSION } from "./package-version.js";
4
+ import { readBundledText, renderBundledTemplate } from "./utils/bundled-text.js";
4
5
  import { ensureDir, fileExists } from "./utils/fs.js";
5
6
  function toProjectSlug(projectName) {
6
7
  const normalized = projectName
@@ -78,16 +79,18 @@ ${providerEnvLine}npm run start -- "Research the latest model serving stack for
78
79
  - \`src/run.mjs\`: minimal launcher
79
80
  - \`config/\`: workspace runtime and agent topology
80
81
  - \`config/knowledge/knowledge-runtime.yaml\`: optional standalone durable-knowledge policy mirror
82
+ - \`config/knowledge/procedural-memory-runtime.yaml\`: optional background procedural-memory runtime backed by ReMe-compatible provider config
81
83
  - \`resources/\`: place local \`tool({...})\` tools and skills here as your product grows
82
84
 
83
85
  ## Customize
84
86
 
85
- - change \`config/catalogs/models.yaml\` to switch models or providers
87
+ - change \`config/models.yaml\` to switch models or providers
86
88
  - keep \`config/runtime/runtime-memory.yaml\` for runtime-owned durable memory defaults
87
89
  - keep \`config/knowledge/knowledge-runtime.yaml\` when the same policy should also run in a standalone knowledge worker or server
90
+ - keep \`config/knowledge/procedural-memory-runtime.yaml\` when background experience learning should stay separate from the durable knowledge store
88
91
  - add local \`tool({...})\` tools under \`resources/tools/\`
89
92
  - add product-specific skills under \`resources/skills/\`
90
- - edit the prompts in \`config/agents/\` to turn this into your own product
93
+ - edit the prompt files in \`config/prompts/\` to turn this into your own product
91
94
  `;
92
95
  }
93
96
  function renderGitignore() {
@@ -102,20 +105,30 @@ metadata:
102
105
  name: default
103
106
  spec:
104
107
  applicationRoot: .
105
- dataRoot: ./.agent
108
+ dataRoot: ./.botbotgo
106
109
  profile: default
107
110
  `;
108
111
  }
112
+ function resolveResearchHostPromptTemplate(options) {
113
+ return options.template === "deep-research"
114
+ ? (options.withWebSearch
115
+ ? "init-templates/prompts/research-host-deep-research-web-search.md"
116
+ : "init-templates/prompts/research-host-deep-research-basic.md")
117
+ : (options.withWebSearch
118
+ ? "init-templates/prompts/research-host-single-agent-web-search.md"
119
+ : "init-templates/prompts/research-host-single-agent-basic.md");
120
+ }
121
+ function resolveResearchAnalystPromptTemplate(options) {
122
+ return options.withWebSearch
123
+ ? "init-templates/prompts/research-analyst-web-search.md"
124
+ : "init-templates/prompts/research-analyst-basic.md";
125
+ }
109
126
  function renderAgentContext(options) {
110
- const webSearchGuidance = options.withWebSearch
111
- ? "- Favor recent, attributable sources when the request depends on current information."
112
- : "- Favor clear internal reasoning and add search or local tools as your product needs evolve.";
113
- return `# Deep Research Workspace Context
114
-
115
- - This workspace is a starter for product-oriented research applications.
116
- ${webSearchGuidance}
117
- - Synthesize findings clearly, call out uncertainty, and separate facts from inference.
118
- `;
127
+ return renderBundledTemplate("init-templates/agent-context/deep-research.md", {
128
+ webSearchGuidance: options.withWebSearch
129
+ ? "- Favor recent, attributable sources when the request depends on current information."
130
+ : "- Favor clear internal reasoning and add search or local tools as your product needs evolve.",
131
+ });
119
132
  }
120
133
  function renderModelsYaml(options) {
121
134
  return `apiVersion: agent-harness/v1alpha1
@@ -153,7 +166,7 @@ spec:
153
166
  enabled: true
154
167
  store:
155
168
  kind: SqliteStore
156
- path: knowledge/records.sqlite
169
+ path: knowledge/knowledge.sqlite
157
170
  namespaces:
158
171
  users: memories/users/{userId}
159
172
  projects: memories/projects/{projectId}
@@ -176,25 +189,59 @@ spec:
176
189
  - intermediate_results
177
190
  ingestion:
178
191
  backgroundConsolidation: true
179
- writeOnApprovalResolution: true
180
- writeOnRequestCompletion: true
192
+ writeOnApprovalResolution: false
193
+ writeOnRequestCompletion: false
181
194
  formation:
182
195
  hotPath:
183
196
  enabled: true
184
197
  manager:
185
198
  enabled: true
186
- strategy: rules
199
+ strategy: model
200
+ prompt: |-
201
+ You are the runtime memory manager.
202
+ Decide whether a candidate should be stored as durable memory and refine it if appropriate.
203
+ Return JSON only.
204
+
205
+ Rules:
206
+ - Store only durable reusable knowledge. Reject transient chatter, scratchpad, or duplication without added value.
207
+ - Reject raw request/session summaries, source-specific page/news recaps, and generic "we learned how to use the tools/workflow" reflections unless they clearly contain reusable preferences, facts, decisions, or procedures.
208
+ - If transcript evidence shows the user explicitly asked the system to remember or follow a future instruction and the assistant confirmed that intent, store the durable instruction instead of rejecting it as a generic summary.
209
+ - Treat durable knowledge as generic mutable records with database-like operations over the same underlying knowledge item.
210
+ - One candidate may yield zero, one, or multiple durable knowledge items. Split it only when the input clearly contains multiple independently mutable knowledge points.
211
+ - When storing a knowledge item, always return a \`knowledgeMutation\` object with a stable \`identity\` and an \`operation\` of \`create\`, \`update\`, or \`delete\`.
212
+ - Keep \`knowledgeMutation.identity\` stable across revisions of the same knowledge point, even when the wording changes.
213
+ - Use \`create\` for a newly introduced knowledge item, \`update\` for a revised active state of an existing knowledge item, and \`delete\` when the candidate says an existing knowledge item should no longer remain active.
214
+ - If an existing relevant record already represents the same underlying knowledge item, reuse that record's \`knowledge_identity\` instead of inventing a new one.
215
+ - Do not invent a second identity just because the new statement negates, revokes, deletes, or replaces the old wording. That is usually the same knowledge item with a different mutation operation.
216
+ - The stored \`content\` must be canonical knowledge text, not an assistant acknowledgement such as "已记住" or "I will remember".
217
+ - You may optionally include \`operationalRule\` when the knowledge is naturally a rule, instruction, or recurring procedure. Treat it as structured metadata, not as the primary identity mechanism.
218
+ - Prefer semantic/episodic/procedural kinds only.
219
+ - Prefer scopes session/agent/workspace/user/project only.
220
+ - If the candidate should not be stored, return {"store": false, "reason": "..."}
221
+ - If the candidate maps to one durable item, you may return {"store": true, "content": "...", "summary": "...", "kind": "...", "scope": "...", "tags": ["..."], "confidence": 0.0, "knowledgeMutation": {"identity": "...", "operation": "create|update|delete"}, "operationalRule": {"trigger": "...", "action": "...", "target": "...", "effect": "apply|invalidate"}}
222
+ - If the candidate maps to multiple durable items, return {"store": true, "mutations": [{"content": "...", "summary": "...", "kind": "...", "scope": "...", "tags": ["..."], "confidence": 0.0, "knowledgeMutation": {"identity": "...", "operation": "create|update|delete"}, "operationalRule": {"trigger": "...", "action": "...", "target": "...", "effect": "apply|invalidate"}}]}
223
+
224
+ sessionId={{sessionId}}
225
+ requestId={{requestId}}
226
+
227
+ Candidate:
228
+ {{candidateJson}}
229
+
230
+ Existing relevant records:
231
+ {{existingRecords}}
187
232
  maxContextRecords: 12
188
233
  background:
189
234
  enabled: true
190
235
  scopes:
191
- - session
236
+ - user
237
+ - project
238
+ - workspace
192
239
  stateStorePath: knowledge/formation-state.json
193
240
  maxMessagesPerRequest: 40
194
241
  writeOnApprovalResolution: true
195
242
  writeOnRequestCompletion: true
196
243
  sessionMemorySync:
197
- enabled: true
244
+ enabled: false
198
245
  mem0:
199
246
  enabled: false
200
247
  apiKeyEnv: MEM0_API_KEY
@@ -212,7 +259,7 @@ spec:
212
259
  enabled: true
213
260
  store:
214
261
  kind: SqliteStore
215
- path: knowledge/records.sqlite
262
+ path: knowledge/knowledge.sqlite
216
263
  namespaces:
217
264
  users: memories/users/{userId}
218
265
  projects: memories/projects/{projectId}
@@ -227,12 +274,46 @@ spec:
227
274
  enabled: true
228
275
  manager:
229
276
  enabled: true
230
- strategy: rules
277
+ strategy: model
278
+ prompt: |-
279
+ You are the runtime memory manager.
280
+ Decide whether a candidate should be stored as durable memory and refine it if appropriate.
281
+ Return JSON only.
282
+
283
+ Rules:
284
+ - Store only durable reusable knowledge. Reject transient chatter, scratchpad, or duplication without added value.
285
+ - Reject raw request/session summaries, source-specific page/news recaps, and generic "we learned how to use the tools/workflow" reflections unless they clearly contain reusable preferences, facts, decisions, or procedures.
286
+ - If transcript evidence shows the user explicitly asked the system to remember or follow a future instruction and the assistant confirmed that intent, store the durable instruction instead of rejecting it as a generic summary.
287
+ - Treat durable knowledge as generic mutable records with database-like operations over the same underlying knowledge item.
288
+ - One candidate may yield zero, one, or multiple durable knowledge items. Split it only when the input clearly contains multiple independently mutable knowledge points.
289
+ - When storing a knowledge item, always return a \`knowledgeMutation\` object with a stable \`identity\` and an \`operation\` of \`create\`, \`update\`, or \`delete\`.
290
+ - Keep \`knowledgeMutation.identity\` stable across revisions of the same knowledge point, even when the wording changes.
291
+ - Use \`create\` for a newly introduced knowledge item, \`update\` for a revised active state of an existing knowledge item, and \`delete\` when the candidate says an existing knowledge item should no longer remain active.
292
+ - If an existing relevant record already represents the same underlying knowledge item, reuse that record's \`knowledge_identity\` instead of inventing a new one.
293
+ - Do not invent a second identity just because the new statement negates, revokes, deletes, or replaces the old wording. That is usually the same knowledge item with a different mutation operation.
294
+ - The stored \`content\` must be canonical knowledge text, not an assistant acknowledgement such as "已记住" or "I will remember".
295
+ - You may optionally include \`operationalRule\` when the knowledge is naturally a rule, instruction, or recurring procedure. Treat it as structured metadata, not as the primary identity mechanism.
296
+ - Prefer semantic/episodic/procedural kinds only.
297
+ - Prefer scopes session/agent/workspace/user/project only.
298
+ - If the candidate should not be stored, return {"store": false, "reason": "..."}
299
+ - If the candidate maps to one durable item, you may return {"store": true, "content": "...", "summary": "...", "kind": "...", "scope": "...", "tags": ["..."], "confidence": 0.0, "knowledgeMutation": {"identity": "...", "operation": "create|update|delete"}, "operationalRule": {"trigger": "...", "action": "...", "target": "...", "effect": "apply|invalidate"}}
300
+ - If the candidate maps to multiple durable items, return {"store": true, "mutations": [{"content": "...", "summary": "...", "kind": "...", "scope": "...", "tags": ["..."], "confidence": 0.0, "knowledgeMutation": {"identity": "...", "operation": "create|update|delete"}, "operationalRule": {"trigger": "...", "action": "...", "target": "...", "effect": "apply|invalidate"}}]}
301
+
302
+ sessionId={{sessionId}}
303
+ requestId={{requestId}}
304
+
305
+ Candidate:
306
+ {{candidateJson}}
307
+
308
+ Existing relevant records:
309
+ {{existingRecords}}
231
310
  maxContextRecords: 12
232
311
  background:
233
312
  enabled: true
234
313
  scopes:
235
- - session
314
+ - user
315
+ - project
316
+ - workspace
236
317
  stateStorePath: knowledge/formation-state.json
237
318
  maxMessagesPerRequest: 40
238
319
  writeOnApprovalResolution: true
@@ -245,6 +326,72 @@ spec:
245
326
  maxMessagesPerRequest: 200
246
327
  `;
247
328
  }
329
+ function renderProceduralMemoryRuntimeYaml() {
330
+ return `apiVersion: agent-harness/v1alpha1
331
+ kind: ProceduralMemoryRuntime
332
+ metadata:
333
+ name: default
334
+ spec:
335
+ enabled: true
336
+ provider:
337
+ kind: reme
338
+ mode:
339
+ backgroundOnly: true
340
+ trigger:
341
+ onRequestCompleted: true
342
+ onApprovalResolved: true
343
+ store:
344
+ kind: SqliteStore
345
+ path: knowledge/procedural-memory.sqlite
346
+ vectorStore:
347
+ kind: LibSQLVectorStore
348
+ url: file:knowledge/procedural-vectors.sqlite
349
+ table: procedural_memory
350
+ column: embedding
351
+ embeddingModel:
352
+ ref: embedding-model/default
353
+ extraction:
354
+ focus:
355
+ - coding_patterns
356
+ - debugging_lessons
357
+ - workflow_patterns
358
+ - failure_prevention
359
+ - reusable_procedures
360
+ maxMessagesPerRequest: 60
361
+ retrieval:
362
+ enabled: true
363
+ defaultTopK: 5
364
+ maxPromptItems: 4
365
+ state:
366
+ cursorPath: knowledge/procedural-memory-state.json
367
+ maintenance:
368
+ enabled: true
369
+ onWrite:
370
+ dedupeNearby: true
371
+ updateFrequency: true
372
+ schedule:
373
+ enabled: true
374
+ everyMinutes: 60
375
+ idle:
376
+ enabled: true
377
+ minIdleMinutes: 20
378
+ maxRunsPerIdleWindow: 1
379
+ tasks:
380
+ - dedupe
381
+ - merge_similar
382
+ - decay_stale
383
+ - prune_low_value
384
+ limits:
385
+ maxRecordsPerRun: 200
386
+ maxClustersPerRun: 50
387
+ decay:
388
+ enabled: true
389
+ maxAgeDays: 90
390
+ pruning:
391
+ minScore: 0.2
392
+ minFrequency: 2
393
+ `;
394
+ }
248
395
  function renderToolsYaml(options) {
249
396
  if (!options.withWebSearch) {
250
397
  return `apiVersion: agent-harness/v1alpha1
@@ -268,12 +415,6 @@ spec:
268
415
  function renderResearchAgentYaml(options) {
269
416
  const toolsBlock = options.withWebSearch ? " tools:\n - web-search\n" : " tools: []\n";
270
417
  const subagentsBlock = options.template === "deep-research" ? " subagents:\n - research-analyst\n" : " subagents: []\n";
271
- const prompt = options.withWebSearch
272
- ? "Break complex research requests into a clear plan, use web search when current information matters, and return a concise synthesis with sources and explicit uncertainty."
273
- : "Break complex research requests into a clear plan and return a concise synthesis with explicit assumptions and uncertainty.";
274
- const delegationLine = options.template === "deep-research"
275
- ? " Delegate detailed investigation to the analyst when useful."
276
- : "";
277
418
  return `apiVersion: agent-harness/v1alpha1
278
419
  kind: Agent
279
420
  metadata:
@@ -282,6 +423,7 @@ metadata:
282
423
  spec:
283
424
  runtime:
284
425
  runtimeMemory: default
426
+ proceduralMemory: default
285
427
  backend: deepagent
286
428
  modelRef: model/default
287
429
  ${toolsBlock} skills:
@@ -293,14 +435,12 @@ ${toolsBlock} skills:
293
435
  - deep-research
294
436
  ${subagentsBlock} config:
295
437
  backend: default
296
- systemPrompt: ${prompt}${delegationLine}
438
+ systemPrompt:
439
+ path: ../prompts/research-system.md
297
440
  `;
298
441
  }
299
442
  function renderResearchAnalystYaml(options) {
300
443
  const toolsBlock = options.withWebSearch ? " tools:\n - web-search\n" : " tools: []\n";
301
- const prompt = options.withWebSearch
302
- ? "Gather current sources, compare claims carefully, extract the most decision-relevant facts, and return clean notes the host agent can synthesize."
303
- : "Break down the problem, compare alternatives carefully, extract the most decision-relevant facts, and return clean notes the host agent can synthesize.";
304
444
  return `apiVersion: agent-harness/v1alpha1
305
445
  kind: Agent
306
446
  metadata:
@@ -309,6 +449,7 @@ metadata:
309
449
  spec:
310
450
  runtime:
311
451
  runtimeMemory: default
452
+ proceduralMemory: default
312
453
  backend: deepagent
313
454
  modelRef: model/default
314
455
  ${toolsBlock} skills:
@@ -318,7 +459,8 @@ ${toolsBlock} skills:
318
459
  - deep-research
319
460
  config:
320
461
  backend: default
321
- systemPrompt: ${prompt}
462
+ systemPrompt:
463
+ path: ../prompts/research-analyst-system.md
322
464
  `;
323
465
  }
324
466
  function renderResourcePackageJson(projectSlug) {
@@ -476,8 +618,10 @@ export async function initProject(projectRoot, projectName, options = {}) {
476
618
  ["src/run.mjs", renderRunScript(resolved)],
477
619
  ["config/runtime/workspace.yaml", renderWorkspaceYaml()],
478
620
  ["config/agent-context.md", renderAgentContext(resolved)],
479
- ["config/catalogs/models.yaml", renderModelsYaml(resolved)],
621
+ ["config/prompts/research-system.md", readBundledText(resolveResearchHostPromptTemplate(resolved)).trim()],
622
+ ["config/models.yaml", renderModelsYaml(resolved)],
480
623
  ["config/knowledge/knowledge-runtime.yaml", renderKnowledgeRuntimeYaml(projectSlug)],
624
+ ["config/knowledge/procedural-memory-runtime.yaml", renderProceduralMemoryRuntimeYaml()],
481
625
  ["config/runtime/runtime-memory.yaml", renderRuntimeMemoryYaml(projectSlug)],
482
626
  ["config/catalogs/backends.yaml", renderBackendsYaml()],
483
627
  ["config/catalogs/tools.yaml", renderToolsYaml(resolved)],
@@ -491,6 +635,7 @@ export async function initProject(projectRoot, projectName, options = {}) {
491
635
  ["resources/skills/completion-discipline/SKILL.md", renderStarterSkill("completion-discipline")],
492
636
  ]);
493
637
  if (resolved.template === "deep-research") {
638
+ files.set("config/prompts/research-analyst-system.md", readBundledText(resolveResearchAnalystPromptTemplate(resolved)).trim());
494
639
  files.set("config/agents/research-analyst.yaml", renderResearchAnalystYaml(resolved));
495
640
  }
496
641
  await ensureDir(projectRoot);
@@ -7,6 +7,7 @@ import type { Mem0SearchInput, Mem0SearchResult } from "../runtime/harness/syste
7
7
  export type KnowledgeMemorizeInput = {
8
8
  records: MemorizeInputRecord[];
9
9
  storeCandidateLog?: boolean;
10
+ forceStore?: boolean;
10
11
  };
11
12
  export type KnowledgeRecallInput = {
12
13
  query: string;
@@ -38,6 +39,10 @@ export type KnowledgeModuleDependencies = {
38
39
  export type KnowledgeModule = {
39
40
  memorize(input: KnowledgeMemorizeInput, context: KnowledgeRuntimeContext): Promise<MemorizeResult>;
40
41
  recall(input: KnowledgeRecallInput, context: KnowledgeRuntimeContext): Promise<RecallResult>;
42
+ buildPromptRecall(input: KnowledgeRecallInput, context: KnowledgeRuntimeContext): Promise<{
43
+ items: MemoryRecord[];
44
+ context?: string;
45
+ }>;
41
46
  buildPromptContext(input: KnowledgeRecallInput, context: KnowledgeRuntimeContext): Promise<string | undefined>;
42
47
  list(input: KnowledgeListInput, context: KnowledgeRuntimeContext): Promise<ListMemoriesResult>;
43
48
  update(input: UpdateMemoryInput, context: KnowledgeRuntimeContext): Promise<MemoryRecord>;
@@ -5,12 +5,17 @@ export declare class DefaultKnowledgeModule implements KnowledgeModule {
5
5
  constructor(deps: KnowledgeModuleDependencies);
6
6
  memorize(input: KnowledgeMemorizeInput, context: KnowledgeRuntimeContext): Promise<MemorizeResult>;
7
7
  recall(input: KnowledgeRecallInput, context: KnowledgeRuntimeContext): Promise<RecallResult>;
8
+ buildPromptRecall(input: KnowledgeRecallInput, context: KnowledgeRuntimeContext): Promise<{
9
+ items: MemoryRecord[];
10
+ context?: string;
11
+ }>;
8
12
  buildPromptContext(input: KnowledgeRecallInput, context: KnowledgeRuntimeContext): Promise<string | undefined>;
9
13
  list(input: KnowledgeListInput | undefined, context: KnowledgeRuntimeContext): Promise<ListMemoriesResult>;
10
14
  update(input: UpdateMemoryInput, context: KnowledgeRuntimeContext): Promise<MemoryRecord>;
11
15
  remove(input: RemoveMemoryInput, context: KnowledgeRuntimeContext): Promise<MemoryRecord>;
12
16
  memorizeCandidates(candidates: MemoryCandidate[], context: KnowledgeRuntimeContext, options: {
13
17
  storeCandidateLog: boolean;
18
+ forceStore?: boolean;
14
19
  }): Promise<MemorizeResult>;
15
20
  private refreshAfterWrite;
16
21
  private appendMemoryDigest;