dna-sdk 0.1.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 (240) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -0
  3. package/dist/adapters/embedding/onnx.d.ts +32 -0
  4. package/dist/adapters/embedding/onnx.js +51 -0
  5. package/dist/adapters/filesystem/cache.d.ts +16 -0
  6. package/dist/adapters/filesystem/cache.js +113 -0
  7. package/dist/adapters/filesystem/index.d.ts +2 -0
  8. package/dist/adapters/filesystem/index.js +2 -0
  9. package/dist/adapters/filesystem/source.d.ts +82 -0
  10. package/dist/adapters/filesystem/source.js +357 -0
  11. package/dist/adapters/postgres/index.d.ts +2 -0
  12. package/dist/adapters/postgres/index.js +2 -0
  13. package/dist/adapters/postgres/migrations.d.ts +14 -0
  14. package/dist/adapters/postgres/migrations.js +88 -0
  15. package/dist/adapters/postgres/source.d.ts +172 -0
  16. package/dist/adapters/postgres/source.js +569 -0
  17. package/dist/adapters/resolvers/github.d.ts +12 -0
  18. package/dist/adapters/resolvers/github.js +47 -0
  19. package/dist/adapters/resolvers/http.d.ts +22 -0
  20. package/dist/adapters/resolvers/http.js +145 -0
  21. package/dist/adapters/resolvers/index.d.ts +3 -0
  22. package/dist/adapters/resolvers/index.js +3 -0
  23. package/dist/adapters/resolvers/local.d.ts +24 -0
  24. package/dist/adapters/resolvers/local.js +132 -0
  25. package/dist/adapters/search/driver.d.ts +45 -0
  26. package/dist/adapters/search/driver.js +138 -0
  27. package/dist/adapters/search/migrations.d.ts +26 -0
  28. package/dist/adapters/search/migrations.js +58 -0
  29. package/dist/adapters/search/rrf.d.ts +23 -0
  30. package/dist/adapters/search/rrf.js +42 -0
  31. package/dist/adapters/search/sqlite-vec.d.ts +66 -0
  32. package/dist/adapters/search/sqlite-vec.js +294 -0
  33. package/dist/bootstrap.d.ts +45 -0
  34. package/dist/bootstrap.js +134 -0
  35. package/dist/extensions/agentskills/DOCS.md +18 -0
  36. package/dist/extensions/agentskills.d.ts +28 -0
  37. package/dist/extensions/agentskills.js +252 -0
  38. package/dist/extensions/agentsmd/DOCS.md +18 -0
  39. package/dist/extensions/agentsmd.d.ts +22 -0
  40. package/dist/extensions/agentsmd.js +170 -0
  41. package/dist/extensions/audit/kinds/audit-log.kind.yaml +148 -0
  42. package/dist/extensions/audit.d.ts +25 -0
  43. package/dist/extensions/audit.js +62 -0
  44. package/dist/extensions/automation/kinds/automation.kind.yaml +296 -0
  45. package/dist/extensions/automation/query.d.ts +49 -0
  46. package/dist/extensions/automation/query.js +77 -0
  47. package/dist/extensions/automation/write-guards.d.ts +59 -0
  48. package/dist/extensions/automation/write-guards.js +153 -0
  49. package/dist/extensions/automation.d.ts +41 -0
  50. package/dist/extensions/automation.js +54 -0
  51. package/dist/extensions/collab.d.ts +16 -0
  52. package/dist/extensions/collab.js +79 -0
  53. package/dist/extensions/doc/kinds/doc.kind.yaml +118 -0
  54. package/dist/extensions/doc.d.ts +25 -0
  55. package/dist/extensions/doc.js +10 -0
  56. package/dist/extensions/eval/kinds/eval-baseline.kind.yaml +65 -0
  57. package/dist/extensions/eval/kinds/eval-case.kind.yaml +140 -0
  58. package/dist/extensions/eval/kinds/eval-run.kind.yaml +134 -0
  59. package/dist/extensions/eval/kinds/eval-suite.kind.yaml +87 -0
  60. package/dist/extensions/eval.d.ts +24 -0
  61. package/dist/extensions/eval.js +31 -0
  62. package/dist/extensions/evidence/kinds/evidence.kind.yaml +92 -0
  63. package/dist/extensions/evidence.d.ts +17 -0
  64. package/dist/extensions/evidence.js +94 -0
  65. package/dist/extensions/federation.d.ts +22 -0
  66. package/dist/extensions/federation.js +173 -0
  67. package/dist/extensions/guardrails/DOCS.md +20 -0
  68. package/dist/extensions/guardrails.d.ts +31 -0
  69. package/dist/extensions/guardrails.js +228 -0
  70. package/dist/extensions/helix/DOCS-Actor.md +20 -0
  71. package/dist/extensions/helix/DOCS-Agent.md +20 -0
  72. package/dist/extensions/helix/DOCS-UseCase.md +20 -0
  73. package/dist/extensions/helix/layers.d.ts +12 -0
  74. package/dist/extensions/helix/layers.js +18 -0
  75. package/dist/extensions/helix/write-guards.d.ts +70 -0
  76. package/dist/extensions/helix/write-guards.js +172 -0
  77. package/dist/extensions/helix.d.ts +29 -0
  78. package/dist/extensions/helix.js +963 -0
  79. package/dist/extensions/helix_extras.d.ts +124 -0
  80. package/dist/extensions/helix_extras.js +328 -0
  81. package/dist/extensions/hooks.d.ts +31 -0
  82. package/dist/extensions/hooks.js +247 -0
  83. package/dist/extensions/kinddef/DOCS.md +24 -0
  84. package/dist/extensions/kinddef.d.ts +40 -0
  85. package/dist/extensions/kinddef.js +171 -0
  86. package/dist/extensions/lesson.d.ts +6 -0
  87. package/dist/extensions/lesson.js +194 -0
  88. package/dist/extensions/modelreg/kinds/model-profile.kind.yaml +155 -0
  89. package/dist/extensions/modelreg.d.ts +30 -0
  90. package/dist/extensions/modelreg.js +38 -0
  91. package/dist/extensions/recognizer.d.ts +34 -0
  92. package/dist/extensions/recognizer.js +272 -0
  93. package/dist/extensions/research.d.ts +32 -0
  94. package/dist/extensions/research.js +292 -0
  95. package/dist/extensions/safety.d.ts +33 -0
  96. package/dist/extensions/safety.js +230 -0
  97. package/dist/extensions/sdlc/kinds/adr.kind.yaml +136 -0
  98. package/dist/extensions/sdlc/kinds/archive-proposal.kind.yaml +107 -0
  99. package/dist/extensions/sdlc/kinds/changelog.kind.yaml +108 -0
  100. package/dist/extensions/sdlc/kinds/cognitive-policy.kind.yaml +470 -0
  101. package/dist/extensions/sdlc/kinds/forecast.kind.yaml +125 -0
  102. package/dist/extensions/sdlc/kinds/insight.kind.yaml +87 -0
  103. package/dist/extensions/sdlc/kinds/kaizen.kind.yaml +106 -0
  104. package/dist/extensions/sdlc/kinds/lesson-learned.kind.yaml +270 -0
  105. package/dist/extensions/sdlc/kinds/narrative.kind.yaml +189 -0
  106. package/dist/extensions/sdlc/kinds/pattern-insight.kind.yaml +204 -0
  107. package/dist/extensions/sdlc/kinds/postmortem.kind.yaml +168 -0
  108. package/dist/extensions/sdlc/kinds/pre-mortem.kind.yaml +145 -0
  109. package/dist/extensions/sdlc/kinds/prompt-template.kind.yaml +109 -0
  110. package/dist/extensions/sdlc/kinds/retrospective.kind.yaml +186 -0
  111. package/dist/extensions/sdlc/kinds/risk-register.kind.yaml +178 -0
  112. package/dist/extensions/sdlc/kinds/saved-view.kind.yaml +127 -0
  113. package/dist/extensions/sdlc/kinds/status-report.kind.yaml +129 -0
  114. package/dist/extensions/sdlc/kinds/synthesis-run.kind.yaml +279 -0
  115. package/dist/extensions/sdlc/kinds/synthesizer-state.kind.yaml +196 -0
  116. package/dist/extensions/sdlc/kinds/workflow-event.kind.yaml +195 -0
  117. package/dist/extensions/sdlc.d.ts +32 -0
  118. package/dist/extensions/sdlc.js +1318 -0
  119. package/dist/extensions/soulspec/DOCS.md +19 -0
  120. package/dist/extensions/soulspec.d.ts +22 -0
  121. package/dist/extensions/soulspec.js +287 -0
  122. package/dist/extensions/tenant.d.ts +6 -0
  123. package/dist/extensions/tenant.js +291 -0
  124. package/dist/extensions/testkit.d.ts +24 -0
  125. package/dist/extensions/testkit.js +211 -0
  126. package/dist/index.d.ts +80 -0
  127. package/dist/index.js +102 -0
  128. package/dist/kernel/_text.d.ts +28 -0
  129. package/dist/kernel/_text.js +42 -0
  130. package/dist/kernel/bundle-handle.d.ts +83 -0
  131. package/dist/kernel/bundle-handle.js +184 -0
  132. package/dist/kernel/capabilities.d.ts +157 -0
  133. package/dist/kernel/capabilities.js +109 -0
  134. package/dist/kernel/collaborator-ports.d.ts +91 -0
  135. package/dist/kernel/collaborator-ports.js +1 -0
  136. package/dist/kernel/composition-resolver.d.ts +215 -0
  137. package/dist/kernel/composition-resolver.js +558 -0
  138. package/dist/kernel/composition.d.ts +10 -0
  139. package/dist/kernel/composition.js +1 -0
  140. package/dist/kernel/descriptor-loader.d.ts +13 -0
  141. package/dist/kernel/descriptor-loader.js +48 -0
  142. package/dist/kernel/document.d.ts +43 -0
  143. package/dist/kernel/document.js +71 -0
  144. package/dist/kernel/embedding.d.ts +28 -0
  145. package/dist/kernel/embedding.js +78 -0
  146. package/dist/kernel/errors.d.ts +62 -0
  147. package/dist/kernel/errors.js +82 -0
  148. package/dist/kernel/events.d.ts +6 -0
  149. package/dist/kernel/events.js +21 -0
  150. package/dist/kernel/evidence-capture.d.ts +69 -0
  151. package/dist/kernel/evidence-capture.js +138 -0
  152. package/dist/kernel/fs.d.ts +20 -0
  153. package/dist/kernel/fs.js +128 -0
  154. package/dist/kernel/generic-rw.d.ts +33 -0
  155. package/dist/kernel/generic-rw.js +235 -0
  156. package/dist/kernel/hooks.d.ts +172 -0
  157. package/dist/kernel/hooks.js +256 -0
  158. package/dist/kernel/index.d.ts +624 -0
  159. package/dist/kernel/index.js +1638 -0
  160. package/dist/kernel/instance.d.ts +211 -0
  161. package/dist/kernel/instance.js +487 -0
  162. package/dist/kernel/kind-registry.d.ts +183 -0
  163. package/dist/kernel/kind-registry.js +710 -0
  164. package/dist/kernel/kind_base.d.ts +106 -0
  165. package/dist/kernel/kind_base.js +244 -0
  166. package/dist/kernel/layer-resolver.d.ts +48 -0
  167. package/dist/kernel/layer-resolver.js +284 -0
  168. package/dist/kernel/lock-manager.d.ts +21 -0
  169. package/dist/kernel/lock-manager.js +43 -0
  170. package/dist/kernel/lock.d.ts +38 -0
  171. package/dist/kernel/lock.js +115 -0
  172. package/dist/kernel/meta.d.ts +135 -0
  173. package/dist/kernel/meta.js +817 -0
  174. package/dist/kernel/models.d.ts +3089 -0
  175. package/dist/kernel/models.js +764 -0
  176. package/dist/kernel/navigator.d.ts +36 -0
  177. package/dist/kernel/navigator.js +132 -0
  178. package/dist/kernel/port-surface.d.ts +33 -0
  179. package/dist/kernel/port-surface.js +180 -0
  180. package/dist/kernel/preview.d.ts +60 -0
  181. package/dist/kernel/preview.js +54 -0
  182. package/dist/kernel/prompt-budget.d.ts +39 -0
  183. package/dist/kernel/prompt-budget.js +43 -0
  184. package/dist/kernel/prompt-builder.d.ts +25 -0
  185. package/dist/kernel/prompt-builder.js +237 -0
  186. package/dist/kernel/protocols.d.ts +751 -0
  187. package/dist/kernel/protocols.js +493 -0
  188. package/dist/kernel/reports.d.ts +26 -0
  189. package/dist/kernel/reports.js +215 -0
  190. package/dist/kernel/resolver.d.ts +146 -0
  191. package/dist/kernel/resolver.js +232 -0
  192. package/dist/kernel/resource.d.ts +57 -0
  193. package/dist/kernel/resource.js +97 -0
  194. package/dist/kernel/runtime.d.ts +16 -0
  195. package/dist/kernel/runtime.js +18 -0
  196. package/dist/kernel/safety-scanner.d.ts +38 -0
  197. package/dist/kernel/safety-scanner.js +228 -0
  198. package/dist/kernel/serialize-to-files.d.ts +29 -0
  199. package/dist/kernel/serialize-to-files.js +23 -0
  200. package/dist/kernel/spec-access.d.ts +23 -0
  201. package/dist/kernel/spec-access.js +40 -0
  202. package/dist/kernel/studio_ui.d.ts +88 -0
  203. package/dist/kernel/studio_ui.js +135 -0
  204. package/dist/kernel/templates.d.ts +77 -0
  205. package/dist/kernel/templates.js +116 -0
  206. package/dist/kernel/tool-registry.d.ts +52 -0
  207. package/dist/kernel/tool-registry.js +89 -0
  208. package/dist/kernel/write-pipeline.d.ts +65 -0
  209. package/dist/kernel/write-pipeline.js +271 -0
  210. package/dist/kernel/writer-helpers.d.ts +24 -0
  211. package/dist/kernel/writer-helpers.js +42 -0
  212. package/dist/memory/decay.d.ts +31 -0
  213. package/dist/memory/decay.js +97 -0
  214. package/dist/memory/ecphory.d.ts +25 -0
  215. package/dist/memory/ecphory.js +178 -0
  216. package/dist/memory/encodingContext.d.ts +21 -0
  217. package/dist/memory/encodingContext.js +62 -0
  218. package/dist/memory/index.d.ts +23 -0
  219. package/dist/memory/index.js +23 -0
  220. package/dist/memory/memoryType.d.ts +7 -0
  221. package/dist/memory/memoryType.js +24 -0
  222. package/dist/memory/policy.d.ts +35 -0
  223. package/dist/memory/policy.js +35 -0
  224. package/dist/memory/retrieval.d.ts +21 -0
  225. package/dist/memory/retrieval.js +145 -0
  226. package/dist/testing/index.d.ts +8 -0
  227. package/dist/testing/index.js +8 -0
  228. package/dist/testing/recordSearchConformance.d.ts +43 -0
  229. package/dist/testing/recordSearchConformance.js +147 -0
  230. package/dist/viz/ascii.d.ts +7 -0
  231. package/dist/viz/ascii.js +60 -0
  232. package/dist/viz/health.d.ts +8 -0
  233. package/dist/viz/health.js +161 -0
  234. package/dist/viz/index.d.ts +10 -0
  235. package/dist/viz/index.js +10 -0
  236. package/dist/viz/matrix.d.ts +8 -0
  237. package/dist/viz/matrix.js +84 -0
  238. package/dist/viz/mermaid.d.ts +38 -0
  239. package/dist/viz/mermaid.js +706 -0
  240. package/package.json +82 -0
@@ -0,0 +1,237 @@
1
+ /**
2
+ * PromptBuilder — namespace class extracting prompt-related logic
3
+ * from ManifestInstance.
4
+ *
5
+ * Usage: `mi.prompt.build()` — equivalent to `mi.buildPrompt()`.
6
+ *
7
+ * This is an extraction (Chunk 2 of the kernel simplification plan).
8
+ * The original methods on ManifestInstance are preserved; both APIs
9
+ * return identical results.
10
+ */
11
+ import Mustache from "mustache";
12
+ import { stripPromptBlock } from "./_text.js";
13
+ // ---------------------------------------------------------------------------
14
+ // PromptBuilder
15
+ // ---------------------------------------------------------------------------
16
+ export class PromptBuilder {
17
+ host;
18
+ constructor(host) {
19
+ this.host = host;
20
+ }
21
+ /**
22
+ * Build the final prompt string for the given (or default) agent.
23
+ * Equivalent to `mi.buildPrompt(opts)`.
24
+ */
25
+ async build(opts) {
26
+ const agentOpt = opts?.agent;
27
+ const extra = opts?.context;
28
+ // Resolve agent name
29
+ let agentName = agentOpt ?? null;
30
+ if (!agentName) {
31
+ const root = this.host.root;
32
+ if (root) {
33
+ const kp = this.host._kinds.get(`${root.apiVersion}\0${root.kind}`);
34
+ if (kp) {
35
+ agentName = kp.getDefaultAgentName(root);
36
+ }
37
+ }
38
+ }
39
+ const agentDoc = agentName ? this._findAgent(agentName) : null;
40
+ if (!agentDoc) {
41
+ return `Agent '${agentName}' not found`;
42
+ }
43
+ // Build context — merge backwards-compat params into enabledSlots
44
+ const enabledSlots = { ...(opts?.enabledSlots ?? {}) };
45
+ if (opts?.enabledSkills && !enabledSlots.skills)
46
+ enabledSlots.skills = opts.enabledSkills;
47
+ if (opts?.enabledGuardrails && !enabledSlots.guardrails)
48
+ enabledSlots.guardrails = opts.enabledGuardrails;
49
+ let ctx = await this._buildContext(agentDoc, extra, enabledSlots);
50
+ // Hook: pre_build_prompt — middleware can modify context
51
+ const kernel = this.host._kernel;
52
+ if (kernel?.hooks?.has("pre_build_prompt")) {
53
+ const hookCtx = {
54
+ scope: this.host.scope,
55
+ agent: agentName ?? undefined,
56
+ data: { context: ctx },
57
+ };
58
+ const result = kernel.hooks.runMiddleware("pre_build_prompt", hookCtx);
59
+ ctx = result.data.context ?? ctx;
60
+ }
61
+ // Render via template cascade
62
+ const prompt = await this._renderPrompt(ctx, agentDoc);
63
+ // Hook: post_build_prompt — event notification
64
+ if (kernel?.hooks?.has("post_build_prompt")) {
65
+ kernel.hooks.emit("post_build_prompt", {
66
+ scope: this.host.scope,
67
+ agent: agentName ?? undefined,
68
+ prompt,
69
+ data: {},
70
+ });
71
+ }
72
+ return prompt;
73
+ }
74
+ // -------------------------------------------------------------------------
75
+ // Private helpers
76
+ // -------------------------------------------------------------------------
77
+ _findAgent(name) {
78
+ let best = null;
79
+ let bestPriority = -1;
80
+ const kinds = this.host._kinds;
81
+ for (const d of this.host.documents) {
82
+ const kp = kinds.get(`${d.apiVersion}\0${d.kind}`);
83
+ if (kp?.isPromptTarget && d.name === name) {
84
+ const priority = kp.promptTargetPriority ?? 0;
85
+ if (priority > bestPriority) {
86
+ best = d;
87
+ bestPriority = priority;
88
+ }
89
+ }
90
+ }
91
+ return best;
92
+ }
93
+ async _buildContext(agentDoc, extra, enabledSlots) {
94
+ const ctx = {};
95
+ const kinds = this.host._kinds;
96
+ // Root metadata + spec
97
+ const root = this.host.root;
98
+ if (root) {
99
+ ctx.metadata = { ...root.metadata };
100
+ ctx.spec = { ...root.spec };
101
+ }
102
+ // Agent entry
103
+ const agentSpec = agentDoc.spec;
104
+ const instructionRef = agentSpec.instruction ?? "";
105
+ ctx.agent = {
106
+ name: agentDoc.name,
107
+ description: PromptBuilder._getDescription(agentDoc),
108
+ // stripPromptBlock: composition-only trailing-whitespace
109
+ // normalization (i-013) — storage stays byte-faithful.
110
+ instruction: instructionRef
111
+ ? stripPromptBlock(await this.host.ref(instructionRef))
112
+ : "",
113
+ };
114
+ ctx.agentId = agentDoc.name;
115
+ // All documents grouped by alias (for Mustache sections)
116
+ for (const doc of this.host.documents) {
117
+ const kp = kinds.get(`${doc.apiVersion}\0${doc.kind}`);
118
+ if (!kp)
119
+ continue;
120
+ const alias = kp.alias;
121
+ if (!ctx[alias])
122
+ ctx[alias] = [];
123
+ const entry = {
124
+ name: doc.name,
125
+ description: PromptBuilder._getDescription(doc),
126
+ };
127
+ const spec = doc.spec;
128
+ for (const [k, v] of Object.entries(spec)) {
129
+ if (k.startsWith("_") || v == null)
130
+ continue;
131
+ entry[k] = typeof v === "string" ? await this.host.ref(v) : v;
132
+ }
133
+ ctx[alias].push(entry);
134
+ }
135
+ // Dep filtering: agent's dep_filters restrict which docs appear per alias
136
+ const agentKp = kinds.get(`${agentDoc.apiVersion}\0${agentDoc.kind}`);
137
+ if (agentKp) {
138
+ const filters = agentKp.depFilters();
139
+ if (filters) {
140
+ for (const [specField, targetAlias] of Object.entries(filters)) {
141
+ if (!(targetAlias in ctx))
142
+ continue;
143
+ const declared = agentSpec[specField];
144
+ if (declared == null || declared === "") {
145
+ // Field not declared or empty -> filter to empty
146
+ ctx[targetAlias] = [];
147
+ continue;
148
+ }
149
+ if (typeof declared === "string") {
150
+ ctx[targetAlias] = ctx[targetAlias].filter((e) => e.name === declared);
151
+ }
152
+ else if (Array.isArray(declared)) {
153
+ if (declared.length === 0) {
154
+ ctx[targetAlias] = [];
155
+ }
156
+ else {
157
+ ctx[targetAlias] = ctx[targetAlias].filter((e) => declared.includes(e.name));
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+ // Generic slot filtering: caller restricts which docs appear per slot.
164
+ if (agentKp && enabledSlots && Object.keys(enabledSlots).length > 0) {
165
+ const filters = agentKp.depFilters();
166
+ if (filters) {
167
+ for (const [slotName, enabledNames] of Object.entries(enabledSlots)) {
168
+ const alias = filters[slotName];
169
+ if (alias && alias in ctx) {
170
+ ctx[alias] = ctx[alias]
171
+ .filter((e) => enabledNames.includes(e.name));
172
+ }
173
+ }
174
+ }
175
+ }
176
+ // Flatten: kinds with flattenInContext have their spec entries merged into ctx.
177
+ // String values (soul_content, agents_content, ...) get trailing
178
+ // whitespace normalized — the template supplies the joiners (i-013).
179
+ for (const doc of this.host.documents) {
180
+ const kp = kinds.get(`${doc.apiVersion}\0${doc.kind}`);
181
+ if (!kp?.flattenInContext)
182
+ continue;
183
+ const spec = doc.spec;
184
+ for (const [k, v] of Object.entries(spec)) {
185
+ if (k.startsWith("_") || v == null)
186
+ continue;
187
+ ctx[k] =
188
+ typeof v === "string"
189
+ ? stripPromptBlock(await this.host.ref(v))
190
+ : v;
191
+ }
192
+ }
193
+ // Extra context from caller
194
+ if (extra) {
195
+ Object.assign(ctx, extra);
196
+ }
197
+ return ctx;
198
+ }
199
+ async _renderPrompt(ctx, agentDoc) {
200
+ const agentSpec = agentDoc.spec;
201
+ const kinds = this.host._kinds;
202
+ // 1. Agent-level template override
203
+ const agentTemplate = agentSpec.promptTemplate ??
204
+ agentSpec.prompt_template ??
205
+ null;
206
+ if (agentTemplate) {
207
+ return await this._mustacheRender(agentTemplate, ctx);
208
+ }
209
+ // 2. Kind default template
210
+ const agentKp = kinds.get(`${agentDoc.apiVersion}\0${agentDoc.kind}`);
211
+ if (agentKp) {
212
+ const kindTemplate = agentKp.promptTemplate();
213
+ if (kindTemplate) {
214
+ return await this._mustacheRender(kindTemplate, ctx);
215
+ }
216
+ }
217
+ // 3. Fallback: agent instruction as plain text
218
+ const agent = ctx.agent;
219
+ return agent?.instruction ?? "";
220
+ }
221
+ async _mustacheRender(template, ctx) {
222
+ // Resolve template if it's a file reference
223
+ let tmpl = template;
224
+ if (tmpl.includes("/") ||
225
+ tmpl.endsWith(".mustache") ||
226
+ tmpl.endsWith(".md")) {
227
+ tmpl = await this.host.ref(tmpl);
228
+ }
229
+ // Double render: first pass resolves Mustache tags, second pass resolves
230
+ // any tags that were inside resolved content.
231
+ const firstPass = Mustache.render(tmpl, ctx);
232
+ return Mustache.render(firstPass, ctx);
233
+ }
234
+ static _getDescription(doc) {
235
+ return doc.metadata.description ?? "";
236
+ }
237
+ }