Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions apps/docs/app/[lang]/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import type { ApiPageProps } from 'fumadocs-openapi/ui'
import { createAPIPage } from 'fumadocs-openapi/ui'
import { Pre } from 'fumadocs-ui/components/codeblock'
import defaultMdxComponents from 'fumadocs-ui/mdx'
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page'
import { DocsBody, DocsPage, DocsTitle } from 'fumadocs-ui/page'
import { notFound } from 'next/navigation'
import { PageFooter } from '@/components/docs-layout/page-footer'
import { PageNavigationArrows } from '@/components/docs-layout/page-navigation-arrows'
import { LLMCopyButton } from '@/components/page-actions'
import { PageTypeBadge } from '@/components/page-type-badge'
import { StructuredData } from '@/components/structured-data'
import { CodeBlock } from '@/components/ui/code-block'
import { Heading } from '@/components/ui/heading'
Expand Down Expand Up @@ -173,7 +174,6 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
<PageNavigationArrows previous={neighbours?.previous} next={neighbours?.next} />
</div>
<DocsTitle className='mb-2'>{data.title}</DocsTitle>
<DocsDescription>{data.description}</DocsDescription>
</div>
<DocsBody>
<APIPage {...apiProps} />
Expand Down Expand Up @@ -222,8 +222,8 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
</div>
<PageNavigationArrows previous={neighbours?.previous} next={neighbours?.next} />
</div>
{data.pageType && <PageTypeBadge type={data.pageType} className='mb-3' />}
<DocsTitle className='mb-2'>{data.title}</DocsTitle>
<DocsDescription>{data.description}</DocsDescription>
</div>
<DocsBody>
<MDX
Expand Down
44 changes: 44 additions & 0 deletions apps/docs/components/page-type-badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { DocsPageType } from '@/lib/source'
import { cn } from '@/lib/utils'

const CONFIG = {
tutorial: { label: 'Tutorial', className: 'text-[#33c482] border-[#33c482]/30 bg-[#33c482]/10' },
guide: {
label: 'Guide',
className: 'text-blue-600 border-blue-500/30 bg-blue-500/10 dark:text-blue-400',
},
reference: {
label: 'Reference',
className: 'text-violet-600 border-violet-500/30 bg-violet-500/10 dark:text-violet-400',
},
concept: {
label: 'Concept',
className: 'text-amber-600 border-amber-500/30 bg-amber-500/10 dark:text-amber-400',
},
} as const satisfies Record<DocsPageType, { label: string; className: string }>

interface PageTypeBadgeProps {
type: DocsPageType
className?: string
}

/**
* Small label that tells the reader which Diátaxis mode a page is — learning,
* task, lookup, or understanding. Rendered only when a page declares `type`.
*/
export function PageTypeBadge({ type, className }: PageTypeBadgeProps) {
const config = CONFIG[type]
if (!config) return null

return (
<span
className={cn(
'inline-flex items-center rounded-full border px-2 py-0.5 font-medium text-[11px] uppercase tracking-[0.04em]',
config.className,
className
)}
>
{config.label}
</span>
)
}
85 changes: 85 additions & 0 deletions apps/docs/components/workflow-preview/block-icons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import type { SVGProps } from 'react'
import {
Code2,
CornerDownRight,
Database,
GitBranch,
Globe,
Repeat,
Split,
Table,
} from 'lucide-react'

/**
* The two Sim-specific block glyphs we need, ported verbatim from
* `apps/sim/components/icons.tsx` so the preview matches the real builder.
* Other block types fall back to lucide-react stand-ins for now.
*/
export function StartIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
width='26'
height='16'
viewBox='0 0 26 16'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M7.8 13C9.23 13 10.45 12.49 11.47 11.47C12.49 10.45 13 9.23 13 7.8C13 6.37 12.49 5.15 11.47 4.13C10.45 3.11 9.23 2.6 7.8 2.6C6.37 2.6 5.15 3.11 4.13 4.13C3.11 5.15 2.6 6.37 2.6 7.8C2.6 9.23 3.11 10.45 4.13 11.47C5.15 12.49 6.37 13 7.8 13ZM7.8 15.6C5.63 15.6 3.79 14.84 2.28 13.33C0.76 11.81 0 9.97 0 7.8C0 5.63 0.76 3.79 2.28 2.28C3.79 0.76 5.63 0 7.8 0C9.75 0 11.45 0.62 12.89 1.85C14.33 3.09 15.2 4.64 15.5 6.5H24.7C25.07 6.5 25.38 6.62 25.63 6.87C25.88 7.12 26 7.43 26 7.8C26 8.17 25.87 8.48 25.63 8.73C25.38 8.98 25.07 9.1 24.7 9.1H15.5C15.2 10.96 14.33 12.51 12.89 13.75C11.44 14.98 9.75 15.6 7.8 15.6Z'
fill='currentColor'
/>
</svg>
)
}

export function AgentIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
width='21'
height='24'
viewBox='0 0 21 24'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M15.67 9.25H4.67C2.64 9.25 1 10.89 1 12.92V18.42C1 20.44 2.64 22.08 4.67 22.08H15.67C17.69 22.08 19.33 20.44 19.33 18.42V12.92C19.33 10.89 17.69 9.25 15.67 9.25Z'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
/>
<path
d='M10.17 5.58C11.18 5.58 12 4.76 12 3.75C12 2.74 11.18 1.92 10.17 1.92C9.15 1.92 8.33 2.74 8.33 3.75C8.33 4.76 9.15 5.58 10.17 5.58Z'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
/>
<path
d='M10.17 5.59V9.25M7.42 16.59V14.75M12.92 14.75V16.59'
stroke='currentColor'
strokeWidth='2'
strokeLinecap='round'
strokeLinejoin='round'
/>
</svg>
)
}

/** Block type → glyph. Sim glyphs where it matters; lucide stand-ins elsewhere. */
export const BLOCK_ICONS: Record<string, React.ComponentType<{ className?: string }>> = {
starter: StartIcon,
start_trigger: StartIcon,
agent: AgentIcon,
response: CornerDownRight,
function: Code2,
condition: Split,
router: GitBranch,
loop: Repeat,
api: Globe,
knowledge_base: Database,
knowledge: Database,
table: Table,
}
182 changes: 182 additions & 0 deletions apps/docs/components/workflow-preview/examples.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import type { PreviewWorkflow } from '@/components/workflow-preview/workflow-data'

/**
* The running example used across the Workflows overview: a workflow that takes
* an incoming customer message, classifies its category and urgency, and returns
* the result. Colors match the real Start / Agent / Response blocks.
*/
export const CLASSIFY_WORKFLOW: PreviewWorkflow = {
id: 'classify-message',
name: 'Classify customer message',
blocks: [
{
id: 'start',
name: 'Start',
type: 'start_trigger',
bgColor: '#34B5FF',
position: { x: 0, y: 0 },
hideTargetHandle: true,
rows: [{ title: 'Input', value: 'Customer message' }],
},
{
id: 'agent',
name: 'Agent',
type: 'agent',
bgColor: '#6f3dfa',
position: { x: 340, y: 0 },
hideSourceHandle: true,
rows: [
{ title: 'Model', value: 'gpt-4o' },
{ title: 'Prompt', value: 'Classify <start.input>' },
],
},
],
edges: [{ id: 'start-agent', source: 'start', target: 'agent' }],
}

/**
* A three-block chain used on the Data flow page: the message is classified, then
* a reply is drafted from that classification. Shows values moving forward along
* the chain (Reply reads Classify's output; Classify reads the Start input).
*/
export const CLASSIFY_REPLY_WORKFLOW: PreviewWorkflow = {
id: 'classify-reply',
name: 'Classify and reply',
blocks: [
{
id: 'start',
name: 'Start',
type: 'start_trigger',
bgColor: '#34B5FF',
position: { x: 0, y: 0 },
hideTargetHandle: true,
rows: [{ title: 'Input', value: 'Customer message' }],
},
{
id: 'classify',
name: 'Classify',
type: 'agent',
bgColor: '#6f3dfa',
position: { x: 330, y: 0 },
rows: [
{ title: 'Model', value: 'gpt-4o' },
{ title: 'Prompt', value: 'Classify <start.input>' },
],
},
{
id: 'reply',
name: 'Reply',
type: 'agent',
bgColor: '#6f3dfa',
position: { x: 660, y: 0 },
hideSourceHandle: true,
rows: [
{ title: 'Model', value: 'gpt-4o' },
{ title: 'Prompt', value: 'Draft a reply for <classify.content>' },
],
},
],
edges: [
{ id: 'start-classify', source: 'start', target: 'classify' },
{ id: 'classify-reply', source: 'classify', target: 'reply' },
],
}

/**
* A support workflow used on the "Using a knowledge base" page: a question is
* searched against a knowledge base, and an Agent answers from the matches.
*/
export const SUPPORT_KB_WORKFLOW: PreviewWorkflow = {
id: 'support-kb',
name: 'Answer from docs',
blocks: [
{
id: 'start',
name: 'Start',
type: 'start_trigger',
bgColor: '#34B5FF',
position: { x: 0, y: 0 },
hideTargetHandle: true,
rows: [{ title: 'Input', value: 'Customer question' }],
},
{
id: 'knowledge',
name: 'Knowledge',
type: 'knowledge',
bgColor: '#00B0B0',
position: { x: 330, y: 0 },
rows: [
{ title: 'Operation', value: 'Search' },
{ title: 'Query', value: '<start.input>' },
],
},
{
id: 'agent',
name: 'Agent',
type: 'agent',
bgColor: '#6f3dfa',
position: { x: 660, y: 0 },
hideSourceHandle: true,
rows: [
{ title: 'Model', value: 'gpt-4o' },
{ title: 'Prompt', value: 'Answer from <knowledge.results>' },
],
},
],
edges: [
{ id: 'start-knowledge', source: 'start', target: 'knowledge' },
{ id: 'knowledge-agent', source: 'knowledge', target: 'agent' },
],
}

/**
* The lead-enrichment chain from the "Using tables in workflows" page: query
* unprocessed rows, classify each with an Agent, write the result back. The
* first Table block is named "Table 1" to match the `<table1.rows>` references
* in the prose.
*/
export const TABLE_ENRICH_WORKFLOW: PreviewWorkflow = {
id: 'table-enrich',
name: 'Enrich leads',
blocks: [
{
id: 'table1',
name: 'Table 1',
type: 'table',
bgColor: '#10B981',
position: { x: 0, y: 0 },
hideTargetHandle: true,
rows: [
{ title: 'Operation', value: 'Query Rows' },
{ title: 'Filter', value: 'status = unprocessed' },
],
},
{
id: 'classify',
name: 'Classify',
type: 'agent',
bgColor: '#6f3dfa',
position: { x: 330, y: 0 },
rows: [
{ title: 'Model', value: 'gpt-4o' },
{ title: 'Prompt', value: 'Classify each lead' },
],
},
{
id: 'table2',
name: 'Table 2',
type: 'table',
bgColor: '#10B981',
position: { x: 660, y: 0 },
hideSourceHandle: true,
rows: [
{ title: 'Operation', value: 'Update Rows' },
{ title: 'Set', value: 'status = qualified' },
],
},
],
edges: [
{ id: 'table1-classify', source: 'table1', target: 'classify' },
{ id: 'classify-table2', source: 'classify', target: 'table2' },
],
}
13 changes: 13 additions & 0 deletions apps/docs/components/workflow-preview/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export {
CLASSIFY_REPLY_WORKFLOW,
CLASSIFY_WORKFLOW,
SUPPORT_KB_WORKFLOW,
TABLE_ENRICH_WORKFLOW,
} from '@/components/workflow-preview/examples'
export { OutputBundle } from '@/components/workflow-preview/output-bundle'
export type {
PreviewBlock,
PreviewTool,
PreviewWorkflow,
} from '@/components/workflow-preview/workflow-data'
export { WorkflowPreview } from '@/components/workflow-preview/workflow-preview'
Loading
Loading