export const MINDSPACE_SERVER_ADAPTER_CONTRACT_VERSION = 2; export const MINDSPACE_SERVER_ADAPTER_REQUIRED_CAPABILITIES = Object.freeze([ 'chat-save-authority', 'public-finish-authority', 'workspace-publication-delivery-authority', 'scoped-workspace-tools', ]); export const MINDSPACE_SERVER_ADAPTER_BINDINGS = Object.freeze({ serviceFacade: Object.freeze(['prepareConversationPackageRead']), chatSaveService: Object.freeze([ 'createSharedHtml', 'materializeWorkspaceHtml', 'readWorkspaceHtml', 'ensurePreviewThumbnail', 'renderPreviewThumbnailSvg', ]), conversationArtifactService: Object.freeze([ 'registerChatDocxArtifact', 'registerPublicHtmlArtifacts', 'registerPublishedLongImageArtifact', 'registerWorkspaceFileArtifact', ]), publicFinishService: Object.freeze([ 'ensureWechatFreshPageThumbnails', 'materializeSessionEvent', 'preparePageDataAfterFinish', 'prepareWechatHtmlDelivery', 'prepareWechatPageDataDelivery', 'syncAfterFinish', ]), workspacePublicationDeliveryService: Object.freeze([ 'listRecentlyModifiedPublicHtml', 'readOwnerPublicAsset', 'renderLongImage', 'resolveWorkspaceRequest', 'validateRunDeliverables', ]), workspacePageDeliveryService: Object.freeze(['syncAndDeliver']), workspaceToolService: Object.freeze([ 'createDirectory', 'editFile', 'generateLongImage', 'listDirectory', 'publishPage', 'readFile', 'writeBinaryFile', 'writeFile', ]), conversationPackageRegistry: Object.freeze([ 'readArtifactObject', 'readManifestForSession', ]), assetService: Object.freeze([ 'cancelUpload', 'claimUploadArtifactsForConversation', 'completeUpload', 'createChatAsset', 'createUpload', 'deleteAsset', 'listAssets', 'readAssetContent', 'readPublicAssetContent', 'renderAssetPreview', 'renderAssetThumbnail', 'syncWorkspaceAssets', 'writeUploadContent', 'expireStaleUploads', ]), pageService: Object.freeze([ 'createFromChat', 'createPage', 'deletePage', 'findPageByRelativePath', 'findPageBySourceAsset', 'findPageBySourceMessage', 'findPlazaContextByWorkspacePath', 'getDeletePreview', 'getPage', 'listPages', 'listVersions', 'localizePrivateResources', 'redactPage', 'regenerateThumbnail', 'renderDraftPreview', 'renderPreview', 'renderThumbnail', 'rewriteHtmlDownloadLinksForPage', 'updatePage', 'uploadThumbnail', ]), pageSyncService: Object.freeze(['syncUserGeneratedPages']), pageLiveEditService: Object.freeze(['applyAgentPatch', 'bindSession', 'getRevisionSnapshot']), assetAgentService: Object.freeze(['applyAgentDelete']), publicationService: Object.freeze([ 'check', 'cleanupExpiredUnconfirmedPublications', 'getCurrent', 'getPublicHomepage', 'getStats', 'offline', 'publish', 'refreshOnlinePublicationHtml', 'resolvePrivateLink', 'resolvePublic', 'updatePublicationStatus', ]), cleanupService: Object.freeze(['listCandidates', 'runCleanup']), agentJobService: Object.freeze([ 'cancelJob', 'claimJob', 'claimNextJob', 'completeJob', 'createJob', 'getAssetForJob', 'getJob', 'heartbeat', 'listJobs', 'reapStaleJobs', 'retryJob', ]), }); export const MINDSPACE_SERVER_ADAPTER_BINDING_KEYS = Object.freeze( Object.keys(MINDSPACE_SERVER_ADAPTER_BINDINGS), ); export const MINDSPACE_SERVER_ADAPTER_REQUIRED_BINDINGS = Object.freeze({ chatSaveService: Object.freeze([ 'createSharedHtml', 'materializeWorkspaceHtml', 'readWorkspaceHtml', ]), conversationArtifactService: Object.freeze([ 'registerPublicHtmlArtifacts', 'registerWorkspaceFileArtifact', ]), publicFinishService: Object.freeze([ 'prepareWechatHtmlDelivery', 'syncAfterFinish', ]), workspacePublicationDeliveryService: Object.freeze([ 'resolveWorkspaceRequest', 'validateRunDeliverables', ]), workspaceToolService: Object.freeze([ 'readFile', 'writeFile', 'editFile', 'publishPage', 'writeBinaryFile', ]), }); export function createMindSpaceServerAdapterContractPayload({ adapter = {}, serviceMeta = {}, env = process.env, } = {}) { return { contractVersion: MINDSPACE_SERVER_ADAPTER_CONTRACT_VERSION, service: 'mindspace-service', adapterKind: adapter.kind ?? null, implementationStatus: adapter.implementationStatus ?? null, buildId: serviceMeta.buildId ?? env.MINDSPACE_SERVICE_BUILD_ID ?? null, gitSha: serviceMeta.gitSha ?? env.MINDSPACE_SERVICE_GIT_SHA ?? null, builtAt: serviceMeta.builtAt ?? env.MINDSPACE_SERVICE_BUILT_AT ?? null, requiredCapabilities: MINDSPACE_SERVER_ADAPTER_REQUIRED_CAPABILITIES, requiredBindings: MINDSPACE_SERVER_ADAPTER_REQUIRED_BINDINGS, bindings: MINDSPACE_SERVER_ADAPTER_BINDINGS, bindingKeys: MINDSPACE_SERVER_ADAPTER_BINDING_KEYS, }; } export function assertMindSpaceServerAdapterBindingContract(bindingKey, service) { const methods = MINDSPACE_SERVER_ADAPTER_BINDINGS[bindingKey]; if (!methods) { throw new Error(`Unknown MindSpace server adapter binding: ${bindingKey}`); } for (const method of methods) { if (typeof service?.[method] !== 'function') { throw new Error( `MindSpace server adapter binding "${bindingKey}" is missing method ${bindingKey}.${method}()`, ); } } return service; } export function assertMindSpaceServerAdapterBindings(bindings) { for (const bindingKey of MINDSPACE_SERVER_ADAPTER_BINDING_KEYS) { assertMindSpaceServerAdapterBindingContract(bindingKey, bindings?.[bindingKey]); } return bindings; }