@open-mercato/ai-assistant 0.6.2-develop.3461.1.605f31c2c9 → 0.6.2

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 (63) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +2 -2
  3. package/dist/modules/ai_assistant/acl.js +1 -0
  4. package/dist/modules/ai_assistant/acl.js.map +2 -2
  5. package/dist/modules/ai_assistant/api/ai/chat/route.js +197 -2
  6. package/dist/modules/ai_assistant/api/ai/chat/route.js.map +2 -2
  7. package/dist/modules/ai_assistant/api/ai/conversations/[conversationId]/route.js +272 -0
  8. package/dist/modules/ai_assistant/api/ai/conversations/[conversationId]/route.js.map +7 -0
  9. package/dist/modules/ai_assistant/api/ai/conversations/import/route.js +108 -0
  10. package/dist/modules/ai_assistant/api/ai/conversations/import/route.js.map +7 -0
  11. package/dist/modules/ai_assistant/api/ai/conversations/route.js +207 -0
  12. package/dist/modules/ai_assistant/api/ai/conversations/route.js.map +7 -0
  13. package/dist/modules/ai_assistant/data/entities/AiChatConversation.js +5 -0
  14. package/dist/modules/ai_assistant/data/entities/AiChatConversation.js.map +7 -0
  15. package/dist/modules/ai_assistant/data/entities/AiChatConversationParticipant.js +5 -0
  16. package/dist/modules/ai_assistant/data/entities/AiChatConversationParticipant.js.map +7 -0
  17. package/dist/modules/ai_assistant/data/entities/AiChatMessage.js +5 -0
  18. package/dist/modules/ai_assistant/data/entities/AiChatMessage.js.map +7 -0
  19. package/dist/modules/ai_assistant/data/entities.js +200 -0
  20. package/dist/modules/ai_assistant/data/entities.js.map +2 -2
  21. package/dist/modules/ai_assistant/data/repositories/AiChatConversationRepository.js +448 -0
  22. package/dist/modules/ai_assistant/data/repositories/AiChatConversationRepository.js.map +7 -0
  23. package/dist/modules/ai_assistant/data/validators.js +72 -0
  24. package/dist/modules/ai_assistant/data/validators.js.map +7 -0
  25. package/dist/modules/ai_assistant/i18n/de.json +3 -0
  26. package/dist/modules/ai_assistant/i18n/en.json +3 -0
  27. package/dist/modules/ai_assistant/i18n/es.json +3 -0
  28. package/dist/modules/ai_assistant/i18n/pl.json +3 -0
  29. package/dist/modules/ai_assistant/lib/conversation-storage.js +43 -0
  30. package/dist/modules/ai_assistant/lib/conversation-storage.js.map +7 -0
  31. package/dist/modules/ai_assistant/migrations/Migration20260518092853_ai_assistant.js +28 -0
  32. package/dist/modules/ai_assistant/migrations/Migration20260518092853_ai_assistant.js.map +7 -0
  33. package/dist/modules/ai_assistant/setup.js +1 -0
  34. package/dist/modules/ai_assistant/setup.js.map +2 -2
  35. package/generated/entities/ai_chat_conversation/index.ts +15 -0
  36. package/generated/entities/ai_chat_conversation_participant/index.ts +9 -0
  37. package/generated/entities/ai_chat_message/index.ts +16 -0
  38. package/generated/entities.ids.generated.ts +4 -1
  39. package/generated/entity-fields-registry.ts +46 -0
  40. package/jest.config.cjs +3 -1
  41. package/package.json +14 -15
  42. package/src/modules/ai_assistant/acl.ts +1 -0
  43. package/src/modules/ai_assistant/api/ai/chat/__tests__/route.test.ts +107 -0
  44. package/src/modules/ai_assistant/api/ai/chat/route.ts +245 -1
  45. package/src/modules/ai_assistant/api/ai/conversations/[conversationId]/route.ts +320 -0
  46. package/src/modules/ai_assistant/api/ai/conversations/__tests__/route.test.ts +93 -0
  47. package/src/modules/ai_assistant/api/ai/conversations/import/route.ts +122 -0
  48. package/src/modules/ai_assistant/api/ai/conversations/route.ts +241 -0
  49. package/src/modules/ai_assistant/data/entities/AiChatConversation.ts +2 -0
  50. package/src/modules/ai_assistant/data/entities/AiChatConversationParticipant.ts +2 -0
  51. package/src/modules/ai_assistant/data/entities/AiChatMessage.ts +2 -0
  52. package/src/modules/ai_assistant/data/entities.ts +255 -0
  53. package/src/modules/ai_assistant/data/repositories/AiChatConversationRepository.ts +597 -0
  54. package/src/modules/ai_assistant/data/repositories/__tests__/AiChatConversationRepository.test.ts +592 -0
  55. package/src/modules/ai_assistant/data/validators.ts +134 -0
  56. package/src/modules/ai_assistant/i18n/de.json +3 -0
  57. package/src/modules/ai_assistant/i18n/en.json +3 -0
  58. package/src/modules/ai_assistant/i18n/es.json +3 -0
  59. package/src/modules/ai_assistant/i18n/pl.json +3 -0
  60. package/src/modules/ai_assistant/lib/conversation-storage.ts +93 -0
  61. package/src/modules/ai_assistant/migrations/.snapshot-open-mercato.json +822 -0
  62. package/src/modules/ai_assistant/migrations/Migration20260518092853_ai_assistant.ts +39 -0
  63. package/src/modules/ai_assistant/setup.ts +1 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/modules/ai_assistant/api/ai/conversations/route.ts"],
4
+ "sourcesContent": ["import { NextResponse, type NextRequest } from 'next/server'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'\nimport {\n aiChatConversationCreateSchema,\n aiChatConversationListQuerySchema,\n} from '../../../data/validators'\nimport { hasRequiredFeatures } from '../../../lib/auth'\nimport {\n createConversationStorage,\n serializeAiChatConversation,\n} from '../../../lib/conversation-storage'\n\nconst REQUIRED_FEATURE = 'ai_assistant.view'\nconst MANAGE_CONVERSATIONS_FEATURE = 'ai_assistant.conversations.manage'\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'AI Assistant',\n summary: 'Server-side AI chat conversations',\n methods: {\n GET: {\n operationId: 'aiAssistantListConversations',\n summary: 'List AI chat conversations visible to the caller.',\n description:\n 'Returns `{ items, nextCursor }` for the authenticated caller, ordered by `lastMessageAt` ' +\n 'descending. View-only callers receive only their own conversations. Callers with ' +\n '`ai_assistant.conversations.manage` may list conversations across users in the same ' +\n 'tenant/organization. The ' +\n '`agent` and `status` filters are optional; `cursor` is the ISO timestamp returned by a ' +\n 'previous response.',\n responses: [\n {\n status: 200,\n description: 'Caller-owned conversation summaries.',\n mediaType: 'application/json',\n },\n ],\n errors: [\n { status: 400, description: 'Invalid query parameters.' },\n { status: 401, description: 'Unauthenticated caller.' },\n { status: 403, description: 'Caller lacks the `ai_assistant.view` feature.' },\n ],\n },\n POST: {\n operationId: 'aiAssistantCreateConversation',\n summary: 'Idempotently create a new AI chat conversation.',\n description:\n 'If a non-deleted conversation already exists with the supplied `conversationId` for the ' +\n 'authenticated caller in this tenant/org, returns the existing summary. Otherwise creates a ' +\n 'fresh row and writes the owner-participant row in the same transaction.',\n responses: [\n {\n status: 200,\n description: 'Existing conversation (idempotent path).',\n mediaType: 'application/json',\n },\n {\n status: 201,\n description: 'Newly created conversation.',\n mediaType: 'application/json',\n },\n ],\n errors: [\n { status: 400, description: 'Invalid request body.' },\n { status: 401, description: 'Unauthenticated caller.' },\n { status: 403, description: 'Caller lacks the `ai_assistant.view` feature.' },\n ],\n },\n },\n}\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: [REQUIRED_FEATURE] },\n POST: { requireAuth: true, requireFeatures: [REQUIRED_FEATURE] },\n}\n\nfunction jsonError(\n status: number,\n message: string,\n code: string,\n extra?: Record<string, unknown>,\n): NextResponse {\n return NextResponse.json({ error: message, code, ...(extra ?? {}) }, { status })\n}\n\nasync function loadCallerContext(req: NextRequest): Promise<\n | { kind: 'unauthorized' }\n | { kind: 'forbidden' }\n | { kind: 'missing-tenant' }\n | {\n kind: 'ok'\n tenantId: string\n organizationId: string | null\n userId: string\n canManageConversations: boolean\n }\n> {\n const auth = await getAuthFromRequest(req)\n if (!auth) return { kind: 'unauthorized' }\n const container = await createRequestContainer()\n const rbacService = container.resolve<RbacService>('rbacService')\n const acl = await rbacService.loadAcl(auth.sub, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n })\n if (!hasRequiredFeatures([REQUIRED_FEATURE], acl.features, acl.isSuperAdmin, rbacService)) {\n return { kind: 'forbidden' }\n }\n const canManageConversations = hasRequiredFeatures(\n [MANAGE_CONVERSATIONS_FEATURE],\n acl.features,\n acl.isSuperAdmin,\n rbacService,\n )\n if (!auth.tenantId) {\n return { kind: 'missing-tenant' }\n }\n return {\n kind: 'ok',\n tenantId: auth.tenantId,\n organizationId: auth.orgId ?? null,\n userId: auth.sub,\n canManageConversations,\n }\n}\n\nexport async function GET(req: NextRequest): Promise<Response> {\n const callerCtx = await loadCallerContext(req)\n if (callerCtx.kind === 'unauthorized') return jsonError(401, 'Unauthorized', 'unauthenticated')\n if (callerCtx.kind === 'forbidden') {\n return jsonError(403, `Caller lacks required feature \"${REQUIRED_FEATURE}\".`, 'forbidden')\n }\n if (callerCtx.kind === 'missing-tenant') {\n return NextResponse.json({ items: [], nextCursor: null })\n }\n\n const url = new URL(req.url)\n const parseResult = aiChatConversationListQuerySchema.safeParse({\n agent: url.searchParams.get('agent') ?? undefined,\n status: url.searchParams.get('status') ?? undefined,\n limit: url.searchParams.get('limit') ?? undefined,\n cursor: url.searchParams.get('cursor') ?? undefined,\n })\n if (!parseResult.success) {\n return jsonError(400, 'Invalid query parameters.', 'validation_error', {\n issues: parseResult.error.issues,\n })\n }\n\n try {\n const container = await createRequestContainer()\n const repo = createConversationStorage(container)\n const result = await repo.list(\n {\n tenantId: callerCtx.tenantId,\n organizationId: callerCtx.organizationId,\n userId: callerCtx.userId,\n canManageConversations: callerCtx.canManageConversations,\n },\n {\n agentId: parseResult.data.agent ?? null,\n status: parseResult.data.status ?? null,\n limit: parseResult.data.limit,\n cursor: parseResult.data.cursor ?? null,\n },\n )\n return NextResponse.json({\n items: result.items.map(serializeAiChatConversation),\n nextCursor: result.nextCursor,\n })\n } catch (error) {\n console.error('[AI Conversations GET] Failure:', error)\n return jsonError(\n 500,\n error instanceof Error ? error.message : 'Failed to list conversations.',\n 'internal_error',\n )\n }\n}\n\nexport async function POST(req: NextRequest): Promise<Response> {\n const callerCtx = await loadCallerContext(req)\n if (callerCtx.kind === 'unauthorized') return jsonError(401, 'Unauthorized', 'unauthenticated')\n if (callerCtx.kind === 'forbidden') {\n return jsonError(403, `Caller lacks required feature \"${REQUIRED_FEATURE}\".`, 'forbidden')\n }\n if (callerCtx.kind === 'missing-tenant') {\n return jsonError(400, 'Caller is not bound to a tenant.', 'tenant_required')\n }\n\n let rawBody: unknown\n try {\n rawBody = await req.json()\n } catch {\n return jsonError(400, 'Request body must be valid JSON.', 'validation_error')\n }\n\n const parseResult = aiChatConversationCreateSchema.safeParse(rawBody)\n if (!parseResult.success) {\n return jsonError(400, 'Invalid conversation payload.', 'validation_error', {\n issues: parseResult.error.issues,\n })\n }\n\n try {\n const container = await createRequestContainer()\n const repo = createConversationStorage(container)\n const ctx = {\n tenantId: callerCtx.tenantId,\n organizationId: callerCtx.organizationId,\n userId: callerCtx.userId,\n canManageConversations: false,\n }\n const beforeRow = parseResult.data.conversationId\n ? await repo.getById(parseResult.data.conversationId, ctx)\n : null\n const row = await repo.createOrGet(\n {\n conversationId: parseResult.data.conversationId,\n agentId: parseResult.data.agentId,\n title: parseResult.data.title ?? null,\n pageContext: parseResult.data.pageContext ?? null,\n },\n ctx,\n )\n const status = beforeRow ? 200 : 201\n return NextResponse.json(serializeAiChatConversation(row), { status })\n } catch (error) {\n if (error instanceof Error && error.name === 'AiChatConversationAccessError') {\n return jsonError(404, error.message, 'conversation_not_found')\n }\n console.error('[AI Conversations POST] Failure:', error)\n return jsonError(\n 500,\n error instanceof Error ? error.message : 'Failed to create conversation.',\n 'internal_error',\n )\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,5 @@
1
+ import { AiChatConversation } from "../entities.js";
2
+ export {
3
+ AiChatConversation
4
+ };
5
+ //# sourceMappingURL=AiChatConversation.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/ai_assistant/data/entities/AiChatConversation.ts"],
4
+ "sourcesContent": ["export { AiChatConversation } from '../entities'\nexport type { AiChatConversation as default } from '../entities'\n"],
5
+ "mappings": "AAAA,SAAS,0BAA0B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,5 @@
1
+ import { AiChatConversationParticipant } from "../entities.js";
2
+ export {
3
+ AiChatConversationParticipant
4
+ };
5
+ //# sourceMappingURL=AiChatConversationParticipant.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/ai_assistant/data/entities/AiChatConversationParticipant.ts"],
4
+ "sourcesContent": ["export { AiChatConversationParticipant } from '../entities'\nexport type { AiChatConversationParticipant as default } from '../entities'\n"],
5
+ "mappings": "AAAA,SAAS,qCAAqC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,5 @@
1
+ import { AiChatMessage } from "../entities.js";
2
+ export {
3
+ AiChatMessage
4
+ };
5
+ //# sourceMappingURL=AiChatMessage.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/ai_assistant/data/entities/AiChatMessage.ts"],
4
+ "sourcesContent": ["export { AiChatMessage } from '../entities'\nexport type { AiChatMessage as default } from '../entities'\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;",
6
+ "names": []
7
+ }
@@ -514,10 +514,210 @@ AiAgentMutationPolicyOverride = __decorateClass([
514
514
  properties: ["tenantId", "agentId"]
515
515
  })
516
516
  ], AiAgentMutationPolicyOverride);
517
+ OptionalProps;
518
+ let AiChatConversation = class {
519
+ constructor() {
520
+ this.status = "open";
521
+ this.visibility = "private";
522
+ this.createdAt = /* @__PURE__ */ new Date();
523
+ this.updatedAt = /* @__PURE__ */ new Date();
524
+ }
525
+ };
526
+ __decorateClass([
527
+ PrimaryKey({ type: "uuid", defaultRaw: "gen_random_uuid()" })
528
+ ], AiChatConversation.prototype, "id", 2);
529
+ __decorateClass([
530
+ Property({ name: "tenant_id", type: "uuid" })
531
+ ], AiChatConversation.prototype, "tenantId", 2);
532
+ __decorateClass([
533
+ Property({ name: "organization_id", type: "uuid", nullable: true })
534
+ ], AiChatConversation.prototype, "organizationId", 2);
535
+ __decorateClass([
536
+ Property({ name: "conversation_id", type: "text" })
537
+ ], AiChatConversation.prototype, "conversationId", 2);
538
+ __decorateClass([
539
+ Property({ name: "agent_id", type: "text" })
540
+ ], AiChatConversation.prototype, "agentId", 2);
541
+ __decorateClass([
542
+ Property({ name: "owner_user_id", type: "uuid" })
543
+ ], AiChatConversation.prototype, "ownerUserId", 2);
544
+ __decorateClass([
545
+ Property({ name: "title", type: "text", nullable: true })
546
+ ], AiChatConversation.prototype, "title", 2);
547
+ __decorateClass([
548
+ Property({ name: "status", type: "text", default: "open" })
549
+ ], AiChatConversation.prototype, "status", 2);
550
+ __decorateClass([
551
+ Property({ name: "visibility", type: "text", default: "private" })
552
+ ], AiChatConversation.prototype, "visibility", 2);
553
+ __decorateClass([
554
+ Property({ name: "page_context", type: "jsonb", nullable: true })
555
+ ], AiChatConversation.prototype, "pageContext", 2);
556
+ __decorateClass([
557
+ Property({ name: "last_message_at", type: Date, nullable: true })
558
+ ], AiChatConversation.prototype, "lastMessageAt", 2);
559
+ __decorateClass([
560
+ Property({ name: "imported_from_local_at", type: Date, nullable: true })
561
+ ], AiChatConversation.prototype, "importedFromLocalAt", 2);
562
+ __decorateClass([
563
+ Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
564
+ ], AiChatConversation.prototype, "createdAt", 2);
565
+ __decorateClass([
566
+ Property({ name: "updated_at", type: Date, onUpdate: () => /* @__PURE__ */ new Date() })
567
+ ], AiChatConversation.prototype, "updatedAt", 2);
568
+ __decorateClass([
569
+ Property({ name: "deleted_at", type: Date, nullable: true })
570
+ ], AiChatConversation.prototype, "deletedAt", 2);
571
+ AiChatConversation = __decorateClass([
572
+ Entity({ tableName: "ai_chat_conversations" }),
573
+ Index({
574
+ name: "ai_chat_conversations_tenant_org_conv_uq",
575
+ expression: 'create unique index "ai_chat_conversations_tenant_org_conv_uq" on "ai_chat_conversations" ("tenant_id", "organization_id", "conversation_id") where "organization_id" is not null and "deleted_at" is null'
576
+ }),
577
+ Index({
578
+ name: "ai_chat_conversations_tenant_conv_null_org_uq",
579
+ expression: 'create unique index "ai_chat_conversations_tenant_conv_null_org_uq" on "ai_chat_conversations" ("tenant_id", "conversation_id") where "organization_id" is null and "deleted_at" is null'
580
+ }),
581
+ Index({
582
+ name: "ai_chat_conversations_tenant_org_owner_agent_idx",
583
+ properties: ["tenantId", "organizationId", "ownerUserId", "agentId", "status", "lastMessageAt"]
584
+ }),
585
+ Index({
586
+ name: "ai_chat_conversations_tenant_org_deleted_idx",
587
+ properties: ["tenantId", "organizationId", "deletedAt"]
588
+ })
589
+ ], AiChatConversation);
590
+ OptionalProps;
591
+ let AiChatConversationParticipant = class {
592
+ constructor() {
593
+ this.role = "owner";
594
+ this.createdAt = /* @__PURE__ */ new Date();
595
+ this.updatedAt = /* @__PURE__ */ new Date();
596
+ }
597
+ };
598
+ __decorateClass([
599
+ PrimaryKey({ type: "uuid", defaultRaw: "gen_random_uuid()" })
600
+ ], AiChatConversationParticipant.prototype, "id", 2);
601
+ __decorateClass([
602
+ Property({ name: "tenant_id", type: "uuid" })
603
+ ], AiChatConversationParticipant.prototype, "tenantId", 2);
604
+ __decorateClass([
605
+ Property({ name: "organization_id", type: "uuid", nullable: true })
606
+ ], AiChatConversationParticipant.prototype, "organizationId", 2);
607
+ __decorateClass([
608
+ Property({ name: "conversation_id", type: "text" })
609
+ ], AiChatConversationParticipant.prototype, "conversationId", 2);
610
+ __decorateClass([
611
+ Property({ name: "user_id", type: "uuid" })
612
+ ], AiChatConversationParticipant.prototype, "userId", 2);
613
+ __decorateClass([
614
+ Property({ name: "role", type: "text", default: "owner" })
615
+ ], AiChatConversationParticipant.prototype, "role", 2);
616
+ __decorateClass([
617
+ Property({ name: "last_read_at", type: Date, nullable: true })
618
+ ], AiChatConversationParticipant.prototype, "lastReadAt", 2);
619
+ __decorateClass([
620
+ Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
621
+ ], AiChatConversationParticipant.prototype, "createdAt", 2);
622
+ __decorateClass([
623
+ Property({ name: "updated_at", type: Date, onUpdate: () => /* @__PURE__ */ new Date() })
624
+ ], AiChatConversationParticipant.prototype, "updatedAt", 2);
625
+ AiChatConversationParticipant = __decorateClass([
626
+ Entity({ tableName: "ai_chat_conversation_participants" }),
627
+ Index({
628
+ name: "ai_chat_conv_participants_tenant_org_conv_user_uq",
629
+ expression: 'create unique index "ai_chat_conv_participants_tenant_org_conv_user_uq" on "ai_chat_conversation_participants" ("tenant_id", "organization_id", "conversation_id", "user_id") where "organization_id" is not null'
630
+ }),
631
+ Index({
632
+ name: "ai_chat_conv_participants_tenant_conv_user_null_org_uq",
633
+ expression: 'create unique index "ai_chat_conv_participants_tenant_conv_user_null_org_uq" on "ai_chat_conversation_participants" ("tenant_id", "conversation_id", "user_id") where "organization_id" is null'
634
+ }),
635
+ Index({
636
+ name: "ai_chat_conv_participants_tenant_org_user_conv_idx",
637
+ properties: ["tenantId", "organizationId", "userId", "conversationId"]
638
+ })
639
+ ], AiChatConversationParticipant);
640
+ OptionalProps;
641
+ let AiChatMessage = class {
642
+ constructor() {
643
+ this.createdAt = /* @__PURE__ */ new Date();
644
+ this.updatedAt = /* @__PURE__ */ new Date();
645
+ }
646
+ };
647
+ __decorateClass([
648
+ PrimaryKey({ type: "uuid", defaultRaw: "gen_random_uuid()" })
649
+ ], AiChatMessage.prototype, "id", 2);
650
+ __decorateClass([
651
+ Property({ name: "tenant_id", type: "uuid" })
652
+ ], AiChatMessage.prototype, "tenantId", 2);
653
+ __decorateClass([
654
+ Property({ name: "organization_id", type: "uuid", nullable: true })
655
+ ], AiChatMessage.prototype, "organizationId", 2);
656
+ __decorateClass([
657
+ Property({ name: "conversation_id", type: "text" })
658
+ ], AiChatMessage.prototype, "conversationId", 2);
659
+ __decorateClass([
660
+ Property({ name: "client_message_id", type: "text", nullable: true })
661
+ ], AiChatMessage.prototype, "clientMessageId", 2);
662
+ __decorateClass([
663
+ Property({ name: "role", type: "text" })
664
+ ], AiChatMessage.prototype, "role", 2);
665
+ __decorateClass([
666
+ Property({ name: "content", type: "text" })
667
+ ], AiChatMessage.prototype, "content", 2);
668
+ __decorateClass([
669
+ Property({ name: "ui_parts", type: "jsonb", nullable: true })
670
+ ], AiChatMessage.prototype, "uiParts", 2);
671
+ __decorateClass([
672
+ Property({ name: "attachment_ids", type: "jsonb", nullable: true })
673
+ ], AiChatMessage.prototype, "attachmentIds", 2);
674
+ __decorateClass([
675
+ Property({ name: "files_metadata", type: "jsonb", nullable: true })
676
+ ], AiChatMessage.prototype, "filesMetadata", 2);
677
+ __decorateClass([
678
+ Property({ name: "model", type: "text", nullable: true })
679
+ ], AiChatMessage.prototype, "model", 2);
680
+ __decorateClass([
681
+ Property({ name: "metadata", type: "jsonb", nullable: true })
682
+ ], AiChatMessage.prototype, "metadata", 2);
683
+ __decorateClass([
684
+ Property({ name: "created_by_user_id", type: "uuid", nullable: true })
685
+ ], AiChatMessage.prototype, "createdByUserId", 2);
686
+ __decorateClass([
687
+ Property({ name: "created_at", type: Date, onCreate: () => /* @__PURE__ */ new Date() })
688
+ ], AiChatMessage.prototype, "createdAt", 2);
689
+ __decorateClass([
690
+ Property({ name: "updated_at", type: Date, onUpdate: () => /* @__PURE__ */ new Date() })
691
+ ], AiChatMessage.prototype, "updatedAt", 2);
692
+ __decorateClass([
693
+ Property({ name: "deleted_at", type: Date, nullable: true })
694
+ ], AiChatMessage.prototype, "deletedAt", 2);
695
+ AiChatMessage = __decorateClass([
696
+ Entity({ tableName: "ai_chat_messages" }),
697
+ Index({
698
+ name: "ai_chat_messages_tenant_org_conv_client_id_uq",
699
+ expression: 'create unique index "ai_chat_messages_tenant_org_conv_client_id_uq" on "ai_chat_messages" ("tenant_id", "organization_id", "conversation_id", "client_message_id") where "organization_id" is not null and "client_message_id" is not null and "deleted_at" is null'
700
+ }),
701
+ Index({
702
+ name: "ai_chat_messages_tenant_conv_client_id_null_org_uq",
703
+ expression: 'create unique index "ai_chat_messages_tenant_conv_client_id_null_org_uq" on "ai_chat_messages" ("tenant_id", "conversation_id", "client_message_id") where "organization_id" is null and "client_message_id" is not null and "deleted_at" is null'
704
+ }),
705
+ Index({
706
+ name: "ai_chat_messages_tenant_org_conv_created_idx",
707
+ properties: ["tenantId", "organizationId", "conversationId", "createdAt"]
708
+ }),
709
+ Index({
710
+ name: "ai_chat_messages_tenant_org_deleted_idx",
711
+ properties: ["tenantId", "organizationId", "deletedAt"]
712
+ })
713
+ ], AiChatMessage);
517
714
  export {
518
715
  AiAgentMutationPolicyOverride,
519
716
  AiAgentPromptOverride,
520
717
  AiAgentRuntimeOverride,
718
+ AiChatConversation,
719
+ AiChatConversationParticipant,
720
+ AiChatMessage,
521
721
  AiPendingAction,
522
722
  AiTenantModelAllowlist,
523
723
  AiTokenUsageDaily,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/ai_assistant/data/entities.ts"],
4
- "sourcesContent": ["import { OptionalProps } from '@mikro-orm/core'\nimport {\n Entity,\n Index,\n PrimaryKey,\n Property,\n} from '@mikro-orm/decorators/legacy'\nimport type {\n AiPendingActionExecutionResult,\n AiPendingActionFailedRecord,\n AiPendingActionFieldDiff,\n AiPendingActionQueueMode,\n AiPendingActionRecordDiff,\n AiPendingActionStatus,\n} from '../lib/pending-action-types'\n\n/**\n * Versioned additive prompt-override for a registered AI agent (Step 5.3).\n *\n * Each write creates a new row with `version = latest + 1`. Rows are never\n * updated in place \u2014 history is preserved so operators can roll back by\n * reading an earlier `version`. Column set is tenant/org-scoped per the\n * standard Open Mercato RBAC contract.\n *\n * `sections` holds additive text keyed by prompt section id. The runtime\n * composes the final `systemPrompt` via `composeSystemPromptWithOverride`\n * (see `lib/prompt-override-merge.ts`), which NEVER replaces a built-in\n * section \u2014 overrides are append-only by contract.\n */\n@Entity({ tableName: 'ai_agent_prompt_overrides' })\n@Index({\n name: 'ai_agent_prompt_overrides_tenant_org_agent_version_uq',\n expression:\n 'create unique index \"ai_agent_prompt_overrides_tenant_org_agent_version_uq\" on \"ai_agent_prompt_overrides\" (\"tenant_id\", \"organization_id\", \"agent_id\", \"version\") where \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_agent_prompt_overrides_tenant_agent_version_null_org_uq',\n expression:\n 'create unique index \"ai_agent_prompt_overrides_tenant_agent_version_null_org_uq\" on \"ai_agent_prompt_overrides\" (\"tenant_id\", \"agent_id\", \"version\") where \"organization_id\" is null',\n})\n@Index({\n name: 'ai_agent_prompt_overrides_tenant_agent_idx',\n properties: ['tenantId', 'agentId'],\n})\n@Index({\n name: 'ai_agent_prompt_overrides_tenant_org_agent_version_idx',\n expression:\n 'create index \"ai_agent_prompt_overrides_tenant_org_agent_version_idx\" on \"ai_agent_prompt_overrides\" (\"tenant_id\", \"organization_id\", \"agent_id\", \"version\" desc)',\n})\nexport class AiAgentPromptOverride {\n [OptionalProps]?: 'createdAt' | 'updatedAt' | 'organizationId' | 'createdByUserId' | 'notes'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'version', type: 'int' })\n version!: number\n\n @Property({ name: 'sections', type: 'jsonb' })\n sections!: Record<string, string>\n\n @Property({ name: 'notes', type: 'text', nullable: true })\n notes?: string | null\n\n @Property({ name: 'created_by_user_id', type: 'uuid', nullable: true })\n createdByUserId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n/**\n * Persistent mutation-approval gate row backing the Phase 3 WS-C contract\n * (spec \u00A78 `AiPendingAction` + \u00A79 confirm/cancel flow, Step 5.5).\n *\n * One row is created by `prepareMutation` (Step 5.6) whenever the runtime\n * intercepts an `isMutation: true` tool call from a non-read-only agent.\n * The row stores the normalized tool input, a precomputed `fieldDiff` (or\n * per-record batch diff in `records[]`), the target record version, an\n * `idempotencyKey` that dedupes double-submits within the TTL, and a\n * `status` that walks the state machine defined in\n * {@link AI_PENDING_ACTION_ALLOWED_TRANSITIONS}.\n *\n * The cleanup worker (Step 5.12) sweeps `status='pending' AND expiresAt < now`\n * rows and transitions them to `expired`. The confirm route (Step 5.8)\n * walks `pending \u2192 confirmed \u2192 executing \u2192 (failed | terminal success)`.\n * Reads always flow through `findOneWithDecryption` /\n * `findWithDecryption`, even though no column is GDPR-flagged today, so\n * future encrypted columns (e.g. `normalizedInput`) are handled.\n */\n@Entity({ tableName: 'ai_pending_actions' })\n@Index({\n name: 'ai_pending_actions_tenant_org_idempotency_uq',\n expression:\n 'create unique index \"ai_pending_actions_tenant_org_idempotency_uq\" on \"ai_pending_actions\" (\"tenant_id\", \"organization_id\", \"idempotency_key\") where \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_pending_actions_tenant_idem_null_org_uq',\n expression:\n 'create unique index \"ai_pending_actions_tenant_idem_null_org_uq\" on \"ai_pending_actions\" (\"tenant_id\", \"idempotency_key\") where \"organization_id\" is null',\n})\n@Index({\n name: 'ai_pending_actions_tenant_org_status_expires_idx',\n properties: ['tenantId', 'organizationId', 'status', 'expiresAt'],\n})\n@Index({\n name: 'ai_pending_actions_tenant_org_agent_status_idx',\n properties: ['tenantId', 'organizationId', 'agentId', 'status'],\n})\nexport class AiPendingAction {\n [OptionalProps]?:\n | 'createdAt'\n | 'organizationId'\n | 'conversationId'\n | 'targetEntityType'\n | 'targetRecordId'\n | 'fieldDiff'\n | 'records'\n | 'failedRecords'\n | 'sideEffectsSummary'\n | 'recordVersion'\n | 'attachmentIds'\n | 'executionResult'\n | 'resolvedAt'\n | 'resolvedByUserId'\n | 'queueMode'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'tool_name', type: 'text' })\n toolName!: string\n\n @Property({ name: 'conversation_id', type: 'text', nullable: true })\n conversationId?: string | null\n\n @Property({ name: 'target_entity_type', type: 'text', nullable: true })\n targetEntityType?: string | null\n\n @Property({ name: 'target_record_id', type: 'text', nullable: true })\n targetRecordId?: string | null\n\n @Property({ name: 'normalized_input', type: 'jsonb' })\n normalizedInput!: Record<string, unknown>\n\n @Property({ name: 'field_diff', type: 'jsonb', default: [] })\n fieldDiff: AiPendingActionFieldDiff[] = []\n\n @Property({ name: 'records', type: 'jsonb', nullable: true })\n records?: AiPendingActionRecordDiff[] | null\n\n @Property({ name: 'failed_records', type: 'jsonb', nullable: true })\n failedRecords?: AiPendingActionFailedRecord[] | null\n\n @Property({ name: 'side_effects_summary', type: 'text', nullable: true })\n sideEffectsSummary?: string | null\n\n @Property({ name: 'record_version', type: 'text', nullable: true })\n recordVersion?: string | null\n\n @Property({ name: 'attachment_ids', type: 'jsonb', default: [] })\n attachmentIds: string[] = []\n\n @Property({ name: 'idempotency_key', type: 'text' })\n idempotencyKey!: string\n\n @Property({ name: 'created_by_user_id', type: 'uuid' })\n createdByUserId!: string\n\n @Property({ name: 'status', type: 'text' })\n status!: AiPendingActionStatus\n\n @Property({ name: 'queue_mode', type: 'text', default: 'inline' })\n queueMode: AiPendingActionQueueMode = 'inline'\n\n @Property({ name: 'execution_result', type: 'jsonb', nullable: true })\n executionResult?: AiPendingActionExecutionResult | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'expires_at', type: Date })\n expiresAt!: Date\n\n @Property({ name: 'resolved_at', type: Date, nullable: true })\n resolvedAt?: Date | null\n\n @Property({ name: 'resolved_by_user_id', type: 'uuid', nullable: true })\n resolvedByUserId?: string | null\n}\n\n/**\n * Per-tenant runtime override row that controls which provider, model, and\n * base URL the AI runtime uses for a given agent (or all agents when\n * `agent_id` is null).\n *\n * Resolution at query time: a non-null `agent_id` row takes precedence over\n * a null `agent_id` (tenant-wide) row for the same `(tenant_id,\n * organization_id)` scope. All value columns are nullable \u2014 an admin can\n * override just the provider, just the model, or any subset. A null value\n * means \"inherit from the next source in the factory resolution chain.\"\n *\n * Soft-delete via `deleted_at` so the unique partial index and audit trail\n * remain intact across upsert operations.\n *\n * Phase 4a of spec `2026-04-27-ai-agents-provider-model-baseurl-overrides`.\n */\n@Entity({ tableName: 'ai_agent_runtime_overrides' })\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_org_agent_uq',\n expression:\n 'create unique index \"ai_agent_runtime_overrides_tenant_org_agent_uq\" on \"ai_agent_runtime_overrides\" (\"tenant_id\", \"organization_id\", \"agent_id\") where \"deleted_at\" is null and \"organization_id\" is not null and \"agent_id\" is not null',\n})\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_agent_null_org_uq',\n expression:\n 'create unique index \"ai_agent_runtime_overrides_tenant_agent_null_org_uq\" on \"ai_agent_runtime_overrides\" (\"tenant_id\", \"agent_id\") where \"deleted_at\" is null and \"organization_id\" is null and \"agent_id\" is not null',\n})\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_null_agent_null_org_uq',\n expression:\n 'create unique index \"ai_agent_runtime_overrides_tenant_null_agent_null_org_uq\" on \"ai_agent_runtime_overrides\" (\"tenant_id\") where \"deleted_at\" is null and \"organization_id\" is null and \"agent_id\" is null',\n})\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_org_null_agent_uq',\n expression:\n 'create unique index \"ai_agent_runtime_overrides_tenant_org_null_agent_uq\" on \"ai_agent_runtime_overrides\" (\"tenant_id\", \"organization_id\") where \"deleted_at\" is null and \"organization_id\" is not null and \"agent_id\" is null',\n})\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_idx',\n properties: ['tenantId'],\n})\nexport class AiAgentRuntimeOverride {\n [OptionalProps]?:\n | 'createdAt'\n | 'updatedAt'\n | 'organizationId'\n | 'agentId'\n | 'providerId'\n | 'modelId'\n | 'baseUrl'\n | 'allowedOverrideProviders'\n | 'allowedOverrideModelsByProvider'\n | 'updatedByUserId'\n | 'deletedAt'\n | 'loopDisabled'\n | 'loopMaxSteps'\n | 'loopMaxToolCalls'\n | 'loopMaxWallClockMs'\n | 'loopMaxTokens'\n | 'loopStopWhenJson'\n | 'loopActiveToolsJson'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'agent_id', type: 'string', columnType: 'varchar(128)', nullable: true })\n agentId?: string | null\n\n @Property({ name: 'provider_id', type: 'string', columnType: 'varchar(64)', nullable: true })\n providerId?: string | null\n\n @Property({ name: 'model_id', type: 'string', columnType: 'varchar(256)', nullable: true })\n modelId?: string | null\n\n @Property({ name: 'base_url', type: 'string', columnType: 'varchar(2048)', nullable: true })\n baseUrl?: string | null\n\n @Property({ name: 'allowed_override_providers', type: 'jsonb', nullable: true })\n allowedOverrideProviders?: string[] | null\n\n @Property({ name: 'allowed_override_models_by_provider', type: 'jsonb', default: '{}' })\n allowedOverrideModelsByProvider: Record<string, string[]> = {}\n\n @Property({ name: 'updated_by_user_id', type: 'uuid', nullable: true })\n updatedByUserId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n\n /**\n * Kill switch \u2014 when `true`, runtime forces `stopWhen: stepCountIs(1)` and\n * ignores all other loop config. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_disabled', type: 'boolean', nullable: true })\n loopDisabled?: boolean | null\n\n /**\n * Override `loop.maxSteps`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_max_steps', type: 'int', nullable: true })\n loopMaxSteps?: number | null\n\n /**\n * Override `loop.budget.maxToolCalls`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_max_tool_calls', type: 'int', nullable: true })\n loopMaxToolCalls?: number | null\n\n /**\n * Override `loop.budget.maxWallClockMs`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_max_wall_clock_ms', type: 'int', nullable: true })\n loopMaxWallClockMs?: number | null\n\n /**\n * Override `loop.budget.maxTokens`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_max_tokens', type: 'int', nullable: true })\n loopMaxTokens?: number | null\n\n /**\n * Override `loop.stopWhen`. JSON-safe variants only (`stepCount`,\n * `hasToolCall`); validator rejects `kind: 'custom'`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_stop_when_json', type: 'jsonb', nullable: true })\n loopStopWhenJson?: unknown | null\n\n /**\n * Override `loop.activeTools` (must be subset of `agent.allowedTools`).\n * Phase 3 of spec `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_active_tools_json', type: 'jsonb', nullable: true })\n loopActiveToolsJson?: unknown | null\n}\n\n/**\n * Append-only event log for token usage per step (chat) or per turn (object).\n *\n * One row is created by `recordTokenUsage` (Phase 6.3) for every completed\n * AI SDK step. Indexed for the three read patterns: daily rollup, per-agent\n * report, and session drill-down.\n *\n * Retention: rows older than `AI_TOKEN_USAGE_EVENTS_RETENTION_DAYS` (default\n * 90) are swept by the `ai-token-usage-prune` worker (Phase 6.4).\n *\n * Phase 6.0 of spec `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n@Entity({ tableName: 'ai_token_usage_events' })\n@Index({\n name: 'ai_token_usage_events_tenant_created_idx',\n properties: ['tenantId', 'createdAt'],\n})\n@Index({\n name: 'ai_token_usage_events_tenant_agent_created_idx',\n properties: ['tenantId', 'agentId', 'createdAt'],\n})\n@Index({\n name: 'ai_token_usage_events_tenant_model_created_idx',\n properties: ['tenantId', 'modelId', 'createdAt'],\n})\n@Index({\n name: 'ai_token_usage_events_tenant_session_turn_step_idx',\n properties: ['tenantId', 'sessionId', 'turnId', 'stepIndex'],\n})\nexport class AiTokenUsageEvent {\n [OptionalProps]?:\n | 'createdAt'\n | 'updatedAt'\n | 'organizationId'\n | 'cachedInputTokens'\n | 'reasoningTokens'\n | 'finishReason'\n | 'loopAbortReason'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'user_id', type: 'uuid' })\n userId!: string\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'module_id', type: 'text' })\n moduleId!: string\n\n @Property({ name: 'session_id', type: 'uuid' })\n sessionId!: string\n\n @Property({ name: 'turn_id', type: 'uuid' })\n turnId!: string\n\n @Property({ name: 'step_index', type: 'int' })\n stepIndex!: number\n\n @Property({ name: 'provider_id', type: 'text' })\n providerId!: string\n\n @Property({ name: 'model_id', type: 'text' })\n modelId!: string\n\n @Property({ name: 'input_tokens', type: 'int' })\n inputTokens!: number\n\n @Property({ name: 'output_tokens', type: 'int' })\n outputTokens!: number\n\n @Property({ name: 'cached_input_tokens', type: 'int', nullable: true })\n cachedInputTokens?: number | null\n\n @Property({ name: 'reasoning_tokens', type: 'int', nullable: true })\n reasoningTokens?: number | null\n\n @Property({ name: 'finish_reason', type: 'text', nullable: true })\n finishReason?: string | null\n\n @Property({ name: 'loop_abort_reason', type: 'text', nullable: true })\n loopAbortReason?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n/**\n * Materialized daily rollup of token usage per `(tenant, day, agent, model)`.\n *\n * Updated incrementally by UPSERT on every `recordTokenUsage` call so the\n * rollup is always current even when the prune worker is behind. A daily\n * reconciliation worker (Phase 6.4) recomputes `session_count` from the events\n * table to correct any drift caused by event delivery delays or outages.\n *\n * `session_count` is maintained via a per-row LATERAL exists check at write\n * time (first event in a `(tenant, day, agent, model, session)` window\n * increments the counter). This counter may drift if events arrive out of\n * order; the daily worker corrects it.\n *\n * Phase 6.1 of spec `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n@Entity({ tableName: 'ai_token_usage_daily' })\n@Index({\n name: 'ai_token_usage_daily_tenant_day_agent_model_org_uq',\n expression:\n 'create unique index \"ai_token_usage_daily_tenant_day_agent_model_org_uq\" on \"ai_token_usage_daily\" (\"tenant_id\", \"day\", \"agent_id\", \"model_id\", \"organization_id\") where \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_token_usage_daily_tenant_day_agent_model_null_org_uq',\n expression:\n 'create unique index \"ai_token_usage_daily_tenant_day_agent_model_null_org_uq\" on \"ai_token_usage_daily\" (\"tenant_id\", \"day\", \"agent_id\", \"model_id\") where \"organization_id\" is null',\n})\n@Index({\n name: 'ai_token_usage_daily_tenant_day_idx',\n properties: ['tenantId', 'day'],\n})\nexport class AiTokenUsageDaily {\n [OptionalProps]?: 'createdAt' | 'updatedAt' | 'organizationId'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'day', type: 'string', columnType: 'date' })\n day!: string\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'model_id', type: 'text' })\n modelId!: string\n\n @Property({ name: 'provider_id', type: 'text' })\n providerId!: string\n\n @Property({ name: 'input_tokens', type: 'string', columnType: 'bigint' })\n inputTokens!: string\n\n @Property({ name: 'output_tokens', type: 'string', columnType: 'bigint' })\n outputTokens!: string\n\n @Property({ name: 'cached_input_tokens', type: 'string', columnType: 'bigint' })\n cachedInputTokens!: string\n\n @Property({ name: 'reasoning_tokens', type: 'string', columnType: 'bigint' })\n reasoningTokens!: string\n\n @Property({ name: 'step_count', type: 'string', columnType: 'bigint' })\n stepCount!: string\n\n @Property({ name: 'turn_count', type: 'string', columnType: 'bigint' })\n turnCount!: string\n\n @Property({ name: 'session_count', type: 'string', columnType: 'bigint' })\n sessionCount!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n/**\n * Tenant-scoped override of an agent's declared `mutationPolicy` (Step 5.4).\n *\n * Unlike {@link AiAgentPromptOverride}, this surface is NOT versioned \u2014 it is\n * a single-value policy switch per `(tenantId, organizationId, agentId)`. The\n * runtime enforces the override as a DOWNGRADE only: the effective policy\n * equals the MOST RESTRICTIVE of `{ code-declared, override }`. Escalation is\n * a code-level change and is rejected at the route layer.\n *\n * Hierarchy (most restrictive \u2192 least): `read-only` < `destructive-confirm-required`\n * < `confirm-required`. The route never allows an override to widen the\n * code-declared policy.\n */\n/**\n * Tenant-scoped allowlist clipping which providers and models the runtime is\n * permitted to use within the env-driven allowlist (Phase 1780-6 of spec\n * `2026-04-27-ai-agents-provider-model-baseurl-overrides`).\n *\n * Effective constraint chain (outer \u2192 inner): `OM_AI_AVAILABLE_*` env vars \u2192\n * this tenant allowlist \u2192 per-tenant runtime overrides \u2192 per-request overrides.\n * The tenant allowlist may NEVER widen the env allowlist; the runtime\n * intersects the two and surfaces the intersection through the settings GET\n * response so the UI never offers a value the runtime would refuse.\n *\n * `allowedProviders === null` means \"inherit env\" (no tenant-level restriction\n * beyond what the env imposes). `allowedModelsByProvider` keys are provider\n * ids; a missing key means \"inherit env\" for that provider; an empty array\n * means \"no models permitted for this provider\" (effectively disabling it).\n */\n@Entity({ tableName: 'ai_tenant_model_allowlists' })\n@Index({\n name: 'ai_tenant_model_allowlists_tenant_org_uq',\n expression:\n 'create unique index \"ai_tenant_model_allowlists_tenant_org_uq\" on \"ai_tenant_model_allowlists\" (\"tenant_id\", \"organization_id\") where \"deleted_at\" is null and \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_tenant_model_allowlists_tenant_null_org_uq',\n expression:\n 'create unique index \"ai_tenant_model_allowlists_tenant_null_org_uq\" on \"ai_tenant_model_allowlists\" (\"tenant_id\") where \"deleted_at\" is null and \"organization_id\" is null',\n})\n@Index({\n name: 'ai_tenant_model_allowlists_tenant_idx',\n properties: ['tenantId'],\n})\nexport class AiTenantModelAllowlist {\n [OptionalProps]?:\n | 'createdAt'\n | 'updatedAt'\n | 'organizationId'\n | 'allowedProviders'\n | 'allowedModelsByProvider'\n | 'updatedByUserId'\n | 'deletedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'allowed_providers', type: 'jsonb', nullable: true })\n allowedProviders?: string[] | null\n\n @Property({ name: 'allowed_models_by_provider', type: 'jsonb', default: '{}' })\n allowedModelsByProvider: Record<string, string[]> = {}\n\n @Property({ name: 'updated_by_user_id', type: 'uuid', nullable: true })\n updatedByUserId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'ai_agent_mutation_policy_overrides' })\n@Index({\n name: 'ai_agent_mutation_policy_overrides_tenant_org_agent_uq',\n expression:\n 'create unique index \"ai_agent_mutation_policy_overrides_tenant_org_agent_uq\" on \"ai_agent_mutation_policy_overrides\" (\"tenant_id\", \"organization_id\", \"agent_id\") where \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_agent_mutation_policy_overrides_tenant_agent_null_org_uq',\n expression:\n 'create unique index \"ai_agent_mutation_policy_overrides_tenant_agent_null_org_uq\" on \"ai_agent_mutation_policy_overrides\" (\"tenant_id\", \"agent_id\") where \"organization_id\" is null',\n})\n@Index({\n name: 'ai_agent_mutation_policy_overrides_tenant_agent_idx',\n properties: ['tenantId', 'agentId'],\n})\nexport class AiAgentMutationPolicyOverride {\n [OptionalProps]?: 'createdAt' | 'updatedAt' | 'organizationId' | 'createdByUserId' | 'notes'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'mutation_policy', type: 'text' })\n mutationPolicy!: string\n\n @Property({ name: 'notes', type: 'text', nullable: true })\n notes?: string | null\n\n @Property({ name: 'created_by_user_id', type: 'uuid', nullable: true })\n createdByUserId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n"],
5
- "mappings": ";;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AA4CJ;AADI,IAAM,wBAAN,MAA4B;AAAA,EAA5B;AA4BL,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAC7B;AA5BE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAHlD,sBAIX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GANlC,sBAOX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GATxD,sBAUX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,OAAO,CAAC;AAAA,GAZjC,sBAaX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,WAAW,MAAM,MAAM,CAAC;AAAA,GAf/B,sBAgBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,QAAQ,CAAC;AAAA,GAlBlC,sBAmBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GArB9C,sBAsBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,sBAAsB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAxB3D,sBAyBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GA3B7D,sBA4BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GA9B7D,sBA+BX;AA/BW,wBAAN;AAAA,EApBN,OAAO,EAAE,WAAW,4BAA4B,CAAC;AAAA,EACjD,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,YAAY,SAAS;AAAA,EACpC,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,GACY;AAyEV;AADI,IAAM,kBAAN,MAAsB;AAAA,EAAtB;AA8CL,qBAAwC,CAAC;AAezC,yBAA0B,CAAC;AAY3B,qBAAsC;AAMtC,qBAAkB,oBAAI,KAAK;AAAA;AAU7B;AAtEE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAlBlD,gBAmBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GArBlC,gBAsBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAxBxD,gBAyBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,OAAO,CAAC;AAAA,GA3BjC,gBA4BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GA9BlC,gBA+BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAjCxD,gBAkCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,sBAAsB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GApC3D,gBAqCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,oBAAoB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAvCzD,gBAwCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,oBAAoB,MAAM,QAAQ,CAAC;AAAA,GA1C1C,gBA2CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,SAAS,SAAS,CAAC,EAAE,CAAC;AAAA,GA7CjD,gBA8CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,WAAW,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GAhDjD,gBAiDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,kBAAkB,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GAnDxD,gBAoDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,wBAAwB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAtD7D,gBAuDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,kBAAkB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAzDvD,gBA0DX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,kBAAkB,MAAM,SAAS,SAAS,CAAC,EAAE,CAAC;AAAA,GA5DrD,gBA6DX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,OAAO,CAAC;AAAA,GA/DxC,gBAgEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,sBAAsB,MAAM,OAAO,CAAC;AAAA,GAlE3C,gBAmEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,UAAU,MAAM,OAAO,CAAC;AAAA,GArE/B,gBAsEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,QAAQ,SAAS,SAAS,CAAC;AAAA,GAxEtD,gBAyEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,oBAAoB,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GA3E1D,gBA4EX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GA9E7D,gBA+EX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,KAAK,CAAC;AAAA,GAjFjC,gBAkFX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,eAAe,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GApFlD,gBAqFX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,uBAAuB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAvF5D,gBAwFX;AAxFW,kBAAN;AAAA,EAnBN,OAAO,EAAE,WAAW,qBAAqB,CAAC;AAAA,EAC1C,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,YAAY,kBAAkB,UAAU,WAAW;AAAA,EAClE,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,YAAY,kBAAkB,WAAW,QAAQ;AAAA,EAChE,CAAC;AAAA,GACY;AAqIV;AADI,IAAM,yBAAN,MAA6B;AAAA,EAA7B;AA8CL,2CAA4D,CAAC;AAM7D,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAuD7B;AAxFE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GArBlD,uBAsBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GAxBlC,uBAyBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GA3BxD,uBA4BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,UAAU,YAAY,gBAAgB,UAAU,KAAK,CAAC;AAAA,GA9B/E,uBA+BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,eAAe,MAAM,UAAU,YAAY,eAAe,UAAU,KAAK,CAAC;AAAA,GAjCjF,uBAkCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,UAAU,YAAY,gBAAgB,UAAU,KAAK,CAAC;AAAA,GApC/E,uBAqCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,UAAU,YAAY,iBAAiB,UAAU,KAAK,CAAC;AAAA,GAvChF,uBAwCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,8BAA8B,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GA1CpE,uBA2CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,uCAAuC,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA7C5E,uBA8CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,sBAAsB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAhD3D,uBAiDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAnD7D,uBAoDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAtD7D,uBAuDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GAzDjD,uBA0DX;AAQA;AAAA,EADC,SAAS,EAAE,MAAM,iBAAiB,MAAM,WAAW,UAAU,KAAK,CAAC;AAAA,GAjEzD,uBAkEX;AAOA;AAAA,EADC,SAAS,EAAE,MAAM,kBAAkB,MAAM,OAAO,UAAU,KAAK,CAAC;AAAA,GAxEtD,uBAyEX;AAOA;AAAA,EADC,SAAS,EAAE,MAAM,uBAAuB,MAAM,OAAO,UAAU,KAAK,CAAC;AAAA,GA/E3D,uBAgFX;AAOA;AAAA,EADC,SAAS,EAAE,MAAM,0BAA0B,MAAM,OAAO,UAAU,KAAK,CAAC;AAAA,GAtF9D,uBAuFX;AAOA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,OAAO,UAAU,KAAK,CAAC;AAAA,GA7FvD,uBA8FX;AAQA;AAAA,EADC,SAAS,EAAE,MAAM,uBAAuB,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GArG7D,uBAsGX;AAOA;AAAA,EADC,SAAS,EAAE,MAAM,0BAA0B,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GA5GhE,uBA6GX;AA7GW,yBAAN;AAAA,EAzBN,OAAO,EAAE,WAAW,6BAA6B,CAAC;AAAA,EAClD,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,UAAU;AAAA,EACzB,CAAC;AAAA,GACY;AA8IV;AADI,IAAM,oBAAN,MAAwB;AAAA,EAAxB;AA8DL,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAC7B;AAvDE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAVlD,kBAWX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GAblC,kBAcX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAhBxD,kBAiBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,WAAW,MAAM,OAAO,CAAC;AAAA,GAnBhC,kBAoBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,OAAO,CAAC;AAAA,GAtBjC,kBAuBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GAzBlC,kBA0BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,OAAO,CAAC;AAAA,GA5BnC,kBA6BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,WAAW,MAAM,OAAO,CAAC;AAAA,GA/BhC,kBAgCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,CAAC;AAAA,GAlClC,kBAmCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,eAAe,MAAM,OAAO,CAAC;AAAA,GArCpC,kBAsCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,OAAO,CAAC;AAAA,GAxCjC,kBAyCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,gBAAgB,MAAM,MAAM,CAAC;AAAA,GA3CpC,kBA4CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,iBAAiB,MAAM,MAAM,CAAC;AAAA,GA9CrC,kBA+CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,uBAAuB,MAAM,OAAO,UAAU,KAAK,CAAC;AAAA,GAjD3D,kBAkDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,oBAAoB,MAAM,OAAO,UAAU,KAAK,CAAC;AAAA,GApDxD,kBAqDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,iBAAiB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAvDtD,kBAwDX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,qBAAqB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GA1D1D,kBA2DX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GA7D7D,kBA8DX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAhE7D,kBAiEX;AAjEW,oBAAN;AAAA,EAjBN,OAAO,EAAE,WAAW,wBAAwB,CAAC;AAAA,EAC7C,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,YAAY,WAAW;AAAA,EACtC,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,YAAY,WAAW,WAAW;AAAA,EACjD,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,YAAY,WAAW,WAAW;AAAA,EACjD,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,YAAY,aAAa,UAAU,WAAW;AAAA,EAC7D,CAAC;AAAA,GACY;AAmGV;AADI,IAAM,oBAAN,MAAwB;AAAA,EAAxB;AA8CL,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAC7B;AA9CE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAHlD,kBAIX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GANlC,kBAOX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GATxD,kBAUX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,MAAM,UAAU,YAAY,OAAO,CAAC;AAAA,GAZlD,kBAaX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,OAAO,CAAC;AAAA,GAfjC,kBAgBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,OAAO,CAAC;AAAA,GAlBjC,kBAmBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,eAAe,MAAM,OAAO,CAAC;AAAA,GArBpC,kBAsBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,gBAAgB,MAAM,UAAU,YAAY,SAAS,CAAC;AAAA,GAxB7D,kBAyBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,iBAAiB,MAAM,UAAU,YAAY,SAAS,CAAC;AAAA,GA3B9D,kBA4BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,uBAAuB,MAAM,UAAU,YAAY,SAAS,CAAC;AAAA,GA9BpE,kBA+BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,oBAAoB,MAAM,UAAU,YAAY,SAAS,CAAC;AAAA,GAjCjE,kBAkCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,UAAU,YAAY,SAAS,CAAC;AAAA,GApC3D,kBAqCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,UAAU,YAAY,SAAS,CAAC;AAAA,GAvC3D,kBAwCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,iBAAiB,MAAM,UAAU,YAAY,SAAS,CAAC;AAAA,GA1C9D,kBA2CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GA7C7D,kBA8CX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAhD7D,kBAiDX;AAjDW,oBAAN;AAAA,EAfN,OAAO,EAAE,WAAW,uBAAuB,CAAC;AAAA,EAC5C,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,YAAY,KAAK;AAAA,EAChC,CAAC;AAAA,GACY;AAiGV;AADI,IAAM,yBAAN,MAA6B;AAAA,EAA7B;AAuBL,mCAAoD,CAAC;AAMrD,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAI7B;AAzBE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAVlD,uBAWX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GAblC,uBAcX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAhBxD,uBAiBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,qBAAqB,MAAM,SAAS,UAAU,KAAK,CAAC;AAAA,GAnB3D,uBAoBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,8BAA8B,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAtBnE,uBAuBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,sBAAsB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAzB3D,uBA0BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GA5B7D,uBA6BX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GA/B7D,uBAgCX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GAlCjD,uBAmCX;AAnCW,yBAAN;AAAA,EAfN,OAAO,EAAE,WAAW,6BAA6B,CAAC;AAAA,EAClD,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,UAAU;AAAA,EACzB,CAAC;AAAA,GACY;AAsDV;AADI,IAAM,gCAAN,MAAoC;AAAA,EAApC;AAyBL,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAAA;AAC7B;AAzBE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GAHlD,8BAIX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,GANlC,8BAOX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GATxD,8BAUX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,YAAY,MAAM,OAAO,CAAC;AAAA,GAZjC,8BAaX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,mBAAmB,MAAM,OAAO,CAAC;AAAA,GAfxC,8BAgBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GAlB9C,8BAmBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,sBAAsB,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,GArB3D,8BAsBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAxB7D,8BAyBX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GA3B7D,8BA4BX;AA5BW,gCAAN;AAAA,EAfN,OAAO,EAAE,WAAW,qCAAqC,CAAC;AAAA,EAC1D,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YACE;AAAA,EACJ,CAAC;AAAA,EACA,MAAM;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,YAAY,SAAS;AAAA,EACpC,CAAC;AAAA,GACY;",
4
+ "sourcesContent": ["import { OptionalProps } from '@mikro-orm/core'\nimport {\n Entity,\n Index,\n PrimaryKey,\n Property,\n} from '@mikro-orm/decorators/legacy'\nimport type {\n AiPendingActionExecutionResult,\n AiPendingActionFailedRecord,\n AiPendingActionFieldDiff,\n AiPendingActionQueueMode,\n AiPendingActionRecordDiff,\n AiPendingActionStatus,\n} from '../lib/pending-action-types'\n\n/**\n * Versioned additive prompt-override for a registered AI agent (Step 5.3).\n *\n * Each write creates a new row with `version = latest + 1`. Rows are never\n * updated in place \u2014 history is preserved so operators can roll back by\n * reading an earlier `version`. Column set is tenant/org-scoped per the\n * standard Open Mercato RBAC contract.\n *\n * `sections` holds additive text keyed by prompt section id. The runtime\n * composes the final `systemPrompt` via `composeSystemPromptWithOverride`\n * (see `lib/prompt-override-merge.ts`), which NEVER replaces a built-in\n * section \u2014 overrides are append-only by contract.\n */\n@Entity({ tableName: 'ai_agent_prompt_overrides' })\n@Index({\n name: 'ai_agent_prompt_overrides_tenant_org_agent_version_uq',\n expression:\n 'create unique index \"ai_agent_prompt_overrides_tenant_org_agent_version_uq\" on \"ai_agent_prompt_overrides\" (\"tenant_id\", \"organization_id\", \"agent_id\", \"version\") where \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_agent_prompt_overrides_tenant_agent_version_null_org_uq',\n expression:\n 'create unique index \"ai_agent_prompt_overrides_tenant_agent_version_null_org_uq\" on \"ai_agent_prompt_overrides\" (\"tenant_id\", \"agent_id\", \"version\") where \"organization_id\" is null',\n})\n@Index({\n name: 'ai_agent_prompt_overrides_tenant_agent_idx',\n properties: ['tenantId', 'agentId'],\n})\n@Index({\n name: 'ai_agent_prompt_overrides_tenant_org_agent_version_idx',\n expression:\n 'create index \"ai_agent_prompt_overrides_tenant_org_agent_version_idx\" on \"ai_agent_prompt_overrides\" (\"tenant_id\", \"organization_id\", \"agent_id\", \"version\" desc)',\n})\nexport class AiAgentPromptOverride {\n [OptionalProps]?: 'createdAt' | 'updatedAt' | 'organizationId' | 'createdByUserId' | 'notes'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'version', type: 'int' })\n version!: number\n\n @Property({ name: 'sections', type: 'jsonb' })\n sections!: Record<string, string>\n\n @Property({ name: 'notes', type: 'text', nullable: true })\n notes?: string | null\n\n @Property({ name: 'created_by_user_id', type: 'uuid', nullable: true })\n createdByUserId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n/**\n * Persistent mutation-approval gate row backing the Phase 3 WS-C contract\n * (spec \u00A78 `AiPendingAction` + \u00A79 confirm/cancel flow, Step 5.5).\n *\n * One row is created by `prepareMutation` (Step 5.6) whenever the runtime\n * intercepts an `isMutation: true` tool call from a non-read-only agent.\n * The row stores the normalized tool input, a precomputed `fieldDiff` (or\n * per-record batch diff in `records[]`), the target record version, an\n * `idempotencyKey` that dedupes double-submits within the TTL, and a\n * `status` that walks the state machine defined in\n * {@link AI_PENDING_ACTION_ALLOWED_TRANSITIONS}.\n *\n * The cleanup worker (Step 5.12) sweeps `status='pending' AND expiresAt < now`\n * rows and transitions them to `expired`. The confirm route (Step 5.8)\n * walks `pending \u2192 confirmed \u2192 executing \u2192 (failed | terminal success)`.\n * Reads always flow through `findOneWithDecryption` /\n * `findWithDecryption`, even though no column is GDPR-flagged today, so\n * future encrypted columns (e.g. `normalizedInput`) are handled.\n */\n@Entity({ tableName: 'ai_pending_actions' })\n@Index({\n name: 'ai_pending_actions_tenant_org_idempotency_uq',\n expression:\n 'create unique index \"ai_pending_actions_tenant_org_idempotency_uq\" on \"ai_pending_actions\" (\"tenant_id\", \"organization_id\", \"idempotency_key\") where \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_pending_actions_tenant_idem_null_org_uq',\n expression:\n 'create unique index \"ai_pending_actions_tenant_idem_null_org_uq\" on \"ai_pending_actions\" (\"tenant_id\", \"idempotency_key\") where \"organization_id\" is null',\n})\n@Index({\n name: 'ai_pending_actions_tenant_org_status_expires_idx',\n properties: ['tenantId', 'organizationId', 'status', 'expiresAt'],\n})\n@Index({\n name: 'ai_pending_actions_tenant_org_agent_status_idx',\n properties: ['tenantId', 'organizationId', 'agentId', 'status'],\n})\nexport class AiPendingAction {\n [OptionalProps]?:\n | 'createdAt'\n | 'organizationId'\n | 'conversationId'\n | 'targetEntityType'\n | 'targetRecordId'\n | 'fieldDiff'\n | 'records'\n | 'failedRecords'\n | 'sideEffectsSummary'\n | 'recordVersion'\n | 'attachmentIds'\n | 'executionResult'\n | 'resolvedAt'\n | 'resolvedByUserId'\n | 'queueMode'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'tool_name', type: 'text' })\n toolName!: string\n\n @Property({ name: 'conversation_id', type: 'text', nullable: true })\n conversationId?: string | null\n\n @Property({ name: 'target_entity_type', type: 'text', nullable: true })\n targetEntityType?: string | null\n\n @Property({ name: 'target_record_id', type: 'text', nullable: true })\n targetRecordId?: string | null\n\n @Property({ name: 'normalized_input', type: 'jsonb' })\n normalizedInput!: Record<string, unknown>\n\n @Property({ name: 'field_diff', type: 'jsonb', default: [] })\n fieldDiff: AiPendingActionFieldDiff[] = []\n\n @Property({ name: 'records', type: 'jsonb', nullable: true })\n records?: AiPendingActionRecordDiff[] | null\n\n @Property({ name: 'failed_records', type: 'jsonb', nullable: true })\n failedRecords?: AiPendingActionFailedRecord[] | null\n\n @Property({ name: 'side_effects_summary', type: 'text', nullable: true })\n sideEffectsSummary?: string | null\n\n @Property({ name: 'record_version', type: 'text', nullable: true })\n recordVersion?: string | null\n\n @Property({ name: 'attachment_ids', type: 'jsonb', default: [] })\n attachmentIds: string[] = []\n\n @Property({ name: 'idempotency_key', type: 'text' })\n idempotencyKey!: string\n\n @Property({ name: 'created_by_user_id', type: 'uuid' })\n createdByUserId!: string\n\n @Property({ name: 'status', type: 'text' })\n status!: AiPendingActionStatus\n\n @Property({ name: 'queue_mode', type: 'text', default: 'inline' })\n queueMode: AiPendingActionQueueMode = 'inline'\n\n @Property({ name: 'execution_result', type: 'jsonb', nullable: true })\n executionResult?: AiPendingActionExecutionResult | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'expires_at', type: Date })\n expiresAt!: Date\n\n @Property({ name: 'resolved_at', type: Date, nullable: true })\n resolvedAt?: Date | null\n\n @Property({ name: 'resolved_by_user_id', type: 'uuid', nullable: true })\n resolvedByUserId?: string | null\n}\n\n/**\n * Per-tenant runtime override row that controls which provider, model, and\n * base URL the AI runtime uses for a given agent (or all agents when\n * `agent_id` is null).\n *\n * Resolution at query time: a non-null `agent_id` row takes precedence over\n * a null `agent_id` (tenant-wide) row for the same `(tenant_id,\n * organization_id)` scope. All value columns are nullable \u2014 an admin can\n * override just the provider, just the model, or any subset. A null value\n * means \"inherit from the next source in the factory resolution chain.\"\n *\n * Soft-delete via `deleted_at` so the unique partial index and audit trail\n * remain intact across upsert operations.\n *\n * Phase 4a of spec `2026-04-27-ai-agents-provider-model-baseurl-overrides`.\n */\n@Entity({ tableName: 'ai_agent_runtime_overrides' })\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_org_agent_uq',\n expression:\n 'create unique index \"ai_agent_runtime_overrides_tenant_org_agent_uq\" on \"ai_agent_runtime_overrides\" (\"tenant_id\", \"organization_id\", \"agent_id\") where \"deleted_at\" is null and \"organization_id\" is not null and \"agent_id\" is not null',\n})\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_agent_null_org_uq',\n expression:\n 'create unique index \"ai_agent_runtime_overrides_tenant_agent_null_org_uq\" on \"ai_agent_runtime_overrides\" (\"tenant_id\", \"agent_id\") where \"deleted_at\" is null and \"organization_id\" is null and \"agent_id\" is not null',\n})\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_null_agent_null_org_uq',\n expression:\n 'create unique index \"ai_agent_runtime_overrides_tenant_null_agent_null_org_uq\" on \"ai_agent_runtime_overrides\" (\"tenant_id\") where \"deleted_at\" is null and \"organization_id\" is null and \"agent_id\" is null',\n})\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_org_null_agent_uq',\n expression:\n 'create unique index \"ai_agent_runtime_overrides_tenant_org_null_agent_uq\" on \"ai_agent_runtime_overrides\" (\"tenant_id\", \"organization_id\") where \"deleted_at\" is null and \"organization_id\" is not null and \"agent_id\" is null',\n})\n@Index({\n name: 'ai_agent_runtime_overrides_tenant_idx',\n properties: ['tenantId'],\n})\nexport class AiAgentRuntimeOverride {\n [OptionalProps]?:\n | 'createdAt'\n | 'updatedAt'\n | 'organizationId'\n | 'agentId'\n | 'providerId'\n | 'modelId'\n | 'baseUrl'\n | 'allowedOverrideProviders'\n | 'allowedOverrideModelsByProvider'\n | 'updatedByUserId'\n | 'deletedAt'\n | 'loopDisabled'\n | 'loopMaxSteps'\n | 'loopMaxToolCalls'\n | 'loopMaxWallClockMs'\n | 'loopMaxTokens'\n | 'loopStopWhenJson'\n | 'loopActiveToolsJson'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'agent_id', type: 'string', columnType: 'varchar(128)', nullable: true })\n agentId?: string | null\n\n @Property({ name: 'provider_id', type: 'string', columnType: 'varchar(64)', nullable: true })\n providerId?: string | null\n\n @Property({ name: 'model_id', type: 'string', columnType: 'varchar(256)', nullable: true })\n modelId?: string | null\n\n @Property({ name: 'base_url', type: 'string', columnType: 'varchar(2048)', nullable: true })\n baseUrl?: string | null\n\n @Property({ name: 'allowed_override_providers', type: 'jsonb', nullable: true })\n allowedOverrideProviders?: string[] | null\n\n @Property({ name: 'allowed_override_models_by_provider', type: 'jsonb', default: '{}' })\n allowedOverrideModelsByProvider: Record<string, string[]> = {}\n\n @Property({ name: 'updated_by_user_id', type: 'uuid', nullable: true })\n updatedByUserId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n\n /**\n * Kill switch \u2014 when `true`, runtime forces `stopWhen: stepCountIs(1)` and\n * ignores all other loop config. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_disabled', type: 'boolean', nullable: true })\n loopDisabled?: boolean | null\n\n /**\n * Override `loop.maxSteps`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_max_steps', type: 'int', nullable: true })\n loopMaxSteps?: number | null\n\n /**\n * Override `loop.budget.maxToolCalls`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_max_tool_calls', type: 'int', nullable: true })\n loopMaxToolCalls?: number | null\n\n /**\n * Override `loop.budget.maxWallClockMs`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_max_wall_clock_ms', type: 'int', nullable: true })\n loopMaxWallClockMs?: number | null\n\n /**\n * Override `loop.budget.maxTokens`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_max_tokens', type: 'int', nullable: true })\n loopMaxTokens?: number | null\n\n /**\n * Override `loop.stopWhen`. JSON-safe variants only (`stepCount`,\n * `hasToolCall`); validator rejects `kind: 'custom'`. Phase 3 of spec\n * `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_stop_when_json', type: 'jsonb', nullable: true })\n loopStopWhenJson?: unknown | null\n\n /**\n * Override `loop.activeTools` (must be subset of `agent.allowedTools`).\n * Phase 3 of spec `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n @Property({ name: 'loop_active_tools_json', type: 'jsonb', nullable: true })\n loopActiveToolsJson?: unknown | null\n}\n\n/**\n * Append-only event log for token usage per step (chat) or per turn (object).\n *\n * One row is created by `recordTokenUsage` (Phase 6.3) for every completed\n * AI SDK step. Indexed for the three read patterns: daily rollup, per-agent\n * report, and session drill-down.\n *\n * Retention: rows older than `AI_TOKEN_USAGE_EVENTS_RETENTION_DAYS` (default\n * 90) are swept by the `ai-token-usage-prune` worker (Phase 6.4).\n *\n * Phase 6.0 of spec `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n@Entity({ tableName: 'ai_token_usage_events' })\n@Index({\n name: 'ai_token_usage_events_tenant_created_idx',\n properties: ['tenantId', 'createdAt'],\n})\n@Index({\n name: 'ai_token_usage_events_tenant_agent_created_idx',\n properties: ['tenantId', 'agentId', 'createdAt'],\n})\n@Index({\n name: 'ai_token_usage_events_tenant_model_created_idx',\n properties: ['tenantId', 'modelId', 'createdAt'],\n})\n@Index({\n name: 'ai_token_usage_events_tenant_session_turn_step_idx',\n properties: ['tenantId', 'sessionId', 'turnId', 'stepIndex'],\n})\nexport class AiTokenUsageEvent {\n [OptionalProps]?:\n | 'createdAt'\n | 'updatedAt'\n | 'organizationId'\n | 'cachedInputTokens'\n | 'reasoningTokens'\n | 'finishReason'\n | 'loopAbortReason'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'user_id', type: 'uuid' })\n userId!: string\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'module_id', type: 'text' })\n moduleId!: string\n\n @Property({ name: 'session_id', type: 'uuid' })\n sessionId!: string\n\n @Property({ name: 'turn_id', type: 'uuid' })\n turnId!: string\n\n @Property({ name: 'step_index', type: 'int' })\n stepIndex!: number\n\n @Property({ name: 'provider_id', type: 'text' })\n providerId!: string\n\n @Property({ name: 'model_id', type: 'text' })\n modelId!: string\n\n @Property({ name: 'input_tokens', type: 'int' })\n inputTokens!: number\n\n @Property({ name: 'output_tokens', type: 'int' })\n outputTokens!: number\n\n @Property({ name: 'cached_input_tokens', type: 'int', nullable: true })\n cachedInputTokens?: number | null\n\n @Property({ name: 'reasoning_tokens', type: 'int', nullable: true })\n reasoningTokens?: number | null\n\n @Property({ name: 'finish_reason', type: 'text', nullable: true })\n finishReason?: string | null\n\n @Property({ name: 'loop_abort_reason', type: 'text', nullable: true })\n loopAbortReason?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n/**\n * Materialized daily rollup of token usage per `(tenant, day, agent, model)`.\n *\n * Updated incrementally by UPSERT on every `recordTokenUsage` call so the\n * rollup is always current even when the prune worker is behind. A daily\n * reconciliation worker (Phase 6.4) recomputes `session_count` from the events\n * table to correct any drift caused by event delivery delays or outages.\n *\n * `session_count` is maintained via a per-row LATERAL exists check at write\n * time (first event in a `(tenant, day, agent, model, session)` window\n * increments the counter). This counter may drift if events arrive out of\n * order; the daily worker corrects it.\n *\n * Phase 6.1 of spec `2026-04-28-ai-agents-agentic-loop-controls`.\n */\n@Entity({ tableName: 'ai_token_usage_daily' })\n@Index({\n name: 'ai_token_usage_daily_tenant_day_agent_model_org_uq',\n expression:\n 'create unique index \"ai_token_usage_daily_tenant_day_agent_model_org_uq\" on \"ai_token_usage_daily\" (\"tenant_id\", \"day\", \"agent_id\", \"model_id\", \"organization_id\") where \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_token_usage_daily_tenant_day_agent_model_null_org_uq',\n expression:\n 'create unique index \"ai_token_usage_daily_tenant_day_agent_model_null_org_uq\" on \"ai_token_usage_daily\" (\"tenant_id\", \"day\", \"agent_id\", \"model_id\") where \"organization_id\" is null',\n})\n@Index({\n name: 'ai_token_usage_daily_tenant_day_idx',\n properties: ['tenantId', 'day'],\n})\nexport class AiTokenUsageDaily {\n [OptionalProps]?: 'createdAt' | 'updatedAt' | 'organizationId'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'day', type: 'string', columnType: 'date' })\n day!: string\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'model_id', type: 'text' })\n modelId!: string\n\n @Property({ name: 'provider_id', type: 'text' })\n providerId!: string\n\n @Property({ name: 'input_tokens', type: 'string', columnType: 'bigint' })\n inputTokens!: string\n\n @Property({ name: 'output_tokens', type: 'string', columnType: 'bigint' })\n outputTokens!: string\n\n @Property({ name: 'cached_input_tokens', type: 'string', columnType: 'bigint' })\n cachedInputTokens!: string\n\n @Property({ name: 'reasoning_tokens', type: 'string', columnType: 'bigint' })\n reasoningTokens!: string\n\n @Property({ name: 'step_count', type: 'string', columnType: 'bigint' })\n stepCount!: string\n\n @Property({ name: 'turn_count', type: 'string', columnType: 'bigint' })\n turnCount!: string\n\n @Property({ name: 'session_count', type: 'string', columnType: 'bigint' })\n sessionCount!: string\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n/**\n * Tenant-scoped override of an agent's declared `mutationPolicy` (Step 5.4).\n *\n * Unlike {@link AiAgentPromptOverride}, this surface is NOT versioned \u2014 it is\n * a single-value policy switch per `(tenantId, organizationId, agentId)`. The\n * runtime enforces the override as a DOWNGRADE only: the effective policy\n * equals the MOST RESTRICTIVE of `{ code-declared, override }`. Escalation is\n * a code-level change and is rejected at the route layer.\n *\n * Hierarchy (most restrictive \u2192 least): `read-only` < `destructive-confirm-required`\n * < `confirm-required`. The route never allows an override to widen the\n * code-declared policy.\n */\n/**\n * Tenant-scoped allowlist clipping which providers and models the runtime is\n * permitted to use within the env-driven allowlist (Phase 1780-6 of spec\n * `2026-04-27-ai-agents-provider-model-baseurl-overrides`).\n *\n * Effective constraint chain (outer \u2192 inner): `OM_AI_AVAILABLE_*` env vars \u2192\n * this tenant allowlist \u2192 per-tenant runtime overrides \u2192 per-request overrides.\n * The tenant allowlist may NEVER widen the env allowlist; the runtime\n * intersects the two and surfaces the intersection through the settings GET\n * response so the UI never offers a value the runtime would refuse.\n *\n * `allowedProviders === null` means \"inherit env\" (no tenant-level restriction\n * beyond what the env imposes). `allowedModelsByProvider` keys are provider\n * ids; a missing key means \"inherit env\" for that provider; an empty array\n * means \"no models permitted for this provider\" (effectively disabling it).\n */\n@Entity({ tableName: 'ai_tenant_model_allowlists' })\n@Index({\n name: 'ai_tenant_model_allowlists_tenant_org_uq',\n expression:\n 'create unique index \"ai_tenant_model_allowlists_tenant_org_uq\" on \"ai_tenant_model_allowlists\" (\"tenant_id\", \"organization_id\") where \"deleted_at\" is null and \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_tenant_model_allowlists_tenant_null_org_uq',\n expression:\n 'create unique index \"ai_tenant_model_allowlists_tenant_null_org_uq\" on \"ai_tenant_model_allowlists\" (\"tenant_id\") where \"deleted_at\" is null and \"organization_id\" is null',\n})\n@Index({\n name: 'ai_tenant_model_allowlists_tenant_idx',\n properties: ['tenantId'],\n})\nexport class AiTenantModelAllowlist {\n [OptionalProps]?:\n | 'createdAt'\n | 'updatedAt'\n | 'organizationId'\n | 'allowedProviders'\n | 'allowedModelsByProvider'\n | 'updatedByUserId'\n | 'deletedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'allowed_providers', type: 'jsonb', nullable: true })\n allowedProviders?: string[] | null\n\n @Property({ name: 'allowed_models_by_provider', type: 'jsonb', default: '{}' })\n allowedModelsByProvider: Record<string, string[]> = {}\n\n @Property({ name: 'updated_by_user_id', type: 'uuid', nullable: true })\n updatedByUserId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n@Entity({ tableName: 'ai_agent_mutation_policy_overrides' })\n@Index({\n name: 'ai_agent_mutation_policy_overrides_tenant_org_agent_uq',\n expression:\n 'create unique index \"ai_agent_mutation_policy_overrides_tenant_org_agent_uq\" on \"ai_agent_mutation_policy_overrides\" (\"tenant_id\", \"organization_id\", \"agent_id\") where \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_agent_mutation_policy_overrides_tenant_agent_null_org_uq',\n expression:\n 'create unique index \"ai_agent_mutation_policy_overrides_tenant_agent_null_org_uq\" on \"ai_agent_mutation_policy_overrides\" (\"tenant_id\", \"agent_id\") where \"organization_id\" is null',\n})\n@Index({\n name: 'ai_agent_mutation_policy_overrides_tenant_agent_idx',\n properties: ['tenantId', 'agentId'],\n})\nexport class AiAgentMutationPolicyOverride {\n [OptionalProps]?: 'createdAt' | 'updatedAt' | 'organizationId' | 'createdByUserId' | 'notes'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'mutation_policy', type: 'text' })\n mutationPolicy!: string\n\n @Property({ name: 'notes', type: 'text', nullable: true })\n notes?: string | null\n\n @Property({ name: 'created_by_user_id', type: 'uuid', nullable: true })\n createdByUserId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n/**\n * Tenant-scoped durable record of a typed AI chat session.\n *\n * Owner-only MVP per spec `2026-05-05-ai-chat-server-side-conversation-storage`.\n * The `participants` table prepares for future sharing without a schema\n * rewrite \u2014 the owner row is always written in the same transaction as the\n * conversation row (see `AiChatConversationRepository.createOrGet`).\n *\n * `conversationId` is the stable, client-visible identifier. It is unique\n * within `(tenant_id, organization_id)` so an idempotent `createOrGet` can\n * accept a client-generated UUID. Pending mutation approvals already store\n * the same id in `AiPendingAction.conversationId` \u2014 the chat-history schema\n * deliberately matches that contract so a future foreign key can be added\n * without churn.\n *\n * `imported_from_local_at` flags conversations that the UI lazily migrated\n * from `localStorage`. The flag is informational only; once a row exists it\n * is always the source of truth for that conversation.\n */\n@Entity({ tableName: 'ai_chat_conversations' })\n@Index({\n name: 'ai_chat_conversations_tenant_org_conv_uq',\n expression:\n 'create unique index \"ai_chat_conversations_tenant_org_conv_uq\" on \"ai_chat_conversations\" (\"tenant_id\", \"organization_id\", \"conversation_id\") where \"organization_id\" is not null and \"deleted_at\" is null',\n})\n@Index({\n name: 'ai_chat_conversations_tenant_conv_null_org_uq',\n expression:\n 'create unique index \"ai_chat_conversations_tenant_conv_null_org_uq\" on \"ai_chat_conversations\" (\"tenant_id\", \"conversation_id\") where \"organization_id\" is null and \"deleted_at\" is null',\n})\n@Index({\n name: 'ai_chat_conversations_tenant_org_owner_agent_idx',\n properties: ['tenantId', 'organizationId', 'ownerUserId', 'agentId', 'status', 'lastMessageAt'],\n})\n@Index({\n name: 'ai_chat_conversations_tenant_org_deleted_idx',\n properties: ['tenantId', 'organizationId', 'deletedAt'],\n})\nexport class AiChatConversation {\n [OptionalProps]?:\n | 'createdAt'\n | 'updatedAt'\n | 'organizationId'\n | 'title'\n | 'status'\n | 'visibility'\n | 'pageContext'\n | 'lastMessageAt'\n | 'importedFromLocalAt'\n | 'deletedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'conversation_id', type: 'text' })\n conversationId!: string\n\n @Property({ name: 'agent_id', type: 'text' })\n agentId!: string\n\n @Property({ name: 'owner_user_id', type: 'uuid' })\n ownerUserId!: string\n\n @Property({ name: 'title', type: 'text', nullable: true })\n title?: string | null\n\n @Property({ name: 'status', type: 'text', default: 'open' })\n status: 'open' | 'closed' = 'open'\n\n @Property({ name: 'visibility', type: 'text', default: 'private' })\n visibility: 'private' | 'shared' | 'organization' = 'private'\n\n @Property({ name: 'page_context', type: 'jsonb', nullable: true })\n pageContext?: Record<string, unknown> | null\n\n @Property({ name: 'last_message_at', type: Date, nullable: true })\n lastMessageAt?: Date | null\n\n @Property({ name: 'imported_from_local_at', type: Date, nullable: true })\n importedFromLocalAt?: Date | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n\n/**\n * Membership row for an `AiChatConversation`.\n *\n * MVP always writes exactly one row per conversation with `role = 'owner'`,\n * written transactionally alongside the conversation. Sharing extensions\n * append additional rows with `role IN ('viewer', 'commenter', ...)`. The\n * access predicate is \"is the caller an undeleted participant\" \u2014 see\n * `AiChatConversationRepository.assertAccessible`.\n *\n * `last_read_at` is reserved for future unread/share UX and is unused in MVP.\n */\n@Entity({ tableName: 'ai_chat_conversation_participants' })\n@Index({\n name: 'ai_chat_conv_participants_tenant_org_conv_user_uq',\n expression:\n 'create unique index \"ai_chat_conv_participants_tenant_org_conv_user_uq\" on \"ai_chat_conversation_participants\" (\"tenant_id\", \"organization_id\", \"conversation_id\", \"user_id\") where \"organization_id\" is not null',\n})\n@Index({\n name: 'ai_chat_conv_participants_tenant_conv_user_null_org_uq',\n expression:\n 'create unique index \"ai_chat_conv_participants_tenant_conv_user_null_org_uq\" on \"ai_chat_conversation_participants\" (\"tenant_id\", \"conversation_id\", \"user_id\") where \"organization_id\" is null',\n})\n@Index({\n name: 'ai_chat_conv_participants_tenant_org_user_conv_idx',\n properties: ['tenantId', 'organizationId', 'userId', 'conversationId'],\n})\nexport class AiChatConversationParticipant {\n [OptionalProps]?:\n | 'createdAt'\n | 'updatedAt'\n | 'organizationId'\n | 'role'\n | 'lastReadAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'conversation_id', type: 'text' })\n conversationId!: string\n\n @Property({ name: 'user_id', type: 'uuid' })\n userId!: string\n\n @Property({ name: 'role', type: 'text', default: 'owner' })\n role: 'owner' | 'viewer' | 'commenter' = 'owner'\n\n @Property({ name: 'last_read_at', type: Date, nullable: true })\n lastReadAt?: Date | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n}\n\n/**\n * Append-only message row for an `AiChatConversation`.\n *\n * `client_message_id` is the idempotency key for retries and lazy imports\n * from `localStorage`. The partial unique index allows a non-null\n * `clientMessageId` to dedupe within the conversation while leaving\n * server-only rows (assistant turns persisted from the streaming dispatcher)\n * free of the constraint.\n *\n * `ui_parts` stores the serializable subset of `AiChatMessageUiPart[]` so the\n * chat surface can re-render record cards, mutation-preview cards, etc.\n * across reloads. Attachment previews (`data:` URLs and transient blob\n * URLs) MUST NOT be persisted here \u2014 the UI strips them before upload.\n */\n@Entity({ tableName: 'ai_chat_messages' })\n@Index({\n name: 'ai_chat_messages_tenant_org_conv_client_id_uq',\n expression:\n 'create unique index \"ai_chat_messages_tenant_org_conv_client_id_uq\" on \"ai_chat_messages\" (\"tenant_id\", \"organization_id\", \"conversation_id\", \"client_message_id\") where \"organization_id\" is not null and \"client_message_id\" is not null and \"deleted_at\" is null',\n})\n@Index({\n name: 'ai_chat_messages_tenant_conv_client_id_null_org_uq',\n expression:\n 'create unique index \"ai_chat_messages_tenant_conv_client_id_null_org_uq\" on \"ai_chat_messages\" (\"tenant_id\", \"conversation_id\", \"client_message_id\") where \"organization_id\" is null and \"client_message_id\" is not null and \"deleted_at\" is null',\n})\n@Index({\n name: 'ai_chat_messages_tenant_org_conv_created_idx',\n properties: ['tenantId', 'organizationId', 'conversationId', 'createdAt'],\n})\n@Index({\n name: 'ai_chat_messages_tenant_org_deleted_idx',\n properties: ['tenantId', 'organizationId', 'deletedAt'],\n})\nexport class AiChatMessage {\n [OptionalProps]?:\n | 'createdAt'\n | 'updatedAt'\n | 'organizationId'\n | 'clientMessageId'\n | 'uiParts'\n | 'attachmentIds'\n | 'filesMetadata'\n | 'model'\n | 'metadata'\n | 'createdByUserId'\n | 'deletedAt'\n\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ name: 'tenant_id', type: 'uuid' })\n tenantId!: string\n\n @Property({ name: 'organization_id', type: 'uuid', nullable: true })\n organizationId?: string | null\n\n @Property({ name: 'conversation_id', type: 'text' })\n conversationId!: string\n\n @Property({ name: 'client_message_id', type: 'text', nullable: true })\n clientMessageId?: string | null\n\n @Property({ name: 'role', type: 'text' })\n role!: 'user' | 'assistant' | 'system'\n\n @Property({ name: 'content', type: 'text' })\n content!: string\n\n @Property({ name: 'ui_parts', type: 'jsonb', nullable: true })\n uiParts?: unknown[] | null\n\n @Property({ name: 'attachment_ids', type: 'jsonb', nullable: true })\n attachmentIds?: string[] | null\n\n @Property({ name: 'files_metadata', type: 'jsonb', nullable: true })\n filesMetadata?: Array<Record<string, unknown>> | null\n\n @Property({ name: 'model', type: 'text', nullable: true })\n model?: string | null\n\n @Property({ name: 'metadata', type: 'jsonb', nullable: true })\n metadata?: Record<string, unknown> | null\n\n @Property({ name: 'created_by_user_id', type: 'uuid', nullable: true })\n createdByUserId?: string | null\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }