diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c846a950da..31a533774c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -7,17 +7,43 @@ on:
jobs:
build-and-push:
- runs-on: ubuntu-latest-8-cores
strategy:
fail-fast: false
matrix:
include:
+ # AMD64 builds on x86 runners
- dockerfile: ./docker/app.Dockerfile
image: ghcr.io/simstudioai/simstudio
+ platform: linux/amd64
+ arch: amd64
+ runner: linux-x64-8-core
- dockerfile: ./docker/db.Dockerfile
image: ghcr.io/simstudioai/migrations
+ platform: linux/amd64
+ arch: amd64
+ runner: linux-x64-8-core
- dockerfile: ./docker/realtime.Dockerfile
image: ghcr.io/simstudioai/realtime
+ platform: linux/amd64
+ arch: amd64
+ runner: linux-x64-8-core
+ # ARM64 builds on native ARM64 runners
+ - dockerfile: ./docker/app.Dockerfile
+ image: ghcr.io/simstudioai/simstudio
+ platform: linux/arm64
+ arch: arm64
+ runner: linux-arm64-8-core
+ - dockerfile: ./docker/db.Dockerfile
+ image: ghcr.io/simstudioai/migrations
+ platform: linux/arm64
+ arch: arm64
+ runner: linux-arm64-8-core
+ - dockerfile: ./docker/realtime.Dockerfile
+ image: ghcr.io/simstudioai/realtime
+ platform: linux/arm64
+ arch: arm64
+ runner: linux-arm64-8-core
+ runs-on: ${{ matrix.runner }}
permissions:
contents: read
packages: write
@@ -26,9 +52,6 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
-
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
@@ -41,6 +64,53 @@ jobs:
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ matrix.image }}
+ tags: |
+ type=raw,value=latest-${{ matrix.arch }},enable=${{ github.ref == 'refs/heads/main' }}
+ type=ref,event=pr,suffix=-${{ matrix.arch }}
+ type=semver,pattern={{version}},suffix=-${{ matrix.arch }}
+ type=semver,pattern={{major}}.{{minor}},suffix=-${{ matrix.arch }}
+ type=semver,pattern={{major}}.{{minor}}.{{patch}},suffix=-${{ matrix.arch }}
+ type=sha,format=long,suffix=-${{ matrix.arch }}
+
+ - name: Build and push Docker image
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: ${{ matrix.dockerfile }}
+ platforms: ${{ matrix.platform }}
+ push: ${{ github.event_name != 'pull_request' }}
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=gha,scope=build-v2
+ cache-to: type=gha,mode=max,scope=build-v2
+
+ create-manifests:
+ runs-on: ubuntu-latest
+ needs: build-and-push
+ if: github.event_name != 'pull_request'
+ strategy:
+ matrix:
+ include:
+ - image: ghcr.io/simstudioai/simstudio
+ - image: ghcr.io/simstudioai/migrations
+ - image: ghcr.io/simstudioai/realtime
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - name: Log in to the Container registry
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.repository_owner }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Extract metadata for manifest
id: meta
uses: docker/metadata-action@v5
with:
@@ -53,14 +123,25 @@ jobs:
type=semver,pattern={{major}}.{{minor}}.{{patch}}
type=sha,format=long
- - name: Build and push Docker image
- uses: docker/build-push-action@v6
- with:
- context: .
- file: ${{ matrix.dockerfile }}
- platforms: linux/amd64,linux/arm64
- push: ${{ github.event_name != 'pull_request' }}
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
- cache-from: type=gha
- cache-to: type=gha,mode=max
+ - name: Create and push manifest
+ run: |
+ # Extract the tags from metadata
+ TAGS="${{ steps.meta.outputs.tags }}"
+
+ # Create manifest for each tag
+ for tag in $TAGS; do
+ echo "Creating manifest for $tag"
+ echo "Looking for images: ${tag}-amd64 and ${tag}-arm64"
+
+ # Check if both architecture images exist before creating manifest
+ if docker manifest inspect ${tag}-amd64 >/dev/null 2>&1 && docker manifest inspect ${tag}-arm64 >/dev/null 2>&1; then
+ docker manifest create $tag \
+ ${tag}-amd64 \
+ ${tag}-arm64
+ docker manifest push $tag
+ echo "Successfully created and pushed manifest for $tag"
+ else
+ echo "Warning: One or both architecture images not found for $tag"
+ echo "Skipping manifest creation for this tag"
+ fi
+ done
\ No newline at end of file
diff --git a/apps/docs/components/ui/video.tsx b/apps/docs/components/ui/video.tsx
new file mode 100644
index 0000000000..3313509f84
--- /dev/null
+++ b/apps/docs/components/ui/video.tsx
@@ -0,0 +1,30 @@
+import { getVideoUrl } from '@/lib/utils'
+
+interface VideoProps {
+ src: string
+ className?: string
+ autoPlay?: boolean
+ loop?: boolean
+ muted?: boolean
+ playsInline?: boolean
+}
+
+export function Video({
+ src,
+ className = 'w-full -mb-2 rounded-lg',
+ autoPlay = true,
+ loop = true,
+ muted = true,
+ playsInline = true,
+}: VideoProps) {
+ return (
+
+ )
+}
diff --git a/apps/docs/content/docs/blocks/evaluator.mdx b/apps/docs/content/docs/blocks/evaluator.mdx
index 89d3417df7..85291f2bf3 100644
--- a/apps/docs/content/docs/blocks/evaluator.mdx
+++ b/apps/docs/content/docs/blocks/evaluator.mdx
@@ -7,6 +7,7 @@ import { Callout } from 'fumadocs-ui/components/callout'
import { Step, Steps } from 'fumadocs-ui/components/steps'
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
import { ThemeImage } from '@/components/ui/theme-image'
+import { Video } from '@/components/ui/video'
The Evaluator block uses AI to score and assess content quality based on metrics you define. Perfect for quality control, A/B testing, and ensuring your AI outputs meet specific standards.
@@ -63,7 +64,7 @@ Choose an AI model to perform the evaluation:
**Local Models**: Any model running on Ollama
-
+
**Recommendation**: Use models with strong reasoning capabilities like GPT-4o or Claude 3.7 Sonnet for more accurate evaluations.
diff --git a/apps/docs/content/docs/blocks/index.mdx b/apps/docs/content/docs/blocks/index.mdx
index 3d46a9e67e..10e8c60253 100644
--- a/apps/docs/content/docs/blocks/index.mdx
+++ b/apps/docs/content/docs/blocks/index.mdx
@@ -7,11 +7,12 @@ import { Card, Cards } from 'fumadocs-ui/components/card'
import { Step, Steps } from 'fumadocs-ui/components/steps'
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
import { BlockTypes } from '@/components/ui/block-types'
+import { Video } from '@/components/ui/video'
Blocks are the building components you connect together to create AI workflows. Think of them as specialized modules that each handle a specific taskāfrom chatting with AI models to making API calls or processing data.
-
+
## Core Block Types
@@ -62,7 +63,7 @@ You create workflows by connecting blocks together. The output of one block beco
- **Branching paths**: Some blocks can route to different paths based on conditions
-
+
## Common Patterns
diff --git a/apps/docs/content/docs/blocks/router.mdx b/apps/docs/content/docs/blocks/router.mdx
index 6f0d353077..27eb1ca734 100644
--- a/apps/docs/content/docs/blocks/router.mdx
+++ b/apps/docs/content/docs/blocks/router.mdx
@@ -8,6 +8,7 @@ import { Step, Steps } from 'fumadocs-ui/components/steps'
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'
import { ThemeImage } from '@/components/ui/theme-image'
+import { Video } from '@/components/ui/video'
The Router block uses AI to intelligently decide which path your workflow should take next. Unlike Condition blocks that use simple rules, Router blocks can understand context and make smart routing decisions based on content analysis.
@@ -103,7 +104,7 @@ Choose an AI model to power the routing decision:
**Local Models**: Any model running on Ollama
-
+
**Recommendation**: Use models with strong reasoning capabilities like GPT-4o or Claude 3.7 Sonnet for more accurate routing decisions.
diff --git a/apps/docs/content/docs/connections/index.mdx b/apps/docs/content/docs/connections/index.mdx
index 82148ae4de..cebeda3b19 100644
--- a/apps/docs/content/docs/connections/index.mdx
+++ b/apps/docs/content/docs/connections/index.mdx
@@ -6,6 +6,7 @@ description: Connect your blocks to one another.
import { Callout } from 'fumadocs-ui/components/callout'
import { Card, Cards } from 'fumadocs-ui/components/card'
import { ConnectIcon } from '@/components/icons'
+import { Video } from '@/components/ui/video'
Connections are the pathways that allow data to flow between blocks in your workflow. They define how information is passed from one block to another, enabling you to create sophisticated, multi-step processes.
@@ -15,7 +16,7 @@ Connections are the pathways that allow data to flow between blocks in your work
-
+
## Connection Types
diff --git a/apps/docs/content/docs/connections/tags.mdx b/apps/docs/content/docs/connections/tags.mdx
index d745990d00..f6f974c40d 100644
--- a/apps/docs/content/docs/connections/tags.mdx
+++ b/apps/docs/content/docs/connections/tags.mdx
@@ -4,11 +4,12 @@ description: Using connection tags to reference data between blocks
---
import { Callout } from 'fumadocs-ui/components/callout'
+import { Video } from '@/components/ui/video'
Connection tags are visual representations of the data available from connected blocks. They provide an easy way to reference outputs from previous blocks in your workflow.
-
+
### What Are Connection Tags?
diff --git a/apps/docs/content/docs/execution/basics.mdx b/apps/docs/content/docs/execution/basics.mdx
index c489d7fa3a..dc6be9e356 100644
--- a/apps/docs/content/docs/execution/basics.mdx
+++ b/apps/docs/content/docs/execution/basics.mdx
@@ -20,6 +20,7 @@ import {
LoopIcon,
ParallelIcon,
} from '@/components/icons'
+import { Video } from '@/components/ui/video'
When you run a workflow in Sim Studio, the execution engine follows a systematic process to ensure blocks are executed in the correct order with proper data flow.
@@ -162,7 +163,7 @@ Run workflows on-demand through the Sim Studio interface by clicking the "Run" b
- Workflows that need human supervision
-
+
### Scheduled Execution
@@ -175,7 +176,7 @@ Configure workflows to run automatically on a specified schedule:
- Set minimum and maximum execution intervals
-
+
### API Endpoints
@@ -188,7 +189,7 @@ Each workflow can be exposed as an API endpoint:
- Receive execution results as JSON responses
-
+
#### Viewing Deployed APIs
@@ -196,7 +197,7 @@ Each workflow can be exposed as an API endpoint:
Monitor your deployed workflow APIs and their current state:
-
+
This shows how to view the deployed state and compare with the original deployed API configuration.
@@ -211,7 +212,7 @@ Configure workflows to execute in response to external events:
- Support for specialized webhooks (GitHub, Stripe, etc.)
-
+
diff --git a/apps/docs/content/docs/getting-started/index.mdx b/apps/docs/content/docs/getting-started/index.mdx
index 0f1e7f1d69..ca7ae7748c 100644
--- a/apps/docs/content/docs/getting-started/index.mdx
+++ b/apps/docs/content/docs/getting-started/index.mdx
@@ -23,6 +23,7 @@ import {
PerplexityIcon,
SlackIcon,
} from '@/components/icons'
+import { Video } from '@/components/ui/video'
This tutorial will guide you through building your first AI workflow in Sim Studio. We'll create a people research agent that can find information about individuals using state-of-the-art LLM-Search tools.
@@ -63,7 +64,7 @@ A people research agent that:
- **User Prompt**: Drag the connection from the Start block's output into this field (this connects `` to the user prompt)
-
+
@@ -77,7 +78,7 @@ A people research agent that:
- Add your API keys for both tools (this allows the agent to search the web and access additional information)
-
+
@@ -92,7 +93,7 @@ A people research agent that:
You should see the agent's response analyzing the person described in your text.
-
+
@@ -105,7 +106,7 @@ A people research agent that:
- The AI will generate a JSON schema for you automatically
-
+
@@ -120,7 +121,7 @@ A people research agent that:
You should now see structured JSON output with the person's information organized into location, profession, and education fields.
-
+
diff --git a/apps/docs/content/docs/triggers/webhook.mdx b/apps/docs/content/docs/triggers/webhook.mdx
index 005345d1ba..fbba8d05bc 100644
--- a/apps/docs/content/docs/triggers/webhook.mdx
+++ b/apps/docs/content/docs/triggers/webhook.mdx
@@ -6,11 +6,12 @@ description: Trigger workflow execution from external webhooks
import { Callout } from 'fumadocs-ui/components/callout'
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
import { ThemeImage } from '@/components/ui/theme-image'
+import { Video } from '@/components/ui/video'
The Webhook block allows external services to automatically trigger your workflow execution through HTTP webhooks.
-
+
## Supported Providers
diff --git a/apps/docs/content/docs/variables/index.mdx b/apps/docs/content/docs/variables/index.mdx
index 41f0007b16..66fa500dac 100644
--- a/apps/docs/content/docs/variables/index.mdx
+++ b/apps/docs/content/docs/variables/index.mdx
@@ -7,11 +7,12 @@ import { Callout } from 'fumadocs-ui/components/callout'
import { Step, Steps } from 'fumadocs-ui/components/steps'
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
import { ThemeImage } from '@/components/ui/theme-image'
+import { Video } from '@/components/ui/video'
Variables in Sim Studio act as a global store for data that can be accessed and modified by any block in your workflow. They provide a powerful way to share information between different parts of your workflow, maintain state, and create more dynamic applications.
-
+
@@ -57,7 +58,7 @@ Variables can be accessed from any block in your workflow using the variable dro
3. Select the variable you want to use
-
+
diff --git a/apps/docs/lib/utils.ts b/apps/docs/lib/utils.ts
index 4a8954ffaa..172f3fd29c 100644
--- a/apps/docs/lib/utils.ts
+++ b/apps/docs/lib/utils.ts
@@ -7,3 +7,15 @@ import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
+
+/**
+ * Get the full URL for a video asset stored in Vercel Blob
+ */
+export function getVideoUrl(filename: string) {
+ const baseUrl = process.env.NEXT_PUBLIC_BLOB_BASE_URL
+ if (!baseUrl) {
+ console.warn('NEXT_PUBLIC_BLOB_BASE_URL not configured, falling back to local path')
+ return `/${filename}`
+ }
+ return `${baseUrl}/${filename}`
+}
diff --git a/docker/app.Dockerfile b/docker/app.Dockerfile
index 53f4e208c4..1d13e01f95 100644
--- a/docker/app.Dockerfile
+++ b/docker/app.Dockerfile
@@ -25,6 +25,9 @@ RUN bun install --omit dev --ignore-scripts
FROM base AS builder
WORKDIR /app
+# Install turbo globally in builder stage
+RUN bun install -g turbo
+
COPY --from=deps /app/node_modules ./node_modules
COPY . .