@hexabot-ai/api 3.2.2-alpha.1 → 3.2.2-alpha.10
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/README.md +1 -1
- package/dist/actions/actions.service.d.ts +3 -3
- package/dist/actions/base-action.d.ts +3 -3
- package/dist/actions/create-action.d.ts +1 -1
- package/dist/actions/types.d.ts +3 -3
- package/dist/analytics/controllers/stats.controller.d.ts +1 -1
- package/dist/analytics/dto/stats.dto.d.ts +1 -1
- package/dist/analytics/entities/stats.entity.d.ts +1 -1
- package/dist/analytics/repositories/stats.repository.d.ts +1 -1
- package/dist/analytics/services/stats.service.d.ts +7 -7
- package/dist/app.controller.d.ts +1 -0
- package/dist/app.controller.js +1 -0
- package/dist/app.controller.js.map +1 -1
- package/dist/app.module.js +11 -1
- package/dist/app.module.js.map +1 -1
- package/dist/attachment/controllers/attachment.controller.d.ts +1 -1
- package/dist/attachment/dto/attachment.dto.d.ts +2 -2
- package/dist/attachment/entities/attachment.entity.d.ts +3 -3
- package/dist/attachment/guards/attachment-ability.guard.d.ts +2 -2
- package/dist/attachment/repositories/attachment.repository.d.ts +2 -2
- package/dist/attachment/services/attachment.service.d.ts +3 -3
- package/dist/attachment/utilities/index.js +2 -2
- package/dist/attachment/utilities/index.js.map +1 -1
- package/dist/audit/controllers/audit-log.controller.d.ts +2 -2
- package/dist/audit/dto/audit-log.dto.d.ts +1 -1
- package/dist/audit/entities/audit-log.entity.d.ts +1 -1
- package/dist/audit/exporters/audit-backend.factory.d.ts +1 -1
- package/dist/audit/exporters/audit-safe.exporter.d.ts +1 -1
- package/dist/audit/repositories/audit-log.repository.d.ts +1 -1
- package/dist/audit/services/audit-log-record.service.d.ts +1 -1
- package/dist/bindings/base-binding-kind.d.ts +2 -2
- package/dist/bindings/runtime-bindings.service.d.ts +2 -2
- package/dist/bootstrap.js +11 -0
- package/dist/bootstrap.js.map +1 -1
- package/dist/channel/channel.controller.d.ts +1 -1
- package/dist/channel/channel.service.d.ts +5 -5
- package/dist/channel/channel.service.js +3 -1
- package/dist/channel/channel.service.js.map +1 -1
- package/dist/channel/dto/source.dto.d.ts +1 -1
- package/dist/channel/entities/source.entity.d.ts +2 -2
- package/dist/channel/lib/Handler.d.ts +7 -7
- package/dist/channel/lib/Handler.js +2 -2
- package/dist/channel/lib/Handler.js.map +1 -1
- package/dist/channel/lib/__test__/label.mock.js +0 -24
- package/dist/channel/lib/__test__/label.mock.js.map +1 -1
- package/dist/channel/lib/channel-event-bus.d.ts +1 -1
- package/dist/channel/lib/inbound-events/channel-inbound-event-context.d.ts +1 -1
- package/dist/channel/lib/inbound-events/channel-inbound-event-decoder.d.ts +1 -1
- package/dist/channel/lib/inbound-events/channel-inbound-event.d.ts +2 -2
- package/dist/channel/lib/inbound-events/message-inbound-event.d.ts +1 -1
- package/dist/channel/lib/transports/http-channel-handler.d.ts +2 -2
- package/dist/channel/lib/transports/websocket-channel-handler.d.ts +3 -3
- package/dist/channel/repositories/source.repository.d.ts +1 -1
- package/dist/channel/services/channel-attachment.service.d.ts +3 -3
- package/dist/channel/services/source.service.d.ts +5 -3
- package/dist/channel/services/source.service.js +22 -0
- package/dist/channel/services/source.service.js.map +1 -1
- package/dist/channel/services/subscriber-resolver.service.d.ts +2 -2
- package/dist/channel/source.controller.d.ts +1 -1
- package/dist/channel/webhook.controller.d.ts +1 -1
- package/dist/chat/chat.module.js +1 -1
- package/dist/chat/chat.module.js.map +1 -1
- package/dist/chat/controllers/label-group.controller.d.ts +1 -1
- package/dist/chat/controllers/label.controller.d.ts +1 -1
- package/dist/chat/controllers/message.controller.d.ts +2 -2
- package/dist/chat/controllers/subscriber.controller.d.ts +3 -3
- package/dist/chat/controllers/thread.controller.d.ts +2 -2
- package/dist/chat/dto/label-group.dto.d.ts +1 -1
- package/dist/chat/dto/label.dto.d.ts +1 -2
- package/dist/chat/dto/label.dto.js +0 -6
- package/dist/chat/dto/label.dto.js.map +1 -1
- package/dist/chat/dto/message.dto.d.ts +1 -1
- package/dist/chat/dto/subscriber.dto.d.ts +3 -3
- package/dist/chat/dto/thread.dto.d.ts +1 -1
- package/dist/chat/entities/label-group.entity.d.ts +1 -3
- package/dist/chat/entities/label.entity.d.ts +1 -5
- package/dist/chat/entities/label.entity.js +0 -5
- package/dist/chat/entities/label.entity.js.map +1 -1
- package/dist/chat/entities/message.entity.d.ts +2 -2
- package/dist/chat/entities/subscriber.entity.d.ts +4 -4
- package/dist/chat/entities/subscriber.entity.js +3 -1
- package/dist/chat/entities/subscriber.entity.js.map +1 -1
- package/dist/chat/entities/thread.entity.d.ts +2 -2
- package/dist/chat/repositories/label-group.repository.d.ts +1 -1
- package/dist/chat/repositories/label.repository.d.ts +1 -1
- package/dist/chat/repositories/message.repository.d.ts +1 -1
- package/dist/chat/repositories/subscriber.repository.d.ts +1 -1
- package/dist/chat/repositories/thread.repository.d.ts +1 -1
- package/dist/chat/services/chat.service.d.ts +4 -4
- package/dist/chat/services/label-group.service.d.ts +1 -1
- package/dist/chat/services/label.service.d.ts +1 -1
- package/dist/chat/services/message.service.d.ts +2 -2
- package/dist/chat/services/subscriber.service.d.ts +5 -6
- package/dist/chat/services/subscriber.service.js +2 -2
- package/dist/chat/services/subscriber.service.js.map +1 -1
- package/dist/chat/services/thread.service.d.ts +2 -2
- package/dist/chat/types/channel.d.ts +1 -1
- package/dist/cms/controllers/content-type.controller.d.ts +1 -1
- package/dist/cms/controllers/content.controller.d.ts +1 -1
- package/dist/cms/controllers/menu.controller.d.ts +2 -2
- package/dist/cms/dto/content.dto.d.ts +1 -1
- package/dist/cms/dto/contentType.dto.d.ts +2 -2
- package/dist/cms/dto/menu.dto.d.ts +1 -1
- package/dist/cms/entities/content-type.entity.d.ts +2 -2
- package/dist/cms/entities/content-type.entity.js +3 -2
- package/dist/cms/entities/content-type.entity.js.map +1 -1
- package/dist/cms/entities/content.entity.d.ts +2 -2
- package/dist/cms/entities/content.entity.js +4 -3
- package/dist/cms/entities/content.entity.js.map +1 -1
- package/dist/cms/entities/menu.entity.d.ts +1 -1
- package/dist/cms/repositories/content-type.repository.d.ts +1 -1
- package/dist/cms/repositories/content.repository.d.ts +1 -1
- package/dist/cms/repositories/menu.repository.d.ts +1 -1
- package/dist/cms/services/content-type.service.d.ts +2 -2
- package/dist/cms/services/content-type.service.js.map +1 -1
- package/dist/cms/services/content.service.d.ts +1 -1
- package/dist/cms/services/menu.service.d.ts +1 -1
- package/dist/cms/services/rag-backend.service.d.ts +2 -2
- package/dist/cms/services/rag-indexer.service.d.ts +2 -2
- package/dist/cms/services/rag-retriever.service.d.ts +1 -1
- package/dist/cms/services/rag.service.d.ts +4 -4
- package/dist/config/index.js +14 -2
- package/dist/config/index.js.map +1 -1
- package/dist/config/types.d.ts +9 -0
- package/dist/database/decorators/json-column.decorator.js +1 -0
- package/dist/database/decorators/json-column.decorator.js.map +1 -1
- package/dist/database/entities/base.entity.d.ts +1 -1
- package/dist/database/typeorm-config.service.js +1 -1
- package/dist/database/typeorm-config.service.js.map +1 -1
- package/dist/extension/cleanup.service.d.ts +3 -3
- package/dist/extension/extension.module.d.ts +1 -1
- package/dist/extension/types.d.ts +1 -1
- package/dist/extensions/actions/ai/agent.action.d.ts +3 -3
- package/dist/extensions/actions/ai/ai-base.action.d.ts +5 -5
- package/dist/extensions/actions/ai/generate-object.action.d.ts +2 -2
- package/dist/extensions/actions/ai/generate-object.base.action.d.ts +3 -3
- package/dist/extensions/actions/ai/generate-reply.action.d.ts +2 -2
- package/dist/extensions/actions/ai/generate-text.action.d.ts +2 -2
- package/dist/extensions/actions/ai/generate-text.base.action.d.ts +3 -3
- package/dist/extensions/actions/ai/infer-object.action.d.ts +2 -2
- package/dist/extensions/actions/ai/mcp.binding.js +4 -3
- package/dist/extensions/actions/ai/mcp.binding.js.map +1 -1
- package/dist/extensions/actions/ai/retrieve-content-rag.action.d.ts +1 -1
- package/dist/extensions/actions/memory/update-memory.action.d.ts +4 -4
- package/dist/extensions/actions/messaging/attachment.action.d.ts +3 -3
- package/dist/extensions/actions/messaging/await-reply.action.d.ts +4 -4
- package/dist/extensions/actions/messaging/buttons.action.d.ts +3 -3
- package/dist/extensions/actions/messaging/list.action.d.ts +3 -3
- package/dist/extensions/actions/messaging/message-action.base.d.ts +6 -6
- package/dist/extensions/actions/messaging/quick-replies.action.d.ts +3 -3
- package/dist/extensions/actions/messaging/text-message.action.d.ts +3 -3
- package/dist/extensions/actions/subscriber/handover.action.d.ts +1 -1
- package/dist/extensions/actions/subscriber/update-labels.action.d.ts +1 -1
- package/dist/extensions/actions/web/http-request.action.d.ts +1 -1
- package/dist/extensions/actions/web/http-request.action.js +15 -4
- package/dist/extensions/actions/web/http-request.action.js.map +1 -1
- package/dist/extensions/actions/web/send-mail.action.d.ts +4 -4
- package/dist/extensions/channels/web/base-web-channel.d.ts +8 -6
- package/dist/extensions/channels/web/base-web-channel.js +37 -17
- package/dist/extensions/channels/web/base-web-channel.js.map +1 -1
- package/dist/extensions/channels/web/inbound/events/base-web-inbound.event.d.ts +3 -3
- package/dist/extensions/channels/web/inbound/events/delivery.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/events/messages/attachment.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/events/messages/location.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/events/messages/payload.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/events/messages/postback.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/events/messages/quick-reply.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/events/messages/text.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/events/messages/web-message.event.d.ts +3 -3
- package/dist/extensions/channels/web/inbound/events/read.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/events/typing.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/events/unsupported.event.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/web-inbound-event-decoder.d.ts +2 -2
- package/dist/extensions/channels/web/inbound/web-inbound-message-encoder.d.ts +1 -1
- package/dist/extensions/channels/web/outbound/web-outbound-message-encoder.d.ts +4 -4
- package/dist/extensions/channels/web/outbound/web-outbound-message-encoder.js +4 -4
- package/dist/extensions/channels/web/outbound/web-outbound-message-encoder.js.map +1 -1
- package/dist/extensions/channels/web/services/web-history.service.d.ts +2 -2
- package/dist/extensions/channels/web/services/web-session.service.d.ts +12 -6
- package/dist/extensions/channels/web/services/web-session.service.js +15 -0
- package/dist/extensions/channels/web/services/web-session.service.js.map +1 -1
- package/dist/extensions/helpers/local-storage/index.helper.d.ts +2 -2
- package/dist/health/health.service.d.ts +3 -3
- package/dist/helper/helper.service.d.ts +2 -2
- package/dist/helper/lib/base-helper.d.ts +2 -2
- package/dist/helper/lib/base-storage-helper.d.ts +1 -1
- package/dist/helper/types.d.ts +1 -1
- package/dist/i18n/controllers/language.controller.d.ts +1 -1
- package/dist/i18n/controllers/translation.controller.d.ts +1 -1
- package/dist/i18n/dto/language.dto.d.ts +1 -1
- package/dist/i18n/dto/translation.dto.d.ts +1 -1
- package/dist/i18n/entities/language.entity.d.ts +1 -1
- package/dist/i18n/entities/translation.entity.d.ts +1 -1
- package/dist/i18n/repositories/language.repository.d.ts +1 -1
- package/dist/i18n/repositories/translation.repository.d.ts +1 -1
- package/dist/i18n/seeds/language.seed.d.ts +1 -1
- package/dist/i18n/seeds/translation.seed.d.ts +1 -1
- package/dist/i18n/services/i18n.service.d.ts +2 -2
- package/dist/i18n/services/language.service.d.ts +1 -1
- package/dist/i18n/services/translation.service.d.ts +3 -3
- package/dist/license/services/lemon-squeezy.service.js +2 -2
- package/dist/license/services/lemon-squeezy.service.js.map +1 -1
- package/dist/license/services/license.service.d.ts +5 -5
- package/dist/mailer/mailer.module.js +1 -49
- package/dist/mailer/mailer.module.js.map +1 -1
- package/dist/mailer/mailer.service.d.ts +11 -2
- package/dist/mailer/mailer.service.js +69 -3
- package/dist/mailer/mailer.service.js.map +1 -1
- package/dist/mcp/controllers/mcp-token.controller.d.ts +47 -0
- package/dist/mcp/controllers/mcp-token.controller.js +70 -0
- package/dist/mcp/controllers/mcp-token.controller.js.map +1 -0
- package/dist/mcp/decorators/mcp-permission.decorator.d.ts +8 -0
- package/dist/mcp/decorators/mcp-permission.decorator.js +11 -0
- package/dist/mcp/decorators/mcp-permission.decorator.js.map +1 -0
- package/dist/mcp/dto/mcp-token.dto.d.ts +17 -0
- package/dist/mcp/dto/mcp-token.dto.js +40 -0
- package/dist/mcp/dto/mcp-token.dto.js.map +1 -0
- package/dist/mcp/entities/mcp-token.entity.d.ts +111 -0
- package/dist/mcp/entities/mcp-token.entity.js +69 -0
- package/dist/mcp/entities/mcp-token.entity.js.map +1 -0
- package/dist/mcp/guards/hexabot-mcp-token.guard.d.ts +9 -0
- package/dist/mcp/guards/hexabot-mcp-token.guard.js +49 -0
- package/dist/mcp/guards/hexabot-mcp-token.guard.js.map +1 -0
- package/dist/mcp/guards/mcp-permission.guard.d.ts +9 -0
- package/dist/mcp/guards/mcp-permission.guard.js +47 -0
- package/dist/mcp/guards/mcp-permission.guard.js.map +1 -0
- package/dist/mcp/mcp-api.module.d.ts +2 -0
- package/dist/mcp/mcp-api.module.js +65 -0
- package/dist/mcp/mcp-api.module.js.map +1 -0
- package/dist/mcp/repositories/mcp-token.repository.d.ts +8 -0
- package/dist/mcp/repositories/mcp-token.repository.js +41 -0
- package/dist/mcp/repositories/mcp-token.repository.js.map +1 -0
- package/dist/mcp/services/mcp-token.service.d.ts +24 -0
- package/dist/mcp/services/mcp-token.service.js +106 -0
- package/dist/mcp/services/mcp-token.service.js.map +1 -0
- package/dist/mcp/tools/hexabot-mcp.tools.d.ts +1141 -0
- package/dist/mcp/tools/hexabot-mcp.tools.js +957 -0
- package/dist/mcp/tools/hexabot-mcp.tools.js.map +1 -0
- package/dist/mcp/types.d.ts +7 -0
- package/dist/{utils/types/extension.js → mcp/types.js} +1 -1
- package/dist/mcp/types.js.map +1 -0
- package/dist/migration/migration.command.d.ts +1 -1
- package/dist/migration/migration.service.d.ts +3 -3
- package/dist/migration/types.d.ts +2 -2
- package/dist/setting/base-setting-group.d.ts +2 -2
- package/dist/setting/controllers/setting.controller.d.ts +1 -1
- package/dist/setting/create-setting-group.d.ts +2 -2
- package/dist/setting/dto/metadata.dto.d.ts +1 -1
- package/dist/setting/dto/setting.dto.d.ts +1 -1
- package/dist/setting/entities/metadata.entity.d.ts +1 -1
- package/dist/setting/entities/setting.entity.d.ts +1 -1
- package/dist/setting/repositories/metadata.repository.d.ts +1 -1
- package/dist/setting/repositories/setting.repository.d.ts +1 -1
- package/dist/setting/runtime-settings.seed.d.ts +3 -3
- package/dist/setting/seeds/metadata.seed.d.ts +1 -1
- package/dist/setting/seeds/setting.seed.d.ts +1 -1
- package/dist/setting/services/metadata.service.d.ts +1 -1
- package/dist/setting/services/runtime-settings.service.d.ts +1 -1
- package/dist/setting/services/setting.service.d.ts +4 -4
- package/dist/static/assets/browser-ponyfill-DN-Mu1Dr.js +2 -0
- package/dist/static/assets/{cssMode-ClQbC1-G.js → cssMode-BCWxI_Ux.js} +1 -1
- package/dist/static/assets/{freemarker2-DRxgvoL0.js → freemarker2-CFvevPey.js} +1 -1
- package/dist/static/assets/{handlebars-CTQECjcj.js → handlebars-BCStA9Eg.js} +1 -1
- package/dist/static/assets/{html-DvVbNWXL.js → html-DkIwCA7q.js} +1 -1
- package/dist/static/assets/{htmlMode-DHCoon1T.js → htmlMode-DHeMkUp8.js} +1 -1
- package/dist/static/assets/{index-BgFwJPy7.js → index-C6VeVxYx.js} +2152 -2149
- package/dist/static/assets/{javascript-CiEs6Ej5.js → javascript-DLPKJzLc.js} +1 -1
- package/dist/static/assets/{jsonMode-DTfAuumC.js → jsonMode-BUIDFK3O.js} +1 -1
- package/dist/static/assets/{liquid-B714yIaN.js → liquid-B0XmwdKh.js} +1 -1
- package/dist/static/assets/{lspLanguageFeatures-r73pyfl4.js → lspLanguageFeatures-Fcpw3Ev_.js} +1 -1
- package/dist/static/assets/{mdx-D5IAs7yq.js → mdx-DmJKi-dU.js} +1 -1
- package/dist/static/assets/{python-ehBpsG6S.js → python-B1WnWY4I.js} +1 -1
- package/dist/static/assets/{razor-V-Gitx5J.js → razor-CL2s-6qt.js} +1 -1
- package/dist/static/assets/{tsMode-D_iFxZ-O.js → tsMode-DSFhDcf0.js} +1 -1
- package/dist/static/assets/{typescript-CEGzsf5j.js → typescript-CmHv7Jwl.js} +1 -1
- package/dist/static/assets/{xml-N5EKZaXL.js → xml-Cyy6zXDM.js} +1 -1
- package/dist/static/assets/{yaml-IWZvbW4T.js → yaml-D_D6TAHE.js} +1 -1
- package/dist/static/assets/{yaml.worker.entry-BdO9k22I.js → yaml.worker.entry-BB81z30Q.js} +228 -228
- package/dist/static/index.html +1 -1
- package/dist/static/locales/en/translation.json +26 -2
- package/dist/static/locales/fr/translation.json +26 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/user/controllers/auth.controller.d.ts +2 -2
- package/dist/user/controllers/credential.controller.d.ts +1 -1
- package/dist/user/controllers/model.controller.d.ts +3 -3
- package/dist/user/controllers/permission.controller.d.ts +2 -2
- package/dist/user/controllers/role.controller.d.ts +1 -1
- package/dist/user/controllers/user.controller.d.ts +3 -5
- package/dist/user/dto/credential.dto.d.ts +1 -1
- package/dist/user/dto/model.dto.d.ts +1 -1
- package/dist/user/dto/permission.dto.d.ts +1 -1
- package/dist/user/dto/role.dto.d.ts +1 -1
- package/dist/user/dto/user-profile.dto.d.ts +1 -1
- package/dist/user/dto/user.dto.d.ts +2 -2
- package/dist/user/entities/credential.entity.d.ts +1 -1
- package/dist/user/entities/model.entity.d.ts +2 -2
- package/dist/user/entities/model.entity.js +4 -3
- package/dist/user/entities/model.entity.js.map +1 -1
- package/dist/user/entities/permission.entity.d.ts +3 -3
- package/dist/user/entities/permission.entity.js +7 -7
- package/dist/user/entities/permission.entity.js.map +1 -1
- package/dist/user/entities/role.entity.d.ts +2 -2
- package/dist/user/entities/role.entity.js +3 -2
- package/dist/user/entities/role.entity.js.map +1 -1
- package/dist/user/entities/user-profile.entity.d.ts +3 -3
- package/dist/user/entities/user.entity.d.ts +1 -3
- package/dist/user/guards/ability.guard.js +12 -2
- package/dist/user/guards/ability.guard.js.map +1 -1
- package/dist/user/repositories/credential.repository.d.ts +1 -1
- package/dist/user/repositories/model.repository.d.ts +1 -1
- package/dist/user/repositories/permission.repository.d.ts +1 -1
- package/dist/user/repositories/role.repository.d.ts +1 -1
- package/dist/user/repositories/user.repository.d.ts +1 -1
- package/dist/user/seeds/model.seed.d.ts +1 -1
- package/dist/user/seeds/permission.seed.d.ts +1 -1
- package/dist/user/seeds/role.seed.d.ts +1 -1
- package/dist/user/seeds/user.seed.d.ts +1 -1
- package/dist/user/services/credential.service.d.ts +1 -1
- package/dist/user/services/model.service.d.ts +1 -1
- package/dist/user/services/passwordReset.service.d.ts +4 -4
- package/dist/user/services/permission.service.d.ts +1 -1
- package/dist/user/services/role.service.d.ts +1 -1
- package/dist/user/services/user.service.d.ts +1 -1
- package/dist/user/services/validate-account.service.d.ts +4 -4
- package/dist/utils/decorators/roles.decorator.d.ts +1 -1
- package/dist/utils/generics/base-orm.controller.d.ts +2 -2
- package/dist/utils/generics/base-orm.repository.d.ts +2 -2
- package/dist/utils/generics/base-orm.seeder.d.ts +1 -1
- package/dist/utils/generics/base-orm.service.d.ts +2 -2
- package/dist/utils/generics/extension.d.ts +3 -4
- package/dist/utils/generics/extension.js.map +1 -1
- package/dist/utils/helpers/zod.d.ts +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/pipes/uuid.pipe.js +3 -3
- package/dist/utils/pipes/uuid.pipe.js.map +1 -1
- package/dist/utils/test/dummy/controllers/dummy.controller.d.ts +1 -1
- package/dist/utils/test/dummy/dto/dummy.dto.d.ts +1 -1
- package/dist/utils/test/dummy/dummy.action.d.ts +1 -1
- package/dist/utils/test/dummy/entities/dummy.entity.d.ts +1 -1
- package/dist/utils/test/dummy/repositories/dummy.repository.d.ts +1 -1
- package/dist/utils/test/dummy/services/dummy.service.d.ts +1 -1
- package/dist/utils/test/fixtures/attachment.d.ts +1 -1
- package/dist/utils/test/fixtures/content.d.ts +2 -2
- package/dist/utils/test/fixtures/contenttype.d.ts +2 -2
- package/dist/utils/test/fixtures/contenttype.js +2 -2
- package/dist/utils/test/fixtures/contenttype.js.map +1 -1
- package/dist/utils/test/fixtures/dummy.d.ts +2 -2
- package/dist/utils/test/fixtures/label-group.d.ts +4 -5
- package/dist/utils/test/fixtures/label.d.ts +3 -4
- package/dist/utils/test/fixtures/label.js +0 -19
- package/dist/utils/test/fixtures/label.js.map +1 -1
- package/dist/utils/test/fixtures/language.d.ts +2 -2
- package/dist/utils/test/fixtures/mcp-server.d.ts +3 -3
- package/dist/utils/test/fixtures/memory-definition.d.ts +2 -2
- package/dist/utils/test/fixtures/memory-record.d.ts +2 -2
- package/dist/utils/test/fixtures/menu.d.ts +1 -1
- package/dist/utils/test/fixtures/message.d.ts +1 -1
- package/dist/utils/test/fixtures/migration.d.ts +1 -1
- package/dist/utils/test/fixtures/model.d.ts +2 -2
- package/dist/utils/test/fixtures/permission.d.ts +4 -4
- package/dist/utils/test/fixtures/role.d.ts +2 -2
- package/dist/utils/test/fixtures/setting.d.ts +1 -1
- package/dist/utils/test/fixtures/stats.d.ts +1 -1
- package/dist/utils/test/fixtures/subscriber.d.ts +4 -4
- package/dist/utils/test/fixtures/translation.d.ts +1 -1
- package/dist/utils/test/fixtures/user.d.ts +2 -2
- package/dist/utils/test/fixtures/workflow-run.d.ts +2 -2
- package/dist/utils/test/fixtures/workflow.d.ts +2 -2
- package/dist/utils/test/providers/i18n-service.provider.d.ts +1 -1
- package/dist/utils/test/providers/i18n-service.provider.js +2 -2
- package/dist/utils/test/providers/i18n-service.provider.js.map +1 -1
- package/dist/utils/test/providers/mailer-service.provider.d.ts +3 -3
- package/dist/utils/test/providers/mailer-service.provider.js +2 -2
- package/dist/utils/test/providers/mailer-service.provider.js.map +1 -1
- package/dist/utils/test/providers/setting-service.provider.d.ts +1 -1
- package/dist/utils/test/providers/setting-service.provider.js +2 -2
- package/dist/utils/test/providers/setting-service.provider.js.map +1 -1
- package/dist/utils/test/test.d.ts +4 -0
- package/dist/utils/test/test.js +34 -1
- package/dist/utils/test/test.js.map +1 -1
- package/dist/utils/test/types.d.ts +1 -1
- package/dist/utils/test/utils.d.ts +2 -1
- package/dist/utils/test/utils.js +203 -46
- package/dist/utils/test/utils.js.map +1 -1
- package/dist/utils/types/dto.types.d.ts +1 -1
- package/dist/utils/types/entity-event.types.d.ts +1 -1
- package/dist/websocket/services/socket-event-dispatcher.service.d.ts +1 -1
- package/dist/websocket/websocket.gateway.d.ts +6 -6
- package/dist/websocket/websocket.gateway.js +2 -2
- package/dist/websocket/websocket.gateway.js.map +1 -1
- package/dist/workflow/contexts/conversational-workflow.context.d.ts +1 -1
- package/dist/workflow/contexts/workflow-runtime.context.d.ts +10 -10
- package/dist/workflow/contexts/workflow-runtime.context.js +6 -6
- package/dist/workflow/contexts/workflow-runtime.context.js.map +1 -1
- package/dist/workflow/controllers/mcp-server.controller.d.ts +1 -1
- package/dist/workflow/controllers/memory-definition.controller.d.ts +1 -1
- package/dist/workflow/controllers/workflow-run.controller.d.ts +1 -1
- package/dist/workflow/controllers/workflow-version.controller.d.ts +1 -1
- package/dist/workflow/controllers/workflow.controller.d.ts +4 -4
- package/dist/workflow/controllers/workflow.controller.js +9 -9
- package/dist/workflow/controllers/workflow.controller.js.map +1 -1
- package/dist/workflow/dto/mcp-server.dto.d.ts +1 -1
- package/dist/workflow/dto/memory-definition.dto.d.ts +1 -1
- package/dist/workflow/dto/memory-record.dto.d.ts +1 -1
- package/dist/workflow/dto/workflow-run.dto.d.ts +1 -1
- package/dist/workflow/dto/workflow-version.dto.d.ts +1 -1
- package/dist/workflow/dto/workflow.dto.d.ts +1 -1
- package/dist/workflow/entities/mcp-server.entity.d.ts +2 -2
- package/dist/workflow/entities/mcp-server.entity.js +4 -4
- package/dist/workflow/entities/mcp-server.entity.js.map +1 -1
- package/dist/workflow/entities/memory-definition.entity.d.ts +1 -1
- package/dist/workflow/entities/memory-record.entity.d.ts +4 -4
- package/dist/workflow/entities/workflow-run.entity.d.ts +4 -4
- package/dist/workflow/entities/workflow-version.entity.d.ts +3 -3
- package/dist/workflow/entities/workflow-version.entity.js +6 -4
- package/dist/workflow/entities/workflow-version.entity.js.map +1 -1
- package/dist/workflow/entities/workflow.entity.d.ts +2 -2
- package/dist/workflow/entities/workflow.entity.js +2 -1
- package/dist/workflow/entities/workflow.entity.js.map +1 -1
- package/dist/workflow/lib/trigger-event-wrapper.d.ts +1 -1
- package/dist/workflow/repositories/mcp-server.repository.d.ts +1 -1
- package/dist/workflow/repositories/memory-definition.repository.d.ts +1 -1
- package/dist/workflow/repositories/memory-record.repository.d.ts +1 -1
- package/dist/workflow/repositories/workflow-run.repository.d.ts +1 -1
- package/dist/workflow/repositories/workflow-version.repository.d.ts +1 -1
- package/dist/workflow/repositories/workflow.repository.d.ts +1 -1
- package/dist/workflow/seeds/memory-definition.seed.d.ts +1 -1
- package/dist/workflow/seeds/workflow.seed.d.ts +1 -1
- package/dist/workflow/services/agentic.service.d.ts +6 -5
- package/dist/workflow/services/agentic.service.js +11 -6
- package/dist/workflow/services/agentic.service.js.map +1 -1
- package/dist/workflow/services/mcp-client-pool.service.d.ts +2 -2
- package/dist/workflow/services/mcp-server.service.d.ts +1 -1
- package/dist/workflow/services/memory-definition.service.d.ts +1 -1
- package/dist/workflow/services/memory-record.service.d.ts +1 -1
- package/dist/workflow/services/memory.service.js +1 -0
- package/dist/workflow/services/memory.service.js.map +1 -1
- package/dist/workflow/services/workflow-run.service.d.ts +1 -1
- package/dist/workflow/services/workflow-scheduler.service.d.ts +3 -3
- package/dist/workflow/services/workflow-scheduler.service.js +2 -2
- package/dist/workflow/services/workflow-scheduler.service.js.map +1 -1
- package/dist/workflow/services/workflow-version.service.d.ts +1 -1
- package/dist/workflow/services/workflow.service.d.ts +3 -3
- package/dist/workflow/utils/memory-store.js +12 -1
- package/dist/workflow/utils/memory-store.js.map +1 -1
- package/dist/workflow/workflow.module.js +4 -4
- package/dist/workflow/workflow.module.js.map +1 -1
- package/package.json +65 -32
- package/src/app.controller.ts +1 -0
- package/src/app.module.ts +15 -1
- package/src/attachment/utilities/index.ts +2 -2
- package/src/bootstrap.ts +13 -1
- package/src/channel/channel.service.ts +5 -2
- package/src/channel/lib/Handler.ts +3 -2
- package/src/channel/lib/__test__/label.mock.ts +0 -24
- package/src/channel/services/source.service.ts +38 -1
- package/src/chat/chat.module.ts +1 -1
- package/src/chat/dto/label.dto.ts +1 -12
- package/src/chat/entities/label.entity.ts +0 -4
- package/src/chat/entities/subscriber.entity.ts +14 -7
- package/src/chat/services/subscriber.service.ts +3 -2
- package/src/cms/entities/content-type.entity.ts +12 -4
- package/src/cms/entities/content.entity.ts +13 -5
- package/src/cms/services/content-type.service.ts +1 -1
- package/src/cms/services/rag.service.ts +1 -1
- package/src/config/index.ts +17 -2
- package/src/config/types.ts +9 -0
- package/src/database/decorators/json-column.decorator.ts +1 -0
- package/src/database/typeorm-config.service.ts +1 -1
- package/src/extensions/actions/ai/mcp.binding.ts +4 -3
- package/src/extensions/actions/web/http-request.action.ts +23 -4
- package/src/extensions/channels/web/base-web-channel.ts +51 -13
- package/src/extensions/channels/web/outbound/web-outbound-message-encoder.ts +2 -2
- package/src/extensions/channels/web/services/web-session.service.ts +35 -0
- package/src/global.d.ts +0 -6
- package/src/license/services/lemon-squeezy.service.ts +3 -2
- package/src/mailer/mailer.module.ts +1 -54
- package/src/mailer/mailer.service.ts +86 -2
- package/src/mcp/README.md +244 -0
- package/src/mcp/controllers/mcp-token.controller.ts +64 -0
- package/src/mcp/decorators/mcp-permission.decorator.ts +23 -0
- package/src/mcp/dto/mcp-token.dto.ts +48 -0
- package/src/mcp/entities/mcp-token.entity.ts +60 -0
- package/src/mcp/guards/hexabot-mcp-token.guard.ts +55 -0
- package/src/mcp/guards/mcp-permission.guard.ts +61 -0
- package/src/mcp/mcp-api.module.ts +61 -0
- package/src/mcp/repositories/mcp-token.repository.ts +34 -0
- package/src/mcp/services/mcp-token.service.ts +138 -0
- package/src/mcp/tools/hexabot-mcp.tools.ts +1041 -0
- package/src/mcp/types.ts +14 -0
- package/src/user/entities/model.entity.ts +13 -5
- package/src/user/entities/permission.entity.ts +21 -9
- package/src/user/entities/role.entity.ts +12 -4
- package/src/user/guards/ability.guard.ts +15 -3
- package/src/utils/generics/extension.ts +1 -3
- package/src/utils/index.ts +0 -2
- package/src/utils/pipes/uuid.pipe.ts +3 -3
- package/src/utils/test/fixtures/contenttype.ts +1 -1
- package/src/utils/test/fixtures/label.ts +0 -19
- package/src/utils/test/fixtures/workflow.ts +1 -1
- package/src/utils/test/providers/i18n-service.provider.ts +1 -1
- package/src/utils/test/providers/mailer-service.provider.ts +1 -1
- package/src/utils/test/providers/setting-service.provider.ts +1 -1
- package/src/utils/test/test.ts +39 -0
- package/src/utils/test/utils.ts +332 -57
- package/src/websocket/websocket.gateway.ts +2 -2
- package/src/workflow/contexts/workflow-runtime.context.ts +2 -2
- package/src/workflow/controllers/workflow.controller.ts +2 -2
- package/src/workflow/entities/mcp-server.entity.ts +2 -2
- package/src/workflow/entities/workflow-version.entity.ts +8 -3
- package/src/workflow/entities/workflow.entity.ts +2 -1
- package/src/workflow/services/agentic.service.ts +19 -8
- package/src/workflow/services/memory.service.ts +1 -0
- package/src/workflow/services/workflow-scheduler.service.ts +1 -1
- package/src/workflow/utils/memory-store.ts +13 -1
- package/src/workflow/workflow.module.ts +2 -2
- package/dist/mailer/mjml-adapter.class.d.ts +0 -4
- package/dist/mailer/mjml-adapter.class.js +0 -67
- package/dist/mailer/mjml-adapter.class.js.map +0 -1
- package/dist/utils/types/extension.d.ts +0 -4
- package/dist/utils/types/extension.js.map +0 -1
- package/src/mailer/mjml-adapter.class.ts +0 -41
- package/src/utils/types/extension.ts +0 -13
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Full terms: see LICENSE.md.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { randomUUID } from 'crypto';
|
|
8
|
+
|
|
7
9
|
import type {
|
|
8
10
|
Attachment,
|
|
9
11
|
Source,
|
|
@@ -25,7 +27,6 @@ import {
|
|
|
25
27
|
import { OnEvent } from '@nestjs/event-emitter';
|
|
26
28
|
import { Request, Response } from 'express';
|
|
27
29
|
import { Socket } from 'socket.io';
|
|
28
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
29
30
|
import type { z } from 'zod';
|
|
30
31
|
|
|
31
32
|
import { AttachmentOrmEntity } from '@/attachment/entities/attachment.entity';
|
|
@@ -37,16 +38,16 @@ import {
|
|
|
37
38
|
import {
|
|
38
39
|
ChannelCapabilities,
|
|
39
40
|
DEFAULT_CHANNEL_CAPABILITIES,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
} from '@/channel';
|
|
41
|
+
} from '@/channel/lib/channel-capabilities';
|
|
42
|
+
import { ExtensionInject } from '@/channel/lib/extension-inject.decorator';
|
|
43
43
|
import { MessageInboundEvent } from '@/channel/lib/inbound-events';
|
|
44
|
+
import { WebSocketChannelHandler } from '@/channel/lib/transports/websocket-channel-handler';
|
|
44
45
|
import { SourceService } from '@/channel/services/source.service';
|
|
45
46
|
import { ChannelName } from '@/channel/types';
|
|
46
|
-
import { SubscriberChannelData } from '@/chat';
|
|
47
47
|
import { MessageCreateDto } from '@/chat/dto/message.dto';
|
|
48
48
|
import { SubscriberCreateDto } from '@/chat/dto/subscriber.dto';
|
|
49
49
|
import { MessageService } from '@/chat/services/message.service';
|
|
50
|
+
import type { SubscriberChannelData } from '@/chat/types/channel';
|
|
50
51
|
import { MenuService } from '@/cms/services/menu.service';
|
|
51
52
|
import { config } from '@/config';
|
|
52
53
|
import { SocketRequest } from '@/websocket/utils/socket-request';
|
|
@@ -73,6 +74,10 @@ import { WebSessionService } from './services/web-session.service';
|
|
|
73
74
|
import { WEB_CHANNEL_NAME } from './settings.schema';
|
|
74
75
|
import { Web } from './types';
|
|
75
76
|
|
|
77
|
+
type WebSocketData = Socket['data'] & {
|
|
78
|
+
webMessageQueue?: Promise<void>;
|
|
79
|
+
};
|
|
80
|
+
|
|
76
81
|
/**
|
|
77
82
|
* Base handler for the Socket.IO-backed "web" channel.
|
|
78
83
|
*
|
|
@@ -125,7 +130,7 @@ export default abstract class BaseWebChannelHandler<N extends ChannelName>
|
|
|
125
130
|
}
|
|
126
131
|
|
|
127
132
|
generateId(): string {
|
|
128
|
-
return `${this.name}-${
|
|
133
|
+
return `${this.name}-${randomUUID()}`;
|
|
129
134
|
}
|
|
130
135
|
|
|
131
136
|
getChannelAttributes(
|
|
@@ -160,6 +165,30 @@ export default abstract class BaseWebChannelHandler<N extends ChannelName>
|
|
|
160
165
|
return normalizedSourceId.length > 0 ? normalizedSourceId : null;
|
|
161
166
|
}
|
|
162
167
|
|
|
168
|
+
private enqueueMessageDispatch(
|
|
169
|
+
req: SocketRequest,
|
|
170
|
+
event: MessageInboundEvent,
|
|
171
|
+
): void {
|
|
172
|
+
const socket = req.socket as Socket & { data?: WebSocketData };
|
|
173
|
+
const socketData = (socket.data ??= {});
|
|
174
|
+
// Keep chatbot processing ordered per socket without making the client ack
|
|
175
|
+
// wait for slow actions, LLM calls, or external integrations.
|
|
176
|
+
const previous = socketData.webMessageQueue ?? Promise.resolve();
|
|
177
|
+
const next = previous
|
|
178
|
+
.catch(() => undefined)
|
|
179
|
+
.then(() => this.channelEventBus.emitMessage(event))
|
|
180
|
+
.catch((err) => {
|
|
181
|
+
this.logger.error('Failed to process web socket message', err);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
socketData.webMessageQueue = next;
|
|
185
|
+
void next.finally(() => {
|
|
186
|
+
if (socketData.webMessageQueue === next) {
|
|
187
|
+
delete socketData.webMessageQueue;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
163
192
|
@OnEvent('hook:websocket:connection', { async: true })
|
|
164
193
|
async onWebSocketConnection(client: Socket) {
|
|
165
194
|
try {
|
|
@@ -546,15 +575,24 @@ export default abstract class BaseWebChannelHandler<N extends ChannelName>
|
|
|
546
575
|
messageEvent.setAuthorForeignId(profile.foreignId);
|
|
547
576
|
}
|
|
548
577
|
messageEvent.setCreatedAt(new Date());
|
|
578
|
+
// Resolve the thread before acknowledging the socket request so the
|
|
579
|
+
// client receives a stable thread_id, then dispatch chatbot work later.
|
|
580
|
+
const thread = await this.sessionService.resolveThreadForIncoming(
|
|
581
|
+
req,
|
|
582
|
+
profile.id,
|
|
583
|
+
{
|
|
584
|
+
explicitThreadId: messageEvent.getThreadId(),
|
|
585
|
+
inactivityHours: this.sessionService.resolveInactivityHours(
|
|
586
|
+
source.settings,
|
|
587
|
+
),
|
|
588
|
+
sourceId: source.id,
|
|
589
|
+
},
|
|
590
|
+
);
|
|
591
|
+
messageEvent.setThreadId(thread.id);
|
|
592
|
+
messageEvent.setThreadIdOnRaw(thread.id);
|
|
549
593
|
|
|
550
594
|
this.broadcast(profile, StdEventType.message, messageEvent.getRaw());
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
const resolvedThreadId = messageEvent.getThreadId();
|
|
554
|
-
if (resolvedThreadId) {
|
|
555
|
-
messageEvent.setThreadIdOnRaw(resolvedThreadId);
|
|
556
|
-
if (req.session.web) req.session.web.threadId = resolvedThreadId;
|
|
557
|
-
}
|
|
595
|
+
this.enqueueMessageDispatch(req, messageEvent);
|
|
558
596
|
|
|
559
597
|
continue;
|
|
560
598
|
}
|
|
@@ -24,8 +24,8 @@ import { ChannelOutboundMessageEncoder } from '@/channel/lib/outbound';
|
|
|
24
24
|
import { ChannelAttachmentService } from '@/channel/services/channel-attachment.service';
|
|
25
25
|
import { VIEW_MORE_PAYLOAD } from '@/chat/helpers/constants';
|
|
26
26
|
import { ContentOrmEntity } from '@/cms/entities/content.entity';
|
|
27
|
-
import { I18nService } from '@/i18n';
|
|
28
|
-
import { LoggerService } from '@/logger';
|
|
27
|
+
import { I18nService } from '@/i18n/services/i18n.service';
|
|
28
|
+
import { LoggerService } from '@/logger/logger.service';
|
|
29
29
|
|
|
30
30
|
import { Web } from '../types';
|
|
31
31
|
|
|
@@ -215,6 +215,10 @@ export class WebSessionService {
|
|
|
215
215
|
return this.threadService.resolveThread({ subscriberId, explicitThreadId });
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
+
resolveInactivityHours(settings: unknown): number {
|
|
219
|
+
return this.threadService.resolveInactivityHours(settings);
|
|
220
|
+
}
|
|
221
|
+
|
|
218
222
|
/**
|
|
219
223
|
* Resolves a thread from the request query/body and writes the result back
|
|
220
224
|
* to the session. Used by the subscribe/history flows.
|
|
@@ -232,4 +236,35 @@ export class WebSessionService {
|
|
|
232
236
|
|
|
233
237
|
return thread;
|
|
234
238
|
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Resolves the writable thread for an incoming message and persists it on the
|
|
242
|
+
* socket session before chatbot processing continues asynchronously.
|
|
243
|
+
*/
|
|
244
|
+
async resolveThreadForIncoming(
|
|
245
|
+
req: SocketRequest,
|
|
246
|
+
subscriberId: string,
|
|
247
|
+
{
|
|
248
|
+
explicitThreadId,
|
|
249
|
+
inactivityHours,
|
|
250
|
+
sourceId,
|
|
251
|
+
}: {
|
|
252
|
+
explicitThreadId?: string;
|
|
253
|
+
inactivityHours?: number;
|
|
254
|
+
sourceId?: string;
|
|
255
|
+
},
|
|
256
|
+
): Promise<Thread> {
|
|
257
|
+
const thread = await this.threadService.resolveThreadForIncoming({
|
|
258
|
+
subscriberId,
|
|
259
|
+
explicitThreadId,
|
|
260
|
+
inactivityHours,
|
|
261
|
+
sourceId,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
if (req.session.web) {
|
|
265
|
+
req.session.web.threadId = thread.id;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return thread;
|
|
269
|
+
}
|
|
235
270
|
}
|
package/src/global.d.ts
CHANGED
|
@@ -8,10 +8,4 @@ import '../types/event-emitter';
|
|
|
8
8
|
import '../types/express-session';
|
|
9
9
|
import './types/ai-sdk-mcp-stdio';
|
|
10
10
|
|
|
11
|
-
declare global {
|
|
12
|
-
type HyphenToUnderscore<S extends string> = S extends `${infer P}-${infer Q}`
|
|
13
|
-
? `${P}_${HyphenToUnderscore<Q>}`
|
|
14
|
-
: S;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
11
|
export {};
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* Full terms: see LICENSE.md.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { randomUUID } from 'crypto';
|
|
8
|
+
|
|
7
9
|
import { HttpService } from '@nestjs/axios';
|
|
8
10
|
import { Injectable } from '@nestjs/common';
|
|
9
11
|
import { AxiosError } from 'axios';
|
|
10
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
11
12
|
|
|
12
13
|
import {
|
|
13
14
|
LemonSqueezyActivationResponse,
|
|
@@ -52,7 +53,7 @@ export class LemonSqueezyService {
|
|
|
52
53
|
`${LEMON_SQUEEZY_API_BASE_URL}/v1/licenses/activate`,
|
|
53
54
|
{
|
|
54
55
|
license_key: licenseKey,
|
|
55
|
-
instance_name:
|
|
56
|
+
instance_name: randomUUID(),
|
|
56
57
|
},
|
|
57
58
|
{
|
|
58
59
|
headers: {
|
|
@@ -4,66 +4,13 @@
|
|
|
4
4
|
* Full terms: see LICENSE.md.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import path from 'path';
|
|
8
|
-
|
|
9
7
|
import { Global, Module } from '@nestjs/common';
|
|
10
|
-
import {
|
|
11
|
-
ISendMailOptions,
|
|
12
|
-
MAILER_OPTIONS,
|
|
13
|
-
MailerOptions,
|
|
14
|
-
MailerModule as NestjsMailerModule,
|
|
15
|
-
} from '@nestjs-modules/mailer';
|
|
16
|
-
import SMTPTransport from 'nodemailer/lib/smtp-transport';
|
|
17
|
-
|
|
18
|
-
import { config } from '@/config';
|
|
19
8
|
|
|
20
9
|
import { MailerService } from './mailer.service';
|
|
21
|
-
import { MjmlAdapter } from './mjml-adapter.class';
|
|
22
|
-
|
|
23
|
-
const mailerOptions: MailerOptions = {
|
|
24
|
-
transport: new SMTPTransport({
|
|
25
|
-
...config.emails.smtp,
|
|
26
|
-
logger: true,
|
|
27
|
-
debug: false,
|
|
28
|
-
}),
|
|
29
|
-
template: {
|
|
30
|
-
adapter: new MjmlAdapter(),
|
|
31
|
-
dir: path.join(process.cwd(), 'dist', 'templates'),
|
|
32
|
-
options: {
|
|
33
|
-
context: {
|
|
34
|
-
appName: config.parameters.appName,
|
|
35
|
-
appUrl: config.uiBaseUrl,
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
defaults: { from: config.emails.from },
|
|
40
|
-
};
|
|
41
10
|
|
|
42
11
|
@Global()
|
|
43
12
|
@Module({
|
|
44
|
-
|
|
45
|
-
...(config.emails.isEnabled
|
|
46
|
-
? [NestjsMailerModule.forRoot(mailerOptions)]
|
|
47
|
-
: []),
|
|
48
|
-
],
|
|
49
|
-
providers: [
|
|
50
|
-
{
|
|
51
|
-
provide: MAILER_OPTIONS,
|
|
52
|
-
useValue: mailerOptions,
|
|
53
|
-
},
|
|
54
|
-
...(config.emails.isEnabled
|
|
55
|
-
? [MailerService]
|
|
56
|
-
: [
|
|
57
|
-
{
|
|
58
|
-
provide: MailerService,
|
|
59
|
-
useValue: {
|
|
60
|
-
sendMail(_options: ISendMailOptions) {
|
|
61
|
-
throw new Error('Email Service is not enabled');
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
]),
|
|
66
|
-
],
|
|
13
|
+
providers: [MailerService],
|
|
67
14
|
exports: [MailerService],
|
|
68
15
|
})
|
|
69
16
|
export class MailerModule {}
|
|
@@ -4,6 +4,90 @@
|
|
|
4
4
|
* Full terms: see LICENSE.md.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { readFile } from 'fs/promises';
|
|
8
|
+
import path from 'path';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
import { Injectable } from '@nestjs/common';
|
|
11
|
+
import Handlebars from 'handlebars';
|
|
12
|
+
import mjml2html from 'mjml';
|
|
13
|
+
import nodemailer, {
|
|
14
|
+
SendMailOptions as NodemailerSendMailOptions,
|
|
15
|
+
SentMessageInfo,
|
|
16
|
+
Transporter,
|
|
17
|
+
} from 'nodemailer';
|
|
18
|
+
import SMTPTransport from 'nodemailer/lib/smtp-transport';
|
|
19
|
+
|
|
20
|
+
import { config } from '@/config';
|
|
21
|
+
|
|
22
|
+
export type SendMailOptions = NodemailerSendMailOptions & {
|
|
23
|
+
template?: string;
|
|
24
|
+
context?: Record<string, unknown>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
@Injectable()
|
|
28
|
+
export class MailerService {
|
|
29
|
+
private readonly transporter?: Transporter<SentMessageInfo>;
|
|
30
|
+
|
|
31
|
+
constructor() {
|
|
32
|
+
if (!config.emails.isEnabled) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
this.transporter = nodemailer.createTransport(
|
|
37
|
+
new SMTPTransport({
|
|
38
|
+
...config.emails.smtp,
|
|
39
|
+
logger: true,
|
|
40
|
+
debug: false,
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async sendMail({ template, context, ...options }: SendMailOptions) {
|
|
46
|
+
if (!this.transporter) {
|
|
47
|
+
throw new Error('Email Service is not enabled');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const html = template
|
|
51
|
+
? await this.renderTemplate(template, context)
|
|
52
|
+
: options.html;
|
|
53
|
+
|
|
54
|
+
return await this.transporter.sendMail({
|
|
55
|
+
from: config.emails.from,
|
|
56
|
+
...options,
|
|
57
|
+
html,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async verifyAllTransporters(): Promise<boolean> {
|
|
62
|
+
if (!this.transporter) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return await this.transporter.verify();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private async renderTemplate(
|
|
70
|
+
template: string,
|
|
71
|
+
context: Record<string, unknown> = {},
|
|
72
|
+
): Promise<string> {
|
|
73
|
+
const templatePath = path.join(
|
|
74
|
+
process.cwd(),
|
|
75
|
+
'dist',
|
|
76
|
+
'templates',
|
|
77
|
+
template,
|
|
78
|
+
);
|
|
79
|
+
const content = await readFile(templatePath, 'utf-8');
|
|
80
|
+
const compiledHandlebars = Handlebars.compile(content)({
|
|
81
|
+
appName: config.parameters.appName,
|
|
82
|
+
appUrl: config.uiBaseUrl,
|
|
83
|
+
...context,
|
|
84
|
+
});
|
|
85
|
+
const { errors, html } = mjml2html(compiledHandlebars);
|
|
86
|
+
|
|
87
|
+
if (errors.length) {
|
|
88
|
+
throw new Error('Unable to compile mjml template');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return html;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Hexabot API MCP Server
|
|
2
|
+
|
|
3
|
+
This module exposes Hexabot API capabilities through the Model Context Protocol
|
|
4
|
+
(MCP) so coding agents can inspect and manage workflows, workflow runs, memory
|
|
5
|
+
definitions, actions, credentials, and CMS content.
|
|
6
|
+
|
|
7
|
+
The implementation uses `@rekog/mcp-nest` with Streamable HTTP transport.
|
|
8
|
+
Authentication is Hexabot-native: users create personal MCP bearer tokens from
|
|
9
|
+
their Hexabot account and paste those tokens into MCP clients such as Codex or
|
|
10
|
+
Claude Code.
|
|
11
|
+
|
|
12
|
+
## Runtime endpoints
|
|
13
|
+
|
|
14
|
+
All routes are mounted under the existing API prefix.
|
|
15
|
+
|
|
16
|
+
| Route | Purpose |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| `/api/mcp` | Streamable HTTP MCP endpoint. |
|
|
19
|
+
| `/api/mcp-token` | List and create MCP personal access tokens for the current Hexabot user. |
|
|
20
|
+
| `/api/mcp-token/:id/revoke` | Revoke one MCP personal access token owned by the current Hexabot user. |
|
|
21
|
+
|
|
22
|
+
The MCP endpoint is stateful and uses `mcp-session-id` headers for sessions.
|
|
23
|
+
|
|
24
|
+
## Enabling the server
|
|
25
|
+
|
|
26
|
+
Set the MCP variables in `packages/api/.env` and restart the API.
|
|
27
|
+
|
|
28
|
+
```dotenv
|
|
29
|
+
MCP_ENABLED=true
|
|
30
|
+
MCP_SERVER_NAME=hexabot-api
|
|
31
|
+
MCP_SERVER_TITLE=Hexabot API MCP Server
|
|
32
|
+
MCP_SERVER_VERSION=1.0.0
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Authentication and authorization
|
|
36
|
+
|
|
37
|
+
MCP requests use Hexabot-issued bearer tokens. Tokens are prefixed with
|
|
38
|
+
`hbt_mcp_` and are shown only once when created.
|
|
39
|
+
|
|
40
|
+
The guard chain is:
|
|
41
|
+
|
|
42
|
+
1. `HexabotMcpTokenGuard` validates the bearer token hash and resolves its
|
|
43
|
+
active Hexabot owner.
|
|
44
|
+
2. `McpPermissionGuard` checks the requested tool against Hexabot role
|
|
45
|
+
permissions.
|
|
46
|
+
|
|
47
|
+
Token storage is intentionally secret-safe:
|
|
48
|
+
|
|
49
|
+
- Raw token values are never stored.
|
|
50
|
+
- Only a SHA-256 token hash and short display prefix are persisted.
|
|
51
|
+
- The full token is returned only in the create-token response.
|
|
52
|
+
- Revoked, expired, unknown, or inactive-owner tokens are rejected.
|
|
53
|
+
|
|
54
|
+
The token owner must be an active Hexabot user.
|
|
55
|
+
|
|
56
|
+
Tool permissions use `@McpPermission(model, action)` metadata and the existing
|
|
57
|
+
`PermissionService`. For example, workflow read tools require the caller role to
|
|
58
|
+
have `workflow:read`; workflow mutation tools require the corresponding create
|
|
59
|
+
or update permission.
|
|
60
|
+
|
|
61
|
+
## Creating a bearer token
|
|
62
|
+
|
|
63
|
+
Use the authenticated Hexabot REST API to create a token for the current user:
|
|
64
|
+
|
|
65
|
+
```http
|
|
66
|
+
POST /api/mcp-token
|
|
67
|
+
Content-Type: application/json
|
|
68
|
+
|
|
69
|
+
{
|
|
70
|
+
"name": "Codex",
|
|
71
|
+
"expiresAt": "2026-12-31T23:59:59.000Z"
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The response includes the raw bearer token once:
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"token": "hbt_mcp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
|
80
|
+
"record": {
|
|
81
|
+
"id": "token-id",
|
|
82
|
+
"name": "Codex",
|
|
83
|
+
"tokenPrefix": "hbt_mcp_xxxxxxxx",
|
|
84
|
+
"owner": "user-id",
|
|
85
|
+
"expiresAt": "2026-12-31T23:59:59.000Z",
|
|
86
|
+
"lastUsedAt": null,
|
|
87
|
+
"revokedAt": null,
|
|
88
|
+
"createdAt": "2026-05-05T00:00:00.000Z",
|
|
89
|
+
"updatedAt": "2026-05-05T00:00:00.000Z"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Copy the `token` value into the MCP client. After this response, Hexabot cannot
|
|
95
|
+
show the raw token again.
|
|
96
|
+
|
|
97
|
+
List token metadata:
|
|
98
|
+
|
|
99
|
+
```http
|
|
100
|
+
GET /api/mcp-token
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Revoke a token:
|
|
104
|
+
|
|
105
|
+
```http
|
|
106
|
+
POST /api/mcp-token/{id}/revoke
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Connecting an MCP client
|
|
110
|
+
|
|
111
|
+
Use a Streamable HTTP MCP client pointed at:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
http://localhost:3000/api/mcp
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Production clients should use the public API origin, for example:
|
|
118
|
+
|
|
119
|
+
```text
|
|
120
|
+
https://api.example.com/api/mcp
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
If a client requires a JSON config entry, the exact field names depend on the
|
|
124
|
+
client, but the effective configuration should be equivalent to:
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"mcpServers": {
|
|
129
|
+
"hexabot": {
|
|
130
|
+
"type": "http",
|
|
131
|
+
"url": "http://localhost:3000/api/mcp",
|
|
132
|
+
"headers": {
|
|
133
|
+
"Authorization": "Bearer hbt_mcp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Tool surface
|
|
141
|
+
|
|
142
|
+
### Workflows
|
|
143
|
+
|
|
144
|
+
| Tool | Permission | Purpose |
|
|
145
|
+
| --- | --- | --- |
|
|
146
|
+
| `hexabot_workflow_search` | `workflow:read` | Search workflows by metadata. |
|
|
147
|
+
| `hexabot_workflow_get` | `workflow:read` | Read one workflow with populated version metadata. |
|
|
148
|
+
| `hexabot_workflow_create` | `workflow:create` | Create a workflow and optionally commit initial YAML. |
|
|
149
|
+
| `hexabot_workflow_update` | `workflow:update` | Update workflow metadata and optionally commit YAML. |
|
|
150
|
+
| `hexabot_workflow_yaml_commit` | `workflowversion:create` | Validate and commit workflow definition YAML. |
|
|
151
|
+
| `hexabot_workflow_publish` | `workflow:update` | Publish the current workflow version. |
|
|
152
|
+
| `hexabot_workflow_unpublish` | `workflow:update` | Clear the published workflow version. |
|
|
153
|
+
| `hexabot_workflow_run` | `workflowrun:create` | Run a manual or scheduled workflow and return the run summary. |
|
|
154
|
+
|
|
155
|
+
Workflow YAML is validated with `parseWorkflowDefinition()` before a version is
|
|
156
|
+
created.
|
|
157
|
+
|
|
158
|
+
### Workflow versions and runs
|
|
159
|
+
|
|
160
|
+
| Tool | Permission | Purpose |
|
|
161
|
+
| --- | --- | --- |
|
|
162
|
+
| `hexabot_workflow_version_search` | `workflowversion:read` | List YAML versions for a workflow. |
|
|
163
|
+
| `hexabot_workflow_version_get` | `workflowversion:read` | Read one workflow YAML version. |
|
|
164
|
+
| `hexabot_workflow_version_update` | `workflowversion:update` | Update workflow version metadata. |
|
|
165
|
+
| `hexabot_workflow_version_restore` | `workflowversion:create` | Restore a previous version by creating a new snapshot. |
|
|
166
|
+
| `hexabot_workflow_run_search` | `workflowrun:read` | Search workflow runs by workflow and status. |
|
|
167
|
+
| `hexabot_workflow_run_get` | `workflowrun:read` | Read one workflow run with populated workflow metadata. |
|
|
168
|
+
|
|
169
|
+
### Memory definitions
|
|
170
|
+
|
|
171
|
+
| Tool | Permission | Purpose |
|
|
172
|
+
| --- | --- | --- |
|
|
173
|
+
| `hexabot_memory_definition_search` | `memorydefinition:read` | Search memory definitions. |
|
|
174
|
+
| `hexabot_memory_definition_get` | `memorydefinition:read` | Read one memory definition. |
|
|
175
|
+
| `hexabot_memory_definition_create` | `memorydefinition:create` | Create a memory definition. |
|
|
176
|
+
| `hexabot_memory_definition_update` | `memorydefinition:update` | Update a memory definition. |
|
|
177
|
+
|
|
178
|
+
### Actions and runtime bindings
|
|
179
|
+
|
|
180
|
+
| Tool | Permission | Purpose |
|
|
181
|
+
| --- | --- | --- |
|
|
182
|
+
| `hexabot_action_search` | `workflow:read` | Search available workflow actions and schemas. |
|
|
183
|
+
| `hexabot_action_get` | `workflow:read` | Read one workflow action schema. |
|
|
184
|
+
| `hexabot_binding_search` | `workflow:read` | Search runtime binding kind schemas. |
|
|
185
|
+
| `hexabot_binding_get` | `workflow:read` | Read one runtime binding schema. |
|
|
186
|
+
|
|
187
|
+
### Credentials
|
|
188
|
+
|
|
189
|
+
| Tool | Permission | Purpose |
|
|
190
|
+
| --- | --- | --- |
|
|
191
|
+
| `hexabot_credential_search` | `credential:read` | Search credential metadata by name or owner. |
|
|
192
|
+
| `hexabot_credential_get` | `credential:read` | Read credential metadata. |
|
|
193
|
+
|
|
194
|
+
Credential secret values are never returned. The MCP tools remove the `value`
|
|
195
|
+
field from all credential responses and do not support searching by secret
|
|
196
|
+
value.
|
|
197
|
+
|
|
198
|
+
### CMS and RAG content
|
|
199
|
+
|
|
200
|
+
| Tool | Permission | Purpose |
|
|
201
|
+
| --- | --- | --- |
|
|
202
|
+
| `hexabot_content_type_search` | `contenttype:read` | Search CMS content types. |
|
|
203
|
+
| `hexabot_content_type_get` | `contenttype:read` | Read one content type. |
|
|
204
|
+
| `hexabot_content_type_create` | `contenttype:create` | Create a content type. |
|
|
205
|
+
| `hexabot_content_type_update` | `contenttype:update` | Update a content type. |
|
|
206
|
+
| `hexabot_content_search` | `content:read` | Search CMS content records. |
|
|
207
|
+
| `hexabot_content_get` | `content:read` | Read one content record. |
|
|
208
|
+
| `hexabot_content_create` | `content:create` | Create a content record. |
|
|
209
|
+
| `hexabot_content_update` | `content:update` | Update a content record. |
|
|
210
|
+
| `hexabot_rag_content_search` | `content:read` | Search indexed CMS content through RAG retrieval. |
|
|
211
|
+
|
|
212
|
+
## Extending the MCP module
|
|
213
|
+
|
|
214
|
+
Add new tools in `tools/hexabot-mcp.tools.ts`.
|
|
215
|
+
|
|
216
|
+
Each tool should:
|
|
217
|
+
|
|
218
|
+
1. Use `@Tool()` with a stable `hexabot_*` name and a Zod parameter schema.
|
|
219
|
+
2. Use `@ToolGuards([McpPermissionGuard])`.
|
|
220
|
+
3. Use `@McpPermission(model, action)` with existing Hexabot permission models.
|
|
221
|
+
4. Return plain JSON-serializable data.
|
|
222
|
+
5. Avoid exposing secrets, tokens, connection strings, or raw credential values.
|
|
223
|
+
|
|
224
|
+
If a tool changes API behavior or a public contract, update this README and the
|
|
225
|
+
relevant tests in `packages/api/src/mcp`.
|
|
226
|
+
|
|
227
|
+
## Tests
|
|
228
|
+
|
|
229
|
+
Run the API checks from the repository root:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
pnpm --filter @hexabot-ai/api run typecheck
|
|
233
|
+
pnpm --filter @hexabot-ai/api run lint
|
|
234
|
+
pnpm --filter @hexabot-ai/api run test
|
|
235
|
+
pnpm --filter @hexabot-ai/api run test:e2e
|
|
236
|
+
pnpm --filter @hexabot-ai/api run build
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The MCP e2e tests are enabled only when `MCP_ENABLED=true`. A local test command
|
|
240
|
+
is:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
NODE_ENV=test MCP_ENABLED=true pnpm --filter @hexabot-ai/api run test:e2e
|
|
244
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2026 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
Body,
|
|
9
|
+
Controller,
|
|
10
|
+
Get,
|
|
11
|
+
HttpCode,
|
|
12
|
+
Post,
|
|
13
|
+
Req,
|
|
14
|
+
UnauthorizedException,
|
|
15
|
+
} from '@nestjs/common';
|
|
16
|
+
import { Request } from 'express';
|
|
17
|
+
|
|
18
|
+
import { UuidParam } from '@/utils';
|
|
19
|
+
|
|
20
|
+
import { McpTokenCreateDto } from '../dto/mcp-token.dto';
|
|
21
|
+
import { McpTokenService } from '../services/mcp-token.service';
|
|
22
|
+
|
|
23
|
+
type AuthenticatedRequest = Request & {
|
|
24
|
+
user?: { id?: string };
|
|
25
|
+
session?: Request['session'] & {
|
|
26
|
+
passport?: { user?: { id?: string } };
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
@Controller('mcp-token')
|
|
31
|
+
export class McpTokenController {
|
|
32
|
+
constructor(private readonly mcpTokenService: McpTokenService) {}
|
|
33
|
+
|
|
34
|
+
@Get()
|
|
35
|
+
async list(@Req() req: AuthenticatedRequest) {
|
|
36
|
+
return await this.mcpTokenService.findOwnedTokens(this.getUserId(req));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Post()
|
|
40
|
+
async create(
|
|
41
|
+
@Body() dto: McpTokenCreateDto,
|
|
42
|
+
@Req() req: AuthenticatedRequest,
|
|
43
|
+
) {
|
|
44
|
+
return await this.mcpTokenService.createPersonalToken(
|
|
45
|
+
this.getUserId(req),
|
|
46
|
+
dto,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@Post(':id/revoke')
|
|
51
|
+
@HttpCode(200)
|
|
52
|
+
async revoke(@UuidParam('id') id: string, @Req() req: AuthenticatedRequest) {
|
|
53
|
+
return await this.mcpTokenService.revokeOwnedToken(this.getUserId(req), id);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private getUserId(req: AuthenticatedRequest): string {
|
|
57
|
+
const userId = req.user?.id ?? req.session?.passport?.user?.id;
|
|
58
|
+
if (!userId) {
|
|
59
|
+
throw new UnauthorizedException('Authenticated user is required');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return userId;
|
|
63
|
+
}
|
|
64
|
+
}
|