@open-mercato/ai-assistant 0.5.1-develop.3036.f02c281f23 → 0.5.1-develop.3045.b4b3320cc2
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.
- package/.turbo/turbo-build.log +1 -1
- package/AGENTS.md +361 -0
- package/README.md +5 -0
- package/dist/index.js +154 -0
- package/dist/index.js.map +2 -2
- package/dist/modules/ai_assistant/__integration__/TC-AI-002-agent-policy.spec.js +73 -0
- package/dist/modules/ai_assistant/__integration__/TC-AI-002-agent-policy.spec.js.map +7 -0
- package/dist/modules/ai_assistant/__integration__/TC-AI-AGENT-SETTINGS-005-settings-page.spec.js +484 -0
- package/dist/modules/ai_assistant/__integration__/TC-AI-AGENT-SETTINGS-005-settings-page.spec.js.map +7 -0
- package/dist/modules/ai_assistant/__integration__/TC-AI-PLAYGROUND-004-playground.spec.js +251 -0
- package/dist/modules/ai_assistant/__integration__/TC-AI-PLAYGROUND-004-playground.spec.js.map +7 -0
- package/dist/modules/ai_assistant/__integration__/TC-INT-AI-TOOLS.spec.js +91 -0
- package/dist/modules/ai_assistant/__integration__/TC-INT-AI-TOOLS.spec.js.map +7 -0
- package/dist/modules/ai_assistant/ai-tools/attachments-pack.js +202 -0
- package/dist/modules/ai_assistant/ai-tools/attachments-pack.js.map +7 -0
- package/dist/modules/ai_assistant/ai-tools/meta-pack.js +121 -0
- package/dist/modules/ai_assistant/ai-tools/meta-pack.js.map +7 -0
- package/dist/modules/ai_assistant/ai-tools/search-pack.js +94 -0
- package/dist/modules/ai_assistant/ai-tools/search-pack.js.map +7 -0
- package/dist/modules/ai_assistant/ai-tools.js +14 -0
- package/dist/modules/ai_assistant/ai-tools.js.map +7 -0
- package/dist/modules/ai_assistant/api/ai/actions/[id]/cancel/route.js +175 -0
- package/dist/modules/ai_assistant/api/ai/actions/[id]/cancel/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/ai/actions/[id]/confirm/route.js +174 -0
- package/dist/modules/ai_assistant/api/ai/actions/[id]/confirm/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/ai/actions/[id]/route.js +101 -0
- package/dist/modules/ai_assistant/api/ai/actions/[id]/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/route.js +311 -0
- package/dist/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/route.js +246 -0
- package/dist/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/ai/agents/route.js +94 -0
- package/dist/modules/ai_assistant/api/ai/agents/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/ai/chat/route.js +173 -0
- package/dist/modules/ai_assistant/api/ai/chat/route.js.map +7 -0
- package/dist/modules/ai_assistant/api/ai/run-object/route.js +167 -0
- package/dist/modules/ai_assistant/api/ai/run-object/route.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/AiAgentSettingsPageClient.js +1111 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/AiAgentSettingsPageClient.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/page.js +10 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/page.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/page.meta.js +28 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/agents/page.meta.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/legacy/page.js +10 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/legacy/page.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/legacy/page.meta.js +30 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/legacy/page.meta.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js +4 -6
- package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js.map +2 -2
- package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js +1 -21
- package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js.map +2 -2
- package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/AiPlaygroundPageClient.js +462 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/AiPlaygroundPageClient.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/page.js +10 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/page.js.map +7 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/page.meta.js +28 -0
- package/dist/modules/ai_assistant/backend/config/ai-assistant/playground/page.meta.js.map +7 -0
- package/dist/modules/ai_assistant/cli.js +78 -12
- package/dist/modules/ai_assistant/cli.js.map +2 -2
- package/dist/modules/ai_assistant/data/entities/AiAgentMutationPolicyOverride.js +5 -0
- package/dist/modules/ai_assistant/data/entities/AiAgentMutationPolicyOverride.js.map +7 -0
- package/dist/modules/ai_assistant/data/entities/AiAgentPromptOverride.js +5 -0
- package/dist/modules/ai_assistant/data/entities/AiAgentPromptOverride.js.map +7 -0
- package/dist/modules/ai_assistant/data/entities/AiPendingAction.js +5 -0
- package/dist/modules/ai_assistant/data/entities/AiPendingAction.js.map +7 -0
- package/dist/modules/ai_assistant/data/entities.js +228 -0
- package/dist/modules/ai_assistant/data/entities.js.map +7 -0
- package/dist/modules/ai_assistant/data/repositories/AiAgentMutationPolicyOverrideRepository.js +95 -0
- package/dist/modules/ai_assistant/data/repositories/AiAgentMutationPolicyOverrideRepository.js.map +7 -0
- package/dist/modules/ai_assistant/data/repositories/AiAgentPromptOverrideRepository.js +95 -0
- package/dist/modules/ai_assistant/data/repositories/AiAgentPromptOverrideRepository.js.map +7 -0
- package/dist/modules/ai_assistant/data/repositories/AiPendingActionRepository.js +223 -0
- package/dist/modules/ai_assistant/data/repositories/AiPendingActionRepository.js.map +7 -0
- package/dist/modules/ai_assistant/events.js +33 -0
- package/dist/modules/ai_assistant/events.js.map +7 -0
- package/dist/modules/ai_assistant/i18n/de.json +252 -0
- package/dist/modules/ai_assistant/i18n/en.json +252 -0
- package/dist/modules/ai_assistant/i18n/es.json +252 -0
- package/dist/modules/ai_assistant/i18n/pl.json +252 -0
- package/dist/modules/ai_assistant/lib/agent-policy.js +168 -0
- package/dist/modules/ai_assistant/lib/agent-policy.js.map +7 -0
- package/dist/modules/ai_assistant/lib/agent-registry.js +195 -0
- package/dist/modules/ai_assistant/lib/agent-registry.js.map +7 -0
- package/dist/modules/ai_assistant/lib/agent-runtime.js +451 -0
- package/dist/modules/ai_assistant/lib/agent-runtime.js.map +7 -0
- package/dist/modules/ai_assistant/lib/agent-tools.js +223 -0
- package/dist/modules/ai_assistant/lib/agent-tools.js.map +7 -0
- package/dist/modules/ai_assistant/lib/agent-transport.js +25 -0
- package/dist/modules/ai_assistant/lib/agent-transport.js.map +7 -0
- package/dist/modules/ai_assistant/lib/ai-agent-definition.js +11 -0
- package/dist/modules/ai_assistant/lib/ai-agent-definition.js.map +7 -0
- package/dist/modules/ai_assistant/lib/ai-agents-generated.d.js +1 -0
- package/dist/modules/ai_assistant/lib/ai-agents-generated.d.js.map +7 -0
- package/dist/modules/ai_assistant/lib/ai-api-operation-runner.js +239 -0
- package/dist/modules/ai_assistant/lib/ai-api-operation-runner.js.map +7 -0
- package/dist/modules/ai_assistant/lib/ai-overrides.js +189 -0
- package/dist/modules/ai_assistant/lib/ai-overrides.js.map +7 -0
- package/dist/modules/ai_assistant/lib/ai-tool-definition.js +7 -0
- package/dist/modules/ai_assistant/lib/ai-tool-definition.js.map +7 -0
- package/dist/modules/ai_assistant/lib/ai-tools-generated.d.js +1 -0
- package/dist/modules/ai_assistant/lib/ai-tools-generated.d.js.map +7 -0
- package/dist/modules/ai_assistant/lib/api-backed-tool.js +48 -0
- package/dist/modules/ai_assistant/lib/api-backed-tool.js.map +7 -0
- package/dist/modules/ai_assistant/lib/attachment-bridge-types.js +1 -0
- package/dist/modules/ai_assistant/lib/attachment-bridge-types.js.map +7 -0
- package/dist/modules/ai_assistant/lib/attachment-parts.js +276 -0
- package/dist/modules/ai_assistant/lib/attachment-parts.js.map +7 -0
- package/dist/modules/ai_assistant/lib/model-factory.js +68 -0
- package/dist/modules/ai_assistant/lib/model-factory.js.map +7 -0
- package/dist/modules/ai_assistant/lib/pending-action-cancel.js +86 -0
- package/dist/modules/ai_assistant/lib/pending-action-cancel.js.map +7 -0
- package/dist/modules/ai_assistant/lib/pending-action-client.js +35 -0
- package/dist/modules/ai_assistant/lib/pending-action-client.js.map +7 -0
- package/dist/modules/ai_assistant/lib/pending-action-executor.js +243 -0
- package/dist/modules/ai_assistant/lib/pending-action-executor.js.map +7 -0
- package/dist/modules/ai_assistant/lib/pending-action-recheck.js +246 -0
- package/dist/modules/ai_assistant/lib/pending-action-recheck.js.map +7 -0
- package/dist/modules/ai_assistant/lib/pending-action-types.js +70 -0
- package/dist/modules/ai_assistant/lib/pending-action-types.js.map +7 -0
- package/dist/modules/ai_assistant/lib/prepare-mutation.js +315 -0
- package/dist/modules/ai_assistant/lib/prepare-mutation.js.map +7 -0
- package/dist/modules/ai_assistant/lib/prompt-composition-types.js +7 -0
- package/dist/modules/ai_assistant/lib/prompt-composition-types.js.map +7 -0
- package/dist/modules/ai_assistant/lib/prompt-override-merge.js +175 -0
- package/dist/modules/ai_assistant/lib/prompt-override-merge.js.map +7 -0
- package/dist/modules/ai_assistant/lib/schema-utils.js +5 -1
- package/dist/modules/ai_assistant/lib/schema-utils.js.map +2 -2
- package/dist/modules/ai_assistant/lib/tool-executor.js +13 -2
- package/dist/modules/ai_assistant/lib/tool-executor.js.map +2 -2
- package/dist/modules/ai_assistant/lib/tool-loader.js +86 -11
- package/dist/modules/ai_assistant/lib/tool-loader.js.map +2 -2
- package/dist/modules/ai_assistant/lib/tool-test-fixtures.js +120 -0
- package/dist/modules/ai_assistant/lib/tool-test-fixtures.js.map +7 -0
- package/dist/modules/ai_assistant/lib/tool-test-runner.js +418 -0
- package/dist/modules/ai_assistant/lib/tool-test-runner.js.map +7 -0
- package/dist/modules/ai_assistant/migrations/Migration20260419100521.js +17 -0
- package/dist/modules/ai_assistant/migrations/Migration20260419100521.js.map +7 -0
- package/dist/modules/ai_assistant/migrations/Migration20260419132948.js +16 -0
- package/dist/modules/ai_assistant/migrations/Migration20260419132948.js.map +7 -0
- package/dist/modules/ai_assistant/migrations/Migration20260419134235.js +17 -0
- package/dist/modules/ai_assistant/migrations/Migration20260419134235.js.map +7 -0
- package/dist/modules/ai_assistant/setup.js +36 -0
- package/dist/modules/ai_assistant/setup.js.map +2 -2
- package/dist/modules/ai_assistant/workers/ai-pending-action-cleanup.js +161 -0
- package/dist/modules/ai_assistant/workers/ai-pending-action-cleanup.js.map +7 -0
- package/generated/entities/ai_agent_mutation_policy_override/index.ts +9 -0
- package/generated/entities/ai_agent_prompt_override/index.ts +10 -0
- package/generated/entities/ai_pending_action/index.ts +24 -0
- package/generated/entities.ids.generated.ts +13 -0
- package/generated/entity-fields-registry.ts +57 -0
- package/jest.config.cjs +7 -0
- package/package.json +4 -4
- package/src/index.ts +215 -0
- package/src/modules/ai_assistant/__integration__/README.md +5 -0
- package/src/modules/ai_assistant/__integration__/TC-AI-002-agent-policy.spec.ts +115 -0
- package/src/modules/ai_assistant/__integration__/TC-AI-AGENT-SETTINGS-005-settings-page.spec.ts +574 -0
- package/src/modules/ai_assistant/__integration__/TC-AI-PLAYGROUND-004-playground.spec.ts +333 -0
- package/src/modules/ai_assistant/__integration__/TC-INT-AI-TOOLS.spec.ts +135 -0
- package/src/modules/ai_assistant/__tests__/events.test.ts +145 -0
- package/src/modules/ai_assistant/__tests__/integration/pending-action-contract.test.ts +1015 -0
- package/src/modules/ai_assistant/__tests__/integration/ws-c-attachment-bridge.test.ts +235 -0
- package/src/modules/ai_assistant/__tests__/integration/ws-c-policy-and-tools.test.ts +330 -0
- package/src/modules/ai_assistant/__tests__/integration/ws-c-tool-pack-coverage.test.ts +285 -0
- package/src/modules/ai_assistant/ai-tools/__tests__/attachments-pack.test.ts +322 -0
- package/src/modules/ai_assistant/ai-tools/__tests__/meta-pack.test.ts +218 -0
- package/src/modules/ai_assistant/ai-tools/__tests__/search-pack.test.ts +192 -0
- package/src/modules/ai_assistant/ai-tools/attachments-pack.ts +269 -0
- package/src/modules/ai_assistant/ai-tools/meta-pack.ts +140 -0
- package/src/modules/ai_assistant/ai-tools/search-pack.ts +122 -0
- package/src/modules/ai_assistant/ai-tools.ts +21 -0
- package/src/modules/ai_assistant/api/ai/actions/[id]/__tests__/route.test.ts +222 -0
- package/src/modules/ai_assistant/api/ai/actions/[id]/cancel/__tests__/route.test.ts +286 -0
- package/src/modules/ai_assistant/api/ai/actions/[id]/cancel/route.ts +237 -0
- package/src/modules/ai_assistant/api/ai/actions/[id]/confirm/__tests__/route.test.ts +339 -0
- package/src/modules/ai_assistant/api/ai/actions/[id]/confirm/route.ts +229 -0
- package/src/modules/ai_assistant/api/ai/actions/[id]/route.ts +142 -0
- package/src/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/__tests__/route.test.ts +367 -0
- package/src/modules/ai_assistant/api/ai/agents/[agentId]/mutation-policy/route.ts +380 -0
- package/src/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/__tests__/route.test.ts +333 -0
- package/src/modules/ai_assistant/api/ai/agents/[agentId]/prompt-override/route.ts +307 -0
- package/src/modules/ai_assistant/api/ai/agents/route.ts +107 -0
- package/src/modules/ai_assistant/api/ai/chat/__tests__/route.test.ts +282 -0
- package/src/modules/ai_assistant/api/ai/chat/route.ts +207 -0
- package/src/modules/ai_assistant/api/ai/run-object/__tests__/route.test.ts +282 -0
- package/src/modules/ai_assistant/api/ai/run-object/route.ts +204 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/agents/AiAgentSettingsPageClient.tsx +1419 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/agents/page.meta.ts +26 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/agents/page.tsx +12 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/legacy/page.meta.ts +28 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/legacy/page.tsx +12 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/page.meta.ts +8 -23
- package/src/modules/ai_assistant/backend/config/ai-assistant/page.tsx +15 -10
- package/src/modules/ai_assistant/backend/config/ai-assistant/playground/AiPlaygroundPageClient.tsx +604 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/playground/page.meta.ts +26 -0
- package/src/modules/ai_assistant/backend/config/ai-assistant/playground/page.tsx +12 -0
- package/src/modules/ai_assistant/cli.ts +99 -24
- package/src/modules/ai_assistant/data/__tests__/schema-unique-indexes.test.ts +69 -0
- package/src/modules/ai_assistant/data/entities/AiAgentMutationPolicyOverride.ts +7 -0
- package/src/modules/ai_assistant/data/entities/AiAgentPromptOverride.ts +7 -0
- package/src/modules/ai_assistant/data/entities/AiPendingAction.ts +7 -0
- package/src/modules/ai_assistant/data/entities.ts +270 -0
- package/src/modules/ai_assistant/data/repositories/AiAgentMutationPolicyOverrideRepository.ts +129 -0
- package/src/modules/ai_assistant/data/repositories/AiAgentPromptOverrideRepository.ts +132 -0
- package/src/modules/ai_assistant/data/repositories/AiPendingActionRepository.ts +334 -0
- package/src/modules/ai_assistant/data/repositories/__tests__/AiAgentMutationPolicyOverrideRepository.test.ts +195 -0
- package/src/modules/ai_assistant/data/repositories/__tests__/AiAgentPromptOverrideRepository.test.ts +197 -0
- package/src/modules/ai_assistant/data/repositories/__tests__/AiPendingActionRepository.test.ts +357 -0
- package/src/modules/ai_assistant/events.ts +112 -0
- package/src/modules/ai_assistant/i18n/de.json +252 -0
- package/src/modules/ai_assistant/i18n/en.json +252 -0
- package/src/modules/ai_assistant/i18n/es.json +252 -0
- package/src/modules/ai_assistant/i18n/pl.json +252 -0
- package/src/modules/ai_assistant/lib/__tests__/agent-policy.mutation-override.test.ts +203 -0
- package/src/modules/ai_assistant/lib/__tests__/agent-policy.test.ts +385 -0
- package/src/modules/ai_assistant/lib/__tests__/agent-registry.test.ts +217 -0
- package/src/modules/ai_assistant/lib/__tests__/agent-runtime-object.test.ts +329 -0
- package/src/modules/ai_assistant/lib/__tests__/agent-runtime-parity.test.ts +573 -0
- package/src/modules/ai_assistant/lib/__tests__/agent-runtime.test.ts +291 -0
- package/src/modules/ai_assistant/lib/__tests__/agent-tools.test.ts +172 -0
- package/src/modules/ai_assistant/lib/__tests__/agent-transport.test.ts +41 -0
- package/src/modules/ai_assistant/lib/__tests__/ai-agent-definition.test.ts +183 -0
- package/src/modules/ai_assistant/lib/__tests__/ai-api-operation-runner.test.ts +432 -0
- package/src/modules/ai_assistant/lib/__tests__/ai-overrides.test.ts +308 -0
- package/src/modules/ai_assistant/lib/__tests__/api-backed-tool.test.ts +302 -0
- package/src/modules/ai_assistant/lib/__tests__/attachment-bridge-and-prompt-types.test.ts +188 -0
- package/src/modules/ai_assistant/lib/__tests__/attachment-parts.test.ts +531 -0
- package/src/modules/ai_assistant/lib/__tests__/max-steps-budget.integration.test.ts +263 -0
- package/src/modules/ai_assistant/lib/__tests__/model-factory.integration.test.ts +183 -0
- package/src/modules/ai_assistant/lib/__tests__/model-factory.test.ts +168 -0
- package/src/modules/ai_assistant/lib/__tests__/pending-action-cancel.test.ts +235 -0
- package/src/modules/ai_assistant/lib/__tests__/pending-action-client.test.ts +148 -0
- package/src/modules/ai_assistant/lib/__tests__/pending-action-executor.test.ts +348 -0
- package/src/modules/ai_assistant/lib/__tests__/pending-action-recheck.test.ts +378 -0
- package/src/modules/ai_assistant/lib/__tests__/phase-0-additive-contract.test.ts +299 -0
- package/src/modules/ai_assistant/lib/__tests__/prepare-mutation.test.ts +610 -0
- package/src/modules/ai_assistant/lib/__tests__/prompt-override-merge.test.ts +136 -0
- package/src/modules/ai_assistant/lib/__tests__/tool-loader.test.ts +125 -0
- package/src/modules/ai_assistant/lib/agent-policy.ts +270 -0
- package/src/modules/ai_assistant/lib/agent-registry.ts +277 -0
- package/src/modules/ai_assistant/lib/agent-runtime.ts +751 -0
- package/src/modules/ai_assistant/lib/agent-tools.ts +396 -0
- package/src/modules/ai_assistant/lib/agent-transport.ts +51 -0
- package/src/modules/ai_assistant/lib/ai-agent-definition.ts +86 -0
- package/src/modules/ai_assistant/lib/ai-agents-generated.d.ts +18 -0
- package/src/modules/ai_assistant/lib/ai-api-operation-runner.ts +333 -0
- package/src/modules/ai_assistant/lib/ai-overrides.ts +389 -0
- package/src/modules/ai_assistant/lib/ai-tool-definition.ts +7 -0
- package/src/modules/ai_assistant/lib/ai-tools-generated.d.ts +7 -0
- package/src/modules/ai_assistant/lib/api-backed-tool.ts +85 -0
- package/src/modules/ai_assistant/lib/attachment-bridge-types.ts +24 -0
- package/src/modules/ai_assistant/lib/attachment-parts.ts +433 -0
- package/src/modules/ai_assistant/lib/model-factory.ts +212 -0
- package/src/modules/ai_assistant/lib/pending-action-cancel.ts +179 -0
- package/src/modules/ai_assistant/lib/pending-action-client.ts +126 -0
- package/src/modules/ai_assistant/lib/pending-action-executor.ts +424 -0
- package/src/modules/ai_assistant/lib/pending-action-recheck.ts +410 -0
- package/src/modules/ai_assistant/lib/pending-action-types.ts +194 -0
- package/src/modules/ai_assistant/lib/prepare-mutation.ts +448 -0
- package/src/modules/ai_assistant/lib/prompt-composition-types.ts +24 -0
- package/src/modules/ai_assistant/lib/prompt-override-merge.ts +253 -0
- package/src/modules/ai_assistant/lib/schema-utils.ts +14 -2
- package/src/modules/ai_assistant/lib/tool-executor.ts +25 -3
- package/src/modules/ai_assistant/lib/tool-loader.ts +159 -13
- package/src/modules/ai_assistant/lib/tool-test-fixtures.ts +160 -0
- package/src/modules/ai_assistant/lib/tool-test-runner.ts +596 -0
- package/src/modules/ai_assistant/lib/types.ts +105 -2
- package/src/modules/ai_assistant/migrations/.snapshot-open-mercato.json +871 -0
- package/src/modules/ai_assistant/migrations/Migration20260419100521.ts +17 -0
- package/src/modules/ai_assistant/migrations/Migration20260419132948.ts +16 -0
- package/src/modules/ai_assistant/migrations/Migration20260419134235.ts +17 -0
- package/src/modules/ai_assistant/setup.ts +53 -0
- package/src/modules/ai_assistant/workers/__tests__/ai-pending-action-cleanup.test.ts +333 -0
- package/src/modules/ai_assistant/workers/ai-pending-action-cleanup.ts +269 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import {
|
|
2
|
+
registerModuleOverrideApplier,
|
|
3
|
+
type ModuleOverrideEntry,
|
|
4
|
+
} from '@open-mercato/shared/modules/overrides'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Module-to-module override pipeline for AI agents and AI tools.
|
|
8
|
+
*
|
|
9
|
+
* Modules contribute overrides through two surfaces:
|
|
10
|
+
*
|
|
11
|
+
* 1. Per-module: declare additional `aiAgentOverrides` / `aiToolOverrides`
|
|
12
|
+
* exports in the existing `<module>/ai-agents.ts` / `<module>/ai-tools.ts`
|
|
13
|
+
* files (no separate `ai-overrides.ts` file). The generator picks the
|
|
14
|
+
* exports up alongside `aiAgents` / `aiTools` and emits override entries
|
|
15
|
+
* inside `apps/<app>/.mercato/generated/ai-agents.generated.ts`
|
|
16
|
+
* (`aiAgentOverrideEntries`) and `ai-tools.generated.ts`
|
|
17
|
+
* (`aiToolOverrideEntries`).
|
|
18
|
+
*
|
|
19
|
+
* 2. App-level: declare `aiAgentOverrides` / `aiToolOverrides` directly on a
|
|
20
|
+
* `ModuleEntry` inside the app's `src/modules.ts`. {@link
|
|
21
|
+
* applyAiOverridesFromEnabledModules} feeds these into the runtime; they
|
|
22
|
+
* sit one tier higher than the per-module file-based entries but below
|
|
23
|
+
* explicit programmatic calls.
|
|
24
|
+
*
|
|
25
|
+
* Tests and bootstrap code can also override imperatively via
|
|
26
|
+
* {@link applyAiAgentOverrides} and {@link applyAiToolOverrides}, which
|
|
27
|
+
* supersede every other tier and persist for the process lifetime.
|
|
28
|
+
*
|
|
29
|
+
* `null` always means "remove from the registry"; a definition replaces.
|
|
30
|
+
*
|
|
31
|
+
* @see ../../../../../../.ai/specs/2026-04-30-ai-overrides-and-module-disable.md
|
|
32
|
+
*/
|
|
33
|
+
import type { AiAgentDefinition, AiAgentExtension } from './ai-agent-definition'
|
|
34
|
+
import type { AiToolDefinition } from './types'
|
|
35
|
+
|
|
36
|
+
/** Override for a single agent: replace with a definition or remove with `null`. */
|
|
37
|
+
export type AiAgentOverride = AiAgentDefinition | null
|
|
38
|
+
|
|
39
|
+
/** Override for a single tool: replace with a definition or remove with `null`. */
|
|
40
|
+
export type AiToolOverride = AiToolDefinition | null
|
|
41
|
+
|
|
42
|
+
/** Map of agent id → override. Used in the per-module `ai-agents.ts` file. */
|
|
43
|
+
export type AiAgentOverridesMap = Record<string, AiAgentOverride>
|
|
44
|
+
|
|
45
|
+
/** Map of tool name → override. Used in the per-module `ai-tools.ts` file. */
|
|
46
|
+
export type AiToolOverridesMap = Record<string, AiToolOverride>
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Per-entry shape produced by the agent generator. Mirrors the per-module
|
|
50
|
+
* record format used elsewhere in the registry generators so the file
|
|
51
|
+
* stays grep-friendly.
|
|
52
|
+
*/
|
|
53
|
+
export interface AiAgentOverrideConfigEntry {
|
|
54
|
+
moduleId: string
|
|
55
|
+
overrides: AiAgentOverridesMap
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface AiAgentExtensionConfigEntry {
|
|
59
|
+
moduleId: string
|
|
60
|
+
extensions: AiAgentExtension[]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Per-entry shape produced by the tool generator. Same record format as
|
|
65
|
+
* {@link AiAgentOverrideConfigEntry}, but with tool definitions.
|
|
66
|
+
*/
|
|
67
|
+
export interface AiToolOverrideConfigEntry {
|
|
68
|
+
moduleId: string
|
|
69
|
+
overrides: AiToolOverridesMap
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Shape of the `entry.overrides.ai` sub-tree on a `modules.ts` entry. */
|
|
73
|
+
export interface AiModuleOverridesShape {
|
|
74
|
+
agents?: AiAgentOverridesMap
|
|
75
|
+
tools?: AiToolOverridesMap
|
|
76
|
+
extensions?: AiAgentExtension[]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Shape of a `modules.ts` `ModuleEntry` with the umbrella `overrides.ai`. */
|
|
80
|
+
export interface EnabledModuleAiOverrides {
|
|
81
|
+
id: string
|
|
82
|
+
overrides?: { ai?: AiModuleOverridesShape }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const programmaticAgentOverrides: AiAgentOverridesMap = {}
|
|
86
|
+
const programmaticToolOverrides: AiToolOverridesMap = {}
|
|
87
|
+
const programmaticAgentExtensions: AiAgentExtension[] = []
|
|
88
|
+
|
|
89
|
+
const modulesConfigAgentOverrides: AiAgentOverridesMap = {}
|
|
90
|
+
const modulesConfigToolOverrides: AiToolOverridesMap = {}
|
|
91
|
+
const modulesConfigAgentExtensions: AiAgentExtension[] = []
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Apply programmatic agent overrides — survive after the registries load
|
|
95
|
+
* and take precedence over both file-based and `modules.ts`-tier overrides
|
|
96
|
+
* for the same id.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* applyAiAgentOverrides({
|
|
101
|
+
* 'catalog.catalog_assistant': null, // disable
|
|
102
|
+
* 'catalog.merchandising_assistant': customAgent, // replace
|
|
103
|
+
* })
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export function applyAiAgentOverrides(overrides: AiAgentOverridesMap): void {
|
|
107
|
+
for (const [id, value] of Object.entries(overrides)) {
|
|
108
|
+
programmaticAgentOverrides[id] = value
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Apply programmatic tool overrides — survive after the registries load
|
|
114
|
+
* and take precedence over both file-based and `modules.ts`-tier overrides
|
|
115
|
+
* for the same name.
|
|
116
|
+
*/
|
|
117
|
+
export function applyAiToolOverrides(overrides: AiToolOverridesMap): void {
|
|
118
|
+
for (const [name, value] of Object.entries(overrides)) {
|
|
119
|
+
programmaticToolOverrides[name] = value
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Apply programmatic additive agent extensions. Extensions append to an
|
|
125
|
+
* already-registered agent after replacements/disable overrides resolve.
|
|
126
|
+
*/
|
|
127
|
+
export function applyAiAgentExtensions(extensions: readonly AiAgentExtension[]): void {
|
|
128
|
+
programmaticAgentExtensions.push(...extensions)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Walk a list of `enabledModules` entries (the `apps/<app>/src/modules.ts`
|
|
133
|
+
* shape) and register their `overrides.ai.agents` / `overrides.ai.tools`
|
|
134
|
+
* into the `modules.ts` tier. Tier precedence (highest first):
|
|
135
|
+
*
|
|
136
|
+
* 1. {@link applyAiAgentOverrides} / {@link applyAiToolOverrides}
|
|
137
|
+
* 2. `modules.ts` inline (this function)
|
|
138
|
+
* 3. `<module>/ai-agents.ts` `aiAgentOverrides` / `<module>/ai-tools.ts`
|
|
139
|
+
* `aiToolOverrides`
|
|
140
|
+
* 4. base `aiAgents` / `aiTools`
|
|
141
|
+
*
|
|
142
|
+
* Calling this multiple times is additive: later calls overlay on the
|
|
143
|
+
* existing tier (last wins per id). Use only at boot time — re-entering
|
|
144
|
+
* mid-request blurs the resolution order.
|
|
145
|
+
*
|
|
146
|
+
* In practice this is invoked from `applyModuleOverridesFromEnabledModules`
|
|
147
|
+
* (the umbrella dispatcher in `@open-mercato/shared/modules/overrides`)
|
|
148
|
+
* via the registered `'ai'` applier; downstream apps call the dispatcher
|
|
149
|
+
* once from `bootstrap.ts`. The standalone signature is kept for tests
|
|
150
|
+
* and ad-hoc use.
|
|
151
|
+
*/
|
|
152
|
+
export function applyAiOverridesFromEnabledModules(
|
|
153
|
+
modules: ReadonlyArray<EnabledModuleAiOverrides>,
|
|
154
|
+
): void {
|
|
155
|
+
for (const entry of modules) {
|
|
156
|
+
if (!entry || typeof entry.id !== 'string' || !entry.id) continue
|
|
157
|
+
const ai = entry.overrides?.ai
|
|
158
|
+
if (!ai || typeof ai !== 'object') continue
|
|
159
|
+
if (ai.agents && typeof ai.agents === 'object') {
|
|
160
|
+
for (const [id, value] of Object.entries(ai.agents)) {
|
|
161
|
+
modulesConfigAgentOverrides[id] = value as AiAgentOverride
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (ai.tools && typeof ai.tools === 'object') {
|
|
165
|
+
for (const [name, value] of Object.entries(ai.tools)) {
|
|
166
|
+
modulesConfigToolOverrides[name] = value as AiToolOverride
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (Array.isArray(ai.extensions)) {
|
|
170
|
+
modulesConfigAgentExtensions.push(...ai.extensions)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Bucketed entry shape passed to the umbrella dispatcher's per-domain
|
|
177
|
+
* applier. Each entry carries one module's `overrides.ai` sub-tree.
|
|
178
|
+
*/
|
|
179
|
+
type AiOverrideEntryFromDispatcher = {
|
|
180
|
+
moduleId: string
|
|
181
|
+
overrides: AiModuleOverridesShape
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Applier registered with `@open-mercato/shared/modules/overrides` for
|
|
186
|
+
* the `'ai'` domain. The dispatcher hands us per-module entries already
|
|
187
|
+
* scoped to `overrides.ai`; we re-shape into `EnabledModuleAiOverrides`
|
|
188
|
+
* and reuse {@link applyAiOverridesFromEnabledModules} so the AI tier
|
|
189
|
+
* has exactly one code path.
|
|
190
|
+
*/
|
|
191
|
+
export function applyAiOverridesDispatcherEntries(
|
|
192
|
+
entries: ReadonlyArray<AiOverrideEntryFromDispatcher>,
|
|
193
|
+
): void {
|
|
194
|
+
applyAiOverridesFromEnabledModules(
|
|
195
|
+
entries.map((entry) => ({
|
|
196
|
+
id: entry.moduleId,
|
|
197
|
+
overrides: { ai: entry.overrides },
|
|
198
|
+
})),
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Side-effect: register the `'ai'` applier on first module load so the
|
|
203
|
+
// umbrella dispatcher in `@open-mercato/shared/modules/overrides` can
|
|
204
|
+
// route `entry.overrides.ai` here. Any consumer that imports
|
|
205
|
+
// `@open-mercato/ai-assistant` (which apps do via `bootstrap.ts`) gets
|
|
206
|
+
// the registration for free — no second import needed.
|
|
207
|
+
registerModuleOverrideApplier<AiModuleOverridesShape>(
|
|
208
|
+
'ai',
|
|
209
|
+
(entries: ReadonlyArray<ModuleOverrideEntry<AiModuleOverridesShape>>) => {
|
|
210
|
+
applyAiOverridesDispatcherEntries(entries)
|
|
211
|
+
},
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
/** @__internal Test-only hook — reset programmatic + modules.ts override state. */
|
|
215
|
+
export function resetProgrammaticOverridesForTests(): void {
|
|
216
|
+
for (const key of Object.keys(programmaticAgentOverrides)) {
|
|
217
|
+
delete programmaticAgentOverrides[key]
|
|
218
|
+
}
|
|
219
|
+
for (const key of Object.keys(programmaticToolOverrides)) {
|
|
220
|
+
delete programmaticToolOverrides[key]
|
|
221
|
+
}
|
|
222
|
+
for (const key of Object.keys(modulesConfigAgentOverrides)) {
|
|
223
|
+
delete modulesConfigAgentOverrides[key]
|
|
224
|
+
}
|
|
225
|
+
for (const key of Object.keys(modulesConfigToolOverrides)) {
|
|
226
|
+
delete modulesConfigToolOverrides[key]
|
|
227
|
+
}
|
|
228
|
+
programmaticAgentExtensions.length = 0
|
|
229
|
+
modulesConfigAgentExtensions.length = 0
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Resolve the final agent override map from a list of file-based entries
|
|
234
|
+
* plus the `modules.ts` and programmatic state.
|
|
235
|
+
*
|
|
236
|
+
* Resolution order (lowest precedence → highest):
|
|
237
|
+
* 1. file entries in module load order
|
|
238
|
+
* 2. modules.ts entries
|
|
239
|
+
* 3. programmatic
|
|
240
|
+
*/
|
|
241
|
+
export function composeAgentOverrideMap(
|
|
242
|
+
fileEntries: readonly AiAgentOverrideConfigEntry[],
|
|
243
|
+
): AiAgentOverridesMap {
|
|
244
|
+
const out: AiAgentOverridesMap = {}
|
|
245
|
+
for (const entry of fileEntries) {
|
|
246
|
+
const overrides = entry?.overrides
|
|
247
|
+
if (!overrides || typeof overrides !== 'object') continue
|
|
248
|
+
for (const [id, value] of Object.entries(overrides)) {
|
|
249
|
+
if (typeof id !== 'string' || !id) continue
|
|
250
|
+
out[id] = value as AiAgentOverride
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
for (const [id, value] of Object.entries(modulesConfigAgentOverrides)) {
|
|
254
|
+
out[id] = value
|
|
255
|
+
}
|
|
256
|
+
for (const [id, value] of Object.entries(programmaticAgentOverrides)) {
|
|
257
|
+
out[id] = value
|
|
258
|
+
}
|
|
259
|
+
return out
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Resolve the final tool override map from a list of file-based entries
|
|
264
|
+
* plus the `modules.ts` and programmatic state.
|
|
265
|
+
*/
|
|
266
|
+
export function composeToolOverrideMap(
|
|
267
|
+
fileEntries: readonly AiToolOverrideConfigEntry[],
|
|
268
|
+
): AiToolOverridesMap {
|
|
269
|
+
const out: AiToolOverridesMap = {}
|
|
270
|
+
for (const entry of fileEntries) {
|
|
271
|
+
const overrides = entry?.overrides
|
|
272
|
+
if (!overrides || typeof overrides !== 'object') continue
|
|
273
|
+
for (const [name, value] of Object.entries(overrides)) {
|
|
274
|
+
if (typeof name !== 'string' || !name) continue
|
|
275
|
+
out[name] = value as AiToolOverride
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
for (const [name, value] of Object.entries(modulesConfigToolOverrides)) {
|
|
279
|
+
out[name] = value
|
|
280
|
+
}
|
|
281
|
+
for (const [name, value] of Object.entries(programmaticToolOverrides)) {
|
|
282
|
+
out[name] = value
|
|
283
|
+
}
|
|
284
|
+
return out
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export function composeAgentExtensionEntries(
|
|
288
|
+
fileEntries: readonly AiAgentExtensionConfigEntry[],
|
|
289
|
+
): AiAgentExtension[] {
|
|
290
|
+
const out: AiAgentExtension[] = []
|
|
291
|
+
for (const entry of fileEntries) {
|
|
292
|
+
if (Array.isArray(entry?.extensions)) out.push(...entry.extensions)
|
|
293
|
+
}
|
|
294
|
+
out.push(...modulesConfigAgentExtensions)
|
|
295
|
+
out.push(...programmaticAgentExtensions)
|
|
296
|
+
return out
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Apply an agent override map to a base list. Returns a new array.
|
|
301
|
+
* `null` removes the entry; a non-null override replaces it. Override
|
|
302
|
+
* entries naming an id that is not in `base` log a structured warning so
|
|
303
|
+
* an operator can spot stale override files.
|
|
304
|
+
*/
|
|
305
|
+
export function applyAgentOverrideMap(
|
|
306
|
+
base: readonly AiAgentDefinition[],
|
|
307
|
+
overrides: AiAgentOverridesMap,
|
|
308
|
+
): AiAgentDefinition[] {
|
|
309
|
+
if (!overrides || Object.keys(overrides).length === 0) return base.slice()
|
|
310
|
+
const byId = new Map<string, AiAgentDefinition>()
|
|
311
|
+
for (const agent of base) {
|
|
312
|
+
if (agent && typeof agent.id === 'string' && agent.id) {
|
|
313
|
+
byId.set(agent.id, agent)
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
for (const [id, value] of Object.entries(overrides)) {
|
|
317
|
+
if (!byId.has(id) && value !== null) {
|
|
318
|
+
// Allow registering a brand-new agent through the override surface
|
|
319
|
+
// — useful for app-level "synthetic" agents without authoring a
|
|
320
|
+
// module file. Warn at the structured logger so the operator
|
|
321
|
+
// notices a stale id slipping through.
|
|
322
|
+
console.warn(
|
|
323
|
+
`[AI Overrides] Override registers a new agent "${id}" — no base entry to replace.`,
|
|
324
|
+
)
|
|
325
|
+
}
|
|
326
|
+
if (value === null) {
|
|
327
|
+
byId.delete(id)
|
|
328
|
+
continue
|
|
329
|
+
}
|
|
330
|
+
if (!value || typeof value.id !== 'string' || value.id !== id) {
|
|
331
|
+
console.warn(
|
|
332
|
+
`[AI Overrides] Skipping malformed agent override for id "${id}" — id mismatch or missing fields.`,
|
|
333
|
+
)
|
|
334
|
+
continue
|
|
335
|
+
}
|
|
336
|
+
byId.set(id, value)
|
|
337
|
+
}
|
|
338
|
+
return Array.from(byId.values())
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Apply a tool override map to a base map. Returns a new Map.
|
|
343
|
+
* `null` removes the entry; a non-null override replaces it.
|
|
344
|
+
*/
|
|
345
|
+
export function applyToolOverrideMap<TTool extends { name: string }>(
|
|
346
|
+
base: ReadonlyMap<string, TTool>,
|
|
347
|
+
overrides: Record<string, TTool | null | undefined>,
|
|
348
|
+
): Map<string, TTool> {
|
|
349
|
+
const out = new Map<string, TTool>(base)
|
|
350
|
+
if (!overrides) return out
|
|
351
|
+
for (const [name, value] of Object.entries(overrides)) {
|
|
352
|
+
if (value === null) {
|
|
353
|
+
out.delete(name)
|
|
354
|
+
continue
|
|
355
|
+
}
|
|
356
|
+
if (value === undefined) continue
|
|
357
|
+
if (!value || typeof (value as TTool).name !== 'string' || (value as TTool).name !== name) {
|
|
358
|
+
console.warn(
|
|
359
|
+
`[AI Overrides] Skipping malformed tool override for name "${name}" — name mismatch or missing fields.`,
|
|
360
|
+
)
|
|
361
|
+
continue
|
|
362
|
+
}
|
|
363
|
+
out.set(name, value as TTool)
|
|
364
|
+
}
|
|
365
|
+
return out
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* @__internal — read the snapshot of programmatic + modules.ts overrides.
|
|
370
|
+
* Used by tests and by the diagnostic helper that reports which overrides
|
|
371
|
+
* are in effect.
|
|
372
|
+
*/
|
|
373
|
+
export function snapshotProgrammaticOverrides(): {
|
|
374
|
+
agents: Readonly<AiAgentOverridesMap>
|
|
375
|
+
tools: Readonly<AiToolOverridesMap>
|
|
376
|
+
modulesConfigAgents: Readonly<AiAgentOverridesMap>
|
|
377
|
+
modulesConfigTools: Readonly<AiToolOverridesMap>
|
|
378
|
+
agentExtensions: readonly AiAgentExtension[]
|
|
379
|
+
modulesConfigAgentExtensions: readonly AiAgentExtension[]
|
|
380
|
+
} {
|
|
381
|
+
return {
|
|
382
|
+
agents: { ...programmaticAgentOverrides },
|
|
383
|
+
tools: { ...programmaticToolOverrides },
|
|
384
|
+
modulesConfigAgents: { ...modulesConfigAgentOverrides },
|
|
385
|
+
modulesConfigTools: { ...modulesConfigToolOverrides },
|
|
386
|
+
agentExtensions: programmaticAgentExtensions.slice(),
|
|
387
|
+
modulesConfigAgentExtensions: modulesConfigAgentExtensions.slice(),
|
|
388
|
+
}
|
|
389
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Phase 2 of spec 2026-04-27-ai-tools-api-backed-dry-refactor.md.
|
|
2
|
+
//
|
|
3
|
+
// Sugar over `defineAiTool` that wires the in-process API operation runner so
|
|
4
|
+
// typed AI tools can reuse documented API route logic without HTTP, fetch, or
|
|
5
|
+
// a second RBAC pass. The synthesized handler delegates to
|
|
6
|
+
// `createAiApiOperationRunner(ctx).run(toOperation(input, ctx))` and pipes the
|
|
7
|
+
// response through `mapResponse(...)`. All other tool-runtime concerns
|
|
8
|
+
// (registry indexing, schema serialization, mutation policy, pending-action
|
|
9
|
+
// flow, `loadBeforeRecord(s)`, telemetry) remain owned by `defineAiTool`.
|
|
10
|
+
import type { z } from 'zod'
|
|
11
|
+
import { defineAiTool } from './ai-tool-definition'
|
|
12
|
+
import {
|
|
13
|
+
createAiApiOperationRunner,
|
|
14
|
+
type AiApiOperationRequest,
|
|
15
|
+
type AiApiOperationResponse,
|
|
16
|
+
type AiToolExecutionContext,
|
|
17
|
+
} from './ai-api-operation-runner'
|
|
18
|
+
import type { AiToolDefinition, McpToolContext } from './types'
|
|
19
|
+
|
|
20
|
+
export type ApiBackedAiToolConfig<TInput, TApi, TOutput> = {
|
|
21
|
+
name: string
|
|
22
|
+
displayName?: string
|
|
23
|
+
description: string
|
|
24
|
+
inputSchema: z.ZodType<TInput>
|
|
25
|
+
requiredFeatures: string[]
|
|
26
|
+
isMutation?: boolean
|
|
27
|
+
toOperation: (
|
|
28
|
+
input: TInput,
|
|
29
|
+
ctx: AiToolExecutionContext,
|
|
30
|
+
) => AiApiOperationRequest | Promise<AiApiOperationRequest>
|
|
31
|
+
mapResponse: (
|
|
32
|
+
response: AiApiOperationResponse<TApi>,
|
|
33
|
+
input: TInput,
|
|
34
|
+
ctx: AiToolExecutionContext,
|
|
35
|
+
) => TOutput | Promise<TOutput>
|
|
36
|
+
loadBeforeRecord?: AiToolDefinition<TInput, TOutput>['loadBeforeRecord']
|
|
37
|
+
loadBeforeRecords?: AiToolDefinition<TInput, TOutput>['loadBeforeRecords']
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function defineApiBackedAiTool<TInput, TApi, TOutput>(
|
|
41
|
+
config: ApiBackedAiToolConfig<TInput, TApi, TOutput>,
|
|
42
|
+
): AiToolDefinition<TInput, TOutput> {
|
|
43
|
+
const {
|
|
44
|
+
name,
|
|
45
|
+
displayName,
|
|
46
|
+
description,
|
|
47
|
+
inputSchema,
|
|
48
|
+
requiredFeatures,
|
|
49
|
+
isMutation,
|
|
50
|
+
toOperation,
|
|
51
|
+
mapResponse,
|
|
52
|
+
loadBeforeRecord,
|
|
53
|
+
loadBeforeRecords,
|
|
54
|
+
} = config
|
|
55
|
+
|
|
56
|
+
let definition: AiToolDefinition<TInput, TOutput>
|
|
57
|
+
|
|
58
|
+
const handler = async (input: TInput, context: McpToolContext): Promise<TOutput> => {
|
|
59
|
+
const toolCtx: AiToolExecutionContext = {
|
|
60
|
+
...context,
|
|
61
|
+
tool: definition as unknown as AiToolDefinition,
|
|
62
|
+
}
|
|
63
|
+
const operation = await toOperation(input, toolCtx)
|
|
64
|
+
const runner = createAiApiOperationRunner(toolCtx)
|
|
65
|
+
const response = await runner.run<TApi>(operation)
|
|
66
|
+
if (!response.success) {
|
|
67
|
+
throw new Error(response.error ?? `API operation failed for tool "${name}"`)
|
|
68
|
+
}
|
|
69
|
+
return await mapResponse(response, input, toolCtx)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
definition = defineAiTool<TInput, TOutput>({
|
|
73
|
+
name,
|
|
74
|
+
description,
|
|
75
|
+
inputSchema,
|
|
76
|
+
requiredFeatures,
|
|
77
|
+
handler,
|
|
78
|
+
...(displayName !== undefined ? { displayName } : {}),
|
|
79
|
+
...(isMutation !== undefined ? { isMutation } : {}),
|
|
80
|
+
...(loadBeforeRecord !== undefined ? { loadBeforeRecord } : {}),
|
|
81
|
+
...(loadBeforeRecords !== undefined ? { loadBeforeRecords } : {}),
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
return definition
|
|
85
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type AttachmentSource = 'bytes' | 'signed-url' | 'text' | 'metadata-only'
|
|
2
|
+
|
|
3
|
+
export interface AiResolvedAttachmentPart {
|
|
4
|
+
attachmentId: string
|
|
5
|
+
fileName: string
|
|
6
|
+
mediaType: string
|
|
7
|
+
source: AttachmentSource
|
|
8
|
+
textContent?: string | null
|
|
9
|
+
url?: string | null
|
|
10
|
+
data?: Uint8Array | string | null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AiUiPart {
|
|
14
|
+
componentId: string
|
|
15
|
+
props: Record<string, unknown>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AiChatRequestContext {
|
|
19
|
+
tenantId: string | null
|
|
20
|
+
organizationId: string | null
|
|
21
|
+
userId: string
|
|
22
|
+
features: string[]
|
|
23
|
+
isSuperAdmin: boolean
|
|
24
|
+
}
|