(input: {
readonly code: string;
readonly title: string;
readonly description?: string | undefined;
readonly connections?: Readonly<Record<string, string>> | undefined;
readonly existing: Artifact | null;
})
| 1797 | * would have refused. |
| 1798 | */ |
| 1799 | const validateRenderAndSave = (input: { |
| 1800 | readonly code: string; |
| 1801 | readonly title: string; |
| 1802 | readonly description?: string | undefined; |
| 1803 | readonly connections?: Readonly<Record<string, string>> | undefined; |
| 1804 | readonly existing: Artifact | null; |
| 1805 | }): Effect.Effect<McpToolResult, unknown> => |
| 1806 | Effect.gen(function* () { |
| 1807 | const rejection = validateArtifactCode(input.code); |
| 1808 | if (rejection) return renderRejectedResult(rejection); |
| 1809 | |
| 1810 | // Static checks first, then the real one: render it. See |
| 1811 | // `smokeRenderRejection` for what the model is told. |
| 1812 | // |
| 1813 | // FAIL OPEN. The renderer is injected, runs on three different hosts, |
| 1814 | // and is the newest thing in this path — if IT breaks (a missing |
| 1815 | // module, an environment gap on some host), the right outcome is a |
| 1816 | // saved artifact and a logged warning, never a refused create of code |
| 1817 | // that is perfectly good. Only a definite `failed` blocks a save. |
| 1818 | const smoke = config.smokeRenderArtifact; |
| 1819 | // The render that validates the artifact is also the render that |
| 1820 | // previews it: the same pass produces the loading-state markup the |
| 1821 | // gallery draws, so a preview costs nothing beyond sanitizing it. |
| 1822 | let preview: string | null = null; |
| 1823 | if (smoke) { |
| 1824 | const smokeResult: ArtifactSmokeRenderResult = yield* Effect.tryPromise(() => |
| 1825 | smoke(input.code), |
| 1826 | ).pipe( |
| 1827 | Effect.catchCause((cause) => |
| 1828 | Effect.as(Effect.logWarning("create-artifact smoke render was unavailable", cause), { |
| 1829 | status: "ok", |
| 1830 | } satisfies ArtifactSmokeRenderResult), |
| 1831 | ), |
| 1832 | ); |
| 1833 | const renderRejection = smokeRenderRejection(smokeResult); |
| 1834 | if (renderRejection) { |
| 1835 | yield* Effect.annotateCurrentSpan({ "mcp.artifact.smoke_render": "failed" }); |
| 1836 | return renderRejectedResult(renderRejection); |
| 1837 | } |
| 1838 | // Fail open, exactly as the verdict does: a preview that cannot be |
| 1839 | // produced or cannot be sanitized is a card that falls back to its |
| 1840 | // schematic, never a create that is refused. |
| 1841 | preview = |
| 1842 | smokeResult.status === "ok" && smokeResult.markup !== undefined |
| 1843 | ? sanitizeArtifactPreviewMarkup(smokeResult.markup) |
| 1844 | : null; |
| 1845 | } |
| 1846 | |
| 1847 | const saveInput = { |
| 1848 | code: input.code, |
| 1849 | title: input.title, |
| 1850 | preview, |
| 1851 | ...(input.description === undefined ? {} : { description: input.description }), |
| 1852 | ...(input.existing === null ? {} : { existingId: input.existing.id }), |
| 1853 | }; |
| 1854 | |
| 1855 | const roles = extractArtifactRoles(input.code); |
| 1856 | if (roles.length === 0 && input.connections === undefined) { |
no test coverage detected