Artifact catalog
19 artifact types the Conductor can render inline today — from research briefs and charts to A/B variant pairs, live publish status cards, variant performance comparisons, and master-context-diff cards.
Artifacts are the visible output of the system. Every chart, card, and diagram you see in a conversation is an artifact — a typed, structured object rendered by a dedicated React component. The Conductor emits them via the generate_artifact tool; some (like project_status) are also seeded directly by database triggers or background events.
Available today
project_statusProject statusSlice 2 · shippedPinned card at the top of the primary conversation: master_context version + channel connections (Connect / Reconnect buttons, status pills) + autopilot state + last_audit_at. Always seeded on project creation; hydrated live from DB on every render + subscribed to channel_connections Realtime updates.
{ autopilot_enabled, connected_channels[], master_context_version, last_audit_at }master_context_viewMaster context viewSlice 2 · shippedStructured render of the current master_context — tagline, positioning, voice guidelines, audience segments.
{ payload, version_n, section }research_briefResearch briefSlice 2 · shippedSignals list grouped by PESTEL domain. Also serves the "research kicked off" and analyze_domain output views.
{ signals[], domain? } OR { kind: "research_running", runId, ... } OR { domain, question, signals, gaps }project_audit_summaryProject audit summarySlice 2 · shippedThe onboarding artifact — first thing shown on a project after the initial audit. Signals-by-domain grid + positioning highlight.
{ signalsByDomain, masterContextPayload }scorecardScorecardSlice 2 · shippedMetric tiles with values, trends (up/down/neutral), optional progress bars.
{ metrics: [{ label, value, trend?, change?, maxValue? }] }comparison_tableComparison tableSlice 2 · shippedSide-by-side columns comparing options, competitors, approaches. Highlighted cells for winners.
{ rows, columns, cells } (shape per pre-hack comparison-table.tsx)bar_chartBar chartSlice 2 · shippedCategorical bar chart via recharts. Good for rankings, distributions, A/B comparisons.
{ data: [{ name, value, ... }], keys?, indexBy? }pie_chartPie chartSlice 2 · shippedShare-of-whole breakdown. Best for 3–6 slices.
{ data: [{ name, value }] }radar_chartRadar chartSlice 2 · shippedMulti-dimensional capability map. Good for feature-set comparisons across ~5–8 axes.
{ data, dimensions, series? }mind_mapMind mapSlice 2 · shippedHierarchical decomposition tree via @xyflow/react. Good for topic maps, problem breakdowns.
{ nodes | root | items } (multiple input shapes supported)mermaid_diagramMermaid diagramSlice 2 · shippedAny mermaid-syntax diagram — flowchart, sequence, state, ERD, gantt, etc.
{ definition: "graph TD\nA --> B" }key_findingsKey findingsSlice 2 · shippedRanked insight list. 3–7 top takeaways with short descriptions.
{ findings: [{ title, description, source? }] }swot_analysisSWOT analysisSlice 2 · shippedFour-quadrant strengths / weaknesses / opportunities / threats breakdown.
{ strengths[], weaknesses[], opportunities[], threats[] }timelineTimelineSlice 2 · shippedChronological events / milestones / roadmap with type-coloured dots.
{ events: [{ date, title, description?, type? }] }document_export_cardDocument export cardSlice 2 · shippedDownload card for a generated PPTX / DOCX / XLSX / CSV. Includes section preview + download button.
{ format: "pptx"|"docx"|"xlsx"|"csv", sections: [{ heading, content }], projectId }variant_pairVariant pairSlice 3 · shippedSide-by-side A/B drafts for one channel. Chips: Publish A, Publish B, Publish both, Regenerate. The first artifact in the generate → publish arc.
{ channel, variantPairId, topic, variants: [{ label: "A"|"B", body, meta? }] }publish_statusPublish statusSlice 3 · shipped6-state card showing where a publish is in its lifecycle. States: awaiting_confirmation → publishing → live / sandboxed / failed (plus scheduled for future). Border + icon colour keyed to state. For real LinkedIn publishes, externalUrl is the live share_url returned by Unipile getPost.
{ state, channel, variantLabel, publishId?, sandboxedPublishId?, externalUrl?, error? }variant_performanceVariant performanceSlice 4 · shippedA/B winner card produced by the Variant Comparator. Shows per-variant metric rollup (impressions / reactions / comments for LinkedIn, views / reading time for Sanity), the winner, and the Comparator's reasoning. Emitted once both A and B have engagement_batch learnings.
{ variantPairId, channel, topic, winner: "A"|"B"|"tie", variantA: {...}, variantB: {...}, reasoning, learningId }master_context_diffMaster context diffSlice 4 · shippedVersion-bump card emitted by the Curator. Shows the old and new master_context side by side with a concise summary of what changed, plus how many unapplied learnings got consumed.
{ projectId, previousVersion, newVersion, appliedLearningIds[], summary, previousPayload, newPayload }How an artifact lands
- You ask (or pick a slash command).
- The Conductor calls a tool whose
execute()returns{ artifact: { type, title, description?, data } }. - AI SDK v6 emits that as a
tool-toolNameUI message part. components/chat/message.tsxdispatches the part toArtifactRenderer.ArtifactRendererlazy-imports the component incomponents/artifacts/{type}.tsxand mounts it.- After the stream ends,
onFinisharchives the artifact row into theartifactstable (idempotently, keyed onconversation_id, turn_id, type).
Data validation
Every renderer validates props.data through a Zod schema at the top of the file. If the LLM emits malformed payload, the renderer shows a <details> fallback with the raw JSON instead of crashing the page.