import crypto from 'node:crypto'; export const DOCX_MIME_TYPE = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; export async function registerChatDocxArtifactForConversation({ registry, user, bundle, requestBody = {}, filename, buffer, now = Date.now(), }) { if (!registry || !user?.id || !filename || !Buffer.isBuffer(buffer)) return null; const sessionId = String(requestBody.session_id ?? requestBody.sessionId ?? '').trim(); const messageId = String(requestBody.message_id ?? requestBody.messageId ?? '').trim(); if (!sessionId || !messageId) return null; const selectedLinkIndex = Number(requestBody.selected_link_index ?? requestBody.selectedLinkIndex ?? 0); const hash = crypto .createHash('sha256') .update(`${user.id}:${sessionId}:${messageId}:${selectedLinkIndex}:${filename}`) .digest('hex') .slice(0, 16); const artifactId = `ca_docx_${hash}`; const relativePath = `artifacts/${artifactId}/${filename}`; const { packageRecord, writeResult } = await registry.putObjectForSession({ userId: user.id, sessionId, title: bundle?.source?.session?.name ?? null, relativePath, body: buffer, }); const canonicalUrl = `/api/mindspace/v1/conversation-packages/${encodeURIComponent(sessionId)}` + `/artifacts/${encodeURIComponent(artifactId)}/download`; const artifact = await registry.recordArtifact({ id: artifactId, packageId: packageRecord.id, artifactKind: 'docx', messageId, displayName: filename, mimeType: DOCX_MIME_TYPE, sizeBytes: buffer.length, storageKey: writeResult.key, canonicalUrl, sortOrder: now, now, }); await registry.writeManifestForSession({ userId: user.id, sessionId, }); return artifact; }