// A phase-completion gate sometimes arrives with an artifact that is only a file // *reference* (e.g. `{ kind: "phase", data: { file: "question.md" } }`) instead of // the embedded content. The full content is already served by the session-documents // endpoint, so we resolve the referenced file to the document key that carries it. // Filename -> session-document key (see harness build_documents). Only markdown // documents are listed: those we can render in full from the reference alone. export const DOC_KEY_BY_FILE: Record = { "question.md": "revised_question", "validation_report.md": "validation_report", }; type ArtifactLike = { data?: unknown; content?: unknown; [k: string]: unknown }; /** * If the artifact is a bare file reference we can resolve, return the filename and * the session-document key holding its content. Returns null when the artifact * carries inline content (nothing to resolve) or points at an unmapped file. */ export function resolveFileArtifact( artifact: ArtifactLike ): { filename: string; docKey: string } | null { const payload = artifact.data ?? artifact.content; const rec = payload && typeof payload === "object" && !Array.isArray(payload) ? (payload as Record) : null; const raw = rec?.file ?? rec?.path ?? artifact.file ?? artifact.path; if (typeof raw !== "string") return null; const filename = raw.split("/").pop() || raw; const docKey = DOC_KEY_BY_FILE[filename]; return docKey ? { filename, docKey } : null; }