aimeat 1.5.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.env.example +15 -0
- package/dist/bin/aimeat.js +0 -0
- package/dist/locales/en.json +291 -8
- package/dist/locales/fi.json +291 -8
- package/dist/public/css/views/admin.css +97 -0
- package/dist/public/css/views/agents-detail.css +563 -0
- package/dist/public/css/views/foundry.css +1 -0
- package/dist/public/css/views/marketplace.css +1 -0
- package/dist/public/css/views/profile.css +2 -0
- package/dist/public/js/services/admin.js +20 -1
- package/dist/public/js/services/agent-activity.js +20 -0
- package/dist/public/js/services/agent-capabilities.js +15 -0
- package/dist/public/js/services/agent-directives.js +28 -0
- package/dist/public/js/services/agent-messages.js +34 -0
- package/dist/public/js/services/agent-services.js +17 -0
- package/dist/public/js/services/agent-tasks.js +46 -0
- package/dist/public/js/services/memory.js +6 -3
- package/dist/public/js/services/sharing-groups.js +51 -0
- package/dist/public/spa.html +21 -2
- package/dist/public/views/admin/agent-tasks-tab.js +156 -0
- package/dist/public/views/admin/federation-tab.js +60 -0
- package/dist/public/views/admin/memory-tab.js +1 -0
- package/dist/public/views/admin/overview-tab.js +25 -0
- package/dist/public/views/admin/sharing-groups-tab.js +86 -0
- package/dist/public/views/admin/stats-tab.js +480 -187
- package/dist/public/views/admin.js +4 -0
- package/dist/public/views/profile/access-tab.js +511 -5
- package/dist/public/views/profile/agents-activity-subtab.js +242 -0
- package/dist/public/views/profile/agents-capabilities-subtab.js +165 -0
- package/dist/public/views/profile/agents-directives-subtab.js +292 -0
- package/dist/public/views/profile/agents-messages-subtab.js +222 -0
- package/dist/public/views/profile/agents-services-subtab.js +111 -0
- package/dist/public/views/profile/agents-tab.js +94 -47
- package/dist/public/views/profile/agents-tasks-subtab.js +254 -0
- package/dist/public/views/profile/knowledge-tab.js +5 -5
- package/dist/public/views/profile/memory-tab.js +90 -25
- package/dist/src/auth/node-keys.d.ts.map +1 -1
- package/dist/src/auth/node-keys.js +3 -0
- package/dist/src/auth/node-keys.js.map +1 -1
- package/dist/src/config.d.ts +18 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +23 -2
- package/dist/src/config.js.map +1 -1
- package/dist/src/index.js +41 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/agent-capabilities.d.ts +18 -0
- package/dist/src/mcp/agent-capabilities.d.ts.map +1 -0
- package/dist/src/mcp/agent-capabilities.js +85 -0
- package/dist/src/mcp/agent-capabilities.js.map +1 -0
- package/dist/src/mcp/agent-messages.d.ts +15 -0
- package/dist/src/mcp/agent-messages.d.ts.map +1 -0
- package/dist/src/mcp/agent-messages.js +81 -0
- package/dist/src/mcp/agent-messages.js.map +1 -0
- package/dist/src/mcp/agent-tasks.d.ts +16 -0
- package/dist/src/mcp/agent-tasks.d.ts.map +1 -0
- package/dist/src/mcp/agent-tasks.js +350 -0
- package/dist/src/mcp/agent-tasks.js.map +1 -0
- package/dist/src/mcp/core.d.ts.map +1 -1
- package/dist/src/mcp/core.js +8 -4
- package/dist/src/mcp/core.js.map +1 -1
- package/dist/src/mcp/extensions.js +1 -1
- package/dist/src/mcp/extensions.js.map +1 -1
- package/dist/src/mcp/index.d.ts.map +1 -1
- package/dist/src/mcp/index.js +8 -0
- package/dist/src/mcp/index.js.map +1 -1
- package/dist/src/mcp/memory-extended.js +1 -1
- package/dist/src/mcp/memory-extended.js.map +1 -1
- package/dist/src/mcp/sharing-groups.d.ts +16 -0
- package/dist/src/mcp/sharing-groups.d.ts.map +1 -0
- package/dist/src/mcp/sharing-groups.js +240 -0
- package/dist/src/mcp/sharing-groups.js.map +1 -0
- package/dist/src/middleware/rate-limit.d.ts.map +1 -1
- package/dist/src/middleware/rate-limit.js +4 -1
- package/dist/src/middleware/rate-limit.js.map +1 -1
- package/dist/src/models/agent-capabilities-schemas.d.ts +20 -0
- package/dist/src/models/agent-capabilities-schemas.d.ts.map +1 -0
- package/dist/src/models/agent-capabilities-schemas.js +16 -0
- package/dist/src/models/agent-capabilities-schemas.js.map +1 -0
- package/dist/src/models/agent-directives-schemas.d.ts +44 -0
- package/dist/src/models/agent-directives-schemas.d.ts.map +1 -0
- package/dist/src/models/agent-directives-schemas.js +41 -0
- package/dist/src/models/agent-directives-schemas.js.map +1 -0
- package/dist/src/models/agent-message-schemas.d.ts +32 -0
- package/dist/src/models/agent-message-schemas.d.ts.map +1 -0
- package/dist/src/models/agent-message-schemas.js +25 -0
- package/dist/src/models/agent-message-schemas.js.map +1 -0
- package/dist/src/models/agent-task-schemas.d.ts +133 -0
- package/dist/src/models/agent-task-schemas.d.ts.map +1 -0
- package/dist/src/models/agent-task-schemas.js +84 -0
- package/dist/src/models/agent-task-schemas.js.map +1 -0
- package/dist/src/models/schemas.d.ts +50 -0
- package/dist/src/models/schemas.d.ts.map +1 -1
- package/dist/src/models/schemas.js +42 -4
- package/dist/src/models/schemas.js.map +1 -1
- package/dist/src/models/sharing-group-schemas.d.ts +52 -0
- package/dist/src/models/sharing-group-schemas.d.ts.map +1 -0
- package/dist/src/models/sharing-group-schemas.js +46 -0
- package/dist/src/models/sharing-group-schemas.js.map +1 -0
- package/dist/src/routes/actions.d.ts.map +1 -1
- package/dist/src/routes/actions.js +1 -0
- package/dist/src/routes/actions.js.map +1 -1
- package/dist/src/routes/admin-agent-tasks.d.ts +12 -0
- package/dist/src/routes/admin-agent-tasks.d.ts.map +1 -0
- package/dist/src/routes/admin-agent-tasks.js +62 -0
- package/dist/src/routes/admin-agent-tasks.js.map +1 -0
- package/dist/src/routes/admin-monitoring.d.ts +2 -1
- package/dist/src/routes/admin-monitoring.d.ts.map +1 -1
- package/dist/src/routes/admin-monitoring.js +82 -2
- package/dist/src/routes/admin-monitoring.js.map +1 -1
- package/dist/src/routes/admin-sharing-groups.d.ts +12 -0
- package/dist/src/routes/admin-sharing-groups.d.ts.map +1 -0
- package/dist/src/routes/admin-sharing-groups.js +37 -0
- package/dist/src/routes/admin-sharing-groups.js.map +1 -0
- package/dist/src/routes/admin.d.ts +1 -1
- package/dist/src/routes/admin.d.ts.map +1 -1
- package/dist/src/routes/admin.js +35 -17
- package/dist/src/routes/admin.js.map +1 -1
- package/dist/src/routes/agent-activity.d.ts +17 -0
- package/dist/src/routes/agent-activity.d.ts.map +1 -0
- package/dist/src/routes/agent-activity.js +130 -0
- package/dist/src/routes/agent-activity.js.map +1 -0
- package/dist/src/routes/agent-capabilities.d.ts +17 -0
- package/dist/src/routes/agent-capabilities.d.ts.map +1 -0
- package/dist/src/routes/agent-capabilities.js +106 -0
- package/dist/src/routes/agent-capabilities.js.map +1 -0
- package/dist/src/routes/agent-directives.d.ts +17 -0
- package/dist/src/routes/agent-directives.d.ts.map +1 -0
- package/dist/src/routes/agent-directives.js +206 -0
- package/dist/src/routes/agent-directives.js.map +1 -0
- package/dist/src/routes/agent-integration.d.ts +17 -0
- package/dist/src/routes/agent-integration.d.ts.map +1 -0
- package/dist/src/routes/agent-integration.js +169 -0
- package/dist/src/routes/agent-integration.js.map +1 -0
- package/dist/src/routes/agent-messages.d.ts +17 -0
- package/dist/src/routes/agent-messages.d.ts.map +1 -0
- package/dist/src/routes/agent-messages.js +168 -0
- package/dist/src/routes/agent-messages.js.map +1 -0
- package/dist/src/routes/agent-tasks.d.ts +24 -0
- package/dist/src/routes/agent-tasks.d.ts.map +1 -0
- package/dist/src/routes/agent-tasks.js +425 -0
- package/dist/src/routes/agent-tasks.js.map +1 -0
- package/dist/src/routes/agents.js +2 -2
- package/dist/src/routes/agents.js.map +1 -1
- package/dist/src/routes/apps.d.ts.map +1 -1
- package/dist/src/routes/apps.js +5 -1
- package/dist/src/routes/apps.js.map +1 -1
- package/dist/src/routes/auth.d.ts.map +1 -1
- package/dist/src/routes/auth.js +19 -1
- package/dist/src/routes/auth.js.map +1 -1
- package/dist/src/routes/boards.js +2 -2
- package/dist/src/routes/boards.js.map +1 -1
- package/dist/src/routes/capabilities.js +4 -4
- package/dist/src/routes/capabilities.js.map +1 -1
- package/dist/src/routes/consent.d.ts.map +1 -1
- package/dist/src/routes/consent.js +2 -1
- package/dist/src/routes/consent.js.map +1 -1
- package/dist/src/routes/cortex.d.ts.map +1 -1
- package/dist/src/routes/cortex.js +1 -2
- package/dist/src/routes/cortex.js.map +1 -1
- package/dist/src/routes/disputes.js +4 -4
- package/dist/src/routes/disputes.js.map +1 -1
- package/dist/src/routes/extensions.d.ts.map +1 -1
- package/dist/src/routes/extensions.js +73 -23
- package/dist/src/routes/extensions.js.map +1 -1
- package/dist/src/routes/federation-auth.d.ts.map +1 -1
- package/dist/src/routes/federation-auth.js +2 -62
- package/dist/src/routes/federation-auth.js.map +1 -1
- package/dist/src/routes/federation-peer.d.ts.map +1 -1
- package/dist/src/routes/federation-peer.js +13 -1
- package/dist/src/routes/federation-peer.js.map +1 -1
- package/dist/src/routes/flags.d.ts.map +1 -1
- package/dist/src/routes/flags.js +2 -1
- package/dist/src/routes/flags.js.map +1 -1
- package/dist/src/routes/foundry.d.ts.map +1 -1
- package/dist/src/routes/foundry.js +2 -2
- package/dist/src/routes/foundry.js.map +1 -1
- package/dist/src/routes/generator.d.ts.map +1 -1
- package/dist/src/routes/generator.js +35 -7
- package/dist/src/routes/generator.js.map +1 -1
- package/dist/src/routes/ghii.d.ts.map +1 -1
- package/dist/src/routes/ghii.js +67 -31
- package/dist/src/routes/ghii.js.map +1 -1
- package/dist/src/routes/knowledge.d.ts.map +1 -1
- package/dist/src/routes/knowledge.js +4 -3
- package/dist/src/routes/knowledge.js.map +1 -1
- package/dist/src/routes/memory.d.ts.map +1 -1
- package/dist/src/routes/memory.js +10 -4
- package/dist/src/routes/memory.js.map +1 -1
- package/dist/src/routes/owners.d.ts.map +1 -1
- package/dist/src/routes/owners.js +104 -8
- package/dist/src/routes/owners.js.map +1 -1
- package/dist/src/routes/packages.js +1 -1
- package/dist/src/routes/packages.js.map +1 -1
- package/dist/src/routes/permissions.js +1 -1
- package/dist/src/routes/permissions.js.map +1 -1
- package/dist/src/routes/prompts.d.ts +9 -0
- package/dist/src/routes/prompts.d.ts.map +1 -1
- package/dist/src/routes/prompts.js +57 -1
- package/dist/src/routes/prompts.js.map +1 -1
- package/dist/src/routes/sharing-groups.d.ts +20 -0
- package/dist/src/routes/sharing-groups.d.ts.map +1 -0
- package/dist/src/routes/sharing-groups.js +297 -0
- package/dist/src/routes/sharing-groups.js.map +1 -0
- package/dist/src/routes/stats.d.ts +14 -0
- package/dist/src/routes/stats.d.ts.map +1 -1
- package/dist/src/routes/stats.js +79 -4
- package/dist/src/routes/stats.js.map +1 -1
- package/dist/src/routes/storage-files.d.ts.map +1 -1
- package/dist/src/routes/storage-files.js +8 -1
- package/dist/src/routes/storage-files.js.map +1 -1
- package/dist/src/routes/upload.js +2 -2
- package/dist/src/routes/upload.js.map +1 -1
- package/dist/src/routes/wallet.d.ts.map +1 -1
- package/dist/src/routes/wallet.js +2 -1
- package/dist/src/routes/wallet.js.map +1 -1
- package/dist/src/routes/work.d.ts.map +1 -1
- package/dist/src/routes/work.js +5 -1
- package/dist/src/routes/work.js.map +1 -1
- package/dist/src/schemas/knowledge-package.js +1 -1
- package/dist/src/schemas/knowledge-package.js.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +24 -4
- package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
- package/dist/src/server-bootstrap/service-init.d.ts.map +1 -1
- package/dist/src/server-bootstrap/service-init.js +2 -0
- package/dist/src/server-bootstrap/service-init.js.map +1 -1
- package/dist/src/server-bootstrap/static-files.d.ts.map +1 -1
- package/dist/src/server-bootstrap/static-files.js +10 -7
- package/dist/src/server-bootstrap/static-files.js.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +4 -2
- package/dist/src/server.js.map +1 -1
- package/dist/src/services/activity-recorder.d.ts +16 -0
- package/dist/src/services/activity-recorder.d.ts.map +1 -0
- package/dist/src/services/activity-recorder.js +59 -0
- package/dist/src/services/activity-recorder.js.map +1 -0
- package/dist/src/services/capability-invoke.d.ts.map +1 -1
- package/dist/src/services/capability-invoke.js +5 -18
- package/dist/src/services/capability-invoke.js.map +1 -1
- package/dist/src/services/config-schema.d.ts.map +1 -1
- package/dist/src/services/config-schema.js +18 -0
- package/dist/src/services/config-schema.js.map +1 -1
- package/dist/src/services/consent.d.ts +1 -1
- package/dist/src/services/consent.d.ts.map +1 -1
- package/dist/src/services/consent.js +29 -11
- package/dist/src/services/consent.js.map +1 -1
- package/dist/src/services/core-jobs.d.ts.map +1 -1
- package/dist/src/services/core-jobs.js +5 -0
- package/dist/src/services/core-jobs.js.map +1 -1
- package/dist/src/services/directory.d.ts.map +1 -1
- package/dist/src/services/directory.js +10 -4
- package/dist/src/services/directory.js.map +1 -1
- package/dist/src/services/email.d.ts +17 -4
- package/dist/src/services/email.d.ts.map +1 -1
- package/dist/src/services/email.js +30 -12
- package/dist/src/services/email.js.map +1 -1
- package/dist/src/services/extension-runtime.d.ts.map +1 -1
- package/dist/src/services/extension-runtime.js +5 -0
- package/dist/src/services/extension-runtime.js.map +1 -1
- package/dist/src/services/federation.d.ts +2 -0
- package/dist/src/services/federation.d.ts.map +1 -1
- package/dist/src/services/federation.js.map +1 -1
- package/dist/src/services/job-seeding.d.ts.map +1 -1
- package/dist/src/services/job-seeding.js +2 -0
- package/dist/src/services/job-seeding.js.map +1 -1
- package/dist/src/services/mailbox-notification.d.ts +17 -0
- package/dist/src/services/mailbox-notification.d.ts.map +1 -1
- package/dist/src/services/mailbox-notification.js +25 -0
- package/dist/src/services/mailbox-notification.js.map +1 -1
- package/dist/src/services/morsel.d.ts.map +1 -1
- package/dist/src/services/morsel.js +10 -9
- package/dist/src/services/morsel.js.map +1 -1
- package/dist/src/services/password.d.ts +1 -6
- package/dist/src/services/password.d.ts.map +1 -1
- package/dist/src/services/password.js +19 -10
- package/dist/src/services/password.js.map +1 -1
- package/dist/src/services/push.d.ts +16 -0
- package/dist/src/services/push.d.ts.map +1 -1
- package/dist/src/services/push.js +20 -0
- package/dist/src/services/push.js.map +1 -1
- package/dist/src/services/quota.d.ts.map +1 -1
- package/dist/src/services/quota.js +2 -1
- package/dist/src/services/quota.js.map +1 -1
- package/dist/src/services/scheduler.d.ts.map +1 -1
- package/dist/src/services/scheduler.js +17 -1
- package/dist/src/services/scheduler.js.map +1 -1
- package/dist/src/services/stats.d.ts +43 -2
- package/dist/src/services/stats.d.ts.map +1 -1
- package/dist/src/services/stats.js +177 -1
- package/dist/src/services/stats.js.map +1 -1
- package/dist/src/services/task-stall-detector.d.ts +10 -0
- package/dist/src/services/task-stall-detector.d.ts.map +1 -0
- package/dist/src/services/task-stall-detector.js +38 -0
- package/dist/src/services/task-stall-detector.js.map +1 -0
- package/dist/src/services/totp.js +2 -2
- package/dist/src/services/work-task-bridge.d.ts +10 -0
- package/dist/src/services/work-task-bridge.d.ts.map +1 -0
- package/dist/src/services/work-task-bridge.js +53 -0
- package/dist/src/services/work-task-bridge.js.map +1 -0
- package/dist/src/storage/interface.d.ts +175 -5
- package/dist/src/storage/interface.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.d.ts +105 -2
- package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.js +738 -8
- package/dist/src/storage/providers/mongodb/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/index.d.ts +83 -1
- package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/index.js +204 -5
- package/dist/src/storage/providers/sqlite/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent-activity.d.ts +14 -0
- package/dist/src/storage/providers/sqlite/repos/agent-activity.d.ts.map +1 -0
- package/dist/src/storage/providers/sqlite/repos/agent-activity.js +44 -0
- package/dist/src/storage/providers/sqlite/repos/agent-activity.js.map +1 -0
- package/dist/src/storage/providers/sqlite/repos/agent-directives.d.ts +14 -0
- package/dist/src/storage/providers/sqlite/repos/agent-directives.d.ts.map +1 -0
- package/dist/src/storage/providers/sqlite/repos/agent-directives.js +65 -0
- package/dist/src/storage/providers/sqlite/repos/agent-directives.js.map +1 -0
- package/dist/src/storage/providers/sqlite/repos/agent-message.d.ts +28 -0
- package/dist/src/storage/providers/sqlite/repos/agent-message.d.ts.map +1 -0
- package/dist/src/storage/providers/sqlite/repos/agent-message.js +93 -0
- package/dist/src/storage/providers/sqlite/repos/agent-message.js.map +1 -0
- package/dist/src/storage/providers/sqlite/repos/agent-task.d.ts +45 -0
- package/dist/src/storage/providers/sqlite/repos/agent-task.d.ts.map +1 -0
- package/dist/src/storage/providers/sqlite/repos/agent-task.js +155 -0
- package/dist/src/storage/providers/sqlite/repos/agent-task.js.map +1 -0
- package/dist/src/storage/providers/sqlite/repos/consent.d.ts +1 -0
- package/dist/src/storage/providers/sqlite/repos/consent.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/consent.js +4 -0
- package/dist/src/storage/providers/sqlite/repos/consent.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/sharing-group.d.ts +16 -0
- package/dist/src/storage/providers/sqlite/repos/sharing-group.d.ts.map +1 -0
- package/dist/src/storage/providers/sqlite/repos/sharing-group.js +68 -0
- package/dist/src/storage/providers/sqlite/repos/sharing-group.js.map +1 -0
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +121 -0
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/agent-activity.repository.d.ts +15 -0
- package/dist/src/storage/repositories/agent-activity.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/agent-activity.repository.js +8 -0
- package/dist/src/storage/repositories/agent-activity.repository.js.map +1 -0
- package/dist/src/storage/repositories/agent-directives.repository.d.ts +15 -0
- package/dist/src/storage/repositories/agent-directives.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/agent-directives.repository.js +8 -0
- package/dist/src/storage/repositories/agent-directives.repository.js.map +1 -0
- package/dist/src/storage/repositories/agent-message.repository.d.ts +29 -0
- package/dist/src/storage/repositories/agent-message.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/agent-message.repository.js +8 -0
- package/dist/src/storage/repositories/agent-message.repository.js.map +1 -0
- package/dist/src/storage/repositories/agent-task.repository.d.ts +46 -0
- package/dist/src/storage/repositories/agent-task.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/agent-task.repository.js +8 -0
- package/dist/src/storage/repositories/agent-task.repository.js.map +1 -0
- package/dist/src/storage/repositories/consent.repository.d.ts +1 -0
- package/dist/src/storage/repositories/consent.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/device-auth.repository.d.ts +1 -0
- package/dist/src/storage/repositories/device-auth.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/extension-instance.repository.d.ts +1 -0
- package/dist/src/storage/repositories/extension-instance.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/index.d.ts +6 -0
- package/dist/src/storage/repositories/index.d.ts.map +1 -1
- package/dist/src/storage/repositories/knowledge.repository.d.ts +2 -0
- package/dist/src/storage/repositories/knowledge.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/moderation.repository.d.ts +1 -0
- package/dist/src/storage/repositories/moderation.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/sharing-group.repository.d.ts +17 -0
- package/dist/src/storage/repositories/sharing-group.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/sharing-group.repository.js +8 -0
- package/dist/src/storage/repositories/sharing-group.repository.js.map +1 -0
- package/dist/src/storage/repositories/stats.repository.d.ts +12 -0
- package/dist/src/storage/repositories/stats.repository.d.ts.map +1 -0
- package/dist/src/storage/repositories/stats.repository.js +7 -0
- package/dist/src/storage/repositories/stats.repository.js.map +1 -0
- package/dist/src/storage/storage-factory.js +1 -0
- package/dist/src/storage/storage-factory.js.map +1 -1
- package/dist/src/utils/password-validation.d.ts +8 -0
- package/dist/src/utils/password-validation.d.ts.map +1 -0
- package/dist/src/utils/password-validation.js +25 -0
- package/dist/src/utils/password-validation.js.map +1 -0
- package/dist/src/utils/service-summary.d.ts +6 -1
- package/dist/src/utils/service-summary.d.ts.map +1 -1
- package/dist/src/utils/service-summary.js +6 -1
- package/dist/src/utils/service-summary.js.map +1 -1
- package/package.json +97 -77
- package/prisma/schema.prisma +128 -10
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* @file mongodb/index.ts
|
|
3
|
+
* @description MongoDB Storage Implementation using Prisma Client.
|
|
4
|
+
* Auto-syncs collections & indexes on startup via `prisma db push`.
|
|
3
5
|
*
|
|
4
6
|
* To use:
|
|
5
7
|
* 1. pnpm add @prisma/client prisma
|
|
6
8
|
* 2. npx prisma generate
|
|
7
9
|
* 3. Set DATABASE_URL environment variable
|
|
8
10
|
* 4. Start with: aimeat --db mongodb://localhost:27017/aimeat
|
|
11
|
+
*
|
|
12
|
+
* @version-history
|
|
13
|
+
* v1.0.0 — 2025-01-15 — Initial MongoDB storage implementation
|
|
14
|
+
* v1.1.0 — 2026-05-21 — Auto-sync Prisma schema on startup (prisma db push)
|
|
9
15
|
*/
|
|
16
|
+
import { execSync } from 'node:child_process';
|
|
10
17
|
import { randomUUID } from 'node:crypto';
|
|
18
|
+
import { existsSync } from 'node:fs';
|
|
19
|
+
import { dirname, resolve } from 'node:path';
|
|
20
|
+
import { fileURLToPath } from 'node:url';
|
|
21
|
+
import { logger } from '../../../utils/logger.js';
|
|
11
22
|
import { matchesRecipient } from '../../../services/consent.js';
|
|
12
23
|
import { parseGaiiLoose } from '../../../utils/gaii.js';
|
|
13
24
|
// Prisma client will be imported dynamically at runtime
|
|
@@ -22,10 +33,49 @@ export class MongoStorage {
|
|
|
22
33
|
this.ready = this.init(databaseUrl);
|
|
23
34
|
}
|
|
24
35
|
async init(databaseUrl) {
|
|
36
|
+
this.syncSchema(databaseUrl);
|
|
25
37
|
const { PrismaClient } = await import('@prisma/client');
|
|
26
38
|
this.prisma = new PrismaClient({ datasourceUrl: databaseUrl });
|
|
27
39
|
await this.prisma.$connect();
|
|
28
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Run `prisma db push --skip-generate` to create any missing
|
|
43
|
+
* MongoDB collections & indexes. Safe and idempotent — never drops data.
|
|
44
|
+
* Skips silently if the prisma CLI is not available.
|
|
45
|
+
*/
|
|
46
|
+
syncSchema(databaseUrl) {
|
|
47
|
+
const schemaPath = this.findPrismaSchema();
|
|
48
|
+
if (!schemaPath) {
|
|
49
|
+
logger.warn('prisma/schema.prisma not found — skipping auto schema sync');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
execSync(`npx prisma db push --skip-generate --schema "${schemaPath}"`, {
|
|
54
|
+
stdio: 'pipe',
|
|
55
|
+
env: { ...process.env, DATABASE_URL: databaseUrl },
|
|
56
|
+
timeout: 30_000,
|
|
57
|
+
});
|
|
58
|
+
logger.info('MongoDB schema synced');
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const stderr = err.stderr?.toString() ?? '';
|
|
62
|
+
logger.warn(`Auto schema sync skipped — run "pnpm db:push" manually if needed. ${stderr || err.message}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Walk up from this file to find the nearest prisma/schema.prisma */
|
|
66
|
+
findPrismaSchema() {
|
|
67
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
68
|
+
for (let i = 0; i < 10; i++) {
|
|
69
|
+
const candidate = resolve(dir, 'prisma', 'schema.prisma');
|
|
70
|
+
if (existsSync(candidate))
|
|
71
|
+
return candidate;
|
|
72
|
+
const parent = dirname(dir);
|
|
73
|
+
if (parent === dir)
|
|
74
|
+
break;
|
|
75
|
+
dir = parent;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
29
79
|
ensureReady() {
|
|
30
80
|
if (!this.prisma)
|
|
31
81
|
throw new Error('MongoDB storage not yet initialized');
|
|
@@ -98,6 +148,16 @@ export class MongoStorage {
|
|
|
98
148
|
await this.prisma.chatInstance.deleteMany({ where: { ownerName: name } });
|
|
99
149
|
// 10. Delete email verifications for this owner (Prisma)
|
|
100
150
|
await this.prisma.emailVerification.deleteMany({ where: { ownerName: name } });
|
|
151
|
+
// 10b. Delete owner-level agent dashboard data
|
|
152
|
+
const ghiiRows = await this.prisma.ghii.findMany({ where: { ownerName: name }, select: { ghii: true } });
|
|
153
|
+
for (const g of ghiiRows) {
|
|
154
|
+
await this.prisma.agentTask.deleteMany({ where: { ownerGaii: g.ghii } });
|
|
155
|
+
await this.prisma.sharingGroup.deleteMany({ where: { ownerGaii: g.ghii } });
|
|
156
|
+
try {
|
|
157
|
+
await this.prisma.ownerAgentDefault.delete({ where: { ownerGaii: g.ghii } });
|
|
158
|
+
}
|
|
159
|
+
catch { /* not found */ }
|
|
160
|
+
}
|
|
101
161
|
// 11. Delete the owner record
|
|
102
162
|
await this.prisma.owner.delete({ where: { name } });
|
|
103
163
|
return true;
|
|
@@ -123,6 +183,9 @@ export class MongoStorage {
|
|
|
123
183
|
allowedOrigins: agent.allowedOrigins ?? [],
|
|
124
184
|
defaultScopes: agent.defaultScopes ?? ['*'],
|
|
125
185
|
federate: agent.federate ?? false,
|
|
186
|
+
technicalCapabilities: agent.technicalCapabilities ?? null,
|
|
187
|
+
domainCapabilities: agent.domainCapabilities ?? null,
|
|
188
|
+
activityStats: agent.activityStats ?? null,
|
|
126
189
|
createdAt: new Date(agent.createdAt),
|
|
127
190
|
lastSeen: new Date(agent.lastSeen),
|
|
128
191
|
},
|
|
@@ -218,6 +281,19 @@ export class MongoStorage {
|
|
|
218
281
|
// OAuth refresh tokens and approvals for this agent
|
|
219
282
|
await this.prisma.oAuthRefreshToken.deleteMany({ where: { gaii } });
|
|
220
283
|
await this.prisma.oAuthApproval.deleteMany({ where: { gaii } });
|
|
284
|
+
// Agent tasks and events
|
|
285
|
+
const tasks = await this.prisma.agentTask.findMany({ where: { agentGaii: gaii }, select: { id: true } });
|
|
286
|
+
for (const t of tasks) {
|
|
287
|
+
await this.prisma.agentTaskEvent.deleteMany({ where: { taskId: t.id } });
|
|
288
|
+
}
|
|
289
|
+
await this.prisma.agentTask.deleteMany({ where: { agentGaii: gaii } });
|
|
290
|
+
// Agent directives
|
|
291
|
+
try {
|
|
292
|
+
await this.prisma.agentDirective.delete({ where: { agentGaii: gaii } });
|
|
293
|
+
}
|
|
294
|
+
catch { /* not found */ }
|
|
295
|
+
// Agent activity
|
|
296
|
+
await this.prisma.agentActivity.deleteMany({ where: { agentGaii: gaii } });
|
|
221
297
|
}
|
|
222
298
|
async listAgents() {
|
|
223
299
|
this.ensureReady();
|
|
@@ -342,6 +418,7 @@ export class MongoStorage {
|
|
|
342
418
|
ownerGaii: record.ownerGaii,
|
|
343
419
|
value: record.value,
|
|
344
420
|
visibility: record.visibility,
|
|
421
|
+
groupId: record.groupId ?? null,
|
|
345
422
|
tags: record.tags,
|
|
346
423
|
ttlHours: record.ttlHours,
|
|
347
424
|
version: record.version,
|
|
@@ -353,6 +430,7 @@ export class MongoStorage {
|
|
|
353
430
|
update: {
|
|
354
431
|
value: record.value,
|
|
355
432
|
visibility: record.visibility,
|
|
433
|
+
groupId: record.groupId ?? null,
|
|
356
434
|
tags: record.tags,
|
|
357
435
|
ttlHours: record.ttlHours,
|
|
358
436
|
version: record.version,
|
|
@@ -375,6 +453,7 @@ export class MongoStorage {
|
|
|
375
453
|
data: {
|
|
376
454
|
value: record.value,
|
|
377
455
|
visibility: record.visibility,
|
|
456
|
+
groupId: record.groupId ?? null,
|
|
378
457
|
tags: record.tags,
|
|
379
458
|
ttlHours: record.ttlHours,
|
|
380
459
|
version: record.version,
|
|
@@ -1150,6 +1229,7 @@ export class MongoStorage {
|
|
|
1150
1229
|
data: file.data,
|
|
1151
1230
|
tags: file.tags || [],
|
|
1152
1231
|
federate: file.federate ?? false,
|
|
1232
|
+
groupId: file.groupId ?? null,
|
|
1153
1233
|
createdAt: new Date(file.createdAt),
|
|
1154
1234
|
},
|
|
1155
1235
|
});
|
|
@@ -1162,16 +1242,16 @@ export class MongoStorage {
|
|
|
1162
1242
|
});
|
|
1163
1243
|
if (!row)
|
|
1164
1244
|
return null;
|
|
1165
|
-
return { key: row.key, ownerGaii: row.ownerGaii, visibility: row.visibility, mimeType: row.mimeType, size: row.size, data: Buffer.from(row.data), tags: row.tags || [], federate: row.federate ?? false, createdAt: row.createdAt.toISOString() };
|
|
1245
|
+
return { key: row.key, ownerGaii: row.ownerGaii, visibility: row.visibility, groupId: row.groupId ?? undefined, mimeType: row.mimeType, size: row.size, data: Buffer.from(row.data), tags: row.tags || [], federate: row.federate ?? false, createdAt: row.createdAt.toISOString() };
|
|
1166
1246
|
}
|
|
1167
1247
|
async listStorageFiles(ownerGaii) {
|
|
1168
1248
|
this.ensureReady();
|
|
1169
1249
|
const rows = await this.prisma.storageFile.findMany({
|
|
1170
1250
|
where: { ownerGaii },
|
|
1171
|
-
select: { key: true, ownerGaii: true, visibility: true, mimeType: true, size: true, tags: true, federate: true, createdAt: true },
|
|
1251
|
+
select: { key: true, ownerGaii: true, visibility: true, groupId: true, mimeType: true, size: true, tags: true, federate: true, createdAt: true },
|
|
1172
1252
|
});
|
|
1173
1253
|
return rows.map((r) => ({
|
|
1174
|
-
key: r.key, ownerGaii: r.ownerGaii, visibility: r.visibility, mimeType: r.mimeType, size: r.size, data: Buffer.alloc(0), tags: r.tags || [], federate: r.federate ?? false, createdAt: r.createdAt.toISOString(),
|
|
1254
|
+
key: r.key, ownerGaii: r.ownerGaii, visibility: r.visibility, groupId: r.groupId ?? undefined, mimeType: r.mimeType, size: r.size, data: Buffer.alloc(0), tags: r.tags || [], federate: r.federate ?? false, createdAt: r.createdAt.toISOString(),
|
|
1175
1255
|
}));
|
|
1176
1256
|
}
|
|
1177
1257
|
async deleteStorageFile(ownerGaii, key) {
|
|
@@ -1300,10 +1380,10 @@ export class MongoStorage {
|
|
|
1300
1380
|
return { name: row.name, displayName: row.displayName ?? undefined, publicKey: row.publicKey, roles: row.roles, createdAt: row.createdAt.toISOString() };
|
|
1301
1381
|
}
|
|
1302
1382
|
toAgentRecord(row) {
|
|
1303
|
-
return { name: row.name, owner: row.owner, gaii: row.gaii, displayName: row.displayName ?? undefined, description: row.description ?? undefined, capabilities: row.capabilities, publicKey: row.publicKey, trustScore: row.trustScore, morselBalance: row.morselBalance, defaultScopes: row.defaultScopes?.length ? row.defaultScopes : undefined, allowedOrigins: row.allowedOrigins?.length ? row.allowedOrigins : undefined, federate: row.federate ?? false, createdAt: row.createdAt.toISOString(), lastSeen: row.lastSeen.toISOString() };
|
|
1383
|
+
return { name: row.name, owner: row.owner, gaii: row.gaii, displayName: row.displayName ?? undefined, description: row.description ?? undefined, capabilities: row.capabilities, publicKey: row.publicKey, trustScore: row.trustScore, morselBalance: row.morselBalance, defaultScopes: row.defaultScopes?.length ? row.defaultScopes : undefined, allowedOrigins: row.allowedOrigins?.length ? row.allowedOrigins : undefined, federate: row.federate ?? false, technicalCapabilities: row.technicalCapabilities ?? undefined, domainCapabilities: row.domainCapabilities ?? undefined, activityStats: row.activityStats ?? undefined, createdAt: row.createdAt.toISOString(), lastSeen: row.lastSeen.toISOString() };
|
|
1304
1384
|
}
|
|
1305
1385
|
toMemoryRecord(row) {
|
|
1306
|
-
return { key: row.key, ownerGaii: row.ownerGaii, value: row.value, visibility: row.visibility, tags: row.tags, ttlHours: row.ttlHours, version: row.version, createdAt: row.createdAt.toISOString(), updatedAt: row.updatedAt.toISOString(), flagCount: row.flagCount ?? undefined, allowedOrigins: row.allowedOrigins?.length ? row.allowedOrigins : undefined };
|
|
1386
|
+
return { key: row.key, ownerGaii: row.ownerGaii, value: row.value, visibility: row.visibility, groupId: row.groupId ?? undefined, tags: row.tags, ttlHours: row.ttlHours, version: row.version, createdAt: row.createdAt.toISOString(), updatedAt: row.updatedAt.toISOString(), flagCount: row.flagCount ?? undefined, allowedOrigins: row.allowedOrigins?.length ? row.allowedOrigins : undefined };
|
|
1307
1387
|
}
|
|
1308
1388
|
toActionRecord(row) {
|
|
1309
1389
|
return { id: row.actionId, providerGaii: row.providerGaii, displayName: row.displayName, description: row.description, category: row.category ?? undefined, inputSchema: row.inputSchema, outputSchema: row.outputSchema, pricing: { baseMorsels: row.pricingBaseMorsels, perUnit: row.pricingPerUnit }, estimatedTimeSeconds: row.estimatedTimeSeconds ?? undefined, maxInputSizeBytes: row.maxInputSizeBytes ?? undefined, tags: row.tags, webhookUrl: row.webhookUrl ?? undefined, semantic: row.semantic ?? undefined, federate: row.federate ?? false, createdAt: row.createdAt.toISOString(), updatedAt: row.updatedAt.toISOString() };
|
|
@@ -1845,6 +1925,14 @@ export class MongoStorage {
|
|
|
1845
1925
|
}
|
|
1846
1926
|
return results;
|
|
1847
1927
|
}
|
|
1928
|
+
async expireStaleConsents(before) {
|
|
1929
|
+
this.ensureReady();
|
|
1930
|
+
const result = await this.prisma.consent.updateMany({
|
|
1931
|
+
where: { status: 'active', expires: { not: null, lt: new Date(before) } },
|
|
1932
|
+
data: { status: 'expired' },
|
|
1933
|
+
});
|
|
1934
|
+
return result.count;
|
|
1935
|
+
}
|
|
1848
1936
|
// Consent Audit
|
|
1849
1937
|
async addConsentAuditEntry(entry) {
|
|
1850
1938
|
this.ensureReady();
|
|
@@ -2145,6 +2233,11 @@ export class MongoStorage {
|
|
|
2145
2233
|
const result = await this.prisma.match.deleteMany({ where: { expiresAt: { lt: new Date() }, status: { not: 'accepted' } } });
|
|
2146
2234
|
return result.count;
|
|
2147
2235
|
}
|
|
2236
|
+
async deleteMatchesByProfile(profile) {
|
|
2237
|
+
this.ensureReady();
|
|
2238
|
+
const result = await this.prisma.match.deleteMany({ where: { OR: [{ profileA: profile }, { profileB: profile }] } });
|
|
2239
|
+
return result.count;
|
|
2240
|
+
}
|
|
2148
2241
|
async listAllMatches(limit = 10000) {
|
|
2149
2242
|
this.ensureReady();
|
|
2150
2243
|
const rows = await this.prisma.match.findMany({ take: Math.min(limit, 10000) });
|
|
@@ -3620,6 +3713,11 @@ export class MongoStorage {
|
|
|
3620
3713
|
}
|
|
3621
3714
|
return broken;
|
|
3622
3715
|
}
|
|
3716
|
+
async deleteLinksByContributor(gaii) {
|
|
3717
|
+
this.ensureReady();
|
|
3718
|
+
const result = await this.prisma.knowledgeLink.deleteMany({ where: { linkedBy: gaii } });
|
|
3719
|
+
return result.count;
|
|
3720
|
+
}
|
|
3623
3721
|
// ══════════════════════════════════════════════════════════
|
|
3624
3722
|
// ── Knowledge: Operator Reviews (Prisma-persisted) ──
|
|
3625
3723
|
// ══════════════════════════════════════════════════════════
|
|
@@ -3665,6 +3763,11 @@ export class MongoStorage {
|
|
|
3665
3763
|
});
|
|
3666
3764
|
return rows.map((r) => this.toOperatorReviewRecord(r));
|
|
3667
3765
|
}
|
|
3766
|
+
async deleteReviewsByOperator(gaii) {
|
|
3767
|
+
this.ensureReady();
|
|
3768
|
+
const result = await this.prisma.knowledgeReview.deleteMany({ where: { operatorGaii: gaii } });
|
|
3769
|
+
return result.count;
|
|
3770
|
+
}
|
|
3668
3771
|
// ══════════════════════════════════════════════════════════
|
|
3669
3772
|
// ── Scheduler: Scheduled Jobs ──
|
|
3670
3773
|
// ══════════════════════════════════════════════════════════
|
|
@@ -3866,6 +3969,7 @@ export class MongoStorage {
|
|
|
3866
3969
|
status: row.status,
|
|
3867
3970
|
translations: row.translations,
|
|
3868
3971
|
createdBy: row.createdBy,
|
|
3972
|
+
createdByAgent: row.createdByAgent ?? undefined,
|
|
3869
3973
|
createdAt: row.createdAt instanceof Date ? row.createdAt.toISOString() : row.createdAt,
|
|
3870
3974
|
updatedAt: row.updatedAt instanceof Date ? row.updatedAt.toISOString() : row.updatedAt,
|
|
3871
3975
|
};
|
|
@@ -3880,6 +3984,7 @@ export class MongoStorage {
|
|
|
3880
3984
|
status: record.status,
|
|
3881
3985
|
translations: record.translations ? record.translations : undefined,
|
|
3882
3986
|
createdBy: record.createdBy,
|
|
3987
|
+
createdByAgent: record.createdByAgent ?? null,
|
|
3883
3988
|
createdAt: new Date(record.createdAt),
|
|
3884
3989
|
},
|
|
3885
3990
|
});
|
|
@@ -3932,6 +4037,11 @@ export class MongoStorage {
|
|
|
3932
4037
|
return false;
|
|
3933
4038
|
}
|
|
3934
4039
|
}
|
|
4040
|
+
async deleteExtensionInstancesByOwner(ownerIdentity) {
|
|
4041
|
+
this.ensureReady();
|
|
4042
|
+
const result = await this.prisma.extensionInstance.deleteMany({ where: { createdBy: ownerIdentity } });
|
|
4043
|
+
return result.count;
|
|
4044
|
+
}
|
|
3935
4045
|
// ══════════════════════════════════════════════════════════
|
|
3936
4046
|
// ── Federation Peers (persisted active peer connections) ──
|
|
3937
4047
|
// ══════════════════════════════════════════════════════════
|
|
@@ -3939,8 +4049,8 @@ export class MongoStorage {
|
|
|
3939
4049
|
this.ensureReady();
|
|
3940
4050
|
await this.prisma.federationPeer.upsert({
|
|
3941
4051
|
where: { nodeId: peer.nodeId },
|
|
3942
|
-
create: { nodeId: peer.nodeId, url: peer.url, publicKey: peer.publicKey, status: peer.status, addedAt: new Date(peer.addedAt), lastSeen: new Date(peer.lastSeen), shareCatalogue: peer.shareCatalogue, replicateMemory: peer.replicateMemory, allowRouting: peer.allowRouting, peerMode: peer.peerMode || 'federation' },
|
|
3943
|
-
update: { url: peer.url, publicKey: peer.publicKey, status: peer.status, lastSeen: new Date(peer.lastSeen), shareCatalogue: peer.shareCatalogue, replicateMemory: peer.replicateMemory, allowRouting: peer.allowRouting, peerMode: peer.peerMode || 'federation' },
|
|
4052
|
+
create: { nodeId: peer.nodeId, url: peer.url, publicKey: peer.publicKey, status: peer.status, addedAt: new Date(peer.addedAt), lastSeen: new Date(peer.lastSeen), shareCatalogue: peer.shareCatalogue, replicateMemory: peer.replicateMemory, allowRouting: peer.allowRouting, peerMode: peer.peerMode || 'federation', allowFederatedAuth: peer.allowFederatedAuth ?? false, federationAuthScopes: peer.federationAuthScopes ?? [] },
|
|
4053
|
+
update: { url: peer.url, publicKey: peer.publicKey, status: peer.status, lastSeen: new Date(peer.lastSeen), shareCatalogue: peer.shareCatalogue, replicateMemory: peer.replicateMemory, allowRouting: peer.allowRouting, peerMode: peer.peerMode || 'federation', allowFederatedAuth: peer.allowFederatedAuth ?? false, federationAuthScopes: peer.federationAuthScopes ?? [] },
|
|
3944
4054
|
});
|
|
3945
4055
|
}
|
|
3946
4056
|
async listFederationPeers() {
|
|
@@ -3957,6 +4067,8 @@ export class MongoStorage {
|
|
|
3957
4067
|
replicateMemory: r.replicateMemory ?? true,
|
|
3958
4068
|
allowRouting: r.allowRouting ?? true,
|
|
3959
4069
|
peerMode: r.peerMode || 'federation',
|
|
4070
|
+
allowFederatedAuth: r.allowFederatedAuth ?? false,
|
|
4071
|
+
federationAuthScopes: r.federationAuthScopes ?? [],
|
|
3960
4072
|
}));
|
|
3961
4073
|
}
|
|
3962
4074
|
async deleteFederationPeer(nodeId) {
|
|
@@ -4104,6 +4216,11 @@ export class MongoStorage {
|
|
|
4104
4216
|
});
|
|
4105
4217
|
return result.count;
|
|
4106
4218
|
}
|
|
4219
|
+
async deleteDeviceAuthByOwner(ownerName) {
|
|
4220
|
+
this.ensureReady();
|
|
4221
|
+
const result = await this.prisma.deviceAuth.deleteMany({ where: { ownerName } });
|
|
4222
|
+
return result.count;
|
|
4223
|
+
}
|
|
4107
4224
|
toDeviceAuthRecord(row) {
|
|
4108
4225
|
return {
|
|
4109
4226
|
deviceCode: row.deviceCode,
|
|
@@ -5217,6 +5334,619 @@ export class MongoStorage {
|
|
|
5217
5334
|
const trust = { ...cap.trust, vouchCount: Math.max(0, cap.trust.vouchCount - 1) };
|
|
5218
5335
|
await this.prisma.capability.update({ where: { id }, data: { trust: trust } });
|
|
5219
5336
|
}
|
|
5337
|
+
// ── Stats Persistence ──
|
|
5338
|
+
async flushStats(counters) {
|
|
5339
|
+
const ops = Object.entries(counters).map(([key, value]) => this.prisma.statsCounter.upsert({
|
|
5340
|
+
where: { id: key },
|
|
5341
|
+
create: { id: key, value },
|
|
5342
|
+
update: { value },
|
|
5343
|
+
}));
|
|
5344
|
+
await Promise.all(ops);
|
|
5345
|
+
}
|
|
5346
|
+
async loadStats() {
|
|
5347
|
+
const rows = await this.prisma.statsCounter.findMany();
|
|
5348
|
+
const result = {};
|
|
5349
|
+
for (const row of rows) {
|
|
5350
|
+
result[row.id] = row.value;
|
|
5351
|
+
}
|
|
5352
|
+
return result;
|
|
5353
|
+
}
|
|
5354
|
+
async flushDailyHistory(history) {
|
|
5355
|
+
const cutoff = new Date();
|
|
5356
|
+
cutoff.setDate(cutoff.getDate() - 90);
|
|
5357
|
+
const cutoffStr = cutoff.toISOString().split('T')[0];
|
|
5358
|
+
const ops = [];
|
|
5359
|
+
for (const [date, counters] of Object.entries(history)) {
|
|
5360
|
+
for (const [key, value] of Object.entries(counters)) {
|
|
5361
|
+
ops.push(this.prisma.statsDailyHistory.upsert({
|
|
5362
|
+
where: { date_key: { date, key } },
|
|
5363
|
+
create: { date, key, value },
|
|
5364
|
+
update: { value },
|
|
5365
|
+
}));
|
|
5366
|
+
}
|
|
5367
|
+
}
|
|
5368
|
+
ops.push(this.prisma.statsDailyHistory.deleteMany({ where: { date: { lt: cutoffStr } } }));
|
|
5369
|
+
await Promise.all(ops);
|
|
5370
|
+
}
|
|
5371
|
+
async loadDailyHistory() {
|
|
5372
|
+
const rows = await this.prisma.statsDailyHistory.findMany({ orderBy: { date: 'asc' } });
|
|
5373
|
+
const result = {};
|
|
5374
|
+
for (const row of rows) {
|
|
5375
|
+
if (!result[row.date])
|
|
5376
|
+
result[row.date] = {};
|
|
5377
|
+
result[row.date][row.key] = row.value;
|
|
5378
|
+
}
|
|
5379
|
+
return result;
|
|
5380
|
+
}
|
|
5381
|
+
// ── Agent Tasks ──
|
|
5382
|
+
toTaskRecord(row) {
|
|
5383
|
+
return {
|
|
5384
|
+
id: row.id,
|
|
5385
|
+
agentGaii: row.agentGaii,
|
|
5386
|
+
ownerGaii: row.ownerGaii,
|
|
5387
|
+
title: row.title,
|
|
5388
|
+
description: row.description,
|
|
5389
|
+
scope: row.scope,
|
|
5390
|
+
rules: row.rules,
|
|
5391
|
+
verification: row.verification,
|
|
5392
|
+
resources: row.resources ?? undefined,
|
|
5393
|
+
todos: row.todos,
|
|
5394
|
+
status: row.status,
|
|
5395
|
+
parentTaskId: row.parentTaskId ?? undefined,
|
|
5396
|
+
workTrackingCode: row.workTrackingCode ?? undefined,
|
|
5397
|
+
telemetry: row.telemetry ?? undefined,
|
|
5398
|
+
lastEventAt: row.lastEventAt ? (row.lastEventAt instanceof Date ? row.lastEventAt.toISOString() : row.lastEventAt) : undefined,
|
|
5399
|
+
createdAt: row.createdAt instanceof Date ? row.createdAt.toISOString() : row.createdAt,
|
|
5400
|
+
updatedAt: row.updatedAt instanceof Date ? row.updatedAt.toISOString() : row.updatedAt,
|
|
5401
|
+
completedAt: row.completedAt ? (row.completedAt instanceof Date ? row.completedAt.toISOString() : row.completedAt) : undefined,
|
|
5402
|
+
};
|
|
5403
|
+
}
|
|
5404
|
+
toTaskEventRecord(row) {
|
|
5405
|
+
return {
|
|
5406
|
+
id: row.id,
|
|
5407
|
+
taskId: row.taskId,
|
|
5408
|
+
type: row.type,
|
|
5409
|
+
message: row.message,
|
|
5410
|
+
details: row.details ?? undefined,
|
|
5411
|
+
timestamp: row.timestamp instanceof Date ? row.timestamp.toISOString() : row.timestamp,
|
|
5412
|
+
};
|
|
5413
|
+
}
|
|
5414
|
+
async createAgentTask(record) {
|
|
5415
|
+
this.ensureReady();
|
|
5416
|
+
await this.prisma.agentTask.create({
|
|
5417
|
+
data: {
|
|
5418
|
+
id: record.id,
|
|
5419
|
+
agentGaii: record.agentGaii,
|
|
5420
|
+
ownerGaii: record.ownerGaii,
|
|
5421
|
+
title: record.title,
|
|
5422
|
+
description: record.description,
|
|
5423
|
+
scope: record.scope,
|
|
5424
|
+
rules: record.rules,
|
|
5425
|
+
verification: record.verification,
|
|
5426
|
+
resources: record.resources ?? null,
|
|
5427
|
+
todos: record.todos,
|
|
5428
|
+
status: record.status,
|
|
5429
|
+
parentTaskId: record.parentTaskId ?? null,
|
|
5430
|
+
workTrackingCode: record.workTrackingCode ?? null,
|
|
5431
|
+
telemetry: record.telemetry ?? null,
|
|
5432
|
+
lastEventAt: record.lastEventAt ? new Date(record.lastEventAt) : null,
|
|
5433
|
+
createdAt: new Date(record.createdAt),
|
|
5434
|
+
completedAt: record.completedAt ? new Date(record.completedAt) : null,
|
|
5435
|
+
},
|
|
5436
|
+
});
|
|
5437
|
+
return record;
|
|
5438
|
+
}
|
|
5439
|
+
async getAgentTask(id) {
|
|
5440
|
+
this.ensureReady();
|
|
5441
|
+
const row = await this.prisma.agentTask.findUnique({ where: { id } });
|
|
5442
|
+
return row ? this.toTaskRecord(row) : null;
|
|
5443
|
+
}
|
|
5444
|
+
async listAgentTasks(agentGaii, opts) {
|
|
5445
|
+
this.ensureReady();
|
|
5446
|
+
const page = opts?.page ?? 1;
|
|
5447
|
+
const perPage = opts?.perPage ?? 20;
|
|
5448
|
+
const where = { agentGaii };
|
|
5449
|
+
if (opts?.status)
|
|
5450
|
+
where.status = opts.status;
|
|
5451
|
+
const [rows, total] = await Promise.all([
|
|
5452
|
+
this.prisma.agentTask.findMany({
|
|
5453
|
+
where,
|
|
5454
|
+
orderBy: { updatedAt: 'desc' },
|
|
5455
|
+
skip: (page - 1) * perPage,
|
|
5456
|
+
take: perPage,
|
|
5457
|
+
}),
|
|
5458
|
+
this.prisma.agentTask.count({ where }),
|
|
5459
|
+
]);
|
|
5460
|
+
return { tasks: rows.map((r) => this.toTaskRecord(r)), total };
|
|
5461
|
+
}
|
|
5462
|
+
async listAgentTasksByOwner(ownerGaii, opts) {
|
|
5463
|
+
this.ensureReady();
|
|
5464
|
+
const page = opts?.page ?? 1;
|
|
5465
|
+
const perPage = opts?.perPage ?? 20;
|
|
5466
|
+
const where = { ownerGaii };
|
|
5467
|
+
if (opts?.agentGaii)
|
|
5468
|
+
where.agentGaii = opts.agentGaii;
|
|
5469
|
+
if (opts?.status)
|
|
5470
|
+
where.status = opts.status;
|
|
5471
|
+
const [rows, total] = await Promise.all([
|
|
5472
|
+
this.prisma.agentTask.findMany({
|
|
5473
|
+
where,
|
|
5474
|
+
orderBy: { updatedAt: 'desc' },
|
|
5475
|
+
skip: (page - 1) * perPage,
|
|
5476
|
+
take: perPage,
|
|
5477
|
+
}),
|
|
5478
|
+
this.prisma.agentTask.count({ where }),
|
|
5479
|
+
]);
|
|
5480
|
+
return { tasks: rows.map((r) => this.toTaskRecord(r)), total };
|
|
5481
|
+
}
|
|
5482
|
+
async updateAgentTask(id, updates) {
|
|
5483
|
+
this.ensureReady();
|
|
5484
|
+
const existing = await this.getAgentTask(id);
|
|
5485
|
+
if (!existing)
|
|
5486
|
+
return null;
|
|
5487
|
+
const merged = {
|
|
5488
|
+
...existing,
|
|
5489
|
+
...updates,
|
|
5490
|
+
id: existing.id,
|
|
5491
|
+
agentGaii: existing.agentGaii,
|
|
5492
|
+
ownerGaii: existing.ownerGaii,
|
|
5493
|
+
createdAt: existing.createdAt,
|
|
5494
|
+
};
|
|
5495
|
+
try {
|
|
5496
|
+
const row = await this.prisma.agentTask.update({
|
|
5497
|
+
where: { id },
|
|
5498
|
+
data: {
|
|
5499
|
+
title: merged.title,
|
|
5500
|
+
description: merged.description,
|
|
5501
|
+
scope: merged.scope,
|
|
5502
|
+
rules: merged.rules,
|
|
5503
|
+
verification: merged.verification,
|
|
5504
|
+
resources: merged.resources ?? null,
|
|
5505
|
+
todos: merged.todos,
|
|
5506
|
+
status: merged.status,
|
|
5507
|
+
parentTaskId: merged.parentTaskId ?? null,
|
|
5508
|
+
workTrackingCode: merged.workTrackingCode ?? null,
|
|
5509
|
+
telemetry: merged.telemetry ?? null,
|
|
5510
|
+
lastEventAt: merged.lastEventAt ? new Date(merged.lastEventAt) : null,
|
|
5511
|
+
completedAt: merged.completedAt ? new Date(merged.completedAt) : null,
|
|
5512
|
+
},
|
|
5513
|
+
});
|
|
5514
|
+
return this.toTaskRecord(row);
|
|
5515
|
+
}
|
|
5516
|
+
catch {
|
|
5517
|
+
return null;
|
|
5518
|
+
}
|
|
5519
|
+
}
|
|
5520
|
+
async deleteAgentTask(id) {
|
|
5521
|
+
this.ensureReady();
|
|
5522
|
+
try {
|
|
5523
|
+
const result = await this.prisma.agentTask.deleteMany({
|
|
5524
|
+
where: { id, status: { in: ['draft', 'queued'] } },
|
|
5525
|
+
});
|
|
5526
|
+
if (result.count > 0) {
|
|
5527
|
+
await this.prisma.agentTaskEvent.deleteMany({ where: { taskId: id } });
|
|
5528
|
+
return true;
|
|
5529
|
+
}
|
|
5530
|
+
return false;
|
|
5531
|
+
}
|
|
5532
|
+
catch {
|
|
5533
|
+
return false;
|
|
5534
|
+
}
|
|
5535
|
+
}
|
|
5536
|
+
async appendTaskEvent(event) {
|
|
5537
|
+
this.ensureReady();
|
|
5538
|
+
const row = await this.prisma.agentTaskEvent.create({
|
|
5539
|
+
data: {
|
|
5540
|
+
taskId: event.taskId,
|
|
5541
|
+
type: event.type,
|
|
5542
|
+
message: event.message,
|
|
5543
|
+
details: event.details ?? null,
|
|
5544
|
+
timestamp: new Date(event.timestamp),
|
|
5545
|
+
},
|
|
5546
|
+
});
|
|
5547
|
+
return this.toTaskEventRecord(row);
|
|
5548
|
+
}
|
|
5549
|
+
async listTaskEvents(taskId, opts) {
|
|
5550
|
+
this.ensureReady();
|
|
5551
|
+
const page = opts?.page ?? 1;
|
|
5552
|
+
const perPage = opts?.perPage ?? 20;
|
|
5553
|
+
const where = { taskId };
|
|
5554
|
+
const [rows, total] = await Promise.all([
|
|
5555
|
+
this.prisma.agentTaskEvent.findMany({
|
|
5556
|
+
where,
|
|
5557
|
+
orderBy: { timestamp: 'asc' },
|
|
5558
|
+
skip: (page - 1) * perPage,
|
|
5559
|
+
take: perPage,
|
|
5560
|
+
}),
|
|
5561
|
+
this.prisma.agentTaskEvent.count({ where }),
|
|
5562
|
+
]);
|
|
5563
|
+
return { events: rows.map((r) => this.toTaskEventRecord(r)), total };
|
|
5564
|
+
}
|
|
5565
|
+
async countTasksByAgent(agentGaii) {
|
|
5566
|
+
this.ensureReady();
|
|
5567
|
+
const rows = await this.prisma.agentTask.groupBy({
|
|
5568
|
+
by: ['status'],
|
|
5569
|
+
where: { agentGaii },
|
|
5570
|
+
_count: true,
|
|
5571
|
+
});
|
|
5572
|
+
const counts = { queued: 0, active: 0, done: 0, failed: 0 };
|
|
5573
|
+
for (const row of rows) {
|
|
5574
|
+
if (row.status in counts) {
|
|
5575
|
+
counts[row.status] = row._count;
|
|
5576
|
+
}
|
|
5577
|
+
}
|
|
5578
|
+
return counts;
|
|
5579
|
+
}
|
|
5580
|
+
async findStalledTasks(thresholdMinutes) {
|
|
5581
|
+
this.ensureReady();
|
|
5582
|
+
const threshold = new Date(Date.now() - thresholdMinutes * 60 * 1000);
|
|
5583
|
+
const rows = await this.prisma.agentTask.findMany({
|
|
5584
|
+
where: {
|
|
5585
|
+
status: 'active',
|
|
5586
|
+
lastEventAt: { not: null, lt: threshold },
|
|
5587
|
+
},
|
|
5588
|
+
});
|
|
5589
|
+
return rows.map((r) => this.toTaskRecord(r));
|
|
5590
|
+
}
|
|
5591
|
+
// ── Sharing Groups ──
|
|
5592
|
+
toSharingGroupRecord(row) {
|
|
5593
|
+
const record = {
|
|
5594
|
+
id: row.id,
|
|
5595
|
+
name: row.name,
|
|
5596
|
+
ownerGaii: row.ownerGaii,
|
|
5597
|
+
members: row.members,
|
|
5598
|
+
defaultPermissions: row.defaultPermissions,
|
|
5599
|
+
createdAt: row.createdAt instanceof Date ? row.createdAt.toISOString() : row.createdAt,
|
|
5600
|
+
updatedAt: row.updatedAt instanceof Date ? row.updatedAt.toISOString() : row.updatedAt,
|
|
5601
|
+
};
|
|
5602
|
+
if (row.description)
|
|
5603
|
+
record.description = row.description;
|
|
5604
|
+
return record;
|
|
5605
|
+
}
|
|
5606
|
+
async createSharingGroup(record) {
|
|
5607
|
+
this.ensureReady();
|
|
5608
|
+
await this.prisma.sharingGroup.create({
|
|
5609
|
+
data: {
|
|
5610
|
+
id: record.id,
|
|
5611
|
+
name: record.name,
|
|
5612
|
+
description: record.description ?? null,
|
|
5613
|
+
ownerGaii: record.ownerGaii,
|
|
5614
|
+
members: record.members,
|
|
5615
|
+
defaultPermissions: record.defaultPermissions,
|
|
5616
|
+
createdAt: new Date(record.createdAt),
|
|
5617
|
+
},
|
|
5618
|
+
});
|
|
5619
|
+
return record;
|
|
5620
|
+
}
|
|
5621
|
+
async getSharingGroup(id) {
|
|
5622
|
+
this.ensureReady();
|
|
5623
|
+
const row = await this.prisma.sharingGroup.findUnique({ where: { id } });
|
|
5624
|
+
return row ? this.toSharingGroupRecord(row) : null;
|
|
5625
|
+
}
|
|
5626
|
+
async listSharingGroups(ownerGaii) {
|
|
5627
|
+
this.ensureReady();
|
|
5628
|
+
const rows = await this.prisma.sharingGroup.findMany({
|
|
5629
|
+
where: { ownerGaii },
|
|
5630
|
+
orderBy: { createdAt: 'desc' },
|
|
5631
|
+
});
|
|
5632
|
+
return rows.map((r) => this.toSharingGroupRecord(r));
|
|
5633
|
+
}
|
|
5634
|
+
async listSharingGroupsByMember(identifier) {
|
|
5635
|
+
this.ensureReady();
|
|
5636
|
+
// MongoDB JSON arrays can't be queried with SQL json_each; filter in memory
|
|
5637
|
+
const allGroups = await this.prisma.sharingGroup.findMany();
|
|
5638
|
+
return allGroups
|
|
5639
|
+
.filter((g) => {
|
|
5640
|
+
const members = g.members;
|
|
5641
|
+
return Array.isArray(members) && members.some(m => m.identifier === identifier);
|
|
5642
|
+
})
|
|
5643
|
+
.map((r) => this.toSharingGroupRecord(r));
|
|
5644
|
+
}
|
|
5645
|
+
async updateSharingGroup(id, updates) {
|
|
5646
|
+
this.ensureReady();
|
|
5647
|
+
const existing = await this.getSharingGroup(id);
|
|
5648
|
+
if (!existing)
|
|
5649
|
+
return null;
|
|
5650
|
+
const merged = {
|
|
5651
|
+
...existing,
|
|
5652
|
+
...updates,
|
|
5653
|
+
id: existing.id,
|
|
5654
|
+
ownerGaii: existing.ownerGaii,
|
|
5655
|
+
createdAt: existing.createdAt,
|
|
5656
|
+
};
|
|
5657
|
+
try {
|
|
5658
|
+
const row = await this.prisma.sharingGroup.update({
|
|
5659
|
+
where: { id },
|
|
5660
|
+
data: {
|
|
5661
|
+
name: merged.name,
|
|
5662
|
+
description: merged.description ?? null,
|
|
5663
|
+
members: merged.members,
|
|
5664
|
+
defaultPermissions: merged.defaultPermissions,
|
|
5665
|
+
},
|
|
5666
|
+
});
|
|
5667
|
+
return this.toSharingGroupRecord(row);
|
|
5668
|
+
}
|
|
5669
|
+
catch {
|
|
5670
|
+
return null;
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5673
|
+
async deleteSharingGroup(id) {
|
|
5674
|
+
this.ensureReady();
|
|
5675
|
+
try {
|
|
5676
|
+
await this.prisma.sharingGroup.delete({ where: { id } });
|
|
5677
|
+
return true;
|
|
5678
|
+
}
|
|
5679
|
+
catch {
|
|
5680
|
+
return false;
|
|
5681
|
+
}
|
|
5682
|
+
}
|
|
5683
|
+
async countEntriesReferencingGroup(groupId) {
|
|
5684
|
+
this.ensureReady();
|
|
5685
|
+
const [memoryCount, fileCount] = await Promise.all([
|
|
5686
|
+
this.prisma.memory.count({ where: { groupId } }),
|
|
5687
|
+
this.prisma.storageFile.count({ where: { groupId } }),
|
|
5688
|
+
]);
|
|
5689
|
+
return memoryCount + fileCount;
|
|
5690
|
+
}
|
|
5691
|
+
// ── Agent Directives ──
|
|
5692
|
+
toDirectivesRecord(row) {
|
|
5693
|
+
return {
|
|
5694
|
+
agentGaii: row.agentGaii,
|
|
5695
|
+
purpose: row.purpose,
|
|
5696
|
+
rules: row.rules,
|
|
5697
|
+
memoryAreas: row.memoryAreas,
|
|
5698
|
+
resources: row.resources,
|
|
5699
|
+
updatedAt: row.updatedAt instanceof Date ? row.updatedAt.toISOString() : row.updatedAt,
|
|
5700
|
+
};
|
|
5701
|
+
}
|
|
5702
|
+
toOwnerDefaultsRecord(row) {
|
|
5703
|
+
const record = {
|
|
5704
|
+
ownerGaii: row.ownerGaii,
|
|
5705
|
+
rules: row.rules,
|
|
5706
|
+
updatedAt: row.updatedAt instanceof Date ? row.updatedAt.toISOString() : row.updatedAt,
|
|
5707
|
+
};
|
|
5708
|
+
if (row.defaultTokenBudget != null)
|
|
5709
|
+
record.defaultTokenBudget = row.defaultTokenBudget;
|
|
5710
|
+
if (row.defaultMemoryAreas)
|
|
5711
|
+
record.defaultMemoryAreas = row.defaultMemoryAreas;
|
|
5712
|
+
return record;
|
|
5713
|
+
}
|
|
5714
|
+
async getAgentDirectives(agentGaii) {
|
|
5715
|
+
this.ensureReady();
|
|
5716
|
+
const row = await this.prisma.agentDirective.findUnique({ where: { agentGaii } });
|
|
5717
|
+
return row ? this.toDirectivesRecord(row) : null;
|
|
5718
|
+
}
|
|
5719
|
+
async upsertAgentDirectives(record) {
|
|
5720
|
+
this.ensureReady();
|
|
5721
|
+
const row = await this.prisma.agentDirective.upsert({
|
|
5722
|
+
where: { agentGaii: record.agentGaii },
|
|
5723
|
+
create: {
|
|
5724
|
+
id: `dir-${record.agentGaii}`,
|
|
5725
|
+
agentGaii: record.agentGaii,
|
|
5726
|
+
purpose: record.purpose,
|
|
5727
|
+
rules: record.rules,
|
|
5728
|
+
memoryAreas: record.memoryAreas,
|
|
5729
|
+
resources: record.resources,
|
|
5730
|
+
},
|
|
5731
|
+
update: {
|
|
5732
|
+
purpose: record.purpose,
|
|
5733
|
+
rules: record.rules,
|
|
5734
|
+
memoryAreas: record.memoryAreas,
|
|
5735
|
+
resources: record.resources,
|
|
5736
|
+
},
|
|
5737
|
+
});
|
|
5738
|
+
return this.toDirectivesRecord(row);
|
|
5739
|
+
}
|
|
5740
|
+
async deleteAgentDirectives(agentGaii) {
|
|
5741
|
+
this.ensureReady();
|
|
5742
|
+
try {
|
|
5743
|
+
await this.prisma.agentDirective.delete({ where: { agentGaii } });
|
|
5744
|
+
return true;
|
|
5745
|
+
}
|
|
5746
|
+
catch {
|
|
5747
|
+
return false;
|
|
5748
|
+
}
|
|
5749
|
+
}
|
|
5750
|
+
async getOwnerAgentDefaults(ownerGaii) {
|
|
5751
|
+
this.ensureReady();
|
|
5752
|
+
const row = await this.prisma.ownerAgentDefault.findUnique({ where: { ownerGaii } });
|
|
5753
|
+
return row ? this.toOwnerDefaultsRecord(row) : null;
|
|
5754
|
+
}
|
|
5755
|
+
async upsertOwnerAgentDefaults(record) {
|
|
5756
|
+
this.ensureReady();
|
|
5757
|
+
const row = await this.prisma.ownerAgentDefault.upsert({
|
|
5758
|
+
where: { ownerGaii: record.ownerGaii },
|
|
5759
|
+
create: {
|
|
5760
|
+
id: `owd-${record.ownerGaii}`,
|
|
5761
|
+
ownerGaii: record.ownerGaii,
|
|
5762
|
+
rules: record.rules,
|
|
5763
|
+
defaultTokenBudget: record.defaultTokenBudget ?? null,
|
|
5764
|
+
defaultMemoryAreas: record.defaultMemoryAreas ?? [],
|
|
5765
|
+
},
|
|
5766
|
+
update: {
|
|
5767
|
+
rules: record.rules,
|
|
5768
|
+
defaultTokenBudget: record.defaultTokenBudget ?? null,
|
|
5769
|
+
defaultMemoryAreas: record.defaultMemoryAreas ?? [],
|
|
5770
|
+
},
|
|
5771
|
+
});
|
|
5772
|
+
return this.toOwnerDefaultsRecord(row);
|
|
5773
|
+
}
|
|
5774
|
+
// ── Agent Activity ──
|
|
5775
|
+
toActivityRecord(row) {
|
|
5776
|
+
return {
|
|
5777
|
+
agentGaii: row.agentGaii,
|
|
5778
|
+
date: row.date,
|
|
5779
|
+
hour: row.hour,
|
|
5780
|
+
metric: row.metric,
|
|
5781
|
+
value: row.value,
|
|
5782
|
+
};
|
|
5783
|
+
}
|
|
5784
|
+
async recordActivity(record) {
|
|
5785
|
+
this.ensureReady();
|
|
5786
|
+
await this.prisma.agentActivity.upsert({
|
|
5787
|
+
where: {
|
|
5788
|
+
agentGaii_date_hour_metric: {
|
|
5789
|
+
agentGaii: record.agentGaii,
|
|
5790
|
+
date: record.date,
|
|
5791
|
+
hour: record.hour,
|
|
5792
|
+
metric: record.metric,
|
|
5793
|
+
},
|
|
5794
|
+
},
|
|
5795
|
+
create: {
|
|
5796
|
+
agentGaii: record.agentGaii,
|
|
5797
|
+
date: record.date,
|
|
5798
|
+
hour: record.hour,
|
|
5799
|
+
metric: record.metric,
|
|
5800
|
+
value: record.value,
|
|
5801
|
+
},
|
|
5802
|
+
update: {
|
|
5803
|
+
value: { increment: record.value },
|
|
5804
|
+
},
|
|
5805
|
+
});
|
|
5806
|
+
}
|
|
5807
|
+
async getActivityHistory(agentGaii, opts) {
|
|
5808
|
+
this.ensureReady();
|
|
5809
|
+
const days = opts?.days ?? 30;
|
|
5810
|
+
const granularity = opts?.granularity ?? 'daily';
|
|
5811
|
+
const cutoff = new Date();
|
|
5812
|
+
cutoff.setDate(cutoff.getDate() - days);
|
|
5813
|
+
const cutoffStr = cutoff.toISOString().split('T')[0];
|
|
5814
|
+
if (granularity === 'daily') {
|
|
5815
|
+
const rows = await this.prisma.agentActivity.groupBy({
|
|
5816
|
+
by: ['agentGaii', 'date', 'metric'],
|
|
5817
|
+
where: { agentGaii, date: { gte: cutoffStr } },
|
|
5818
|
+
_sum: { value: true },
|
|
5819
|
+
orderBy: { date: 'asc' },
|
|
5820
|
+
});
|
|
5821
|
+
return rows.map((r) => ({
|
|
5822
|
+
agentGaii: r.agentGaii,
|
|
5823
|
+
date: r.date,
|
|
5824
|
+
hour: 0,
|
|
5825
|
+
metric: r.metric,
|
|
5826
|
+
value: r._sum.value ?? 0,
|
|
5827
|
+
}));
|
|
5828
|
+
}
|
|
5829
|
+
// hourly granularity
|
|
5830
|
+
const rows = await this.prisma.agentActivity.findMany({
|
|
5831
|
+
where: { agentGaii, date: { gte: cutoffStr } },
|
|
5832
|
+
orderBy: [{ date: 'asc' }, { hour: 'asc' }],
|
|
5833
|
+
});
|
|
5834
|
+
return rows.map((r) => this.toActivityRecord(r));
|
|
5835
|
+
}
|
|
5836
|
+
// ── Agent Messages ──
|
|
5837
|
+
toMessageRecord(row) {
|
|
5838
|
+
const record = {
|
|
5839
|
+
id: row.id,
|
|
5840
|
+
agentGaii: row.agentGaii,
|
|
5841
|
+
threadId: row.threadId,
|
|
5842
|
+
direction: row.direction,
|
|
5843
|
+
senderGaii: row.senderGaii,
|
|
5844
|
+
content: row.content,
|
|
5845
|
+
status: row.status,
|
|
5846
|
+
createdAt: row.createdAt instanceof Date ? row.createdAt.toISOString() : row.createdAt,
|
|
5847
|
+
};
|
|
5848
|
+
if (row.linkedTaskId)
|
|
5849
|
+
record.linkedTaskId = row.linkedTaskId;
|
|
5850
|
+
if (row.metadata)
|
|
5851
|
+
record.metadata = row.metadata;
|
|
5852
|
+
if (row.processedAt)
|
|
5853
|
+
record.processedAt = row.processedAt instanceof Date ? row.processedAt.toISOString() : row.processedAt;
|
|
5854
|
+
return record;
|
|
5855
|
+
}
|
|
5856
|
+
async createMessage(record) {
|
|
5857
|
+
this.ensureReady();
|
|
5858
|
+
await this.prisma.agentMessage.create({
|
|
5859
|
+
data: {
|
|
5860
|
+
id: record.id,
|
|
5861
|
+
agentGaii: record.agentGaii,
|
|
5862
|
+
threadId: record.threadId,
|
|
5863
|
+
direction: record.direction,
|
|
5864
|
+
senderGaii: record.senderGaii,
|
|
5865
|
+
content: record.content,
|
|
5866
|
+
status: record.status,
|
|
5867
|
+
linkedTaskId: record.linkedTaskId ?? null,
|
|
5868
|
+
metadata: record.metadata ?? null,
|
|
5869
|
+
createdAt: new Date(record.createdAt),
|
|
5870
|
+
processedAt: record.processedAt ? new Date(record.processedAt) : null,
|
|
5871
|
+
},
|
|
5872
|
+
});
|
|
5873
|
+
return record;
|
|
5874
|
+
}
|
|
5875
|
+
async getMessage(id) {
|
|
5876
|
+
this.ensureReady();
|
|
5877
|
+
const row = await this.prisma.agentMessage.findUnique({ where: { id } });
|
|
5878
|
+
return row ? this.toMessageRecord(row) : null;
|
|
5879
|
+
}
|
|
5880
|
+
async listMessages(agentGaii, opts) {
|
|
5881
|
+
this.ensureReady();
|
|
5882
|
+
const page = opts?.page ?? 1;
|
|
5883
|
+
const perPage = opts?.perPage ?? 20;
|
|
5884
|
+
const where = { agentGaii };
|
|
5885
|
+
if (opts?.direction)
|
|
5886
|
+
where.direction = opts.direction;
|
|
5887
|
+
if (opts?.threadId)
|
|
5888
|
+
where.threadId = opts.threadId;
|
|
5889
|
+
const [rows, total] = await Promise.all([
|
|
5890
|
+
this.prisma.agentMessage.findMany({
|
|
5891
|
+
where,
|
|
5892
|
+
orderBy: { createdAt: 'desc' },
|
|
5893
|
+
skip: (page - 1) * perPage,
|
|
5894
|
+
take: perPage,
|
|
5895
|
+
}),
|
|
5896
|
+
this.prisma.agentMessage.count({ where }),
|
|
5897
|
+
]);
|
|
5898
|
+
return { messages: rows.map((r) => this.toMessageRecord(r)), total };
|
|
5899
|
+
}
|
|
5900
|
+
async listPendingMessages(agentGaii) {
|
|
5901
|
+
this.ensureReady();
|
|
5902
|
+
const rows = await this.prisma.agentMessage.findMany({
|
|
5903
|
+
where: { agentGaii, status: 'pending', direction: 'inbound' },
|
|
5904
|
+
orderBy: { createdAt: 'asc' },
|
|
5905
|
+
});
|
|
5906
|
+
return rows.map((r) => this.toMessageRecord(r));
|
|
5907
|
+
}
|
|
5908
|
+
async updateMessageStatus(id, status, processedAt) {
|
|
5909
|
+
this.ensureReady();
|
|
5910
|
+
try {
|
|
5911
|
+
const data = { status };
|
|
5912
|
+
if (processedAt)
|
|
5913
|
+
data.processedAt = new Date(processedAt);
|
|
5914
|
+
const row = await this.prisma.agentMessage.update({
|
|
5915
|
+
where: { id },
|
|
5916
|
+
data,
|
|
5917
|
+
});
|
|
5918
|
+
return this.toMessageRecord(row);
|
|
5919
|
+
}
|
|
5920
|
+
catch {
|
|
5921
|
+
return null;
|
|
5922
|
+
}
|
|
5923
|
+
}
|
|
5924
|
+
async listThreads(agentGaii) {
|
|
5925
|
+
this.ensureReady();
|
|
5926
|
+
const groups = await this.prisma.agentMessage.groupBy({
|
|
5927
|
+
by: ['threadId'],
|
|
5928
|
+
where: { agentGaii },
|
|
5929
|
+
_count: { _all: true },
|
|
5930
|
+
_max: { createdAt: true },
|
|
5931
|
+
});
|
|
5932
|
+
const results = [];
|
|
5933
|
+
for (const g of groups) {
|
|
5934
|
+
const lastMsg = await this.prisma.agentMessage.findFirst({
|
|
5935
|
+
where: { agentGaii, threadId: g.threadId },
|
|
5936
|
+
orderBy: { createdAt: 'desc' },
|
|
5937
|
+
select: { content: true },
|
|
5938
|
+
});
|
|
5939
|
+
results.push({
|
|
5940
|
+
threadId: g.threadId,
|
|
5941
|
+
lastMessage: lastMsg?.content ?? '',
|
|
5942
|
+
messageCount: g._count._all,
|
|
5943
|
+
updatedAt: g._max.createdAt instanceof Date ? g._max.createdAt.toISOString() : (g._max.createdAt ?? ''),
|
|
5944
|
+
});
|
|
5945
|
+
}
|
|
5946
|
+
// Sort by updatedAt descending
|
|
5947
|
+
results.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
5948
|
+
return results;
|
|
5949
|
+
}
|
|
5220
5950
|
}
|
|
5221
5951
|
/**
|
|
5222
5952
|
* Wildcard pattern matching: supports '*' (one segment) and '**' (multiple segments)
|