@cat-factory/agents 0.6.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 (226) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agents/AiAgentExecutor.d.ts +72 -0
  3. package/dist/agents/AiAgentExecutor.d.ts.map +1 -0
  4. package/dist/agents/AiAgentExecutor.js +125 -0
  5. package/dist/agents/AiAgentExecutor.js.map +1 -0
  6. package/dist/agents/acceptance-prompts.d.ts +29 -0
  7. package/dist/agents/acceptance-prompts.d.ts.map +1 -0
  8. package/dist/agents/acceptance-prompts.js +112 -0
  9. package/dist/agents/acceptance-prompts.js.map +1 -0
  10. package/dist/agents/agent-catalog.d.ts +6 -0
  11. package/dist/agents/agent-catalog.d.ts.map +1 -0
  12. package/dist/agents/agent-catalog.js +197 -0
  13. package/dist/agents/agent-catalog.js.map +1 -0
  14. package/dist/agents/agent-configs.d.ts +17 -0
  15. package/dist/agents/agent-configs.d.ts.map +1 -0
  16. package/dist/agents/agent-configs.js +66 -0
  17. package/dist/agents/agent-configs.js.map +1 -0
  18. package/dist/agents/agent-routing.d.ts +57 -0
  19. package/dist/agents/agent-routing.d.ts.map +1 -0
  20. package/dist/agents/agent-routing.js +41 -0
  21. package/dist/agents/agent-routing.js.map +1 -0
  22. package/dist/agents/business-logic-prompts.d.ts +28 -0
  23. package/dist/agents/business-logic-prompts.d.ts.map +1 -0
  24. package/dist/agents/business-logic-prompts.js +96 -0
  25. package/dist/agents/business-logic-prompts.js.map +1 -0
  26. package/dist/agents/catalog.d.ts +6 -0
  27. package/dist/agents/catalog.d.ts.map +1 -0
  28. package/dist/agents/catalog.js +168 -0
  29. package/dist/agents/catalog.js.map +1 -0
  30. package/dist/agents/ci-gate.d.ts +2 -0
  31. package/dist/agents/ci-gate.d.ts.map +1 -0
  32. package/dist/agents/ci-gate.js +33 -0
  33. package/dist/agents/ci-gate.js.map +1 -0
  34. package/dist/agents/companion-prompts.d.ts +4 -0
  35. package/dist/agents/companion-prompts.d.ts.map +1 -0
  36. package/dist/agents/companion-prompts.js +27 -0
  37. package/dist/agents/companion-prompts.js.map +1 -0
  38. package/dist/agents/companions.d.ts +20 -0
  39. package/dist/agents/companions.d.ts.map +1 -0
  40. package/dist/agents/companions.js +38 -0
  41. package/dist/agents/companions.js.map +1 -0
  42. package/dist/agents/kinds/companions.d.ts +20 -0
  43. package/dist/agents/kinds/companions.d.ts.map +1 -0
  44. package/dist/agents/kinds/companions.js +39 -0
  45. package/dist/agents/kinds/companions.js.map +1 -0
  46. package/dist/agents/kinds/configs.d.ts +17 -0
  47. package/dist/agents/kinds/configs.d.ts.map +1 -0
  48. package/dist/agents/kinds/configs.js +66 -0
  49. package/dist/agents/kinds/configs.js.map +1 -0
  50. package/dist/agents/kinds/read-only.d.ts +13 -0
  51. package/dist/agents/kinds/read-only.d.ts.map +1 -0
  52. package/dist/agents/kinds/read-only.js +32 -0
  53. package/dist/agents/kinds/read-only.js.map +1 -0
  54. package/dist/agents/kinds/registry.d.ts +70 -0
  55. package/dist/agents/kinds/registry.d.ts.map +1 -0
  56. package/dist/agents/kinds/registry.js +51 -0
  57. package/dist/agents/kinds/registry.js.map +1 -0
  58. package/dist/agents/kinds/traits.d.ts +60 -0
  59. package/dist/agents/kinds/traits.d.ts.map +1 -0
  60. package/dist/agents/kinds/traits.js +123 -0
  61. package/dist/agents/kinds/traits.js.map +1 -0
  62. package/dist/agents/kinds/versions.d.ts +46 -0
  63. package/dist/agents/kinds/versions.d.ts.map +1 -0
  64. package/dist/agents/kinds/versions.js +22 -0
  65. package/dist/agents/kinds/versions.js.map +1 -0
  66. package/dist/agents/mock-prompts.d.ts +12 -0
  67. package/dist/agents/mock-prompts.d.ts.map +1 -0
  68. package/dist/agents/mock-prompts.js +61 -0
  69. package/dist/agents/mock-prompts.js.map +1 -0
  70. package/dist/agents/prompt-fragments.d.ts +17 -0
  71. package/dist/agents/prompt-fragments.d.ts.map +1 -0
  72. package/dist/agents/prompt-fragments.js +33 -0
  73. package/dist/agents/prompt-fragments.js.map +1 -0
  74. package/dist/agents/prompt-shared.d.ts +7 -0
  75. package/dist/agents/prompt-shared.d.ts.map +1 -0
  76. package/dist/agents/prompt-shared.js +10 -0
  77. package/dist/agents/prompt-shared.js.map +1 -0
  78. package/dist/agents/prompt-versions.d.ts +48 -0
  79. package/dist/agents/prompt-versions.d.ts.map +1 -0
  80. package/dist/agents/prompt-versions.js +55 -0
  81. package/dist/agents/prompt-versions.js.map +1 -0
  82. package/dist/agents/prompts/acceptance.d.ts +29 -0
  83. package/dist/agents/prompts/acceptance.d.ts.map +1 -0
  84. package/dist/agents/prompts/acceptance.js +112 -0
  85. package/dist/agents/prompts/acceptance.js.map +1 -0
  86. package/dist/agents/prompts/business-logic.d.ts +28 -0
  87. package/dist/agents/prompts/business-logic.d.ts.map +1 -0
  88. package/dist/agents/prompts/business-logic.js +98 -0
  89. package/dist/agents/prompts/business-logic.js.map +1 -0
  90. package/dist/agents/prompts/clarity.d.ts +10 -0
  91. package/dist/agents/prompts/clarity.d.ts.map +1 -0
  92. package/dist/agents/prompts/clarity.js +40 -0
  93. package/dist/agents/prompts/clarity.js.map +1 -0
  94. package/dist/agents/prompts/companion.d.ts +4 -0
  95. package/dist/agents/prompts/companion.d.ts.map +1 -0
  96. package/dist/agents/prompts/companion.js +61 -0
  97. package/dist/agents/prompts/companion.js.map +1 -0
  98. package/dist/agents/prompts/delivery-contract.d.ts +2 -0
  99. package/dist/agents/prompts/delivery-contract.d.ts.map +1 -0
  100. package/dist/agents/prompts/delivery-contract.js +33 -0
  101. package/dist/agents/prompts/delivery-contract.js.map +1 -0
  102. package/dist/agents/prompts/mock.d.ts +12 -0
  103. package/dist/agents/prompts/mock.d.ts.map +1 -0
  104. package/dist/agents/prompts/mock.js +61 -0
  105. package/dist/agents/prompts/mock.js.map +1 -0
  106. package/dist/agents/prompts/requirements.d.ts +13 -0
  107. package/dist/agents/prompts/requirements.d.ts.map +1 -0
  108. package/dist/agents/prompts/requirements.js +45 -0
  109. package/dist/agents/prompts/requirements.js.map +1 -0
  110. package/dist/agents/prompts/roles.d.ts +16 -0
  111. package/dist/agents/prompts/roles.d.ts.map +1 -0
  112. package/dist/agents/prompts/roles.js +74 -0
  113. package/dist/agents/prompts/roles.js.map +1 -0
  114. package/dist/agents/prompts/shared.d.ts +19 -0
  115. package/dist/agents/prompts/shared.d.ts.map +1 -0
  116. package/dist/agents/prompts/shared.js +25 -0
  117. package/dist/agents/prompts/shared.js.map +1 -0
  118. package/dist/agents/prompts/standard-templates.generated.d.ts +36 -0
  119. package/dist/agents/prompts/standard-templates.generated.d.ts.map +1 -0
  120. package/dist/agents/prompts/standard-templates.generated.js +122 -0
  121. package/dist/agents/prompts/standard-templates.generated.js.map +1 -0
  122. package/dist/agents/prompts/standard.d.ts +36 -0
  123. package/dist/agents/prompts/standard.d.ts.map +1 -0
  124. package/dist/agents/prompts/standard.js +208 -0
  125. package/dist/agents/prompts/standard.js.map +1 -0
  126. package/dist/agents/prompts/testing.d.ts +12 -0
  127. package/dist/agents/prompts/testing.d.ts.map +1 -0
  128. package/dist/agents/prompts/testing.js +94 -0
  129. package/dist/agents/prompts/testing.js.map +1 -0
  130. package/dist/agents/read-only.d.ts +13 -0
  131. package/dist/agents/read-only.d.ts.map +1 -0
  132. package/dist/agents/read-only.js +29 -0
  133. package/dist/agents/read-only.js.map +1 -0
  134. package/dist/agents/registry.d.ts +70 -0
  135. package/dist/agents/registry.d.ts.map +1 -0
  136. package/dist/agents/registry.js +51 -0
  137. package/dist/agents/registry.js.map +1 -0
  138. package/dist/agents/runtime/executor.d.ts +72 -0
  139. package/dist/agents/runtime/executor.d.ts.map +1 -0
  140. package/dist/agents/runtime/executor.js +125 -0
  141. package/dist/agents/runtime/executor.js.map +1 -0
  142. package/dist/agents/runtime/fragments.d.ts +17 -0
  143. package/dist/agents/runtime/fragments.d.ts.map +1 -0
  144. package/dist/agents/runtime/fragments.js +33 -0
  145. package/dist/agents/runtime/fragments.js.map +1 -0
  146. package/dist/agents/runtime/routing.d.ts +57 -0
  147. package/dist/agents/runtime/routing.d.ts.map +1 -0
  148. package/dist/agents/runtime/routing.js +41 -0
  149. package/dist/agents/runtime/routing.js.map +1 -0
  150. package/dist/agents/runtime/web-search.d.ts +43 -0
  151. package/dist/agents/runtime/web-search.d.ts.map +1 -0
  152. package/dist/agents/runtime/web-search.js +102 -0
  153. package/dist/agents/runtime/web-search.js.map +1 -0
  154. package/dist/agents/standard-prompt-templates.generated.d.ts +36 -0
  155. package/dist/agents/standard-prompt-templates.generated.d.ts.map +1 -0
  156. package/dist/agents/standard-prompt-templates.generated.js +122 -0
  157. package/dist/agents/standard-prompt-templates.generated.js.map +1 -0
  158. package/dist/agents/standard-prompts.d.ts +36 -0
  159. package/dist/agents/standard-prompts.d.ts.map +1 -0
  160. package/dist/agents/standard-prompts.js +202 -0
  161. package/dist/agents/standard-prompts.js.map +1 -0
  162. package/dist/agents/test-prompts.d.ts +12 -0
  163. package/dist/agents/test-prompts.d.ts.map +1 -0
  164. package/dist/agents/test-prompts.js +92 -0
  165. package/dist/agents/test-prompts.js.map +1 -0
  166. package/dist/agents/traits.d.ts +56 -0
  167. package/dist/agents/traits.d.ts.map +1 -0
  168. package/dist/agents/traits.js +100 -0
  169. package/dist/agents/traits.js.map +1 -0
  170. package/dist/agents/web-search.d.ts +43 -0
  171. package/dist/agents/web-search.d.ts.map +1 -0
  172. package/dist/agents/web-search.js +102 -0
  173. package/dist/agents/web-search.js.map +1 -0
  174. package/dist/fragmentLibrary/DeterministicFragmentSelector.d.ts +10 -0
  175. package/dist/fragmentLibrary/DeterministicFragmentSelector.d.ts.map +1 -0
  176. package/dist/fragmentLibrary/DeterministicFragmentSelector.js +12 -0
  177. package/dist/fragmentLibrary/DeterministicFragmentSelector.js.map +1 -0
  178. package/dist/fragmentLibrary/FragmentLibraryService.d.ts +55 -0
  179. package/dist/fragmentLibrary/FragmentLibraryService.d.ts.map +1 -0
  180. package/dist/fragmentLibrary/FragmentLibraryService.js +203 -0
  181. package/dist/fragmentLibrary/FragmentLibraryService.js.map +1 -0
  182. package/dist/fragmentLibrary/FragmentSourceService.d.ts +51 -0
  183. package/dist/fragmentLibrary/FragmentSourceService.d.ts.map +1 -0
  184. package/dist/fragmentLibrary/FragmentSourceService.js +181 -0
  185. package/dist/fragmentLibrary/FragmentSourceService.js.map +1 -0
  186. package/dist/fragmentLibrary/LlmFragmentSelector.d.ts +21 -0
  187. package/dist/fragmentLibrary/LlmFragmentSelector.d.ts.map +1 -0
  188. package/dist/fragmentLibrary/LlmFragmentSelector.js +87 -0
  189. package/dist/fragmentLibrary/LlmFragmentSelector.js.map +1 -0
  190. package/dist/fragmentLibrary/fragment-catalog.d.ts +43 -0
  191. package/dist/fragmentLibrary/fragment-catalog.d.ts.map +1 -0
  192. package/dist/fragmentLibrary/fragment-catalog.js +129 -0
  193. package/dist/fragmentLibrary/fragment-catalog.js.map +1 -0
  194. package/dist/fragmentLibrary/fragment-source.logic.d.ts +34 -0
  195. package/dist/fragmentLibrary/fragment-source.logic.d.ts.map +1 -0
  196. package/dist/fragmentLibrary/fragment-source.logic.js +172 -0
  197. package/dist/fragmentLibrary/fragment-source.logic.js.map +1 -0
  198. package/dist/index.d.ts +30 -0
  199. package/dist/index.d.ts.map +1 -0
  200. package/dist/index.js +43 -0
  201. package/dist/index.js.map +1 -0
  202. package/dist/providers/cache.d.ts +22 -0
  203. package/dist/providers/cache.d.ts.map +1 -0
  204. package/dist/providers/cache.js +64 -0
  205. package/dist/providers/cache.js.map +1 -0
  206. package/dist/providers/endpoints.d.ts +8 -0
  207. package/dist/providers/endpoints.d.ts.map +1 -0
  208. package/dist/providers/endpoints.js +23 -0
  209. package/dist/providers/endpoints.js.map +1 -0
  210. package/dist/providers/index.d.ts +6 -0
  211. package/dist/providers/index.d.ts.map +1 -0
  212. package/dist/providers/index.js +6 -0
  213. package/dist/providers/index.js.map +1 -0
  214. package/dist/providers/instrumented.d.ts +28 -0
  215. package/dist/providers/instrumented.d.ts.map +1 -0
  216. package/dist/providers/instrumented.js +147 -0
  217. package/dist/providers/instrumented.js.map +1 -0
  218. package/dist/providers/registry.d.ts +26 -0
  219. package/dist/providers/registry.d.ts.map +1 -0
  220. package/dist/providers/registry.js +32 -0
  221. package/dist/providers/registry.js.map +1 -0
  222. package/dist/providers/resolvers.d.ts +58 -0
  223. package/dist/providers/resolvers.d.ts.map +1 -0
  224. package/dist/providers/resolvers.js +78 -0
  225. package/dist/providers/resolvers.js.map +1 -0
  226. package/package.json +39 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Igor Savin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,72 @@
1
+ import type { AgentExecutor, AgentRunContext, AgentRunResult } from '@cat-factory/kernel';
2
+ import type { ModelProvider, ModelProviderResolver, ModelRef } from '@cat-factory/kernel';
3
+ import { type AgentRouting } from './agent-routing.js';
4
+ import { type InlineWebSearchOptions } from './web-search.js';
5
+ export interface AiAgentExecutorDependencies {
6
+ /**
7
+ * Resolve a {@link ModelProvider} for a run's credential scope (workspace + owning
8
+ * account + initiator), leasing the DB-backed API keys for that scope. Preferred over
9
+ * the static `modelProvider`; the facades supply it so inline calls use the same
10
+ * per-scope pool the container proxy does.
11
+ */
12
+ modelProviderResolver?: ModelProviderResolver;
13
+ /**
14
+ * A static {@link ModelProvider} (e.g. a fake in tests). Used only when no
15
+ * `modelProviderResolver` is supplied. One of the two MUST be present.
16
+ */
17
+ modelProvider?: ModelProvider;
18
+ agentRouting: AgentRouting;
19
+ /**
20
+ * Resolve a block's selected model id to a concrete ref. Deployment-aware (it
21
+ * honours the direct/Cloudflare fallback based on configured keys), so the
22
+ * worker supplies it; absent/unknown ids return undefined to fall back to the
23
+ * agent routing. Defaults to "no per-block override".
24
+ */
25
+ resolveBlockModel?: (modelId: string | undefined) => ModelRef | undefined;
26
+ /**
27
+ * Resolve the workspace's per-agent-kind default model id, consulted when the
28
+ * block pins no usable model. Optional: absent → the env routing for the kind is
29
+ * used. Supplying it makes the inline kinds honour the workspace defaults exactly
30
+ * like the container executor (block-pinned > workspace default > env routing).
31
+ */
32
+ resolveWorkspaceModelDefault?: (workspaceId: string, agentKind: string) => Promise<string | undefined>;
33
+ /**
34
+ * Opt-in provider-hosted web search for the design/research inline kinds. When
35
+ * supplied (and the resolved model's provider has a hosted search — Anthropic /
36
+ * OpenAI), the allow-listed kinds get a `web_search` tool plus a usage nudge.
37
+ * Absent ⇒ inline agents make a plain one-shot completion, exactly as before.
38
+ */
39
+ webSearch?: InlineWebSearchOptions;
40
+ }
41
+ /**
42
+ * The real agent: performs each pipeline step by calling an LLM through the
43
+ * Vercel AI SDK. The model and generation settings come from the {@link
44
+ * AgentRouting} (configurable per agent kind), and the concrete model is
45
+ * resolved through the {@link ModelProvider} port — so this class never imports
46
+ * a provider SDK or an API key directly.
47
+ */
48
+ export declare class AiAgentExecutor implements AgentExecutor {
49
+ private readonly modelProviderResolver?;
50
+ private readonly modelProvider?;
51
+ private readonly agentRouting;
52
+ private readonly resolveBlockModel;
53
+ private readonly resolveWorkspaceModelDefault?;
54
+ private readonly webSearch?;
55
+ constructor({ modelProviderResolver, modelProvider, agentRouting, resolveBlockModel, resolveWorkspaceModelDefault, webSearch, }: AiAgentExecutorDependencies);
56
+ /** Resolve the model provider for a run's scope (per-scope DB pool, else the static one). */
57
+ private providerFor;
58
+ /**
59
+ * Resolve the step's model ref with the shared step precedence: a block's pinned
60
+ * model wins, else the workspace's per-kind default, else the env routing for the
61
+ * kind. A pinned subscription model (Claude Code / Codex), which can run only in
62
+ * the container harness, is degraded to the kind's env-routing default here — this
63
+ * is an inline executor — via the shared `resolveInlineModelRef` seam. Side-effect-
64
+ * free, so it backs both `run` and the up-front `resolveModel` (which thus reports
65
+ * the model that will actually run, not the un-servable subscription ref).
66
+ */
67
+ private resolveRef;
68
+ /** Preview the model this step will run, without making the LLM call. */
69
+ resolveModel(context: AgentRunContext): Promise<string>;
70
+ run(context: AgentRunContext): Promise<AgentRunResult>;
71
+ }
72
+ //# sourceMappingURL=AiAgentExecutor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiAgentExecutor.d.ts","sourceRoot":"","sources":["../../src/agents/AiAgentExecutor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAGzF,OAAO,EAAE,KAAK,YAAY,EAA6C,MAAM,oBAAoB,CAAA;AAEjG,OAAO,EACL,KAAK,sBAAsB,EAG5B,MAAM,iBAAiB,CAAA;AAExB,MAAM,WAAW,2BAA2B;IAC1C;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,YAAY,EAAE,YAAY,CAAA;IAC1B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,QAAQ,GAAG,SAAS,CAAA;IACzE;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,CAC7B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAChC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,sBAAsB,CAAA;CACnC;AAED;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,aAAa;IACnD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAuB;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAe;IAC9C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuD;IACzF,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAGd;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAwB;IAEnD,YAAY,EACV,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,4BAA4B,EAC5B,SAAS,GACV,EAAE,2BAA2B,EAU7B;IAED,6FAA6F;YAC/E,WAAW;IAgBzB;;;;;;;;OAQG;IACH,OAAO,CAAC,UAAU;IAelB,yEAAyE;IACnE,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAG5D;IAEK,GAAG,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAsD3D;CACF"}
@@ -0,0 +1,125 @@
1
+ import { generateText } from 'ai';
2
+ import { systemPromptFor, userPromptFor } from './agent-catalog.js';
3
+ import { catFactoryObservability } from '../providers/instrumented.js';
4
+ import { resolveAgentConfig, resolveInlineModelRef } from './agent-routing.js';
5
+ import { composeBlockSystemPrompt } from './prompt-fragments.js';
6
+ import { providerWebSearchTools, webResearchGuidanceFor, } from './web-search.js';
7
+ /**
8
+ * The real agent: performs each pipeline step by calling an LLM through the
9
+ * Vercel AI SDK. The model and generation settings come from the {@link
10
+ * AgentRouting} (configurable per agent kind), and the concrete model is
11
+ * resolved through the {@link ModelProvider} port — so this class never imports
12
+ * a provider SDK or an API key directly.
13
+ */
14
+ export class AiAgentExecutor {
15
+ modelProviderResolver;
16
+ modelProvider;
17
+ agentRouting;
18
+ resolveBlockModel;
19
+ resolveWorkspaceModelDefault;
20
+ webSearch;
21
+ constructor({ modelProviderResolver, modelProvider, agentRouting, resolveBlockModel, resolveWorkspaceModelDefault, webSearch, }) {
22
+ if (!modelProviderResolver && !modelProvider) {
23
+ throw new Error('AiAgentExecutor requires a modelProviderResolver or a modelProvider');
24
+ }
25
+ this.modelProviderResolver = modelProviderResolver;
26
+ this.modelProvider = modelProvider;
27
+ this.agentRouting = agentRouting;
28
+ this.resolveBlockModel = resolveBlockModel ?? (() => undefined);
29
+ this.resolveWorkspaceModelDefault = resolveWorkspaceModelDefault;
30
+ this.webSearch = webSearch;
31
+ }
32
+ /** Resolve the model provider for a run's scope (per-scope DB pool, else the static one). */
33
+ async providerFor(context) {
34
+ if (this.modelProviderResolver && context.workspaceId) {
35
+ return this.modelProviderResolver.forScope({
36
+ workspaceId: context.workspaceId,
37
+ userId: context.initiatedByUserId,
38
+ });
39
+ }
40
+ if (this.modelProvider)
41
+ return this.modelProvider;
42
+ if (this.modelProviderResolver) {
43
+ // No workspace scope (rare): lease from no scope — only the opt-in registries
44
+ // (Cloudflare/Bedrock) can resolve.
45
+ return this.modelProviderResolver.forScope({ workspaceId: context.workspaceId ?? '' });
46
+ }
47
+ throw new Error('AiAgentExecutor: no model provider available');
48
+ }
49
+ /**
50
+ * Resolve the step's model ref with the shared step precedence: a block's pinned
51
+ * model wins, else the workspace's per-kind default, else the env routing for the
52
+ * kind. A pinned subscription model (Claude Code / Codex), which can run only in
53
+ * the container harness, is degraded to the kind's env-routing default here — this
54
+ * is an inline executor — via the shared `resolveInlineModelRef` seam. Side-effect-
55
+ * free, so it backs both `run` and the up-front `resolveModel` (which thus reports
56
+ * the model that will actually run, not the un-servable subscription ref).
57
+ */
58
+ resolveRef(context) {
59
+ return resolveInlineModelRef({
60
+ agentRouting: this.agentRouting,
61
+ resolveBlockModel: this.resolveBlockModel,
62
+ resolveWorkspaceModelDefault: this.resolveWorkspaceModelDefault,
63
+ }, {
64
+ agentKind: context.agentKind,
65
+ blockModelId: context.block.modelId,
66
+ workspaceId: context.workspaceId,
67
+ });
68
+ }
69
+ /** Preview the model this step will run, without making the LLM call. */
70
+ async resolveModel(context) {
71
+ const ref = await this.resolveRef(context);
72
+ return `${ref.provider}:${ref.model}`;
73
+ }
74
+ async run(context) {
75
+ const config = resolveAgentConfig(this.agentRouting, context.agentKind);
76
+ // `resolveRef` already degrades a pinned subscription model (Claude Code / Codex,
77
+ // which run only in the container harness and have no provider key here) to this
78
+ // kind's env-routing default, so the ModelProvider always gets a servable ref.
79
+ const ref = await this.resolveRef(context);
80
+ const provider = await this.providerFor(context);
81
+ const model = provider.resolve(ref);
82
+ // Base role prompt, then fold in the best-practice fragments selected for the
83
+ // block — the engine-resolved tenant catalog when present, else the manual ids.
84
+ const baseSystem = config.system ?? systemPromptFor(context.agentKind);
85
+ const composed = composeBlockSystemPrompt(baseSystem, context.block);
86
+ // Provider-hosted web search for the allow-listed design/research kinds, when
87
+ // enabled AND the resolved provider has one. The usage nudge is appended only
88
+ // when the tool is actually attached, so the model is never told about a tool
89
+ // it lacks (mirrors the harness's AGENTS.md guidance gating).
90
+ const tools = this.webSearch && this.webSearch.kinds.has(context.agentKind)
91
+ ? providerWebSearchTools(ref.provider, this.webSearch.maxUses)
92
+ : undefined;
93
+ // Inline tool is web_search only (no web_fetch); the per-kind hint is resolved
94
+ // from the registry/catalog so a custom kind gets its own nudge.
95
+ const system = tools
96
+ ? `${composed}${webResearchGuidanceFor(context.agentKind, { fetch: false })}`
97
+ : composed;
98
+ const { text, usage } = await generateText({
99
+ model,
100
+ system,
101
+ prompt: userPromptFor(context),
102
+ temperature: config.temperature,
103
+ maxOutputTokens: config.maxOutputTokens,
104
+ ...(tools ? { tools } : {}),
105
+ // Tag the call so an instrumented provider can group it under its run's trace
106
+ // (a no-op when no trace sink is wired; ignored by every model provider).
107
+ providerOptions: catFactoryObservability({
108
+ agentKind: context.agentKind,
109
+ workspaceId: context.workspaceId,
110
+ executionId: context.executionId,
111
+ }),
112
+ });
113
+ return {
114
+ output: text.trim(),
115
+ model: `${ref.provider}:${ref.model}`,
116
+ // Report metered tokens so the spend safeguard can price this call. The
117
+ // AI SDK leaves either field undefined when a provider omits it.
118
+ usage: {
119
+ inputTokens: usage.inputTokens ?? 0,
120
+ outputTokens: usage.outputTokens ?? 0,
121
+ },
122
+ };
123
+ }
124
+ }
125
+ //# sourceMappingURL=AiAgentExecutor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AiAgentExecutor.js","sourceRoot":"","sources":["../../src/agents/AiAgentExecutor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { AgentKind } from '@cat-factory/kernel';
2
+ import type { AgentRunContext } from '@cat-factory/kernel';
3
+ /** The agent kinds that make up the acceptance-testing track. */
4
+ export type AcceptanceAgentKind = 'playwright';
5
+ export declare const ACCEPTANCE_AGENT_KINDS: readonly AcceptanceAgentKind[];
6
+ /** True when the agent kind is part of the acceptance-testing track. */
7
+ export declare function isAcceptanceKind(kind: AgentKind): kind is AcceptanceAgentKind;
8
+ /**
9
+ * The built-out system (role) prompt for an acceptance-testing agent kind, or
10
+ * `undefined` when the kind is not part of this track (so callers can fall
11
+ * through to the standard phases / generic role).
12
+ */
13
+ export declare function acceptanceSystemPrompt(kind: AgentKind): string | undefined;
14
+ /**
15
+ * The "where do the tests run" section for an acceptance-testing step, rendered
16
+ * from the block's contributed `playwright.e2eTarget` config value. Empty for
17
+ * non-track kinds or when no target is recorded, so callers can append it
18
+ * unconditionally.
19
+ */
20
+ export declare function e2eTargetSection(context: AgentRunContext): string;
21
+ /**
22
+ * The "how should these tests be written" section for the runnable-tests step
23
+ * (`playwright` kind), chosen from the block type: Playwright for user-facing
24
+ * blocks, the project's own test framework for backend blocks. Empty for the
25
+ * scenario-writing step and any non-track kind, so callers can append it
26
+ * unconditionally. The scenario author stays framework-agnostic by design.
27
+ */
28
+ export declare function testApproachSection(context: AgentRunContext): string;
29
+ //# sourceMappingURL=acceptance-prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acceptance-prompts.d.ts","sourceRoot":"","sources":["../../src/agents/acceptance-prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,qBAAqB,CAAA;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAwB1D,iEAAiE;AACjE,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAA;AAE9C,eAAO,MAAM,sBAAsB,EAAE,SAAS,mBAAmB,EAAmB,CAAA;AAsCpF,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,IAAI,mBAAmB,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAE1E;AAoBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAMjE;AAqBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAIpE"}
@@ -0,0 +1,112 @@
1
+ import { PLATFORM_DELIVERY_CONTRACT } from './ci-gate.js';
2
+ import { PLAYWRIGHT_E2E_TARGET_CONFIG_ID } from './agent-configs.js';
3
+ import { STANDARDS_FOOTER } from './prompt-shared.js';
4
+ export const ACCEPTANCE_AGENT_KINDS = ['playwright'];
5
+ // The runnable-tests step commits tests through a pull request. Tests only earn
6
+ // their keep once they actually run in CI, so "done" means the suite is wired into
7
+ // the project's CI configuration AND passes locally. The agent does NOT push or wait
8
+ // on CI itself (it has no push credentials) — the platform pushes, opens the PR and
9
+ // drives CI per the shared PLATFORM_DELIVERY_CONTRACT; the agent's job is to author
10
+ // the tests and hook them into the CI config.
11
+ const PLAYWRIGHT_DELIVERY_GATE = [
12
+ 'Definition of done: the acceptance tests are written, wired into the project CI configuration, and pass when you run them locally.',
13
+ '- Make sure the suite is actually hooked into the project CI workflow: confirm the workflow executes this suite on a pull request, and add or update the CI configuration if it does not yet run them. (Editing the CI config is part of the work; running CI is not — the platform does that.)',
14
+ PLATFORM_DELIVERY_CONTRACT,
15
+ ].join('\n');
16
+ const SYSTEM_PROMPTS = {
17
+ playwright: [
18
+ 'You are a test automation engineer owning the runnable ACCEPTANCE TESTS for a building block.',
19
+ 'Translate the agreed acceptance scenarios into runnable tests that live in the repository.',
20
+ '',
21
+ 'Pick the test tool to match the surface under test:',
22
+ '- Frontend / user-facing UI: write Playwright end-to-end tests that drive the app through the browser.',
23
+ "- Backend (services, APIs, queues, integrations, data): write the acceptance tests with the project's EXISTING test framework — discover it from the repository (test config, dev dependencies, the tests already present) and match it. Do not pull in Playwright or a browser for behaviour that has no UI.",
24
+ 'The run context below states the test approach for this specific block; follow it.',
25
+ '',
26
+ 'Approach:',
27
+ '- Treat the acceptance scenarios as the source of truth: prefer the Gherkin scenarios in `spec/features/*.feature` when present (each `Scenario` becomes one runnable test, named after it), else the scenarios provided above. One test per scenario so the mapping is obvious.',
28
+ '- Be additive and idempotent: only create tests for scenarios that do not already have one; never duplicate or silently rewrite an existing test.',
29
+ '- Exercise the system through its outermost interface and assert on observable behaviour — user-facing locators (roles, labels, text) for UI, public API / HTTP / message contracts for backend — never on internal implementation.',
30
+ '- Keep tests isolated and deterministic: no shared mutable state, await every action, and rely on auto-retrying assertions instead of fixed sleeps.',
31
+ '- Reach the system under test at the URL / entry point from the run context; read any access credentials from the harness, never hard-code secrets.',
32
+ '- Output the test files to commit, each in the conventional test directory for its tool (e.g. the e2e/Playwright directory for UI tests), ready to run in CI.',
33
+ '',
34
+ PLAYWRIGHT_DELIVERY_GATE,
35
+ '',
36
+ STANDARDS_FOOTER,
37
+ ].join('\n'),
38
+ };
39
+ /** True when the agent kind is part of the acceptance-testing track. */
40
+ export function isAcceptanceKind(kind) {
41
+ return kind === 'playwright';
42
+ }
43
+ /**
44
+ * The built-out system (role) prompt for an acceptance-testing agent kind, or
45
+ * `undefined` when the kind is not part of this track (so callers can fall
46
+ * through to the standard phases / generic role).
47
+ */
48
+ export function acceptanceSystemPrompt(kind) {
49
+ return isAcceptanceKind(kind) ? SYSTEM_PROMPTS[kind] : undefined;
50
+ }
51
+ // Where the generated tests run is a per-block choice, so it is dynamic context
52
+ // rather than part of the static role prompt. These blurbs tell the agent how
53
+ // to wire and where to point the tests for each target.
54
+ const TEST_TARGET_GUIDANCE = {
55
+ ci: [
56
+ 'Test execution target: project CI (GitHub Actions).',
57
+ '- Add the tests to the project so they run in a GitHub Actions workflow on each push / pull request.',
58
+ '- Spin the system under test up inside the same workflow run (e.g. a build/start step or a `services:` container) and wait for it to be healthy before the tests run.',
59
+ '- Point Playwright at the locally started service (e.g. http://localhost:<port>) via its config/baseURL; do not rely on an external environment.',
60
+ ].join('\n'),
61
+ ephemeral: [
62
+ 'Test execution target: the provisioned ephemeral environment for this run.',
63
+ '- Run the tests against the ephemeral environment URL from the run context, not a locally started service.',
64
+ '- Read any access credentials for that environment from the test harness/secrets; never hard-code them.',
65
+ '- Assume the environment is already deployed and healthy before the tests start.',
66
+ ].join('\n'),
67
+ };
68
+ /**
69
+ * The "where do the tests run" section for an acceptance-testing step, rendered
70
+ * from the block's contributed `playwright.e2eTarget` config value. Empty for
71
+ * non-track kinds or when no target is recorded, so callers can append it
72
+ * unconditionally.
73
+ */
74
+ export function e2eTargetSection(context) {
75
+ if (!isAcceptanceKind(context.agentKind))
76
+ return '';
77
+ const raw = context.block.agentConfig?.[PLAYWRIGHT_E2E_TARGET_CONFIG_ID];
78
+ const target = raw === 'ci' || raw === 'ephemeral' ? raw : undefined;
79
+ if (!target)
80
+ return '';
81
+ return `\n${TEST_TARGET_GUIDANCE[target]}`;
82
+ }
83
+ // Block types whose behaviour is exercised through a browser UI, so the runnable
84
+ // tests should be Playwright e2e. Everything else is backend behaviour that gets
85
+ // tested with the project's own framework. Mirrors how the `playwright.e2e`
86
+ // best-practice fragment is scoped in @cat-factory/prompt-fragments.
87
+ const UI_BLOCK_TYPES = ['frontend', 'environment'];
88
+ const UI_TEST_APPROACH = [
89
+ 'Test approach for this block: Playwright end-to-end tests.',
90
+ '- This block has a user-facing surface, so cover its scenarios with Playwright tests that drive the app through the browser.',
91
+ '- Select elements by user-facing locators (getByRole, getByLabel, getByText) and assert on what the user observes.',
92
+ ].join('\n');
93
+ const BACKEND_TEST_APPROACH = [
94
+ "Test approach for this block: the project's existing test framework (do NOT use Playwright).",
95
+ '- This block has no user-facing UI, so do not add Playwright or a browser to it.',
96
+ "- Discover the test framework already used in the repository (test config, dev dependencies, the tests already present) and write the acceptance tests with it, matching the project's conventions.",
97
+ '- Drive the system through its public interface (API / HTTP calls, queue messages, exported functions) and assert on observable behaviour, never on internals.',
98
+ ].join('\n');
99
+ /**
100
+ * The "how should these tests be written" section for the runnable-tests step
101
+ * (`playwright` kind), chosen from the block type: Playwright for user-facing
102
+ * blocks, the project's own test framework for backend blocks. Empty for the
103
+ * scenario-writing step and any non-track kind, so callers can append it
104
+ * unconditionally. The scenario author stays framework-agnostic by design.
105
+ */
106
+ export function testApproachSection(context) {
107
+ if (context.agentKind !== 'playwright')
108
+ return '';
109
+ const isUi = UI_BLOCK_TYPES.includes(context.block.type);
110
+ return `\n${isUi ? UI_TEST_APPROACH : BACKEND_TEST_APPROACH}`;
111
+ }
112
+ //# sourceMappingURL=acceptance-prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acceptance-prompts.js","sourceRoot":"","sources":["../../src/agents/acceptance-prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { AgentKind } from '@cat-factory/kernel';
2
+ import type { AgentRunContext } from '@cat-factory/kernel';
3
+ export declare function systemPromptFor(kind: AgentKind): string;
4
+ /** Build the user prompt from the block context and the run so far. */
5
+ export declare function userPromptFor(context: AgentRunContext): string;
6
+ //# sourceMappingURL=agent-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-catalog.d.ts","sourceRoot":"","sources":["../../src/agents/agent-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAqE1D,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAUvD;AAmED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAE9D"}
@@ -0,0 +1,197 @@
1
+ import { acceptanceSystemPrompt, testApproachSection, e2eTargetSection, } from './acceptance-prompts.js';
2
+ import { companionSystemPrompt } from './companion-prompts.js';
3
+ import { companionTargets, isCompanionKind } from './companions.js';
4
+ import { READ_ONLY_GUARDRAIL, isReadOnlyAgentKind } from './read-only.js';
5
+ import { businessLogicSystemPrompt } from './business-logic-prompts.js';
6
+ import { mockSystemPrompt } from './mock-prompts.js';
7
+ import { testingSystemPrompt, testerEnvironmentSection } from './test-prompts.js';
8
+ import { registeredSystemPrompt, registeredUserPrompt } from './registry.js';
9
+ import { traitGuidanceFor } from './traits.js';
10
+ import { environmentSection, linkedContextSection, phaseForKind, renderStandardUserPrompt, standardSystemPrompt, } from './standard-prompts.js';
11
+ // Role definitions and prompt construction for the built-in agent kinds. These
12
+ // turn an agent kind + block context into the system/user prompts handed to the
13
+ // LLM. The four standard solution phases — design (architect), build (coder),
14
+ // review (reviewer) and test (tester) — use the built-out prompts in
15
+ // ./standard-prompts; the acceptance-testing track (acceptance, playwright) uses
16
+ // the built-out prompts in ./acceptance-prompts; the mock builder (mocker) uses
17
+ // the built-out prompt in ./mock-prompts; the business-logic / domain-rules track
18
+ // (business-documenter, business-reviewer) uses the built-out prompts in
19
+ // ./business-logic-prompts; the remaining kinds use the thin roles below, and
20
+ // custom agent kinds (free-form ids) fall back to a generic role.
21
+ const ROLES = {
22
+ researcher: 'You are a technical researcher. Investigate prior art, libraries and constraints relevant to the building block and summarise concrete recommendations.',
23
+ // Opens the tech-debt recurring pipeline. Clones the repo and inspects it for the
24
+ // highest-value technical debt; it MUST be read-only (make no edits / commits) and
25
+ // produce a single, prioritized, actionable markdown report that a downstream
26
+ // `tracker` step files as an issue and a `coder` step then implements.
27
+ analysis: 'You are a senior engineer performing a technical-debt audit of this service. Explore the repository (build scripts, dependencies, tests, hot spots, TODO/FIXME markers, outdated patterns) and identify the highest-value technical debt to address now. Produce a single prioritized markdown report: for each item give a short title, the affected area, why it matters, and a concrete suggested fix. Lead with the one item most worth doing first, since it will be turned into a tracked issue and implemented.',
28
+ documenter: 'You are a technical writer. Produce concise developer documentation and a usage example for the building block.',
29
+ integrator: 'You are an integration engineer. Describe how to wire this building block into the surrounding system, including contracts and rollout.',
30
+ // Runs before the architect: reviews the collected CONTEXT (the linked-prose brief)
31
+ // and surfaces what would block confident implementation. Its findings are presented
32
+ // to a human at an approval gate (to reject items or supply missing information)
33
+ // before the architect proceeds, so it must read as a clear, editable list.
34
+ 'requirements-review': 'You are a meticulous product / requirements analyst reviewing the collected requirements for a single building block before an engineer designs or builds it. Surface everything that would block confident implementation: missing information (gaps), ambiguities that need clarification, unstated assumptions, risks, and open questions. Be specific, concrete and actionable, and phrase each item so a product owner can answer it directly. Do NOT invent answers or requirements. Group your findings under clear headings and present a concise, readable markdown list — a human will review and edit it before the architect proceeds.',
35
+ // Runs in a container against the PR head branch when CI is red. It must make the
36
+ // failing build/tests pass with the smallest correct change and push to the same
37
+ // branch (no new branch / PR) so CI re-runs.
38
+ 'ci-fixer': 'You are a CI/build engineer. The pull request on this branch has failing CI. Reproduce the failure locally (run the project build / tests), diagnose the root cause, and make the minimal correct change to get every check passing. Do not disable or skip tests to make them pass. Commit your fix to the current branch.',
39
+ // Runs in a container against the PR head branch when the PR conflicts with its
40
+ // base. The harness has already merged the base in, leaving conflict markers; the
41
+ // agent resolves every one and the harness completes the merge commit + pushes to
42
+ // the same branch (no new branch / PR).
43
+ 'conflict-resolver': 'You are a software engineer resolving a merge conflict. The base branch has been merged into this pull-request branch, leaving Git conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`) in one or more files. Find every conflicted file, understand both sides of each conflict, and edit the files to a correct, coherent result that preserves the intent of BOTH the PR changes and the base changes — never just discard one side. Remove all conflict markers and leave the project building. Do not open a new branch or PR; commit your resolution to the current branch.',
44
+ // Runs in a container against the PR head branch as the final pipeline step. It
45
+ // ONLY assesses — it must not modify the repo — and returns a JSON score object.
46
+ merger: 'You are a release manager assessing a pull request before merge. Inspect the change against the base branch and judge three axes, each from 0 (trivial/safe) to 1 (severe): complexity, risk and impact. Be conservative. Make no commits. Respond with ONLY a JSON object {"complexity":0.0,"risk":0.0,"impact":0.0,"rationale":"…"} — no prose, no code fences.',
47
+ };
48
+ export function systemPromptFor(kind) {
49
+ const base = baseSystemPromptFor(kind);
50
+ // Read-only kinds (architect, analysis) explore a real checkout but must never edit
51
+ // it; append the shared guardrail so the harness `/explore` run stays edit-free.
52
+ const withGuardrail = isReadOnlyAgentKind(kind) ? `${base}\n\n${READ_ONLY_GUARDRAIL}` : base;
53
+ // Fold in any guidance contributed by the kind's traits (e.g. the spec-aware kinds get
54
+ // the in-repo-spec reading guidance). Marker traits like `code-aware` add nothing here —
55
+ // their effect (folding the service's fragments) is applied by the execution engine.
56
+ const guidance = traitGuidanceFor(kind);
57
+ return guidance.length ? `${withGuardrail}\n\n${guidance.join('\n\n')}` : withGuardrail;
58
+ }
59
+ function baseSystemPromptFor(kind) {
60
+ // Companion kinds (reviewer, architect-companion, spec-companion, …) win over every
61
+ // built-in track: they grade a prior step's output and return a JSON rating.
62
+ const companion = companionSystemPrompt(kind);
63
+ if (companion)
64
+ return companion;
65
+ const phase = phaseForKind(kind);
66
+ if (phase)
67
+ return standardSystemPrompt(phase);
68
+ // The Tester/Fixer track runs in a container and returns a structured report /
69
+ // pushes fixes; it owns its own prompts rather than the generic `test` phase.
70
+ const testing = testingSystemPrompt(kind);
71
+ if (testing)
72
+ return testing;
73
+ const acceptance = acceptanceSystemPrompt(kind);
74
+ if (acceptance)
75
+ return acceptance;
76
+ const mock = mockSystemPrompt(kind);
77
+ if (mock)
78
+ return mock;
79
+ const businessLogic = businessLogicSystemPrompt(kind);
80
+ if (businessLogic)
81
+ return businessLogic;
82
+ // Custom kinds registered by a deployment (e.g. a proprietary org package) win over
83
+ // the generic fallback below, but never shadow the built-in tracks above.
84
+ const registered = registeredSystemPrompt(kind);
85
+ if (registered !== undefined)
86
+ return registered;
87
+ return (ROLES[kind] ??
88
+ `You are the "${kind}" agent. Do your part of the work for the given building block and report the result concisely.`);
89
+ }
90
+ /**
91
+ * When a human requested changes on this step's gated proposal, append their
92
+ * feedback and the previous proposal so the agent revises rather than restarts.
93
+ * Applied to every inline agent kind (standard-phase and generic alike).
94
+ */
95
+ function withRevision(prompt, context) {
96
+ const revision = context.revision;
97
+ if (!revision)
98
+ return prompt;
99
+ const lines = [
100
+ prompt,
101
+ '',
102
+ 'A human reviewed your previous proposal and requested changes. Revise that',
103
+ 'proposal to address their feedback — keep what still holds, change what they',
104
+ 'flagged. Do not start from scratch.',
105
+ '',
106
+ 'Your previous proposal:',
107
+ revision.previousProposal || '(empty)',
108
+ '',
109
+ 'Reviewer feedback:',
110
+ revision.feedback || '(none given)',
111
+ ];
112
+ // Per-block comments the reviewer left on specific parts of the proposal. Each
113
+ // quotes the exact text it targets, so the agent can locate and revise it.
114
+ if (revision.comments?.length) {
115
+ lines.push('', 'Comments on specific parts of your proposal:');
116
+ for (const c of revision.comments) {
117
+ lines.push('', 'On this part:', c.quotedSource || '(empty)', 'Comment:', c.body || '(none given)');
118
+ }
119
+ }
120
+ return lines.join('\n');
121
+ }
122
+ /** Build the user prompt from the block context and the run so far. */
123
+ export function userPromptFor(context) {
124
+ return withRevision(buildBaseUserPrompt(context), context);
125
+ }
126
+ function buildBaseUserPrompt(context) {
127
+ // Standard phases get their built-out, templated user prompt.
128
+ const phase = phaseForKind(context.agentKind);
129
+ if (phase)
130
+ return renderStandardUserPrompt(phase, context);
131
+ // A registered custom kind may supply its own user prompt; otherwise it falls through
132
+ // to the generic block-context prompt below, like any other non-standard-phase kind.
133
+ const registered = registeredUserPrompt(context);
134
+ if (registered !== undefined)
135
+ return registered;
136
+ const { block, pipelineName, priorOutputs, decisions, resolvedDecision } = context;
137
+ const lines = [
138
+ `Pipeline: ${pipelineName}`,
139
+ `Block: ${block.title} (${block.type})`,
140
+ `Description: ${block.description || '(none provided)'}`,
141
+ ];
142
+ // A companion grades a specific preceding producer; name it explicitly so the
143
+ // model rates the right output rather than guessing among the prior-agent sections.
144
+ const companionTarget = companionTargetSection(context);
145
+ if (companionTarget)
146
+ lines.push(companionTarget);
147
+ const linked = linkedContextSection(context);
148
+ if (linked)
149
+ lines.push(linked);
150
+ const envSection = environmentSection(context);
151
+ if (envSection)
152
+ lines.push(envSection);
153
+ const approachSection = testApproachSection(context);
154
+ if (approachSection)
155
+ lines.push(approachSection);
156
+ const targetSection = e2eTargetSection(context);
157
+ if (targetSection)
158
+ lines.push(targetSection);
159
+ const testerEnv = testerEnvironmentSection(context);
160
+ if (testerEnv)
161
+ lines.push(testerEnv);
162
+ const allDecisions = resolvedDecision ? [...decisions, resolvedDecision] : decisions;
163
+ if (allDecisions.length) {
164
+ lines.push('', 'Resolved decisions:');
165
+ for (const d of allDecisions)
166
+ lines.push(`- ${d.question} → ${d.chosen}`);
167
+ }
168
+ if (priorOutputs.length) {
169
+ lines.push('', 'Work from earlier agents in this pipeline:');
170
+ for (const p of priorOutputs) {
171
+ lines.push(`### ${p.agentKind}`, p.output);
172
+ }
173
+ }
174
+ lines.push('', 'Produce your contribution. Be concise and concrete.');
175
+ return lines.join('\n');
176
+ }
177
+ /**
178
+ * For a companion step, name the specific producer output it must grade: the NEAREST
179
+ * preceding step whose kind is one of the companion's targets. Without this the model
180
+ * has to infer which "### <agentKind>" section is the one under review — fine when the
181
+ * producer is adjacent, ambiguous when other steps sit in between. Undefined for
182
+ * non-companion kinds or when no target output is present yet.
183
+ */
184
+ function companionTargetSection(context) {
185
+ if (!isCompanionKind(context.agentKind))
186
+ return undefined;
187
+ const targets = companionTargets(context.agentKind);
188
+ for (let i = context.priorOutputs.length - 1; i >= 0; i--) {
189
+ const produced = context.priorOutputs[i];
190
+ if (targets.includes(produced.agentKind)) {
191
+ return (`You are grading the output of the \`${produced.agentKind}\` step (shown under ` +
192
+ `"### ${produced.agentKind}" below). Base your rating on THAT output.`);
193
+ }
194
+ }
195
+ return undefined;
196
+ }
197
+ //# sourceMappingURL=agent-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-catalog.js","sourceRoot":"","sources":["../../src/agents/agent-catalog.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AACjF,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,uBAAuB,CAAA;AAE9B,+EAA+E;AAC/E,gFAAgF;AAChF,8EAA8E;AAC9E,qEAAqE;AACrE,iFAAiF;AACjF,gFAAgF;AAChF,kFAAkF;AAClF,yEAAyE;AACzE,8EAA8E;AAC9E,kEAAkE;AAElE,MAAM,KAAK,GAAuC;IAChD,UAAU,EACR,yJAAyJ;IAC3J,kFAAkF;IAClF,mFAAmF;IACnF,8EAA8E;IAC9E,uEAAuE;IACvE,QAAQ,EACN,wfAAwf;IAC1f,UAAU,EACR,iHAAiH;IACnH,UAAU,EACR,yIAAyI;IAC3I,oFAAoF;IACpF,qFAAqF;IACrF,iFAAiF;IACjF,4EAA4E;IAC5E,qBAAqB,EACnB,onBAAonB;IACtnB,kFAAkF;IAClF,iFAAiF;IACjF,6CAA6C;IAC7C,UAAU,EACR,6TAA6T;IAC/T,gFAAgF;IAChF,kFAAkF;IAClF,kFAAkF;IAClF,wCAAwC;IACxC,mBAAmB,EACjB,ijBAAijB;IACnjB,gFAAgF;IAChF,iFAAiF;IACjF,MAAM,EACJ,mWAAmW;CACtW,CAAA;AAED,MAAM,UAAU,eAAe,CAAC,IAAe;IAC7C,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAA;IACtC,oFAAoF;IACpF,iFAAiF;IACjF,MAAM,aAAa,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,mBAAmB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAC5F,uFAAuF;IACvF,yFAAyF;IACzF,qFAAqF;IACrF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACvC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,aAAa,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAA;AACzF,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAe;IAC1C,oFAAoF;IACpF,6EAA6E;IAC7E,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;IAC7C,IAAI,SAAS;QAAE,OAAO,SAAS,CAAA;IAC/B,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IAChC,IAAI,KAAK;QAAE,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAC7C,+EAA+E;IAC/E,8EAA8E;IAC9E,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAA;IACzC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAA;IAC3B,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;IAC/C,IAAI,UAAU;QAAE,OAAO,UAAU,CAAA;IACjC,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,IAAI;QAAE,OAAO,IAAI,CAAA;IACrB,MAAM,aAAa,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAA;IACrD,IAAI,aAAa;QAAE,OAAO,aAAa,CAAA;IACvC,oFAAoF;IACpF,0EAA0E;IAC1E,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAA;IAC/C,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAA;IAC/C,OAAO,CACL,KAAK,CAAC,IAAI,CAAC;QACX,gBAAgB,IAAI,iGAAiG,CACtH,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,MAAc,EAAE,OAAwB;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IACjC,IAAI,CAAC,QAAQ;QAAE,OAAO,MAAM,CAAA;IAC5B,MAAM,KAAK,GAAG;QACZ,MAAM;QACN,EAAE;QACF,4EAA4E;QAC5E,8EAA8E;QAC9E,qCAAqC;QACrC,EAAE;QACF,yBAAyB;QACzB,QAAQ,CAAC,gBAAgB,IAAI,SAAS;QACtC,EAAE;QACF,oBAAoB;QACpB,QAAQ,CAAC,QAAQ,IAAI,cAAc;KACpC,CAAA;IACD,+EAA+E;IAC/E,2EAA2E;IAC3E,IAAI,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,8CAA8C,CAAC,CAAA;QAC9D,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CACR,EAAE,EACF,eAAe,EACf,CAAC,CAAC,YAAY,IAAI,SAAS,EAC3B,UAAU,EACV,CAAC,CAAC,IAAI,IAAI,cAAc,CACzB,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,aAAa,CAAC,OAAwB;IACpD,OAAO,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;AAC5D,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAwB;IACnD,8DAA8D;IAC9D,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC7C,IAAI,KAAK;QAAE,OAAO,wBAAwB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAE1D,sFAAsF;IACtF,qFAAqF;IACrF,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAChD,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAA;IAE/C,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAA;IAClF,MAAM,KAAK,GAAa;QACtB,aAAa,YAAY,EAAE;QAC3B,UAAU,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,GAAG;QACvC,gBAAgB,KAAK,CAAC,WAAW,IAAI,iBAAiB,EAAE;KACzD,CAAA;IACD,8EAA8E;IAC9E,oFAAoF;IACpF,MAAM,eAAe,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAA;IACvD,IAAI,eAAe;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IAChD,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAC5C,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC9B,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;IAC9C,IAAI,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACtC,MAAM,eAAe,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAA;IACpD,IAAI,eAAe;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;IAChD,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAC/C,IAAI,aAAa;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IAC5C,MAAM,SAAS,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAA;IACnD,IAAI,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACpC,MAAM,YAAY,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACpF,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAA;QACrC,KAAK,MAAM,CAAC,IAAI,YAAY;YAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;IAC3E,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,4CAA4C,CAAC,CAAA;QAC5D,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,qDAAqD,CAAC,CAAA;IACrE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,sBAAsB,CAAC,OAAwB;IACtD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAA;IACzD,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACnD,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1D,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAE,CAAA;QACzC,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,OAAO,CACL,uCAAuC,QAAQ,CAAC,SAAS,uBAAuB;gBAChF,QAAQ,QAAQ,CAAC,SAAS,4CAA4C,CACvE,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { AgentConfigDescriptor, AgentKind } from '@cat-factory/kernel';
2
+ /** The Tester's environment choice: stand infra up locally, or use the ephemeral env. */
3
+ export declare const TESTER_ENVIRONMENT_CONFIG_ID = "tester.environment";
4
+ /** The acceptance/e2e execution target: project CI, or the ephemeral env. */
5
+ export declare const PLAYWRIGHT_E2E_TARGET_CONFIG_ID = "playwright.e2eTarget";
6
+ /**
7
+ * The config descriptors an agent kind contributes: the built-in ones plus any a
8
+ * deployment registered for the kind. Empty for kinds that contribute none.
9
+ */
10
+ export declare function configContributionsFor(kind: AgentKind): AgentConfigDescriptor[];
11
+ /**
12
+ * The deduplicated catalog of config descriptors contributed across a set of agent
13
+ * kinds (e.g. all the kinds used by a workspace's pipelines), keyed by descriptor
14
+ * id (first contribution wins). This is what the workspace snapshot carries.
15
+ */
16
+ export declare function configContributionCatalog(kinds: Iterable<AgentKind>): AgentConfigDescriptor[];
17
+ //# sourceMappingURL=agent-configs.d.ts.map