MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / createArtifact

Function createArtifact

packages/hosts/mcp/src/tool-server.ts:1675–1781  ·  view source on GitHub ↗
(input: {
      readonly code: string;
      readonly title?: string;
      readonly description?: string;
      readonly connections?: Readonly<Record<string, string>>;
      readonly artifactId?: string;
    })

Source from the content-addressed store, hash-verified

1673 * what is stored, so a pure code tweak doesn't have to restate them.
1674 */
1675 const createArtifact = (input: {
1676 readonly code: string;
1677 readonly title?: string;
1678 readonly description?: string;
1679 readonly connections?: Readonly<Record<string, string>>;
1680 readonly artifactId?: string;
1681 }): Effect.Effect<McpToolResult, unknown> =>
1682 Effect.gen(function* () {
1683 // An update reads the existing row FIRST, both to carry its title and
1684 // description forward and to refuse a foreign id before any work. The
1685 // refusal is `artifact_unavailable` — the same answer `execute-action`
1686 // gives — so create-artifact cannot be used to probe which ids exist.
1687 const existing =
1688 input.artifactId === undefined ? null : yield* loadArtifact(input.artifactId);
1689 if (input.artifactId !== undefined && !existing) return actionArtifactUnavailableResult();
1690
1691 const title = input.title ?? existing?.title;
1692 if (title === undefined) {
1693 return renderRejectedResult(
1694 "title is required when creating an artifact. Give it a short human-readable name.",
1695 );
1696 }
1697 // Only an update inherits; a create with no description stores none.
1698 const description = input.description ?? existing?.description ?? undefined;
1699
1700 const rejection = validateArtifactCode(input.code);
1701 if (rejection) return renderRejectedResult(rejection);
1702
1703 // Static checks first, then the real one: render it. See
1704 // `smokeRenderRejection` for what the model is told.
1705 //
1706 // FAIL OPEN. The renderer is injected, runs on three different hosts,
1707 // and is the newest thing in this path — if IT breaks (a missing
1708 // module, an environment gap on some host), the right outcome is a
1709 // saved artifact and a logged warning, never a refused create of code
1710 // that is perfectly good. Only a definite `failed` blocks a save.
1711 const smoke = config.smokeRenderArtifact;
1712 // The render that validates the artifact is also the render that
1713 // previews it: the same pass produces the loading-state markup the
1714 // gallery draws, so a preview costs nothing beyond sanitizing it.
1715 let preview: string | null = null;
1716 if (smoke) {
1717 const smokeResult: ArtifactSmokeRenderResult = yield* Effect.tryPromise(() =>
1718 smoke(input.code),
1719 ).pipe(
1720 Effect.catchCause((cause) =>
1721 Effect.as(Effect.logWarning("create-artifact smoke render was unavailable", cause), {
1722 status: "ok",
1723 } satisfies ArtifactSmokeRenderResult),
1724 ),
1725 );
1726 const renderRejection = smokeRenderRejection(smokeResult);
1727 if (renderRejection) {
1728 yield* Effect.annotateCurrentSpan({ "mcp.artifact.smoke_render": "failed" });
1729 return renderRejectedResult(renderRejection);
1730 }
1731 // Fail open, exactly as the verdict does: a preview that cannot be
1732 // produced or cannot be sanitized is a card that falls back to its

Callers 1

createExecutorMcpServerFunction · 0.85

Calls 10

validateArtifactCodeFunction · 0.90
smokeRenderRejectionFunction · 0.90
extractArtifactRolesFunction · 0.90
resolveArtifactBindingsFunction · 0.90
loadArtifactFunction · 0.85
renderRejectedResultFunction · 0.85
saveAndDeliverArtifactFunction · 0.85
listMethod · 0.65

Tested by

no test coverage detected