@open-mercato/ai-assistant 0.6.6-develop.6465.1.019f0fb26f → 0.6.6-develop.6471.1.9ab5bdd79a

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 (199) hide show
  1. package/dist/frontend/hooks/useCommandPalette.js +16 -14
  2. package/dist/frontend/hooks/useCommandPalette.js.map +2 -2
  3. package/dist/modules/ai_assistant/api/ai/actions/[id]/cancel/route.js +3 -1
  4. package/dist/modules/ai_assistant/api/ai/actions/[id]/cancel/route.js.map +2 -2
  5. package/dist/modules/ai_assistant/api/ai/actions/[id]/confirm/route.js +3 -1
  6. package/dist/modules/ai_assistant/api/ai/actions/[id]/confirm/route.js.map +2 -2
  7. package/dist/modules/ai_assistant/api/ai/actions/[id]/route.js +3 -1
  8. package/dist/modules/ai_assistant/api/ai/actions/[id]/route.js.map +2 -2
  9. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/loop-override/route.js +5 -3
  10. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/loop-override/route.js.map +2 -2
  11. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/models/route.js +4 -2
  12. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/models/route.js.map +2 -2
  13. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/route.js +5 -3
  14. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/route.js.map +2 -2
  15. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/route.js +4 -2
  16. package/dist/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/route.js.map +2 -2
  17. package/dist/modules/ai_assistant/api/ai/agents/route.js +3 -1
  18. package/dist/modules/ai_assistant/api/ai/agents/route.js.map +2 -2
  19. package/dist/modules/ai_assistant/api/ai/chat/route.js +6 -7
  20. package/dist/modules/ai_assistant/api/ai/chat/route.js.map +2 -2
  21. package/dist/modules/ai_assistant/api/ai/conversations/[conversationId]/route.js +5 -3
  22. package/dist/modules/ai_assistant/api/ai/conversations/[conversationId]/route.js.map +2 -2
  23. package/dist/modules/ai_assistant/api/ai/conversations/import/route.js +3 -1
  24. package/dist/modules/ai_assistant/api/ai/conversations/import/route.js.map +2 -2
  25. package/dist/modules/ai_assistant/api/ai/conversations/route.js +4 -2
  26. package/dist/modules/ai_assistant/api/ai/conversations/route.js.map +2 -2
  27. package/dist/modules/ai_assistant/api/ai/run-object/route.js +3 -1
  28. package/dist/modules/ai_assistant/api/ai/run-object/route.js.map +2 -2
  29. package/dist/modules/ai_assistant/api/chat/route.js +23 -14
  30. package/dist/modules/ai_assistant/api/chat/route.js.map +2 -2
  31. package/dist/modules/ai_assistant/api/health/route.js +3 -1
  32. package/dist/modules/ai_assistant/api/health/route.js.map +2 -2
  33. package/dist/modules/ai_assistant/api/mcp-key/route.js +3 -1
  34. package/dist/modules/ai_assistant/api/mcp-key/route.js.map +2 -2
  35. package/dist/modules/ai_assistant/api/route/route.js +11 -9
  36. package/dist/modules/ai_assistant/api/route/route.js.map +2 -2
  37. package/dist/modules/ai_assistant/api/session-key/route.js +3 -1
  38. package/dist/modules/ai_assistant/api/session-key/route.js.map +2 -2
  39. package/dist/modules/ai_assistant/api/settings/allowlist/route.js +4 -2
  40. package/dist/modules/ai_assistant/api/settings/allowlist/route.js.map +2 -2
  41. package/dist/modules/ai_assistant/api/settings/route.js +6 -4
  42. package/dist/modules/ai_assistant/api/settings/route.js.map +2 -2
  43. package/dist/modules/ai_assistant/api/tools/execute/route.js +3 -1
  44. package/dist/modules/ai_assistant/api/tools/execute/route.js.map +2 -2
  45. package/dist/modules/ai_assistant/api/tools/route.js +3 -1
  46. package/dist/modules/ai_assistant/api/tools/route.js.map +2 -2
  47. package/dist/modules/ai_assistant/api/usage/daily/route.js +3 -1
  48. package/dist/modules/ai_assistant/api/usage/daily/route.js.map +2 -2
  49. package/dist/modules/ai_assistant/api/usage/sessions/[sessionId]/route.js +3 -1
  50. package/dist/modules/ai_assistant/api/usage/sessions/[sessionId]/route.js.map +2 -2
  51. package/dist/modules/ai_assistant/api/usage/sessions/route.js +3 -1
  52. package/dist/modules/ai_assistant/api/usage/sessions/route.js.map +2 -2
  53. package/dist/modules/ai_assistant/cli.js +3 -0
  54. package/dist/modules/ai_assistant/cli.js.map +2 -2
  55. package/dist/modules/ai_assistant/lib/agent-policy.js +7 -5
  56. package/dist/modules/ai_assistant/lib/agent-policy.js.map +2 -2
  57. package/dist/modules/ai_assistant/lib/agent-registry.js +11 -13
  58. package/dist/modules/ai_assistant/lib/agent-registry.js.map +2 -2
  59. package/dist/modules/ai_assistant/lib/agent-runtime.js +21 -44
  60. package/dist/modules/ai_assistant/lib/agent-runtime.js.map +2 -2
  61. package/dist/modules/ai_assistant/lib/agent-tools.js +5 -10
  62. package/dist/modules/ai_assistant/lib/agent-tools.js.map +2 -2
  63. package/dist/modules/ai_assistant/lib/ai-overrides.js +5 -9
  64. package/dist/modules/ai_assistant/lib/ai-overrides.js.map +2 -2
  65. package/dist/modules/ai_assistant/lib/api-endpoint-index.js +22 -22
  66. package/dist/modules/ai_assistant/lib/api-endpoint-index.js.map +2 -2
  67. package/dist/modules/ai_assistant/lib/attachment-parts.js +10 -26
  68. package/dist/modules/ai_assistant/lib/attachment-parts.js.map +2 -2
  69. package/dist/modules/ai_assistant/lib/auth.js +3 -1
  70. package/dist/modules/ai_assistant/lib/auth.js.map +2 -2
  71. package/dist/modules/ai_assistant/lib/codemode-tools.js +15 -17
  72. package/dist/modules/ai_assistant/lib/codemode-tools.js.map +2 -2
  73. package/dist/modules/ai_assistant/lib/entity-index.js +7 -5
  74. package/dist/modules/ai_assistant/lib/entity-index.js.map +2 -2
  75. package/dist/modules/ai_assistant/lib/generated-registry-loader.js +3 -4
  76. package/dist/modules/ai_assistant/lib/generated-registry-loader.js.map +2 -2
  77. package/dist/modules/ai_assistant/lib/http-server.js +45 -48
  78. package/dist/modules/ai_assistant/lib/http-server.js.map +2 -2
  79. package/dist/modules/ai_assistant/lib/llm-bootstrap.js +5 -12
  80. package/dist/modules/ai_assistant/lib/llm-bootstrap.js.map +2 -2
  81. package/dist/modules/ai_assistant/lib/mcp-client.js +3 -1
  82. package/dist/modules/ai_assistant/lib/mcp-client.js.map +2 -2
  83. package/dist/modules/ai_assistant/lib/mcp-dev-key-resolution.js +3 -1
  84. package/dist/modules/ai_assistant/lib/mcp-dev-key-resolution.js.map +2 -2
  85. package/dist/modules/ai_assistant/lib/mcp-dev-server.js +3 -1
  86. package/dist/modules/ai_assistant/lib/mcp-dev-server.js.map +2 -2
  87. package/dist/modules/ai_assistant/lib/mcp-server.js +24 -19
  88. package/dist/modules/ai_assistant/lib/mcp-server.js.map +2 -2
  89. package/dist/modules/ai_assistant/lib/mcp-tool-adapter.js +3 -1
  90. package/dist/modules/ai_assistant/lib/mcp-tool-adapter.js.map +2 -2
  91. package/dist/modules/ai_assistant/lib/model-factory.js +4 -2
  92. package/dist/modules/ai_assistant/lib/model-factory.js.map +2 -2
  93. package/dist/modules/ai_assistant/lib/opencode-client.js +5 -3
  94. package/dist/modules/ai_assistant/lib/opencode-client.js.map +2 -2
  95. package/dist/modules/ai_assistant/lib/opencode-handlers.js +30 -12
  96. package/dist/modules/ai_assistant/lib/opencode-handlers.js.map +2 -2
  97. package/dist/modules/ai_assistant/lib/pending-action-cancel.js +3 -1
  98. package/dist/modules/ai_assistant/lib/pending-action-cancel.js.map +2 -2
  99. package/dist/modules/ai_assistant/lib/pending-action-executor.js +3 -1
  100. package/dist/modules/ai_assistant/lib/pending-action-executor.js.map +2 -2
  101. package/dist/modules/ai_assistant/lib/prepare-mutation.js +4 -6
  102. package/dist/modules/ai_assistant/lib/prepare-mutation.js.map +2 -2
  103. package/dist/modules/ai_assistant/lib/schema-utils.js +3 -1
  104. package/dist/modules/ai_assistant/lib/schema-utils.js.map +2 -2
  105. package/dist/modules/ai_assistant/lib/token-usage-recorder.js +4 -8
  106. package/dist/modules/ai_assistant/lib/token-usage-recorder.js.map +2 -2
  107. package/dist/modules/ai_assistant/lib/tool-executor.js +3 -1
  108. package/dist/modules/ai_assistant/lib/tool-executor.js.map +2 -2
  109. package/dist/modules/ai_assistant/lib/tool-loader.js +18 -25
  110. package/dist/modules/ai_assistant/lib/tool-loader.js.map +2 -2
  111. package/dist/modules/ai_assistant/lib/tool-registry.js +3 -1
  112. package/dist/modules/ai_assistant/lib/tool-registry.js.map +2 -2
  113. package/dist/modules/ai_assistant/lib/tool-test-runner.js +3 -1
  114. package/dist/modules/ai_assistant/lib/tool-test-runner.js.map +2 -2
  115. package/dist/modules/ai_assistant/setup.js +4 -8
  116. package/dist/modules/ai_assistant/setup.js.map +2 -2
  117. package/dist/modules/ai_assistant/subscribers/conversation-shared-notify.js +3 -1
  118. package/dist/modules/ai_assistant/subscribers/conversation-shared-notify.js.map +2 -2
  119. package/dist/modules/ai_assistant/workers/ai-pending-action-cleanup.js +7 -19
  120. package/dist/modules/ai_assistant/workers/ai-pending-action-cleanup.js.map +2 -2
  121. package/dist/modules/ai_assistant/workers/ai-token-usage-prune.js +5 -11
  122. package/dist/modules/ai_assistant/workers/ai-token-usage-prune.js.map +2 -2
  123. package/package.json +6 -6
  124. package/src/frontend/hooks/useCommandPalette.ts +17 -16
  125. package/src/modules/ai_assistant/__tests__/events.test.ts +23 -5
  126. package/src/modules/ai_assistant/__tests__/integration/ws-c-attachment-bridge.test.ts +21 -3
  127. package/src/modules/ai_assistant/__tests__/integration/ws-c-policy-and-tools.test.ts +22 -3
  128. package/src/modules/ai_assistant/__tests__/token-usage-recorder.test.ts +26 -5
  129. package/src/modules/ai_assistant/api/ai/actions/[id]/cancel/route.ts +4 -1
  130. package/src/modules/ai_assistant/api/ai/actions/[id]/confirm/route.ts +4 -1
  131. package/src/modules/ai_assistant/api/ai/actions/[id]/route.ts +4 -1
  132. package/src/modules/ai_assistant/api/ai/agents/[agentId]/loop-override/route.ts +6 -3
  133. package/src/modules/ai_assistant/api/ai/agents/[agentId]/models/route.ts +5 -2
  134. package/src/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/route.ts +6 -3
  135. package/src/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/route.ts +5 -2
  136. package/src/modules/ai_assistant/api/ai/agents/route.ts +4 -1
  137. package/src/modules/ai_assistant/api/ai/chat/route.ts +7 -7
  138. package/src/modules/ai_assistant/api/ai/conversations/[conversationId]/route.ts +6 -3
  139. package/src/modules/ai_assistant/api/ai/conversations/import/route.ts +4 -1
  140. package/src/modules/ai_assistant/api/ai/conversations/route.ts +5 -2
  141. package/src/modules/ai_assistant/api/ai/run-object/route.ts +4 -1
  142. package/src/modules/ai_assistant/api/chat/route.ts +24 -15
  143. package/src/modules/ai_assistant/api/health/route.ts +4 -1
  144. package/src/modules/ai_assistant/api/mcp-key/route.ts +4 -1
  145. package/src/modules/ai_assistant/api/route/route.ts +12 -9
  146. package/src/modules/ai_assistant/api/session-key/route.ts +4 -1
  147. package/src/modules/ai_assistant/api/settings/allowlist/route.ts +5 -2
  148. package/src/modules/ai_assistant/api/settings/route.ts +7 -4
  149. package/src/modules/ai_assistant/api/tools/execute/route.ts +4 -1
  150. package/src/modules/ai_assistant/api/tools/route.ts +4 -1
  151. package/src/modules/ai_assistant/api/usage/daily/route.ts +4 -1
  152. package/src/modules/ai_assistant/api/usage/sessions/[sessionId]/route.ts +4 -1
  153. package/src/modules/ai_assistant/api/usage/sessions/route.ts +4 -1
  154. package/src/modules/ai_assistant/cli.ts +5 -0
  155. package/src/modules/ai_assistant/lib/__tests__/agent-policy.mutation-override.test.ts +20 -2
  156. package/src/modules/ai_assistant/lib/__tests__/agent-registry.test.ts +25 -5
  157. package/src/modules/ai_assistant/lib/__tests__/agent-runtime-loop-phase0.test.ts +21 -2
  158. package/src/modules/ai_assistant/lib/__tests__/agent-runtime-parity.test.ts +23 -3
  159. package/src/modules/ai_assistant/lib/__tests__/agent-runtime-phase4a.test.ts +20 -2
  160. package/src/modules/ai_assistant/lib/__tests__/agent-tools.test.ts +22 -3
  161. package/src/modules/ai_assistant/lib/__tests__/ai-overrides.test.ts +23 -3
  162. package/src/modules/ai_assistant/lib/__tests__/attachment-parts.test.ts +25 -7
  163. package/src/modules/ai_assistant/lib/__tests__/model-factory.test.ts +25 -5
  164. package/src/modules/ai_assistant/lib/__tests__/pending-action-cancel.test.ts +19 -1
  165. package/src/modules/ai_assistant/lib/__tests__/prepare-mutation.test.ts +22 -3
  166. package/src/modules/ai_assistant/lib/agent-policy.ts +8 -5
  167. package/src/modules/ai_assistant/lib/agent-registry.ts +12 -15
  168. package/src/modules/ai_assistant/lib/agent-runtime.ts +23 -46
  169. package/src/modules/ai_assistant/lib/agent-tools.ts +7 -11
  170. package/src/modules/ai_assistant/lib/ai-overrides.ts +6 -9
  171. package/src/modules/ai_assistant/lib/api-endpoint-index.ts +23 -22
  172. package/src/modules/ai_assistant/lib/attachment-parts.ts +14 -29
  173. package/src/modules/ai_assistant/lib/auth.ts +4 -1
  174. package/src/modules/ai_assistant/lib/codemode-tools.ts +17 -17
  175. package/src/modules/ai_assistant/lib/entity-index.ts +8 -5
  176. package/src/modules/ai_assistant/lib/generated-registry-loader.ts +4 -4
  177. package/src/modules/ai_assistant/lib/http-server.ts +46 -48
  178. package/src/modules/ai_assistant/lib/llm-bootstrap.ts +7 -13
  179. package/src/modules/ai_assistant/lib/mcp-client.ts +4 -1
  180. package/src/modules/ai_assistant/lib/mcp-dev-key-resolution.ts +4 -1
  181. package/src/modules/ai_assistant/lib/mcp-dev-server.ts +4 -1
  182. package/src/modules/ai_assistant/lib/mcp-server.ts +27 -19
  183. package/src/modules/ai_assistant/lib/mcp-tool-adapter.ts +4 -1
  184. package/src/modules/ai_assistant/lib/model-factory.ts +6 -3
  185. package/src/modules/ai_assistant/lib/opencode-client.ts +6 -3
  186. package/src/modules/ai_assistant/lib/opencode-handlers.ts +32 -12
  187. package/src/modules/ai_assistant/lib/pending-action-cancel.ts +4 -1
  188. package/src/modules/ai_assistant/lib/pending-action-executor.ts +4 -1
  189. package/src/modules/ai_assistant/lib/prepare-mutation.ts +5 -6
  190. package/src/modules/ai_assistant/lib/schema-utils.ts +4 -1
  191. package/src/modules/ai_assistant/lib/token-usage-recorder.ts +5 -8
  192. package/src/modules/ai_assistant/lib/tool-executor.ts +4 -1
  193. package/src/modules/ai_assistant/lib/tool-loader.ts +19 -25
  194. package/src/modules/ai_assistant/lib/tool-registry.ts +4 -1
  195. package/src/modules/ai_assistant/lib/tool-test-runner.ts +4 -1
  196. package/src/modules/ai_assistant/setup.ts +5 -8
  197. package/src/modules/ai_assistant/subscribers/conversation-shared-notify.ts +4 -1
  198. package/src/modules/ai_assistant/workers/ai-pending-action-cleanup.ts +8 -19
  199. package/src/modules/ai_assistant/workers/ai-token-usage-prune.ts +6 -11
@@ -1,3 +1,4 @@
1
+ import { createLogger } from "@open-mercato/shared/lib/logger";
1
2
  import { llmProviderRegistry } from "@open-mercato/shared/lib/ai/llm-provider-registry";
2
3
  import {
3
4
  applyAgentOverrideMap,
@@ -6,6 +7,7 @@ import {
6
7
  } from "./ai-overrides.js";
7
8
  import { TASK_PLAN_TOOL_NAME } from "./task-plan-labels.js";
8
9
  import { findGeneratedFile, compileAndImportGenerated } from "./generated-registry-loader.js";
10
+ const logger = createLogger("ai_assistant");
9
11
  const agentsById = /* @__PURE__ */ new Map();
10
12
  let loaded = false;
11
13
  async function importGeneratedAiAgentsModule() {
@@ -94,9 +96,10 @@ function validateAndNormalizeAgent(candidate) {
94
96
  const providerHint = rawProvider.trim();
95
97
  const registered = llmProviderRegistry.get(providerHint);
96
98
  if (!registered) {
97
- console.warn(
98
- `[AI Agents] Agent "${candidate.id}" declares defaultProvider "${providerHint}" which is not registered in llmProviderRegistry. The agent will be registered with defaultProvider: undefined so the resolution chain still works. Built-in provider ids: anthropic, google, openai, deepinfra, groq, together, fireworks, azure, litellm, ollama.`
99
- );
99
+ logger.warn("Agent declares a defaultProvider not registered in llmProviderRegistry; registering with defaultProvider undefined", {
100
+ agentId: candidate.id,
101
+ defaultProvider: providerHint
102
+ });
100
103
  return { ...taskPlanNormalized, defaultProvider: void 0 };
101
104
  }
102
105
  return taskPlanNormalized;
@@ -104,7 +107,7 @@ function validateAndNormalizeAgent(candidate) {
104
107
  function populateFromAgents(agents) {
105
108
  for (const candidate of agents) {
106
109
  if (!isAiAgentDefinition(candidate)) {
107
- console.warn("[AI Agents] Skipping malformed agent entry in ai-agents.generated.ts");
110
+ logger.warn("AI Agents \u2014 Skipping malformed agent entry in ai-agents.generated.ts");
108
111
  continue;
109
112
  }
110
113
  const existing = agentsById.get(candidate.id);
@@ -132,7 +135,7 @@ function applyOverridesToRegistry(entries) {
132
135
  for (const agent of overridden) agentsById.set(agent.id, agent);
133
136
  for (const [id, value] of Object.entries(overrideMap)) {
134
137
  const verb = value === null ? "disabled" : "replaced";
135
- console.info(`[AI Overrides] Agent "${id}" ${verb} by override.`);
138
+ logger.info("Agent changed by override", { agentId: id, change: verb });
136
139
  }
137
140
  }
138
141
  async function loadExtensionEntries() {
@@ -149,9 +152,7 @@ function applyExtensionsToRegistry(extensions) {
149
152
  for (const extension of extensions) {
150
153
  const agent = agentsById.get(extension.targetAgentId);
151
154
  if (!agent) {
152
- console.warn(
153
- `[AI Agents] Skipping extension for unknown agent "${extension.targetAgentId}".`
154
- );
155
+ logger.warn("Skipping extension for unknown agent", { agentId: extension.targetAgentId });
155
156
  continue;
156
157
  }
157
158
  const replacementSystemPrompt = extension.replaceSystemPrompt?.trim();
@@ -187,10 +188,7 @@ async function loadAgentRegistry() {
187
188
  const agents = mod && Array.isArray(mod.allAiAgents) ? mod.allAiAgents : [];
188
189
  populateFromAgents(agents);
189
190
  } catch (error) {
190
- console.error(
191
- "[AI Agents] Could not load ai-agents.generated.ts (agent registry empty):",
192
- error
193
- );
191
+ logger.error("AI Agents \u2014 Could not load ai-agents.generated.ts (agent registry empty)", { err: error });
194
192
  } finally {
195
193
  try {
196
194
  const overrideEntries = await loadOverrideEntries();
@@ -198,7 +196,7 @@ async function loadAgentRegistry() {
198
196
  const extensionEntries = await loadExtensionEntries();
199
197
  applyExtensionsToRegistry(extensionEntries);
200
198
  } catch (error) {
201
- console.error("[AI Agents] Failed to apply agent overrides/extensions:", error);
199
+ logger.error("AI Agents \u2014 Failed to apply agent overrides/extensions", { err: error });
202
200
  }
203
201
  loaded = true;
204
202
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/ai_assistant/lib/agent-registry.ts"],
4
- "sourcesContent": ["import { llmProviderRegistry } from '@open-mercato/shared/lib/ai/llm-provider-registry'\nimport type { AiAgentDefinition, AiAgentExtension, AiAgentSuggestion } from './ai-agent-definition'\nimport {\n applyAgentOverrideMap,\n composeAgentExtensionEntries,\n composeAgentOverrideMap,\n type AiAgentExtensionConfigEntry,\n type AiAgentOverrideConfigEntry,\n} from './ai-overrides'\nimport { TASK_PLAN_TOOL_NAME } from './task-plan-labels'\nimport { findGeneratedFile, compileAndImportGenerated } from './generated-registry-loader'\n\nconst agentsById = new Map<string, AiAgentDefinition>()\nlet loaded = false\n\n/**\n * Import the generated `ai-agents.generated.ts` registry.\n *\n * Dual-strategy, mirroring `tool-loader`'s `importGeneratedAiToolsModule`:\n * 1. Prefer the `@/` path-alias import \u2014 the Next.js bundler resolves it at\n * build time, so the in-app agent runtime is unchanged.\n * 2. Fall back to locating + compiling the file from disk when the alias\n * import throws. That only happens in a standalone Node process (the\n * `mcp:dev` / `mcp:serve` MCP servers), where `@/` is not a real package\n * specifier and Node throws `ERR_MODULE_NOT_FOUND`. Without this the\n * `meta.list_agents` / `meta.describe_agent` tools return an empty agent\n * registry over MCP.\n *\n * Returns `null` when no generated file exists (pre-generate builds, tests).\n */\nasync function importGeneratedAiAgentsModule(): Promise<Record<string, unknown> | null> {\n try {\n return (await import(\n '@/.mercato/generated/ai-agents.generated'\n )) as Record<string, unknown>\n } catch {\n const tsPath = findGeneratedFile('ai-agents.generated.ts')\n if (!tsPath) return null\n return compileAndImportGenerated(tsPath)\n }\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string')\n}\n\nfunction isAiAgentSuggestion(value: unknown): value is AiAgentSuggestion {\n if (!value || typeof value !== 'object') return false\n const candidate = value as Record<string, unknown>\n return typeof candidate.label === 'string' && typeof candidate.prompt === 'string'\n}\n\nfunction isAiAgentExtension(value: unknown): value is AiAgentExtension {\n if (!value || typeof value !== 'object') return false\n const candidate = value as Record<string, unknown>\n return (\n typeof candidate.targetAgentId === 'string' &&\n (!('replaceAllowedTools' in candidate) || isStringArray(candidate.replaceAllowedTools)) &&\n (!('deleteAllowedTools' in candidate) || isStringArray(candidate.deleteAllowedTools)) &&\n (!('appendAllowedTools' in candidate) || isStringArray(candidate.appendAllowedTools)) &&\n (!('taskPlan' in candidate) ||\n (candidate.taskPlan != null &&\n typeof candidate.taskPlan === 'object' &&\n (!('enabled' in candidate.taskPlan) ||\n typeof (candidate.taskPlan as { enabled?: unknown }).enabled === 'boolean'))) &&\n (!('replaceSystemPrompt' in candidate) || typeof candidate.replaceSystemPrompt === 'string') &&\n (!('appendSystemPrompt' in candidate) || typeof candidate.appendSystemPrompt === 'string') &&\n (!('replaceSuggestions' in candidate) ||\n (Array.isArray(candidate.replaceSuggestions) && candidate.replaceSuggestions.every(isAiAgentSuggestion))) &&\n (!('deleteSuggestions' in candidate) || isStringArray(candidate.deleteSuggestions)) &&\n (!('appendSuggestions' in candidate) ||\n (Array.isArray(candidate.appendSuggestions) && candidate.appendSuggestions.every(isAiAgentSuggestion))) &&\n (!('suggestions' in candidate) ||\n (Array.isArray(candidate.suggestions) && candidate.suggestions.every(isAiAgentSuggestion)))\n )\n}\n\nfunction isAiAgentDefinition(value: unknown): value is AiAgentDefinition {\n if (!value || typeof value !== 'object') return false\n const candidate = value as Record<string, unknown>\n return (\n typeof candidate.id === 'string' &&\n typeof candidate.moduleId === 'string' &&\n typeof candidate.label === 'string' &&\n typeof candidate.description === 'string' &&\n typeof candidate.systemPrompt === 'string' &&\n isStringArray(candidate.allowedTools)\n )\n}\n\nfunction uniqueStrings(values: readonly string[]): string[] {\n return Array.from(new Set(values.filter((value) => typeof value === 'string' && value.length > 0)))\n}\n\nexport function isAgentTaskPlanEnabled(agent: Pick<AiAgentDefinition, 'taskPlan'>): boolean {\n return agent.taskPlan?.enabled === true\n}\n\nfunction normalizeTaskPlanTool(agent: AiAgentDefinition): AiAgentDefinition {\n const enabled = isAgentTaskPlanEnabled(agent)\n const withoutInternalTool = agent.allowedTools.filter((toolName) => toolName !== TASK_PLAN_TOOL_NAME)\n const allowedTools = enabled\n ? uniqueStrings([...withoutInternalTool, TASK_PLAN_TOOL_NAME])\n : uniqueStrings(withoutInternalTool)\n if (\n allowedTools.length === agent.allowedTools.length &&\n allowedTools.every((toolName, index) => toolName === agent.allowedTools[index])\n ) {\n return agent\n }\n return {\n ...agent,\n allowedTools,\n }\n}\n\nfunction applyStringListPatch(\n current: readonly string[],\n patch: {\n replace?: readonly string[]\n delete?: readonly string[]\n append?: readonly string[]\n },\n): string[] {\n const deleted = new Set(patch.delete ?? [])\n return uniqueStrings([\n ...(patch.replace ?? current).filter((value) => !deleted.has(value)),\n ...(patch.append ?? []),\n ])\n}\n\nfunction suggestionDeleteKey(suggestion: AiAgentSuggestion): string[] {\n return [suggestion.label, suggestion.prompt].filter((value) => value.length > 0)\n}\n\nfunction applySuggestionPatch(\n current: readonly AiAgentSuggestion[],\n patch: {\n replace?: readonly AiAgentSuggestion[]\n delete?: readonly string[]\n append?: readonly AiAgentSuggestion[]\n },\n): AiAgentSuggestion[] {\n const deleted = new Set(patch.delete ?? [])\n const base = patch.replace ?? current\n const out: AiAgentSuggestion[] = []\n const seen = new Set<string>()\n for (const suggestion of base) {\n if (suggestionDeleteKey(suggestion).some((key) => deleted.has(key))) continue\n const key = `${suggestion.label}\\n${suggestion.prompt}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push(suggestion)\n }\n for (const suggestion of patch.append ?? []) {\n const key = `${suggestion.label}\\n${suggestion.prompt}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push(suggestion)\n }\n return out\n}\n\nfunction validateAndNormalizeAgent(candidate: AiAgentDefinition): AiAgentDefinition {\n const taskPlanNormalized = normalizeTaskPlanTool(candidate)\n const rawProvider = candidate.defaultProvider\n if (typeof rawProvider !== 'string' || rawProvider.trim().length === 0) {\n return taskPlanNormalized\n }\n const providerHint = rawProvider.trim()\n const registered = llmProviderRegistry.get(providerHint)\n if (!registered) {\n console.warn(\n `[AI Agents] Agent \"${candidate.id}\" declares defaultProvider \"${providerHint}\" which is not registered in llmProviderRegistry. ` +\n `The agent will be registered with defaultProvider: undefined so the resolution chain still works. ` +\n `Built-in provider ids: anthropic, google, openai, deepinfra, groq, together, fireworks, azure, litellm, ollama.`,\n )\n return { ...taskPlanNormalized, defaultProvider: undefined }\n }\n return taskPlanNormalized\n}\n\nfunction populateFromAgents(agents: unknown[]): void {\n for (const candidate of agents) {\n if (!isAiAgentDefinition(candidate)) {\n console.warn('[AI Agents] Skipping malformed agent entry in ai-agents.generated.ts')\n continue\n }\n const existing = agentsById.get(candidate.id)\n if (existing) {\n throw new Error(\n `[AI Agents] Duplicate agent id \"${candidate.id}\" \u2014 already registered by module \"${existing.moduleId}\", conflicts with module \"${candidate.moduleId}\". Export \\`aiAgentOverrides\\` from your module's \\`ai-agents.ts\\` (or set it on the modules.ts entry) to replace an agent across modules.`\n )\n }\n agentsById.set(candidate.id, validateAndNormalizeAgent(candidate))\n }\n}\n\nasync function loadOverrideEntries(): Promise<AiAgentOverrideConfigEntry[]> {\n try {\n const mod = (await importGeneratedAiAgentsModule()) as {\n aiAgentOverrideEntries?: unknown[]\n } | null\n return mod && Array.isArray(mod.aiAgentOverrideEntries)\n ? (mod.aiAgentOverrideEntries as AiAgentOverrideConfigEntry[])\n : []\n } catch {\n // No generated file yet \u2014 pre-generate builds and tests fall through.\n return []\n }\n}\n\nfunction applyOverridesToRegistry(entries: readonly AiAgentOverrideConfigEntry[]): void {\n const overrideMap = composeAgentOverrideMap(entries)\n if (Object.keys(overrideMap).length === 0) return\n const overridden = applyAgentOverrideMap(Array.from(agentsById.values()), overrideMap)\n agentsById.clear()\n for (const agent of overridden) agentsById.set(agent.id, agent)\n for (const [id, value] of Object.entries(overrideMap)) {\n const verb = value === null ? 'disabled' : 'replaced'\n console.info(`[AI Overrides] Agent \"${id}\" ${verb} by override.`)\n }\n}\n\nasync function loadExtensionEntries(): Promise<AiAgentExtension[]> {\n try {\n const mod = (await importGeneratedAiAgentsModule()) as {\n aiAgentExtensionEntries?: unknown[]\n } | null\n const entries =\n mod && Array.isArray(mod.aiAgentExtensionEntries)\n ? (mod.aiAgentExtensionEntries as AiAgentExtensionConfigEntry[])\n : []\n return composeAgentExtensionEntries(entries).filter(isAiAgentExtension)\n } catch {\n return []\n }\n}\n\nfunction applyExtensionsToRegistry(extensions: readonly AiAgentExtension[]): void {\n if (extensions.length === 0) return\n for (const extension of extensions) {\n const agent = agentsById.get(extension.targetAgentId)\n if (!agent) {\n console.warn(\n `[AI Agents] Skipping extension for unknown agent \"${extension.targetAgentId}\".`,\n )\n continue\n }\n\n const replacementSystemPrompt = extension.replaceSystemPrompt?.trim()\n const appendSystemPrompt = extension.appendSystemPrompt?.trim()\n const systemPrompt = replacementSystemPrompt ?? agent.systemPrompt.trim()\n const patchedAgent: AiAgentDefinition = {\n ...agent,\n allowedTools: applyStringListPatch(agent.allowedTools, {\n replace: extension.replaceAllowedTools,\n delete: extension.deleteAllowedTools,\n append: extension.appendAllowedTools,\n }),\n taskPlan: extension.taskPlan !== undefined ? extension.taskPlan : agent.taskPlan,\n systemPrompt: appendSystemPrompt\n ? `${systemPrompt}\\n\\n${appendSystemPrompt}`\n : systemPrompt,\n suggestions: applySuggestionPatch(agent.suggestions ?? [], {\n replace: extension.replaceSuggestions,\n delete: extension.deleteSuggestions,\n append: [\n ...(extension.appendSuggestions ?? []),\n ...(extension.suggestions ?? []),\n ],\n }),\n }\n agentsById.set(agent.id, validateAndNormalizeAgent(patchedAgent))\n }\n}\n\nexport async function loadAgentRegistry(): Promise<void> {\n if (loaded) return\n try {\n const mod = (await importGeneratedAiAgentsModule()) as {\n allAiAgents?: unknown[]\n } | null\n const agents = mod && Array.isArray(mod.allAiAgents) ? mod.allAiAgents : []\n populateFromAgents(agents)\n } catch (error) {\n console.error(\n '[AI Agents] Could not load ai-agents.generated.ts (agent registry empty):',\n error\n )\n } finally {\n try {\n const overrideEntries = await loadOverrideEntries()\n applyOverridesToRegistry(overrideEntries)\n const extensionEntries = await loadExtensionEntries()\n applyExtensionsToRegistry(extensionEntries)\n } catch (error) {\n console.error('[AI Agents] Failed to apply agent overrides/extensions:', error)\n }\n loaded = true\n }\n}\n\nexport function getAgent(id: string): AiAgentDefinition | undefined {\n return agentsById.get(id)\n}\n\nexport function listAgents(): AiAgentDefinition[] {\n return Array.from(agentsById.values()).sort((a, b) => a.id.localeCompare(b.id))\n}\n\nexport function listAgentsByModule(moduleId: string): AiAgentDefinition[] {\n return listAgents().filter((agent) => agent.moduleId === moduleId)\n}\n\n/**\n * @__internal\n * Test-only hook \u2014 clears the cached registry so `loadAgentRegistry` re-evaluates its source.\n */\nexport function resetAgentRegistryForTests(): void {\n agentsById.clear()\n loaded = false\n}\n\n/**\n * @__internal\n * Test-only hook \u2014 seeds the registry directly from a fixture array without going through\n * the dynamic generated-file import. Used by the registry's own unit tests.\n */\nexport function seedAgentRegistryForTests(agents: unknown[]): void {\n agentsById.clear()\n populateFromAgents(agents)\n loaded = true\n}\n\n/**\n * @__internal\n * Test-only hook \u2014 apply override entries against the seeded registry to\n * exercise the override pipeline without round-tripping through the\n * generated file.\n */\nexport function applyAgentOverrideEntriesForTests(\n entries: readonly AiAgentOverrideConfigEntry[],\n): void {\n applyOverridesToRegistry(entries)\n}\n\n/**\n * @__internal Test-only hook \u2014 apply additive extension entries against the\n * seeded registry without round-tripping through the generated file.\n */\nexport function applyAgentExtensionEntriesForTests(\n entries: readonly AiAgentExtension[],\n): void {\n applyExtensionsToRegistry(entries)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { createLogger } from '@open-mercato/shared/lib/logger'\nimport { llmProviderRegistry } from '@open-mercato/shared/lib/ai/llm-provider-registry'\nimport type { AiAgentDefinition, AiAgentExtension, AiAgentSuggestion } from './ai-agent-definition'\nimport {\n applyAgentOverrideMap,\n composeAgentExtensionEntries,\n composeAgentOverrideMap,\n type AiAgentExtensionConfigEntry,\n type AiAgentOverrideConfigEntry,\n} from './ai-overrides'\nimport { TASK_PLAN_TOOL_NAME } from './task-plan-labels'\nimport { findGeneratedFile, compileAndImportGenerated } from './generated-registry-loader'\n\nconst logger = createLogger('ai_assistant')\n\nconst agentsById = new Map<string, AiAgentDefinition>()\nlet loaded = false\n\n/**\n * Import the generated `ai-agents.generated.ts` registry.\n *\n * Dual-strategy, mirroring `tool-loader`'s `importGeneratedAiToolsModule`:\n * 1. Prefer the `@/` path-alias import \u2014 the Next.js bundler resolves it at\n * build time, so the in-app agent runtime is unchanged.\n * 2. Fall back to locating + compiling the file from disk when the alias\n * import throws. That only happens in a standalone Node process (the\n * `mcp:dev` / `mcp:serve` MCP servers), where `@/` is not a real package\n * specifier and Node throws `ERR_MODULE_NOT_FOUND`. Without this the\n * `meta.list_agents` / `meta.describe_agent` tools return an empty agent\n * registry over MCP.\n *\n * Returns `null` when no generated file exists (pre-generate builds, tests).\n */\nasync function importGeneratedAiAgentsModule(): Promise<Record<string, unknown> | null> {\n try {\n return (await import(\n '@/.mercato/generated/ai-agents.generated'\n )) as Record<string, unknown>\n } catch {\n const tsPath = findGeneratedFile('ai-agents.generated.ts')\n if (!tsPath) return null\n return compileAndImportGenerated(tsPath)\n }\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string')\n}\n\nfunction isAiAgentSuggestion(value: unknown): value is AiAgentSuggestion {\n if (!value || typeof value !== 'object') return false\n const candidate = value as Record<string, unknown>\n return typeof candidate.label === 'string' && typeof candidate.prompt === 'string'\n}\n\nfunction isAiAgentExtension(value: unknown): value is AiAgentExtension {\n if (!value || typeof value !== 'object') return false\n const candidate = value as Record<string, unknown>\n return (\n typeof candidate.targetAgentId === 'string' &&\n (!('replaceAllowedTools' in candidate) || isStringArray(candidate.replaceAllowedTools)) &&\n (!('deleteAllowedTools' in candidate) || isStringArray(candidate.deleteAllowedTools)) &&\n (!('appendAllowedTools' in candidate) || isStringArray(candidate.appendAllowedTools)) &&\n (!('taskPlan' in candidate) ||\n (candidate.taskPlan != null &&\n typeof candidate.taskPlan === 'object' &&\n (!('enabled' in candidate.taskPlan) ||\n typeof (candidate.taskPlan as { enabled?: unknown }).enabled === 'boolean'))) &&\n (!('replaceSystemPrompt' in candidate) || typeof candidate.replaceSystemPrompt === 'string') &&\n (!('appendSystemPrompt' in candidate) || typeof candidate.appendSystemPrompt === 'string') &&\n (!('replaceSuggestions' in candidate) ||\n (Array.isArray(candidate.replaceSuggestions) && candidate.replaceSuggestions.every(isAiAgentSuggestion))) &&\n (!('deleteSuggestions' in candidate) || isStringArray(candidate.deleteSuggestions)) &&\n (!('appendSuggestions' in candidate) ||\n (Array.isArray(candidate.appendSuggestions) && candidate.appendSuggestions.every(isAiAgentSuggestion))) &&\n (!('suggestions' in candidate) ||\n (Array.isArray(candidate.suggestions) && candidate.suggestions.every(isAiAgentSuggestion)))\n )\n}\n\nfunction isAiAgentDefinition(value: unknown): value is AiAgentDefinition {\n if (!value || typeof value !== 'object') return false\n const candidate = value as Record<string, unknown>\n return (\n typeof candidate.id === 'string' &&\n typeof candidate.moduleId === 'string' &&\n typeof candidate.label === 'string' &&\n typeof candidate.description === 'string' &&\n typeof candidate.systemPrompt === 'string' &&\n isStringArray(candidate.allowedTools)\n )\n}\n\nfunction uniqueStrings(values: readonly string[]): string[] {\n return Array.from(new Set(values.filter((value) => typeof value === 'string' && value.length > 0)))\n}\n\nexport function isAgentTaskPlanEnabled(agent: Pick<AiAgentDefinition, 'taskPlan'>): boolean {\n return agent.taskPlan?.enabled === true\n}\n\nfunction normalizeTaskPlanTool(agent: AiAgentDefinition): AiAgentDefinition {\n const enabled = isAgentTaskPlanEnabled(agent)\n const withoutInternalTool = agent.allowedTools.filter((toolName) => toolName !== TASK_PLAN_TOOL_NAME)\n const allowedTools = enabled\n ? uniqueStrings([...withoutInternalTool, TASK_PLAN_TOOL_NAME])\n : uniqueStrings(withoutInternalTool)\n if (\n allowedTools.length === agent.allowedTools.length &&\n allowedTools.every((toolName, index) => toolName === agent.allowedTools[index])\n ) {\n return agent\n }\n return {\n ...agent,\n allowedTools,\n }\n}\n\nfunction applyStringListPatch(\n current: readonly string[],\n patch: {\n replace?: readonly string[]\n delete?: readonly string[]\n append?: readonly string[]\n },\n): string[] {\n const deleted = new Set(patch.delete ?? [])\n return uniqueStrings([\n ...(patch.replace ?? current).filter((value) => !deleted.has(value)),\n ...(patch.append ?? []),\n ])\n}\n\nfunction suggestionDeleteKey(suggestion: AiAgentSuggestion): string[] {\n return [suggestion.label, suggestion.prompt].filter((value) => value.length > 0)\n}\n\nfunction applySuggestionPatch(\n current: readonly AiAgentSuggestion[],\n patch: {\n replace?: readonly AiAgentSuggestion[]\n delete?: readonly string[]\n append?: readonly AiAgentSuggestion[]\n },\n): AiAgentSuggestion[] {\n const deleted = new Set(patch.delete ?? [])\n const base = patch.replace ?? current\n const out: AiAgentSuggestion[] = []\n const seen = new Set<string>()\n for (const suggestion of base) {\n if (suggestionDeleteKey(suggestion).some((key) => deleted.has(key))) continue\n const key = `${suggestion.label}\\n${suggestion.prompt}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push(suggestion)\n }\n for (const suggestion of patch.append ?? []) {\n const key = `${suggestion.label}\\n${suggestion.prompt}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push(suggestion)\n }\n return out\n}\n\nfunction validateAndNormalizeAgent(candidate: AiAgentDefinition): AiAgentDefinition {\n const taskPlanNormalized = normalizeTaskPlanTool(candidate)\n const rawProvider = candidate.defaultProvider\n if (typeof rawProvider !== 'string' || rawProvider.trim().length === 0) {\n return taskPlanNormalized\n }\n const providerHint = rawProvider.trim()\n const registered = llmProviderRegistry.get(providerHint)\n if (!registered) {\n logger.warn('Agent declares a defaultProvider not registered in llmProviderRegistry; registering with defaultProvider undefined', {\n agentId: candidate.id,\n defaultProvider: providerHint,\n })\n return { ...taskPlanNormalized, defaultProvider: undefined }\n }\n return taskPlanNormalized\n}\n\nfunction populateFromAgents(agents: unknown[]): void {\n for (const candidate of agents) {\n if (!isAiAgentDefinition(candidate)) {\n logger.warn('AI Agents \u2014 Skipping malformed agent entry in ai-agents.generated.ts')\n continue\n }\n const existing = agentsById.get(candidate.id)\n if (existing) {\n throw new Error(\n `[AI Agents] Duplicate agent id \"${candidate.id}\" \u2014 already registered by module \"${existing.moduleId}\", conflicts with module \"${candidate.moduleId}\". Export \\`aiAgentOverrides\\` from your module's \\`ai-agents.ts\\` (or set it on the modules.ts entry) to replace an agent across modules.`\n )\n }\n agentsById.set(candidate.id, validateAndNormalizeAgent(candidate))\n }\n}\n\nasync function loadOverrideEntries(): Promise<AiAgentOverrideConfigEntry[]> {\n try {\n const mod = (await importGeneratedAiAgentsModule()) as {\n aiAgentOverrideEntries?: unknown[]\n } | null\n return mod && Array.isArray(mod.aiAgentOverrideEntries)\n ? (mod.aiAgentOverrideEntries as AiAgentOverrideConfigEntry[])\n : []\n } catch {\n // No generated file yet \u2014 pre-generate builds and tests fall through.\n return []\n }\n}\n\nfunction applyOverridesToRegistry(entries: readonly AiAgentOverrideConfigEntry[]): void {\n const overrideMap = composeAgentOverrideMap(entries)\n if (Object.keys(overrideMap).length === 0) return\n const overridden = applyAgentOverrideMap(Array.from(agentsById.values()), overrideMap)\n agentsById.clear()\n for (const agent of overridden) agentsById.set(agent.id, agent)\n for (const [id, value] of Object.entries(overrideMap)) {\n const verb = value === null ? 'disabled' : 'replaced'\n logger.info('Agent changed by override', { agentId: id, change: verb })\n }\n}\n\nasync function loadExtensionEntries(): Promise<AiAgentExtension[]> {\n try {\n const mod = (await importGeneratedAiAgentsModule()) as {\n aiAgentExtensionEntries?: unknown[]\n } | null\n const entries =\n mod && Array.isArray(mod.aiAgentExtensionEntries)\n ? (mod.aiAgentExtensionEntries as AiAgentExtensionConfigEntry[])\n : []\n return composeAgentExtensionEntries(entries).filter(isAiAgentExtension)\n } catch {\n return []\n }\n}\n\nfunction applyExtensionsToRegistry(extensions: readonly AiAgentExtension[]): void {\n if (extensions.length === 0) return\n for (const extension of extensions) {\n const agent = agentsById.get(extension.targetAgentId)\n if (!agent) {\n logger.warn('Skipping extension for unknown agent', { agentId: extension.targetAgentId })\n continue\n }\n\n const replacementSystemPrompt = extension.replaceSystemPrompt?.trim()\n const appendSystemPrompt = extension.appendSystemPrompt?.trim()\n const systemPrompt = replacementSystemPrompt ?? agent.systemPrompt.trim()\n const patchedAgent: AiAgentDefinition = {\n ...agent,\n allowedTools: applyStringListPatch(agent.allowedTools, {\n replace: extension.replaceAllowedTools,\n delete: extension.deleteAllowedTools,\n append: extension.appendAllowedTools,\n }),\n taskPlan: extension.taskPlan !== undefined ? extension.taskPlan : agent.taskPlan,\n systemPrompt: appendSystemPrompt\n ? `${systemPrompt}\\n\\n${appendSystemPrompt}`\n : systemPrompt,\n suggestions: applySuggestionPatch(agent.suggestions ?? [], {\n replace: extension.replaceSuggestions,\n delete: extension.deleteSuggestions,\n append: [\n ...(extension.appendSuggestions ?? []),\n ...(extension.suggestions ?? []),\n ],\n }),\n }\n agentsById.set(agent.id, validateAndNormalizeAgent(patchedAgent))\n }\n}\n\nexport async function loadAgentRegistry(): Promise<void> {\n if (loaded) return\n try {\n const mod = (await importGeneratedAiAgentsModule()) as {\n allAiAgents?: unknown[]\n } | null\n const agents = mod && Array.isArray(mod.allAiAgents) ? mod.allAiAgents : []\n populateFromAgents(agents)\n } catch (error) {\n logger.error('AI Agents \u2014 Could not load ai-agents.generated.ts (agent registry empty)', { err: error })\n } finally {\n try {\n const overrideEntries = await loadOverrideEntries()\n applyOverridesToRegistry(overrideEntries)\n const extensionEntries = await loadExtensionEntries()\n applyExtensionsToRegistry(extensionEntries)\n } catch (error) {\n logger.error('AI Agents \u2014 Failed to apply agent overrides/extensions', { err: error })\n }\n loaded = true\n }\n}\n\nexport function getAgent(id: string): AiAgentDefinition | undefined {\n return agentsById.get(id)\n}\n\nexport function listAgents(): AiAgentDefinition[] {\n return Array.from(agentsById.values()).sort((a, b) => a.id.localeCompare(b.id))\n}\n\nexport function listAgentsByModule(moduleId: string): AiAgentDefinition[] {\n return listAgents().filter((agent) => agent.moduleId === moduleId)\n}\n\n/**\n * @__internal\n * Test-only hook \u2014 clears the cached registry so `loadAgentRegistry` re-evaluates its source.\n */\nexport function resetAgentRegistryForTests(): void {\n agentsById.clear()\n loaded = false\n}\n\n/**\n * @__internal\n * Test-only hook \u2014 seeds the registry directly from a fixture array without going through\n * the dynamic generated-file import. Used by the registry's own unit tests.\n */\nexport function seedAgentRegistryForTests(agents: unknown[]): void {\n agentsById.clear()\n populateFromAgents(agents)\n loaded = true\n}\n\n/**\n * @__internal\n * Test-only hook \u2014 apply override entries against the seeded registry to\n * exercise the override pipeline without round-tripping through the\n * generated file.\n */\nexport function applyAgentOverrideEntriesForTests(\n entries: readonly AiAgentOverrideConfigEntry[],\n): void {\n applyOverridesToRegistry(entries)\n}\n\n/**\n * @__internal Test-only hook \u2014 apply additive extension entries against the\n * seeded registry without round-tripping through the generated file.\n */\nexport function applyAgentExtensionEntriesForTests(\n entries: readonly AiAgentExtension[],\n): void {\n applyExtensionsToRegistry(entries)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["key"]
7
7
  }
@@ -1,3 +1,4 @@
1
+ import { createLogger } from "@open-mercato/shared/lib/logger";
1
2
  import { randomUUID } from "node:crypto";
2
3
  import { createContainer } from "awilix";
3
4
  import {
@@ -34,6 +35,7 @@ import { recordTokenUsage } from "./token-usage-recorder.js";
34
35
  import { injectTaskPlanIntoStream } from "./task-plan-stream.js";
35
36
  import { TASK_PLAN_RUNTIME_PROMPT_SECTION } from "./task-plan-labels.js";
36
37
  import "./llm-bootstrap.js";
38
+ const logger = createLogger("ai_assistant").child({ component: "agent-runtime" });
37
39
  const WRAPPER_DEFAULT_LOOP_CHAT = { maxSteps: 10 };
38
40
  const WRAPPER_DEFAULT_LOOP_OBJECT = {};
39
41
  function resolveLoopBudgetPreset(preset) {
@@ -172,9 +174,12 @@ class BudgetEnforcer {
172
174
  abort(reason) {
173
175
  if (this.abortReason !== null) return;
174
176
  this.abortReason = reason;
175
- console.info(
176
- `[AI Agents] Budget exceeded \u2014 aborting turn. Reason: ${reason}. toolCalls=${this.toolCallsUsed}, tokens=${this.tokensUsed}, elapsedMs=${Date.now() - this.turnStartMs}.`
177
- );
177
+ logger.info("Budget exceeded \u2014 aborting turn", {
178
+ reason,
179
+ toolCalls: this.toolCallsUsed,
180
+ tokens: this.tokensUsed,
181
+ elapsedMs: Date.now() - this.turnStartMs
182
+ });
178
183
  this.abortController.abort(reason);
179
184
  }
180
185
  wire(userOnStepFinish) {
@@ -189,7 +194,7 @@ class BudgetEnforcer {
189
194
  try {
190
195
  await userOnStepFinish(event);
191
196
  } catch (err) {
192
- console.error("[AI Agents] User onStepFinish threw; ignoring:", err);
197
+ logger.error("User onStepFinish threw; ignoring", { err });
193
198
  }
194
199
  }
195
200
  };
@@ -232,7 +237,7 @@ function buildLoopTraceCollector(agentId, sessionId, turnId, userOnStepFinish) {
232
237
  try {
233
238
  await userOnStepFinish(event);
234
239
  } catch (err) {
235
- console.error("[AI Agents] User onStepFinish in LoopTrace collector threw; ignoring:", err);
240
+ logger.error("User onStepFinish in LoopTrace collector threw; ignoring", { err });
236
241
  }
237
242
  }
238
243
  };
@@ -299,9 +304,7 @@ function mergeStepOverrides(wrapperOverride, userOverride, agent, wrappedToolReg
299
304
  const normalized = normalizeAllowedToolNameForAgent(name, agent);
300
305
  const allowed = normalized !== null;
301
306
  if (!allowed) {
302
- console.warn(
303
- `[AI Agents] loop:active_tools_filtered \u2014 tool "${name}" is not in agent "${agent.id}" allowedTools; dropping from activeTools.`
304
- );
307
+ logger.warn("loop:active_tools_filtered \u2014 tool not in agent allowedTools; dropping from activeTools", { toolName: name, agentId: agent.id });
305
308
  }
306
309
  return normalized ? [normalized] : [];
307
310
  });
@@ -313,9 +316,7 @@ function mergeStepOverrides(wrapperOverride, userOverride, agent, wrappedToolReg
313
316
  for (const [toolKey, userHandler] of Object.entries(userTools)) {
314
317
  const wrappedHandler = wrappedToolRegistry[toolKey];
315
318
  if (!wrappedHandler) {
316
- console.warn(
317
- `[AI Agents] mergeStepOverrides \u2014 tool "${toolKey}" from user prepareStep is not in the wrapper tool registry; dropping.`
318
- );
319
+ logger.warn("mergeStepOverrides \u2014 tool from user prepareStep is not in the wrapper tool registry; dropping", { toolName: toolKey });
319
320
  continue;
320
321
  }
321
322
  if (userHandler !== wrappedHandler) {
@@ -361,9 +362,7 @@ function buildWrapperPrepareStep(agent, effectiveLoop, wrappedTools) {
361
362
  const normalized = normalizeAllowedToolNameForAgent(name, agent);
362
363
  const allowed = normalized !== null;
363
364
  if (!allowed) {
364
- console.warn(
365
- `[AI Agents] loop:active_tools_filtered \u2014 tool "${name}" is not in agent "${agent.id}" allowedTools; dropping from activeTools.`
366
- );
365
+ logger.warn("loop:active_tools_filtered \u2014 tool not in agent allowedTools; dropping from activeTools", { toolName: name, agentId: agent.id });
367
366
  }
368
367
  return normalized ? [normalized] : [];
369
368
  });
@@ -373,10 +372,7 @@ function buildWrapperPrepareStep(agent, effectiveLoop, wrappedTools) {
373
372
  try {
374
373
  userOverride = await effectiveLoop.prepareStep(state);
375
374
  } catch (error) {
376
- console.error(
377
- `[AI Agents] User prepareStep threw for agent "${agent.id}"; ignoring user override:`,
378
- error
379
- );
375
+ logger.error("User prepareStep threw; ignoring user override", { agentId: agent.id, err: error });
380
376
  return mapPrepareStepResultForModel(wrapperOverride, wrappedTools);
381
377
  }
382
378
  return mapPrepareStepResultForModel(
@@ -438,10 +434,7 @@ async function resolveTenantAllowlistSnapshot(container, tenantId, organizationI
438
434
  organizationId: organizationId ?? null
439
435
  });
440
436
  } catch (error) {
441
- console.warn(
442
- "[AI Agents] Tenant allowlist lookup failed; falling back to env-only enforcement.",
443
- error
444
- );
437
+ logger.warn("Tenant allowlist lookup failed; falling back to env-only enforcement", { err: error });
445
438
  return null;
446
439
  }
447
440
  }
@@ -459,9 +452,7 @@ async function composeSystemPrompt(agent, pageContext, container, tenantId, orga
459
452
  if (typeof entityType !== "string" || entityType.length === 0) return baseFromOverride;
460
453
  if (typeof recordId !== "string" || recordId.length === 0) return baseFromOverride;
461
454
  if (!container) {
462
- console.warn(
463
- `[AI Agents] Agent "${agent.id}" declares resolvePageContext but no container was passed to runAiAgentText; skipping hydration.`
464
- );
455
+ logger.warn("Agent declares resolvePageContext but no container was passed to runAiAgentText; skipping hydration", { agentId: agent.id });
465
456
  return baseFromOverride;
466
457
  }
467
458
  const hydrationInput = {
@@ -479,10 +470,7 @@ async function composeSystemPrompt(agent, pageContext, container, tenantId, orga
479
470
  ${hydrated}`;
480
471
  }
481
472
  } catch (error) {
482
- console.error(
483
- `[AI Agents] resolvePageContext for agent "${agent.id}" failed; continuing without hydration:`,
484
- error
485
- );
473
+ logger.error("resolvePageContext failed; continuing without hydration", { agentId: agent.id, err: error });
486
474
  }
487
475
  return baseFromOverride;
488
476
  }
@@ -507,10 +495,7 @@ async function resolveBaseSystemPromptWithOverride(agent, container, tenantId, o
507
495
  }
508
496
  return composeSystemPromptWithOverride(base, { sections: latest.sections });
509
497
  } catch (error) {
510
- console.warn(
511
- `[AI Agents] Prompt-override lookup failed for agent "${agent.id}"; falling back to built-in prompt.`,
512
- error
513
- );
498
+ logger.warn("Prompt-override lookup failed; falling back to built-in prompt", { agentId: agent.id, err: error });
514
499
  return base;
515
500
  }
516
501
  }
@@ -529,17 +514,12 @@ async function resolveMutationPolicyOverride(agentId, container, tenantId, organ
529
514
  if (!row) return null;
530
515
  const raw = row.mutationPolicy;
531
516
  if (!isKnownMutationPolicy(raw)) {
532
- console.warn(
533
- `[AI Agents] Ignoring corrupt mutationPolicy override row for agent "${agentId}": "${raw}". Falling back to code-declared policy.`
534
- );
517
+ logger.warn("Ignoring corrupt mutationPolicy override row; falling back to code-declared policy", { agentId, policy: raw });
535
518
  return null;
536
519
  }
537
520
  return raw;
538
521
  } catch (error) {
539
- console.warn(
540
- `[AI Agents] mutationPolicy override lookup failed for agent "${agentId}"; falling back to code-declared policy.`,
541
- error
542
- );
522
+ logger.warn("mutationPolicy override lookup failed; falling back to code-declared policy", { agentId, err: error });
543
523
  return null;
544
524
  }
545
525
  }
@@ -566,10 +546,7 @@ async function resolveRuntimeModelOverride(agentId, container, tenantId, organiz
566
546
  baseURL: row.baseUrl ?? null
567
547
  };
568
548
  } catch (error) {
569
- console.warn(
570
- `[AI Agents] Runtime model override lookup failed for agent "${agentId}"; falling back to lower-priority sources.`,
571
- error
572
- );
549
+ logger.warn("Runtime model override lookup failed; falling back to lower-priority sources", { agentId, err: error });
573
550
  return null;
574
551
  }
575
552
  }