@botbotgo/agent-harness 0.0.309 → 0.0.311

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 (195) hide show
  1. package/README.md +14 -0
  2. package/README.zh.md +14 -0
  3. package/dist/acp.d.ts +1 -116
  4. package/dist/acp.js +1 -310
  5. package/dist/api.d.ts +1 -1
  6. package/dist/api.js +1 -1
  7. package/dist/cli/chat-interactive.d.ts +24 -0
  8. package/dist/cli/chat-interactive.js +244 -0
  9. package/dist/cli/chat-rendering.d.ts +9 -0
  10. package/dist/cli/chat-rendering.js +102 -0
  11. package/dist/cli/chat-stream.d.ts +23 -0
  12. package/dist/cli/chat-stream.js +330 -0
  13. package/dist/cli/chat-ui.d.ts +20 -0
  14. package/dist/cli/chat-ui.js +198 -0
  15. package/dist/cli/chat-workspace.d.ts +15 -0
  16. package/dist/cli/chat-workspace.js +205 -0
  17. package/dist/cli/main.d.ts +52 -0
  18. package/dist/cli/main.js +323 -0
  19. package/dist/cli/managed-service-commands.d.ts +23 -0
  20. package/dist/cli/managed-service-commands.js +63 -0
  21. package/dist/cli/managed-service.d.ts +27 -0
  22. package/dist/cli/managed-service.js +61 -0
  23. package/dist/cli/options-init-chat.d.ts +16 -0
  24. package/dist/cli/options-init-chat.js +108 -0
  25. package/dist/cli/options-runtime.d.ts +27 -0
  26. package/dist/cli/options-runtime.js +158 -0
  27. package/dist/cli/options-serve.d.ts +24 -0
  28. package/dist/cli/options-serve.js +166 -0
  29. package/dist/cli/options.d.ts +5 -0
  30. package/dist/cli/options.js +47 -0
  31. package/dist/cli/process-guards.d.ts +14 -0
  32. package/dist/cli/process-guards.js +139 -0
  33. package/dist/cli/request-tree.d.ts +12 -0
  34. package/dist/cli/request-tree.js +296 -0
  35. package/dist/cli/runtime-commands.d.ts +15 -0
  36. package/dist/cli/runtime-commands.js +247 -0
  37. package/dist/cli/runtime-output.d.ts +5 -0
  38. package/dist/cli/runtime-output.js +124 -0
  39. package/dist/cli/server-commands.d.ts +36 -0
  40. package/dist/cli/server-commands.js +250 -0
  41. package/dist/cli/workspace.d.ts +6 -0
  42. package/dist/cli/workspace.js +71 -0
  43. package/dist/cli.d.ts +1 -77
  44. package/dist/cli.js +2 -3023
  45. package/dist/client/acp.d.ts +1 -50
  46. package/dist/client/acp.js +1 -219
  47. package/dist/client/in-process.d.ts +5 -5
  48. package/dist/client/index.d.ts +2 -2
  49. package/dist/client/index.js +1 -1
  50. package/dist/contracts/runtime-evaluation.d.ts +103 -0
  51. package/dist/contracts/runtime-evaluation.js +1 -0
  52. package/dist/contracts/runtime-memory.d.ts +162 -0
  53. package/dist/contracts/runtime-memory.js +1 -0
  54. package/dist/contracts/runtime-observability.d.ts +248 -0
  55. package/dist/contracts/runtime-observability.js +1 -0
  56. package/dist/contracts/runtime-requests.d.ts +342 -0
  57. package/dist/contracts/runtime-requests.js +1 -0
  58. package/dist/contracts/runtime-scheduling.d.ts +146 -0
  59. package/dist/contracts/runtime-scheduling.js +1 -0
  60. package/dist/contracts/runtime.d.ts +5 -1042
  61. package/dist/contracts/runtime.js +27 -1
  62. package/dist/flow/build-flow-graph.js +4 -875
  63. package/dist/flow/flow-graph-normalization.d.ts +56 -0
  64. package/dist/flow/flow-graph-normalization.js +214 -0
  65. package/dist/flow/flow-graph-runtime.d.ts +8 -0
  66. package/dist/flow/flow-graph-runtime.js +107 -0
  67. package/dist/flow/flow-graph-upstream.d.ts +18 -0
  68. package/dist/flow/flow-graph-upstream.js +498 -0
  69. package/dist/flow/types.d.ts +1 -1
  70. package/dist/index.d.ts +3 -3
  71. package/dist/index.js +1 -1
  72. package/dist/init-project.d.ts +1 -12
  73. package/dist/init-project.js +1 -651
  74. package/dist/{procedural → knowledge/procedural}/manager.d.ts +3 -3
  75. package/dist/{procedural → knowledge/procedural}/manager.js +6 -6
  76. package/dist/mcp.d.ts +2 -76
  77. package/dist/mcp.js +2 -428
  78. package/dist/package-version.d.ts +1 -1
  79. package/dist/package-version.js +1 -1
  80. package/dist/persistence/file-store.js +1 -1
  81. package/dist/persistence/sqlite-runtime.d.ts +19 -0
  82. package/dist/persistence/sqlite-runtime.js +86 -0
  83. package/dist/persistence/sqlite-store.js +11 -99
  84. package/dist/{request-events.d.ts → projections/request-events.d.ts} +1 -1
  85. package/dist/{upstream-events.js → projections/upstream-events.js} +1 -1
  86. package/dist/protocol/a2a/http-discovery.d.ts +39 -0
  87. package/dist/protocol/a2a/http-discovery.js +178 -0
  88. package/dist/protocol/a2a/http-rpc.d.ts +28 -0
  89. package/dist/protocol/a2a/http-rpc.js +623 -0
  90. package/dist/protocol/a2a/http.d.ts +72 -1
  91. package/dist/protocol/a2a/http.js +14 -1124
  92. package/dist/protocol/a2a/task-state.d.ts +29 -0
  93. package/dist/protocol/a2a/task-state.js +317 -0
  94. package/dist/protocol/acp/client.js +1 -1
  95. package/dist/protocol/acp/harness-client.d.ts +50 -0
  96. package/dist/protocol/acp/harness-client.js +219 -0
  97. package/dist/protocol/acp/server.d.ts +116 -0
  98. package/dist/protocol/acp/server.js +310 -0
  99. package/dist/protocol/ag-ui/http.js +1 -1
  100. package/dist/protocol/mcp/server.d.ts +76 -0
  101. package/dist/protocol/mcp/server.js +428 -0
  102. package/dist/resource/backend/workspace-scoped-backend.d.ts +40 -0
  103. package/dist/resource/backend/workspace-scoped-backend.js +296 -0
  104. package/dist/resource/mcp/tool-support.d.ts +35 -0
  105. package/dist/resource/mcp/tool-support.js +296 -0
  106. package/dist/resource/mcp-tool-support.d.ts +2 -35
  107. package/dist/resource/mcp-tool-support.js +2 -296
  108. package/dist/resource/providers/resource-provider.d.ts +22 -0
  109. package/dist/resource/providers/resource-provider.js +215 -0
  110. package/dist/resource/resource-impl.d.ts +3 -33
  111. package/dist/resource/resource-impl.js +2 -808
  112. package/dist/resource/resource-types.d.ts +33 -0
  113. package/dist/resource/resource-types.js +1 -0
  114. package/dist/resource/tools/function-tool-resolver.d.ts +2 -0
  115. package/dist/resource/tools/function-tool-resolver.js +306 -0
  116. package/dist/runtime/adapter/middleware-assembly.js +1 -1
  117. package/dist/runtime/adapter/model/invocation-request.js +2 -2
  118. package/dist/runtime/adapter/model/message-assembly.js +1 -1
  119. package/dist/runtime/agent-runtime-adapter.d.ts +3 -63
  120. package/dist/runtime/agent-runtime-adapter.js +7 -235
  121. package/dist/runtime/agent-runtime-assembly.d.ts +67 -0
  122. package/dist/runtime/agent-runtime-assembly.js +211 -0
  123. package/dist/runtime/harness/background-runtime.d.ts +1 -1
  124. package/dist/runtime/harness/events/event-sink.js +1 -1
  125. package/dist/runtime/harness/events/runtime-event-operations.d.ts +1 -1
  126. package/dist/runtime/harness/events/streaming.js +1 -1
  127. package/dist/runtime/harness/public-shapes.d.ts +43 -0
  128. package/dist/runtime/harness/public-shapes.js +186 -0
  129. package/dist/runtime/harness/run/inspection.js +2 -2
  130. package/dist/runtime/harness/run/resources.js +1 -1
  131. package/dist/runtime/harness/run/surface-semantics.js +1 -1
  132. package/dist/runtime/harness/system/inventory.d.ts +1 -1
  133. package/dist/runtime/harness/system/inventory.js +2 -2
  134. package/dist/runtime/harness/system/policy-engine.js +1 -1
  135. package/dist/runtime/harness/system/runtime-memory-manager.js +1 -1
  136. package/dist/runtime/harness/system/skill-requirements.d.ts +1 -1
  137. package/dist/runtime/harness/system/skill-requirements.js +1 -1
  138. package/dist/runtime/harness.d.ts +2 -2
  139. package/dist/runtime/harness.js +7 -191
  140. package/dist/runtime/maintenance/checkpoint-maintenance.js +1 -1
  141. package/dist/runtime/maintenance/runtime-record-maintenance.js +1 -1
  142. package/dist/runtime/parsing/output-content.d.ts +11 -0
  143. package/dist/runtime/parsing/output-content.js +442 -0
  144. package/dist/runtime/parsing/output-parsing.d.ts +3 -29
  145. package/dist/runtime/parsing/output-parsing.js +3 -806
  146. package/dist/runtime/parsing/output-recovery.d.ts +14 -0
  147. package/dist/runtime/parsing/output-recovery.js +288 -0
  148. package/dist/runtime/parsing/output-tool-args.d.ts +4 -0
  149. package/dist/runtime/parsing/output-tool-args.js +120 -0
  150. package/dist/runtime/support/runtime-factories.js +1 -1
  151. package/dist/scaffold/init-project.d.ts +12 -0
  152. package/dist/scaffold/init-project.js +651 -0
  153. package/dist/{extensions.d.ts → tooling/extensions.d.ts} +1 -1
  154. package/dist/{extensions.js → tooling/extensions.js} +3 -3
  155. package/dist/{tool-modules.d.ts → tooling/module-loader.d.ts} +1 -1
  156. package/dist/{tool-modules.js → tooling/module-loader.js} +2 -2
  157. package/dist/workspace/agent-binding-compiler.js +2 -2
  158. package/dist/workspace/compile.js +2 -2
  159. package/dist/workspace/object-loader-paths.d.ts +11 -0
  160. package/dist/workspace/object-loader-paths.js +75 -0
  161. package/dist/workspace/object-loader-readers.d.ts +21 -0
  162. package/dist/workspace/object-loader-readers.js +187 -0
  163. package/dist/workspace/object-loader.d.ts +0 -1
  164. package/dist/workspace/object-loader.js +6 -260
  165. package/dist/workspace/resource-compilers.js +1 -1
  166. package/dist/workspace/support/discovery.js +1 -1
  167. package/package.json +1 -1
  168. package/dist/runtime/adapter/index.d.ts +0 -13
  169. package/dist/runtime/adapter/index.js +0 -13
  170. package/dist/runtime/harness/index.d.ts +0 -19
  171. package/dist/runtime/harness/index.js +0 -19
  172. package/dist/runtime/maintenance/index.d.ts +0 -4
  173. package/dist/runtime/maintenance/index.js +0 -4
  174. package/dist/runtime/parsing/index.d.ts +0 -2
  175. package/dist/runtime/parsing/index.js +0 -2
  176. package/dist/runtime/support/index.d.ts +0 -4
  177. package/dist/runtime/support/index.js +0 -4
  178. package/dist/workspace/support/index.d.ts +0 -2
  179. package/dist/workspace/support/index.js +0 -2
  180. /package/dist/{procedural → knowledge/procedural}/config.d.ts +0 -0
  181. /package/dist/{procedural → knowledge/procedural}/config.js +0 -0
  182. /package/dist/{procedural → knowledge/procedural}/index.d.ts +0 -0
  183. /package/dist/{procedural → knowledge/procedural}/index.js +0 -0
  184. /package/dist/{presentation.d.ts → projections/presentation.d.ts} +0 -0
  185. /package/dist/{presentation.js → projections/presentation.js} +0 -0
  186. /package/dist/{request-events.js → projections/request-events.js} +0 -0
  187. /package/dist/{upstream-events.d.ts → projections/upstream-events.d.ts} +0 -0
  188. /package/dist/runtime/{support → env}/runtime-env.d.ts +0 -0
  189. /package/dist/runtime/{support → env}/runtime-env.js +0 -0
  190. /package/dist/runtime/{support → layout}/runtime-layout.d.ts +0 -0
  191. /package/dist/runtime/{support → layout}/runtime-layout.js +0 -0
  192. /package/dist/runtime/{support → prompts}/runtime-prompts.d.ts +0 -0
  193. /package/dist/runtime/{support → prompts}/runtime-prompts.js +0 -0
  194. /package/dist/runtime/{support → skills}/skill-metadata.d.ts +0 -0
  195. /package/dist/runtime/{support → skills}/skill-metadata.js +0 -0
@@ -0,0 +1,651 @@
1
+ import path from "node:path";
2
+ import { writeFile } from "node:fs/promises";
3
+ import { AGENT_HARNESS_VERSION } from "../package-version.js";
4
+ import { readBundledText, renderBundledTemplate } from "../utils/bundled-text.js";
5
+ import { ensureDir, fileExists } from "../utils/fs.js";
6
+ function toProjectSlug(projectName) {
7
+ const normalized = projectName
8
+ .trim()
9
+ .toLowerCase()
10
+ .replace(/[^a-z0-9]+/g, "-")
11
+ .replace(/^-+|-+$/g, "");
12
+ return normalized || "agent-harness-app";
13
+ }
14
+ function toDisplayName(projectName) {
15
+ return projectName
16
+ .trim()
17
+ .split(/[-_\s]+/)
18
+ .filter(Boolean)
19
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
20
+ .join(" ");
21
+ }
22
+ function resolveOptions(options = {}) {
23
+ return {
24
+ template: options.template ?? "deep-research",
25
+ provider: options.provider?.trim() || "openai",
26
+ model: options.model?.trim() || "gpt-4o-mini",
27
+ withWebSearch: options.withWebSearch ?? true,
28
+ };
29
+ }
30
+ function renderPackageJson(projectSlug, template) {
31
+ return `${JSON.stringify({
32
+ name: projectSlug,
33
+ version: "0.0.1",
34
+ private: true,
35
+ type: "module",
36
+ description: `Starter ${template} application generated by agent-harness init.`,
37
+ scripts: {
38
+ start: "node ./src/run.mjs",
39
+ },
40
+ dependencies: {
41
+ "@botbotgo/agent-harness": `^${AGENT_HARNESS_VERSION}`,
42
+ },
43
+ }, null, 2)}\n`;
44
+ }
45
+ function renderReadme(displayName, projectSlug, options) {
46
+ const webSearchLine = options.withWebSearch
47
+ ? `- ${options.provider} native web search enabled through \`config/catalogs/tools.yaml\``
48
+ : "- no provider-native web search by default";
49
+ const providerEnvLine = options.provider === "openai" ? "export OPENAI_API_KEY=your_key_here\n" : "";
50
+ const templateLine = options.template === "deep-research"
51
+ ? "- a host research agent plus an analyst subagent"
52
+ : "- a single host research agent for direct iteration";
53
+ return `# ${displayName}
54
+
55
+ This project was scaffolded with \`agent-harness init ${projectSlug}\`.
56
+
57
+ It is a minimal ${options.template} workspace with:
58
+
59
+ ${templateLine}
60
+ ${webSearchLine}
61
+ - one host agent that already carries the default behavior skills for inspection, safe edits, approvals, and clean completion
62
+
63
+ ## Run
64
+
65
+ \`\`\`bash
66
+ npm install
67
+ ${providerEnvLine}npm run start -- "Research the latest model serving stack for agent products and summarize the tradeoffs."
68
+ \`\`\`
69
+
70
+ ## Fast first prompts
71
+
72
+ - \`Inspect this workspace and explain the main entry points.\`
73
+ - \`Review this project structure before making any edits.\`
74
+ - \`Update README.md to make the setup steps clearer.\`
75
+ - \`Find the likeliest config issue in this workspace and propose the smallest fix.\`
76
+
77
+ ## Structure
78
+
79
+ - \`src/run.mjs\`: minimal launcher
80
+ - \`config/\`: workspace runtime and agent topology
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
83
+ - \`resources/\`: place local \`tool({...})\` tools and skills here as your product grows
84
+
85
+ ## Customize
86
+
87
+ - change \`config/models.yaml\` to switch models or providers
88
+ - keep \`config/runtime/runtime-memory.yaml\` for runtime-owned durable memory defaults
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
91
+ - add local \`tool({...})\` tools under \`resources/tools/\`
92
+ - add product-specific skills under \`resources/skills/\`
93
+ - edit the prompt files in \`config/prompts/\` to turn this into your own product
94
+ `;
95
+ }
96
+ function renderGitignore() {
97
+ return `node_modules
98
+ .agent
99
+ `;
100
+ }
101
+ function renderWorkspaceYaml() {
102
+ return `apiVersion: agent-harness/v1alpha1
103
+ kind: Runtime
104
+ metadata:
105
+ name: default
106
+ spec:
107
+ applicationRoot: .
108
+ dataRoot: ./.botbotgo
109
+ profile: default
110
+ `;
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
+ }
126
+ function renderAgentContext(options) {
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
+ });
132
+ }
133
+ function renderModelsYaml(options) {
134
+ return `apiVersion: agent-harness/v1alpha1
135
+ kind: Models
136
+ spec:
137
+ - name: default
138
+ kind: Model
139
+ provider: ${options.provider}
140
+ model: ${options.model}
141
+ temperature: 0.2
142
+ `;
143
+ }
144
+ function renderBackendsYaml() {
145
+ return `apiVersion: agent-harness/v1alpha1
146
+ kind: Backends
147
+ spec:
148
+ - kind: Backend
149
+ name: default
150
+ description: Default DeepAgent backend preset for generated research apps.
151
+ backendKind: CompositeBackend
152
+ state:
153
+ kind: VfsSandbox
154
+ timeout: 600
155
+ routes:
156
+ /memories/:
157
+ kind: StoreBackend
158
+ `;
159
+ }
160
+ function renderRuntimeMemoryYaml(projectSlug) {
161
+ return `apiVersion: agent-harness/v1alpha1
162
+ kind: RuntimeMemory
163
+ metadata:
164
+ name: default
165
+ spec:
166
+ enabled: true
167
+ store:
168
+ kind: SqliteStore
169
+ path: knowledge/knowledge.sqlite
170
+ namespaces:
171
+ users: memories/users/{userId}
172
+ projects: memories/projects/{projectId}
173
+ sessions: memories/sessions/{sessionId}
174
+ agents: memories/agents/{agentId}
175
+ workspaces: memories/workspaces/{workspaceId}
176
+ retrieval:
177
+ defaultTopK: 5
178
+ maxPromptMemories: 8
179
+ writePolicy:
180
+ mode: selective
181
+ allow:
182
+ - user_preferences
183
+ - project_facts
184
+ - confirmed_decisions
185
+ - reusable_summaries
186
+ deny:
187
+ - scratchpad
188
+ - transient_reasoning
189
+ - intermediate_results
190
+ ingestion:
191
+ backgroundConsolidation: true
192
+ writeOnApprovalResolution: false
193
+ writeOnRequestCompletion: false
194
+ formation:
195
+ hotPath:
196
+ enabled: true
197
+ manager:
198
+ enabled: true
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}}
232
+ maxContextRecords: 12
233
+ background:
234
+ enabled: true
235
+ scopes:
236
+ - user
237
+ - project
238
+ - workspace
239
+ stateStorePath: knowledge/formation-state.json
240
+ maxMessagesPerRequest: 40
241
+ writeOnApprovalResolution: true
242
+ writeOnRequestCompletion: true
243
+ sessionMemorySync:
244
+ enabled: false
245
+ mem0:
246
+ enabled: false
247
+ apiKeyEnv: MEM0_API_KEY
248
+ appId: ${projectSlug}
249
+ stateStorePath: knowledge/mem0-sync-state.json
250
+ maxMessagesPerRequest: 200
251
+ `;
252
+ }
253
+ function renderKnowledgeRuntimeYaml(projectSlug) {
254
+ return `apiVersion: agent-harness/v1alpha1
255
+ kind: KnowledgeRuntime
256
+ metadata:
257
+ name: default
258
+ spec:
259
+ enabled: true
260
+ store:
261
+ kind: SqliteStore
262
+ path: knowledge/knowledge.sqlite
263
+ namespaces:
264
+ users: memories/users/{userId}
265
+ projects: memories/projects/{projectId}
266
+ sessions: memories/sessions/{sessionId}
267
+ agents: memories/agents/{agentId}
268
+ workspaces: memories/workspaces/{workspaceId}
269
+ retrieval:
270
+ defaultTopK: 5
271
+ maxPromptMemories: 8
272
+ formation:
273
+ hotPath:
274
+ enabled: true
275
+ manager:
276
+ enabled: true
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}}
310
+ maxContextRecords: 12
311
+ background:
312
+ enabled: true
313
+ scopes:
314
+ - user
315
+ - project
316
+ - workspace
317
+ stateStorePath: knowledge/formation-state.json
318
+ maxMessagesPerRequest: 40
319
+ writeOnApprovalResolution: true
320
+ writeOnRequestCompletion: true
321
+ mem0:
322
+ enabled: false
323
+ apiKeyEnv: MEM0_API_KEY
324
+ appId: ${projectSlug}
325
+ stateStorePath: knowledge/mem0-sync-state.json
326
+ maxMessagesPerRequest: 200
327
+ `;
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
+ }
395
+ function renderToolsYaml(options) {
396
+ if (!options.withWebSearch) {
397
+ return `apiVersion: agent-harness/v1alpha1
398
+ kind: ToolSets
399
+ spec: []
400
+ `;
401
+ }
402
+ return `apiVersion: agent-harness/v1alpha1
403
+ kind: ToolSets
404
+ spec:
405
+ - name: web-search
406
+ type: provider
407
+ description: ${options.provider} web search tool for current research.
408
+ providerTool:
409
+ provider: ${options.provider}
410
+ tool: webSearch
411
+ args:
412
+ searchContextSize: medium
413
+ `;
414
+ }
415
+ function renderResearchAgentYaml(options) {
416
+ const toolsBlock = options.withWebSearch ? " tools:\n - web-search\n" : " tools: []\n";
417
+ const subagentsBlock = options.template === "deep-research" ? " subagents:\n - research-analyst\n" : " subagents: []\n";
418
+ return `apiVersion: agent-harness/v1alpha1
419
+ kind: Agent
420
+ metadata:
421
+ name: research
422
+ description: Host-facing research agent for investigating and synthesizing answers.
423
+ spec:
424
+ runtime:
425
+ runtimeMemory: default
426
+ proceduralMemory: default
427
+ backend: deepagent
428
+ modelRef: model/default
429
+ ${toolsBlock} skills:
430
+ - workspace-inspection
431
+ - safe-editing
432
+ - delegation-discipline
433
+ - approval-execution-policy
434
+ - completion-discipline
435
+ - deep-research
436
+ ${subagentsBlock} config:
437
+ backend: default
438
+ systemPrompt:
439
+ path: ../prompts/research-system.md
440
+ `;
441
+ }
442
+ function renderResearchAnalystYaml(options) {
443
+ const toolsBlock = options.withWebSearch ? " tools:\n - web-search\n" : " tools: []\n";
444
+ return `apiVersion: agent-harness/v1alpha1
445
+ kind: Agent
446
+ metadata:
447
+ name: research-analyst
448
+ description: Analyst subagent for source gathering, comparison, and evidence extraction.
449
+ spec:
450
+ runtime:
451
+ runtimeMemory: default
452
+ proceduralMemory: default
453
+ backend: deepagent
454
+ modelRef: model/default
455
+ ${toolsBlock} skills:
456
+ - workspace-inspection
457
+ - approval-execution-policy
458
+ - completion-discipline
459
+ - deep-research
460
+ config:
461
+ backend: default
462
+ systemPrompt:
463
+ path: ../prompts/research-analyst-system.md
464
+ `;
465
+ }
466
+ function renderResourcePackageJson(projectSlug) {
467
+ return `${JSON.stringify({
468
+ name: `${projectSlug}-resources`,
469
+ version: "0.0.1",
470
+ private: true,
471
+ type: "module",
472
+ description: "Resource package for a generated agent-harness project.",
473
+ }, null, 2)}\n`;
474
+ }
475
+ function renderSkill(options) {
476
+ const stepTwo = options.withWebSearch
477
+ ? "2. Use `web-search` to collect recent primary or otherwise authoritative sources."
478
+ : "2. Collect the key facts and assumptions needed to answer the request cleanly.";
479
+ return `---
480
+ name: deep-research
481
+ description: Default research workflow for product investigations that need careful synthesis.
482
+ ---
483
+
484
+ # Deep Research
485
+
486
+ Use this skill when the user wants comparisons, source-backed analysis, or a concise brief.
487
+
488
+ ## Workflow
489
+
490
+ 1. Clarify the target question and what "done" looks like.
491
+ ${stepTwo}
492
+ 3. Compare evidence instead of trusting a single source.
493
+ 4. Separate verified facts from inference.
494
+ 5. End with a concise synthesis, explicit caveats, and source links when available.
495
+ `;
496
+ }
497
+ function renderStarterSkill(name) {
498
+ if (name === "workspace-inspection") {
499
+ return `---
500
+ name: workspace-inspection
501
+ description: Inspect the current workspace before making claims or edits.
502
+ ---
503
+
504
+ # Workspace Inspection
505
+
506
+ 1. Start with lightweight discovery such as \`list_files\` or \`search_files\`.
507
+ 2. Read only the files needed to establish the relevant facts.
508
+ 3. Ground each conclusion in inspected workspace evidence instead of guesses.
509
+ 4. If the workspace does not contain the needed evidence, say that plainly before proposing a next step.
510
+ `;
511
+ }
512
+ if (name === "safe-editing") {
513
+ return `---
514
+ name: safe-editing
515
+ description: Make the smallest workspace change that solves the task, then verify it.
516
+ ---
517
+
518
+ # Safe Editing
519
+
520
+ 1. Identify the exact file or files before editing.
521
+ 2. Prefer bounded edits over large rewrites.
522
+ 3. Keep local conventions intact.
523
+ 4. Run the smallest reasonable verification step before you finish.
524
+ `;
525
+ }
526
+ if (name === "delegation-discipline") {
527
+ return `---
528
+ name: delegation-discipline
529
+ description: Delegate only when a subagent is clearly the best fit and the handoff can be bounded cleanly.
530
+ ---
531
+
532
+ # Delegation Discipline
533
+
534
+ 1. Keep the next critical-path step local unless a subagent is clearly better.
535
+ 2. Delegate only with one bounded ask and a clear purpose.
536
+ 3. Integrate delegated results into one final answer instead of forwarding raw output.
537
+ `;
538
+ }
539
+ if (name === "approval-execution-policy") {
540
+ return `---
541
+ name: approval-execution-policy
542
+ description: Treat side effects, command execution, and external actions as governed runtime decisions.
543
+ ---
544
+
545
+ # Approval And Execution Policy
546
+
547
+ 1. Inspect first when the safest next step is still unclear.
548
+ 2. Request approval before destructive, external, privileged, or ambiguous actions.
549
+ 3. After approval, execute only the action that was approved and report the outcome plainly.
550
+ `;
551
+ }
552
+ return `---
553
+ name: completion-discipline
554
+ description: Finish the task cleanly, verify what you can, and leave the user with a clear outcome.
555
+ ---
556
+
557
+ # Completion Discipline
558
+
559
+ 1. Check whether the request is actually complete.
560
+ 2. Verify the changed or inspected area with the smallest relevant check.
561
+ 3. Distinguish completed work, unverified areas, and blocked follow-up.
562
+ 4. Return a concise final answer that makes the outcome easy to trust.
563
+ `;
564
+ }
565
+ function renderRunScript(options) {
566
+ const defaultInput = options.withWebSearch
567
+ ? "Research the latest model and tooling trends for AI product teams. Return a concise brief with sources and caveats."
568
+ : "Analyze the current architecture direction for this product and return a concise brief with assumptions and caveats.";
569
+ return `import { fileURLToPath } from "node:url";
570
+ import { createAgentHarness, request, stop } from "@botbotgo/agent-harness";
571
+
572
+ const appRoot = fileURLToPath(new URL("..", import.meta.url));
573
+ const args = process.argv.slice(2);
574
+ let requestedAgentId = "research";
575
+ const inputParts = [];
576
+
577
+ for (let index = 0; index < args.length; index += 1) {
578
+ const arg = args[index];
579
+ if (arg === "--agent") {
580
+ const next = args[index + 1]?.trim();
581
+ if (next) {
582
+ requestedAgentId = next;
583
+ index += 1;
584
+ continue;
585
+ }
586
+ throw new Error("Missing value for --agent");
587
+ }
588
+ inputParts.push(arg);
589
+ }
590
+
591
+ const input = inputParts.join(" ").trim() ||
592
+ ${JSON.stringify(defaultInput)};
593
+
594
+ const runtime = await createAgentHarness(appRoot);
595
+
596
+ try {
597
+ const result = await request(runtime, {
598
+ agentId: requestedAgentId,
599
+ input,
600
+ });
601
+ process.stdout.write(\`\${result.output}\\n\`);
602
+ } finally {
603
+ await stop(runtime);
604
+ }
605
+ `;
606
+ }
607
+ export async function initProject(projectRoot, projectName, options = {}) {
608
+ if (await fileExists(projectRoot)) {
609
+ throw new Error(`Target path already exists: ${projectRoot}`);
610
+ }
611
+ const resolved = resolveOptions(options);
612
+ const projectSlug = toProjectSlug(projectName);
613
+ const displayName = toDisplayName(projectName) || "Agent Harness App";
614
+ const files = new Map([
615
+ ["package.json", renderPackageJson(projectSlug, resolved.template)],
616
+ [".gitignore", renderGitignore()],
617
+ ["README.md", renderReadme(displayName, projectSlug, resolved)],
618
+ ["src/run.mjs", renderRunScript(resolved)],
619
+ ["config/runtime/workspace.yaml", renderWorkspaceYaml()],
620
+ ["config/agent-context.md", renderAgentContext(resolved)],
621
+ ["config/prompts/research-system.md", readBundledText(resolveResearchHostPromptTemplate(resolved)).trim()],
622
+ ["config/models.yaml", renderModelsYaml(resolved)],
623
+ ["config/knowledge/knowledge-runtime.yaml", renderKnowledgeRuntimeYaml(projectSlug)],
624
+ ["config/knowledge/procedural-memory-runtime.yaml", renderProceduralMemoryRuntimeYaml()],
625
+ ["config/runtime/runtime-memory.yaml", renderRuntimeMemoryYaml(projectSlug)],
626
+ ["config/catalogs/backends.yaml", renderBackendsYaml()],
627
+ ["config/catalogs/tools.yaml", renderToolsYaml(resolved)],
628
+ ["config/agents/research.yaml", renderResearchAgentYaml(resolved)],
629
+ ["resources/package.json", renderResourcePackageJson(projectSlug)],
630
+ ["resources/skills/deep-research/SKILL.md", renderSkill(resolved)],
631
+ ["resources/skills/workspace-inspection/SKILL.md", renderStarterSkill("workspace-inspection")],
632
+ ["resources/skills/safe-editing/SKILL.md", renderStarterSkill("safe-editing")],
633
+ ["resources/skills/delegation-discipline/SKILL.md", renderStarterSkill("delegation-discipline")],
634
+ ["resources/skills/approval-execution-policy/SKILL.md", renderStarterSkill("approval-execution-policy")],
635
+ ["resources/skills/completion-discipline/SKILL.md", renderStarterSkill("completion-discipline")],
636
+ ]);
637
+ if (resolved.template === "deep-research") {
638
+ files.set("config/prompts/research-analyst-system.md", readBundledText(resolveResearchAnalystPromptTemplate(resolved)).trim());
639
+ files.set("config/agents/research-analyst.yaml", renderResearchAnalystYaml(resolved));
640
+ }
641
+ await ensureDir(projectRoot);
642
+ for (const [relativePath, content] of files) {
643
+ const filePath = path.join(projectRoot, relativePath);
644
+ await ensureDir(path.dirname(filePath));
645
+ await writeFile(filePath, content, "utf8");
646
+ }
647
+ return {
648
+ projectRoot,
649
+ projectSlug,
650
+ };
651
+ }
@@ -1,4 +1,4 @@
1
- import type { CompiledTool, EventSubscriber, ParsedToolObject, PolicyEvaluator, SkillInheritancePolicy, SkillPackagingConvention, SkillSourceResolver, ToolKindAdapter } from "./contracts/types.js";
1
+ import type { CompiledTool, EventSubscriber, ParsedToolObject, PolicyEvaluator, SkillInheritancePolicy, SkillPackagingConvention, SkillSourceResolver, ToolKindAdapter } from "../contracts/types.js";
2
2
  export declare function resolveToolTargets(tools: Map<string, ParsedToolObject>, ref: string): ParsedToolObject[];
3
3
  export declare function registerToolKind(adapter: ToolKindAdapter): void;
4
4
  export declare function getToolKindAdapter(type: string): ToolKindAdapter | undefined;
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
- import { defaultResourceSkillsRoot } from "./resource/resource.js";
3
- import { isExternalSourceLocator, resolveExternalResourcePath } from "./resource/sources.js";
4
- import { hasAgentSystemPrompt } from "./workspace/support/agent-capabilities.js";
2
+ import { defaultResourceSkillsRoot } from "../resource/resource.js";
3
+ import { isExternalSourceLocator, resolveExternalResourcePath } from "../resource/sources.js";
4
+ import { hasAgentSystemPrompt } from "../workspace/support/agent-capabilities.js";
5
5
  const toolKindAdapters = new Map();
6
6
  const skillSourceResolvers = new Map();
7
7
  const skillInheritancePolicies = new Map();
@@ -1,4 +1,4 @@
1
- import { normalizeToolSchema } from "./tools.js";
1
+ import { normalizeToolSchema } from "../tools.js";
2
2
  type ImportedToolModule = Record<string, unknown>;
3
3
  export type LoadedToolModule = {
4
4
  implementationName: string;
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
- import { readSkillMetadata } from "./runtime/support/skill-metadata.js";
3
- import { TOOL_DEFINITION_MARKER, buildToolJsonSchema, normalizeToolSchema } from "./tools.js";
2
+ import { readSkillMetadata } from "../runtime/skills/skill-metadata.js";
3
+ import { TOOL_DEFINITION_MARKER, buildToolJsonSchema, normalizeToolSchema } from "../tools.js";
4
4
  const TOOL_MODULE_EXTENSIONS = new Set([".mjs", ".js", ".cjs"]);
5
5
  function isToolDefinitionObject(value) {
6
6
  return typeof value === "object" && value !== null && value[TOOL_DEFINITION_MARKER] === true;