Compare commits

...

72 Commits

Author SHA1 Message Date
Vikhyath Mondreti
a02016e247 v0.4.24: sso for chat deployment, usage indicator for file storage, mcp improvements, local kb file storage 2025-10-27 15:32:53 -07:00
Waleed
8620ab255a improvement(docs): added a copy page button to the docs pages (#1743)
* improvement(docs): added a copy page button to the docs pages

* added copy page button & fixed TOC alignment
2025-10-27 15:05:27 -07:00
Waleed
47ddfb639e fix(dropdown): auto-add character to trigger tag dropdown on connection tag drop in agent tools (#1742) 2025-10-27 14:28:29 -07:00
Waleed
5d48c2780c improvement(ui): enhance ring outline for code subblock and mcp tool subblocks in agent (#1741) 2025-10-27 13:59:19 -07:00
Waleed
38614fad79 fix(mcp): resolve variables & block references in mcp subblocks (#1735)
* fix(mcp): resolve variables & block references in mcp subblocks

* cleanup

* ack PR comment

* added variables access to mcp tools when added in agent block

* fix sequential migrations issues
2025-10-27 13:13:11 -07:00
Waleed
6f32aea96b feat(kb): added support for local file storage for knowledgebase (#1738)
* feat(kb): added support for local file storage for knowledgebase

* updated tests

* ack PR comments

* added back env example
2025-10-27 11:28:45 -07:00
Waleed
98e98496e8 Revert "improvement(consts): removed redundant default consts in favor of env…" (#1739)
This reverts commit 659b46fa2f.
2025-10-26 23:06:14 -07:00
Waleed
659b46fa2f improvement(consts): removed redundant default consts in favor of envvar defaults for storage & usage limits (#1737)
* improvement(consts): removed redundant default consts in favor of envvar defaults for storage & usage limits

* remove unnecessary tests
2025-10-26 21:43:00 -07:00
Waleed
fb3d6d4c88 feat(files): added usage indicator for file storage to settings (#1736)
* feat(files): added usage indicator for file storage to settings

* cleanup
2025-10-26 21:36:25 -07:00
Waleed
ec2cc82b72 feat(i18n): update translations (#1734) 2025-10-26 18:35:20 -07:00
Adam Gough
274d5e3afc fix(clay): fixed clay tool (#1725)
* fixed clay tool

* added metadata

* added metadata to types

* fix(clay): remove (optional) from subblock name

* regen docs
2025-10-26 18:30:08 -07:00
Waleed
c552bb9c5f fix(elevenlabs): added internal auth helper for proxy routes (#1732)
* fix(elevenlabs): added internal auth helper for proxy routes

* remove concurrent tests

* build fix
2025-10-25 17:54:27 -07:00
Vikhyath Mondreti
ad7b791242 improvement(deployments): simplify deployments for chat and indicate active version (#1730)
* improvement(deployment-ux): deployment should indicate and make details configurable when activating previous version

* fix activation UI

* remove redundant code

* revert pulsing dot

* fix redeploy bug

* bill workspace owner for deployed chat

* deployed chat

* fix bugs

* fix tests, address greptile

* fix

* ui bug to load api key

* fix qdrant fetch tool
2025-10-25 16:55:34 -07:00
Waleed
ce4893a53c feat(sso-chat-deployment): added sso auth option for chat deployment (#1729)
* feat(sso-chat-deployment): added sso auth option for chat deployment

* ack PR comments
2025-10-25 14:58:25 -07:00
Vikhyath Mondreti
7f1ff7fd86 fix(billing): should allow restoring subscription (#1728)
* fix(already-cancelled-sub): UI should allow restoring subscription

* restore functionality fixed

* fix
2025-10-25 12:59:57 -07:00
Adam Gough
517f1a91b6 fix(google-scopes): added forms and different drive scope (#1532)
* added google forms scope and google drive scope

* added back file scope

---------

Co-authored-by: Adam Gough <adamgough@Mac.attlocal.net>
Co-authored-by: Adam Gough <adamgough@Mac-530.lan>
2025-10-25 12:08:49 -07:00
Waleed
9b2490c4b1 v0.4.23: webflow tools + triggers, copilot api key fix (#1723)
* fix(debug-mode): remove duplicate debug mode flag (#1714)

* feat(i18n): update translations (#1709)

* improvement(condition): added variable and envvar highlighting for condition input (#1718)

* fix(dashboard): add additional context for paginated logs in dashboard, add empty state when selected cell has no data (#1719)

* fix(dashboard): add additional context for paginated logs in dashboard, add empty state when selected cell has no data

* apps/sim

* renaming

* remove relative import

* feat(tools): added webflow OAuth + tools (#1720)

* feat(tools): added webflow OAuth + tools

* remove itemId from delete item

* remove siteId

* added webhook triggers + oauth scopes + site/collection selector

* update sample payload for webflow triggers

* cleanup

* fix discord color

* feat(i18n): update translations (#1721)

* improvement(schedule): fix UI bug with schedule modal (#1722)
2025-10-23 14:48:09 -07:00
Waleed
dba7514350 improvement(schedule): fix UI bug with schedule modal (#1722) 2025-10-23 14:16:59 -07:00
Waleed
e94de1dd26 feat(i18n): update translations (#1721) 2025-10-23 13:15:05 -07:00
Waleed
a4e874b266 feat(tools): added webflow OAuth + tools (#1720)
* feat(tools): added webflow OAuth + tools

* remove itemId from delete item

* remove siteId

* added webhook triggers + oauth scopes + site/collection selector

* update sample payload for webflow triggers

* cleanup

* fix discord color
2025-10-23 13:08:32 -07:00
Waleed
ec034f3fc7 fix(dashboard): add additional context for paginated logs in dashboard, add empty state when selected cell has no data (#1719)
* fix(dashboard): add additional context for paginated logs in dashboard, add empty state when selected cell has no data

* apps/sim

* renaming

* remove relative import
2025-10-22 14:07:52 -07:00
Waleed
e425d064c0 improvement(condition): added variable and envvar highlighting for condition input (#1718) 2025-10-22 13:12:09 -07:00
Waleed
bcd1a2faf6 feat(i18n): update translations (#1709) 2025-10-22 12:55:36 -07:00
Vikhyath Mondreti
989a77261c fix(debug-mode): remove duplicate debug mode flag (#1714) 2025-10-22 00:49:18 -10:00
Vikhyath Mondreti
71ae27b6cd v0.4.22: fix execution context pass for google sheets 2025-10-21 19:48:06 -07:00
Vikhyath Mondreti
5ab482127d fix(remove-exec-context): tools handle workflow id check themselves 2025-10-21 16:34:08 -10:00
Vikhyath Mondreti
b8bc632baa fix(workflow-auth): adding workflowId param to only internal urls (#1710) 2025-10-21 16:30:22 -10:00
Vikhyath Mondreti
1b7437af14 v0.4.21: more internal auth changes, supabase vector search tool 2025-10-21 18:49:09 -07:00
Waleed
4d7ebd8bcb feat(supabase): added vector search tool and updated docs (#1707)
* feat(supabase): added vector search tool and updated docs

* exclude generic webhook from docs gen

* change items to pages in meta.json for tools directory in the docs
2025-10-21 18:48:18 -07:00
Vikhyath Mondreti
ca1156a6c2 fix(base-url): use getBaseUrl helper in copilot revert state endpoint (#1706)
* revert base url

* fix tests"
;
2025-10-21 15:44:05 -10:00
Vikhyath Mondreti
89eb1849d0 fix(external-route): handleInternalRequest should still check if request internal 2025-10-21 15:00:33 -10:00
Vikhyath Mondreti
1d4833f485 fix case sensitive header (#1705) 2025-10-21 14:51:13 -10:00
Waleed
d5902e91da fix(kb): added internal auth for mistral OCR tool via KB (#1704) 2025-10-21 16:56:53 -07:00
Vikhyath Mondreti
9751c9f5c4 v0.4.20: internal request, kb url fixes, docs styling 2025-10-21 13:00:00 -07:00
Vikhyath Mondreti
e6ba323de4 Merge pull request #1700 from simstudioai/fix/internal-req
fix(internal-req): add internal token to server side
2025-10-21 12:07:54 -07:00
Waleed
859711991f fix(docs): made sidebar directories scrollable, stylistic changes (#1702) 2025-10-21 12:04:19 -07:00
Waleed
c178a90f02 improvement(helm): added additional envvars to helm charts (#1695)
* improvement(helm): added additional envvars to helm charts

* updated docs
2025-10-21 12:02:51 -07:00
Waleed
eb8995ee7c fix(kb): add base URL for kb fetches (#1701) 2025-10-21 12:02:18 -07:00
Vikhyath Mondreti
b269447539 fix(internal-req): add internal token to server side 2025-10-21 08:36:15 -10:00
Vikhyath Mondreti
641e353d03 v0.4.19: landing page fix 2025-10-19 16:06:12 -07:00
Vikhyath Mondreti
ce660e2df9 fix(plan-config): align buttons above divider (#1696)
* fix alignment of buttons on landing page

* revert environment.ts

* revert other change
2025-10-19 16:00:43 -07:00
Vikhyath Mondreti
e4ddeb09d6 v0.4.18: file upload tools, copilot upgrade, docs changes, model filtering 2025-10-19 15:38:39 -07:00
Vikhyath Mondreti
063bd610b1 fix(jira): issue selector inf render (#1693)
* improvement(copilot): version update, edit previous messages, revert logic, model selector, observability, add haiku 4.5 (#1688)

* Add exa to search online tool

* Larger font size

* Copilot UI improvements

* Fix models options

* Add haiku 4.5 to copilot

* Model ui for haiku

* Fix lint

* Revert

* Only allow one revert to message

* Clear diff on revert

* Fix welcome screen flash

* Add focus onto the user input box when clicked

* Fix grayout of new stream on old edit message

* Lint

* Make edit message submit smoother

* Allow message sent while streaming

* Revert popup improvements: gray out stuff below, show cursor on revert

* Fix lint

* Improve chat history dropdown

* Improve get block metadata tool

* Update update cost route

* Fix env

* Context usage endpoint

* Make chat history scrollable

* Fix lint

* Copilot revert popup updates

* Fix lint

* Fix tests and lint

* Add summary tool

* fix(jira): issue selector inf render

* fix

* fixed

* fix endpoints

* fix

* more detailed error

* fix endpoint

* revert environment.ts file

---------

Co-authored-by: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com>
2025-10-19 15:20:08 -07:00
Waleed
9132cd224d fix(mcp): add workflow id to agent-handler for mcp tools (#1694) 2025-10-19 10:40:58 -07:00
Waleed
c70c32a3bd fix(settings-ui): fix settings ui, add upload status (#1691) 2025-10-18 15:37:12 -07:00
Siddharth Ganesan
cc0ace7de6 improvement(copilot): version update (#1689)
* Add exa to search online tool

* Larger font size

* Copilot UI improvements

* Fix models options

* Add haiku 4.5 to copilot

* Model ui for haiku

* Fix lint

* Revert

* Only allow one revert to message

* Clear diff on revert

* Fix welcome screen flash

* Add focus onto the user input box when clicked

* Fix grayout of new stream on old edit message

* Lint

* Make edit message submit smoother

* Allow message sent while streaming

* Revert popup improvements: gray out stuff below, show cursor on revert

* Fix lint

* Improve chat history dropdown

* Improve get block metadata tool

* Update update cost route

* Fix env

* Context usage endpoint

* Make chat history scrollable

* Fix lint

* Copilot revert popup updates

* Fix lint

* Fix tests and lint

* Add summary tool

* Fix env.ts
2025-10-18 12:59:48 -07:00
Vikhyath Mondreti
de1ac9a704 improvement(models): system to blacklist models (#1687)
* improvment(models): system to blacklist models

* move base models endpoint to right place

* remove tngtech models too
2025-10-18 12:09:18 -07:00
Vikhyath Mondreti
728a4c82c6 add inline defaults for storage limits by plan (#1685) 2025-10-18 10:51:18 -07:00
Waleed
37f293a761 feat(i18n): update translations (#1683) 2025-10-18 09:58:18 -07:00
Waleed
d1c08daaf4 improvement(docs): overhaul docs (#1680)
* improvement(docs): overhaul docs

* lint

* light mode

* more light mode

* added llms.txt and llms-full.txt and sitemap

* fixed mobile styling and position for zoom in out

* finished styling

* improvement(docs): overhaul docs

* lint

* remove dups

* renaming components

* cleanup
2025-10-17 22:29:55 -07:00
Waleed
90c34b2c46 fix(airtable): fix airtable oauth connection (#1682) 2025-10-17 22:15:35 -07:00
Waleed
3a0019bd13 fix(docker): remove prebuild lint check from docker (#1681) 2025-10-17 22:10:25 -07:00
Waleed
a6122f2bbc feat(i18n): update translations (#1673) 2025-10-17 21:59:07 -07:00
Adam Gough
9bf5f6e1fc removed raw paylod for gmail and outlook (#1679)
Co-authored-by: Adam Gough <adamgough@Adams-MacBook-Pro.local>
2025-10-17 18:56:48 -07:00
Vikhyath Mondreti
22b3dde155 fix(env-vars): promotion should never leave a copy in personal vars (#1678)
* fix(env-vars): promotion should never leave a copy in personal vars

* fix lint
2025-10-17 18:34:38 -07:00
Vikhyath Mondreti
c1725c1c4b improvement(error-messages): make error extraction generalized abstraction (#1676)
* make error extraction generalized abstraction

* remove comments

* remove console logs
2025-10-17 17:30:12 -07:00
Vikhyath Mondreti
64eee587cd improvement(gdrive): remove mime type subblock from upload file tool (#1674)
* remove mime type subblock from upload file tool for gdrive

* add UI message to limit every x minutes to <60
2025-10-17 14:58:23 -07:00
Vikhyath Mondreti
35c551984f feat(files): gmail upload attachment, workspace files, file storage limits (#1666)
* feat(gmail): add attachment uploads

* add workspace files

* update landing page

* fix lint

* fix test

* fixed UI

* added additional S3 tools to upload files

* added search filters for gmail trigger

* added files to every block

* works

* fix

* register sharepoint tool

---------

Co-authored-by: waleed <waleed>
2025-10-17 14:44:22 -07:00
Vikhyath Mondreti
d92d9a02cd fix(permissions): cannot create workflow with read perms (#1671) 2025-10-17 13:44:44 -07:00
Adam Gough
64ede7f038 added legit urls to the metadata (#1665)
Co-authored-by: Adam Gough <adamgough@Adams-MacBook-Pro.local>
2025-10-17 13:11:02 -07:00
Vikhyath Mondreti
0fbbbe02c7 fix(execution-counts): execution counts by trigger type recorded accurately (#1670) 2025-10-17 12:18:11 -07:00
Waleed
da091dfe8a v0.4.17: input format + files support for webhooks, docs updates, dashboard improvements 2025-10-16 16:51:55 -07:00
Waleed
29c7827d6f fix(deployed-chat): include workspace id in deployed chat request (#1664) 2025-10-16 16:23:28 -07:00
Waleed
22f9d6e2df improvement(dashboard): improve dashboard performance, enrich charts, consolidate routes (#1662)
* improvement(dashboard): improve dashboard performance, enrich charts, consolidate routes

* cleanup
2025-10-16 15:53:06 -07:00
Waleed
0cb615428d feat(powershell): add gitattributes to prevent lint issues for powershell users (#1661) 2025-10-16 15:50:26 -07:00
Waleed
74576ec921 feat(i18n): update translations (#1660) 2025-10-16 15:31:10 -07:00
Waleed
67e681dd7c feat(webhooks): added optioanl input format to webhooks, added support for file uploads (#1654)
* feat(webhooks): added  optioanl input format to webhooks, added support for file uploads

* feat(webhooks): added input format component to generic webhook trigger, added file support

* consolidated execution files utils, extended presigned URL duration for async tasks
2025-10-16 12:16:12 -07:00
Waleed
4b05da31e0 feat(i18n): update translations (#1659) 2025-10-16 11:49:51 -07:00
Vikhyath Mondreti
82fa4e8bbb fix(input-format): allow value field to be cleared (#1658)
* fix(input-format): allow value field to be cleared

* don't let value field be detected as deployment change

* fix zep icon in docs

* exclude collapsed state
2025-10-16 11:11:27 -07:00
Waleed
4cd790b200 feat(i18n): update translations (#1653) 2025-10-15 23:21:26 -07:00
Waleed
b7e0b42d48 improvement(dashboard): cleanup execution dashboard UI, fix logs trace, and improve performance (#1651)
* improvement(dashboard): cleanup execution dashboard UI, fix logs trace, and improve perforamnce

* cleanup

* cleaned up

* ack PR comments
2025-10-15 23:00:07 -07:00
Waleed
c6ef5785c8 fix(i18n): fix SDK and guardrails translation corruption, restore i18n gh action for docs (#1652)
* fix(i18n): fix SDK and guardrails translation corruption

* re-enable i18n gh action
2025-10-15 22:52:48 -07:00
525 changed files with 34226 additions and 8140 deletions

34
.gitattributes vendored Normal file
View File

@@ -0,0 +1,34 @@
# Set default behavior to automatically normalize line endings
* text=auto eol=lf
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout
*.ts text eol=lf
*.tsx text eol=lf
*.js text eol=lf
*.jsx text eol=lf
*.json text eol=lf
*.md text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.toml text eol=lf
*.css text eol=lf
*.scss text eol=lf
*.sh text eol=lf
*.bash text eol=lf
Dockerfile* text eol=lf
.dockerignore text eol=lf
.gitignore text eol=lf
.gitattributes text eol=lf
# Denote all files that are truly binary and should not be modified
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.woff binary
*.woff2 binary
*.ttf binary
*.eot binary
*.pdf binary

View File

@@ -1,13 +1,11 @@
name: 'Auto-translate Documentation'
# Temporarily disabled
on:
workflow_dispatch: # Allow manual triggers only
# push:
# branches: [ staging ]
# paths:
# - 'apps/docs/content/docs/en/**'
# - 'apps/docs/i18n.json'
push:
branches: [ staging ]
paths:
- 'apps/docs/content/docs/en/**'
- 'apps/docs/i18n.json'
permissions:
contents: write

View File

@@ -26,6 +26,9 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Lint code
run: bun run lint:check
- name: Run tests with coverage
env:
NODE_OPTIONS: '--no-warnings'

View File

@@ -5,6 +5,8 @@ import { ChevronLeft, ChevronRight } from 'lucide-react'
import Link from 'next/link'
import { notFound } from 'next/navigation'
import { StructuredData } from '@/components/structured-data'
import { CodeBlock } from '@/components/ui/code-block'
import { CopyPageButton } from '@/components/ui/copy-page-button'
import { source } from '@/lib/source'
export const dynamic = 'force-dynamic'
@@ -22,31 +24,143 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
pageTreeRecord[params.lang] ?? pageTreeRecord.en ?? Object.values(pageTreeRecord)[0]
const neighbours = pageTree ? findNeighbour(pageTree, page.url) : null
const CustomFooter = () => (
<div className='mt-12 flex items-center justify-between border-border border-t py-8'>
{neighbours?.previous ? (
<Link
href={neighbours.previous.url}
className='group flex items-center gap-2 text-muted-foreground transition-colors hover:text-foreground'
>
<ChevronLeft className='group-hover:-translate-x-1 h-4 w-4 transition-transform' />
<span className='font-medium'>{neighbours.previous.name}</span>
</Link>
) : (
<div />
)}
const generateBreadcrumbs = () => {
const breadcrumbs: Array<{ name: string; url: string }> = [
{
name: 'Home',
url: baseUrl,
},
]
{neighbours?.next ? (
const urlParts = page.url.split('/').filter(Boolean)
let currentPath = ''
urlParts.forEach((part, index) => {
if (index === 0 && ['en', 'es', 'fr', 'de', 'ja', 'zh'].includes(part)) {
currentPath = `/${part}`
return
}
currentPath += `/${part}`
const name = part
.split('-')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ')
if (index === urlParts.length - 1) {
breadcrumbs.push({
name: page.data.title,
url: `${baseUrl}${page.url}`,
})
} else {
breadcrumbs.push({
name: name,
url: `${baseUrl}${currentPath}`,
})
}
})
return breadcrumbs
}
const breadcrumbs = generateBreadcrumbs()
const CustomFooter = () => (
<div className='mt-12'>
{/* Navigation links */}
<div className='flex items-center justify-between py-8'>
{neighbours?.previous ? (
<Link
href={neighbours.previous.url}
className='group flex items-center gap-2 text-muted-foreground transition-colors hover:text-foreground'
>
<ChevronLeft className='group-hover:-translate-x-1 h-4 w-4 transition-transform' />
<span className='font-medium'>{neighbours.previous.name}</span>
</Link>
) : (
<div />
)}
{neighbours?.next ? (
<Link
href={neighbours.next.url}
className='group flex items-center gap-2 text-muted-foreground transition-colors hover:text-foreground'
>
<span className='font-medium'>{neighbours.next.name}</span>
<ChevronRight className='h-4 w-4 transition-transform group-hover:translate-x-1' />
</Link>
) : (
<div />
)}
</div>
{/* Divider line */}
<div className='border-border border-t' />
{/* Social icons */}
<div className='flex items-center gap-4 py-6'>
<Link
href={neighbours.next.url}
className='group flex items-center gap-2 text-muted-foreground transition-colors hover:text-foreground'
href='https://x.com/simdotai'
target='_blank'
rel='noopener noreferrer'
aria-label='X (Twitter)'
>
<span className='font-medium'>{neighbours.next.name}</span>
<ChevronRight className='h-4 w-4 transition-transform group-hover:translate-x-1' />
<div
className='h-5 w-5 bg-gray-400 transition-colors hover:bg-gray-500 dark:bg-gray-500 dark:hover:bg-gray-400'
style={{
maskImage:
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z%22/%3E%3C/svg%3E')",
maskRepeat: 'no-repeat',
maskPosition: 'center center',
WebkitMaskImage:
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z%22/%3E%3C/svg%3E')",
WebkitMaskRepeat: 'no-repeat',
WebkitMaskPosition: 'center center',
}}
/>
</Link>
) : (
<div />
)}
<Link
href='https://github.com/simstudioai/sim'
target='_blank'
rel='noopener noreferrer'
aria-label='GitHub'
>
<div
className='h-5 w-5 bg-gray-400 transition-colors hover:bg-gray-500 dark:bg-gray-500 dark:hover:bg-gray-400'
style={{
maskImage:
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z%22/%3E%3C/svg%3E')",
maskRepeat: 'no-repeat',
maskPosition: 'center center',
WebkitMaskImage:
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z%22/%3E%3C/svg%3E')",
WebkitMaskRepeat: 'no-repeat',
WebkitMaskPosition: 'center center',
}}
/>
</Link>
<Link
href='https://discord.gg/Hr4UWYEcTT'
target='_blank'
rel='noopener noreferrer'
aria-label='Discord'
>
<div
className='h-5 w-5 bg-gray-400 transition-colors hover:bg-gray-500 dark:bg-gray-500 dark:hover:bg-gray-400'
style={{
maskImage:
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z%22/%3E%3C/svg%3E')",
maskRepeat: 'no-repeat',
maskPosition: 'center center',
WebkitMaskImage:
"url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22%3E%3Cpath d=%22M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z%22/%3E%3C/svg%3E')",
WebkitMaskRepeat: 'no-repeat',
WebkitMaskPosition: 'center center',
}}
/>
</Link>
</div>
</div>
)
@@ -57,6 +171,7 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
description={page.data.description || ''}
url={`${baseUrl}${page.url}`}
lang={params.lang}
breadcrumb={breadcrumbs}
/>
<DocsPage
toc={page.data.toc}
@@ -79,10 +194,26 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
component: <CustomFooter />,
}}
>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<div className='relative'>
<div className='absolute top-1 right-0'>
<CopyPageButton
content={`# ${page.data.title}
${page.data.description || ''}
${page.data.content || ''}`}
/>
</div>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
</div>
<DocsBody>
<MDX components={defaultMdxComponents} />
<MDX
components={{
...defaultMdxComponents,
CodeBlock,
}}
/>
</DocsBody>
</DocsPage>
</>
@@ -128,8 +259,10 @@ export async function generateMetadata(props: {
url: fullUrl,
siteName: 'Sim Documentation',
type: 'article',
locale: params.lang,
alternateLocale: ['en', 'fr', 'zh'].filter((lang) => lang !== params.lang),
locale: params.lang === 'en' ? 'en_US' : `${params.lang}_${params.lang.toUpperCase()}`,
alternateLocale: ['en', 'es', 'fr', 'de', 'ja', 'zh']
.filter((lang) => lang !== params.lang)
.map((lang) => (lang === 'en' ? 'en_US' : `${lang}_${lang.toUpperCase()}`)),
},
twitter: {
card: 'summary',
@@ -152,8 +285,12 @@ export async function generateMetadata(props: {
alternates: {
canonical: fullUrl,
languages: {
en: `${baseUrl}/en${page.url.replace(`/${params.lang}`, '')}`,
'x-default': `${baseUrl}${page.url.replace(`/${params.lang}`, '')}`,
en: `${baseUrl}${page.url.replace(`/${params.lang}`, '')}`,
es: `${baseUrl}/es${page.url.replace(`/${params.lang}`, '')}`,
fr: `${baseUrl}/fr${page.url.replace(`/${params.lang}`, '')}`,
de: `${baseUrl}/de${page.url.replace(`/${params.lang}`, '')}`,
ja: `${baseUrl}/ja${page.url.replace(`/${params.lang}`, '')}`,
zh: `${baseUrl}/zh${page.url.replace(`/${params.lang}`, '')}`,
},
},

View File

@@ -2,11 +2,14 @@ import type { ReactNode } from 'react'
import { defineI18nUI } from 'fumadocs-ui/i18n'
import { DocsLayout } from 'fumadocs-ui/layouts/docs'
import { RootProvider } from 'fumadocs-ui/provider/next'
import { ExternalLink, GithubIcon } from 'lucide-react'
import { Inter } from 'next/font/google'
import { Geist_Mono, Inter } from 'next/font/google'
import Image from 'next/image'
import Link from 'next/link'
import { LanguageDropdown } from '@/components/ui/language-dropdown'
import {
SidebarFolder,
SidebarItem,
SidebarSeparator,
} from '@/components/docs-layout/sidebar-components'
import { Navbar } from '@/components/navbar/navbar'
import { i18n } from '@/lib/i18n'
import { source } from '@/lib/source'
import '../global.css'
@@ -14,6 +17,12 @@ import { Analytics } from '@vercel/analytics/next'
const inter = Inter({
subsets: ['latin'],
variable: '--font-geist-sans',
})
const geistMono = Geist_Mono({
subsets: ['latin'],
variable: '--font-geist-mono',
})
const { provider } = defineI18nUI(i18n, {
@@ -27,25 +36,18 @@ const { provider } = defineI18nUI(i18n, {
fr: {
displayName: 'Français',
},
de: {
displayName: 'Deutsch',
},
ja: {
displayName: '日本語',
},
zh: {
displayName: '简体中文',
},
},
})
const GitHubLink = () => (
<div className='fixed right-4 bottom-4 z-50'>
<Link
href='https://github.com/simstudioai/sim'
target='_blank'
rel='noopener noreferrer'
className='flex h-8 w-8 items-center justify-center rounded-full border border-border bg-background transition-colors hover:bg-muted'
>
<GithubIcon className='h-4 w-4' />
</Link>
</div>
)
type LayoutProps = {
children: ReactNode
params: Promise<{ lang: string }>
@@ -54,43 +56,82 @@ type LayoutProps = {
export default async function Layout({ children, params }: LayoutProps) {
const { lang } = await params
const structuredData = {
'@context': 'https://schema.org',
'@type': 'WebSite',
name: 'Sim Documentation',
description:
'Comprehensive documentation for Sim - the visual workflow builder for AI Agent Workflows.',
url: 'https://docs.sim.ai',
publisher: {
'@type': 'Organization',
name: 'Sim',
url: 'https://sim.ai',
logo: {
'@type': 'ImageObject',
url: 'https://docs.sim.ai/static/logo.png',
},
},
inLanguage: lang,
potentialAction: {
'@type': 'SearchAction',
target: {
'@type': 'EntryPoint',
urlTemplate: 'https://docs.sim.ai/api/search?q={search_term_string}',
},
'query-input': 'required name=search_term_string',
},
}
return (
<html lang={lang} className={inter.className} suppressHydrationWarning>
<body className='flex min-h-screen flex-col'>
<html
lang={lang}
className={`${inter.variable} ${geistMono.variable}`}
suppressHydrationWarning
>
<head>
<script
type='application/ld+json'
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
/>
</head>
<body className='flex min-h-screen flex-col font-sans'>
<RootProvider i18n={provider(lang)}>
<Navbar />
<DocsLayout
tree={source.pageTree[lang]}
themeSwitch={{
enabled: false,
}}
nav={{
title: (
<div className='flex items-center gap-3'>
<Image
src='/static/logo.png'
alt='Sim'
width={60}
height={24}
className='h-6 w-auto'
/>
<LanguageDropdown />
</div>
<Image
src='/static/logo.png'
alt='Sim'
width={72}
height={28}
className='h-7 w-auto'
priority
/>
),
}}
links={[
{
text: 'Visit Sim',
url: 'https://sim.ai',
icon: <ExternalLink className='h-4 w-4' />,
},
]}
sidebar={{
defaultOpenLevel: 0,
collapsible: true,
collapsible: false,
footer: null,
banner: null,
components: {
Item: SidebarItem,
Folder: SidebarFolder,
Separator: SidebarSeparator,
},
}}
containerProps={{
className: '!pt-10',
}}
>
{children}
</DocsLayout>
<GitHubLink />
<Analytics />
</RootProvider>
</body>

View File

@@ -4,6 +4,19 @@
@theme {
--color-fd-primary: #802fff; /* Purple from control-bar component */
--font-geist-sans: var(--font-geist-sans);
--font-geist-mono: var(--font-geist-mono);
}
/* Font family utilities */
.font-sans {
font-family: var(--font-geist-sans), ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
.font-mono {
font-family: var(--font-geist-mono), ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
"Liberation Mono", "Courier New", monospace;
}
/* Target any potential border classes */
@@ -15,139 +28,441 @@
:root {
--fd-border: transparent !important;
--fd-border-sidebar: transparent !important;
--fd-nav-height: 64px; /* Custom navbar height (h-16 = 4rem = 64px) */
/* Content container width used to center main content */
--spacing-fd-container: 1400px;
/* Edge gutter = leftover space on each side of centered container */
--edge-gutter: max(1rem, calc((100vw - var(--spacing-fd-container)) / 2));
/* Shift the sidebar slightly left from the content edge for extra breathing room */
--sidebar-shift: 90px;
--sidebar-offset: max(0px, calc(var(--edge-gutter) - var(--sidebar-shift)));
/* Shift TOC slightly right to match sidebar spacing for symmetry */
--toc-shift: 90px;
--toc-offset: max(0px, calc(var(--edge-gutter) - var(--toc-shift)));
/* Sidebar and TOC have 20px internal padding - navbar accounts for this directly */
/* Extra gap between sidebar/TOC and the main text content */
--content-gap: 1.75rem;
}
/* Sidebar improvements for cleaner design */
[data-sidebar] {
--fd-sidebar-width: 280px;
background-color: rgb(255 255 255);
padding-top: 16px;
/* Remove custom layout variable overrides to fallback to fumadocs defaults */
/* ============================================
Navbar Light Mode Styling
============================================ */
/* Light mode navbar and search styling */
:root:not(.dark) nav {
background-color: hsla(0, 0%, 96%, 0.92) !important;
backdrop-filter: blur(25px) saturate(180%) brightness(1.05) !important;
-webkit-backdrop-filter: blur(25px) saturate(180%) brightness(1.05) !important;
}
/* Clean sidebar container */
[data-sidebar] > div {
padding: 0 16px;
:root:not(.dark) nav button[type="button"] {
background-color: hsla(0, 0%, 93%, 0.85) !important;
backdrop-filter: blur(33px) saturate(180%) !important;
-webkit-backdrop-filter: blur(33px) saturate(180%) !important;
color: rgba(0, 0, 0, 0.6) !important;
}
/* Section headers/separators styling */
[data-sidebar] .text-sm.font-medium.text-muted-foreground,
[data-sidebar] [data-separator] {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-top: 20px;
margin-bottom: 6px;
padding-left: 12px;
padding-right: 12px;
color: rgb(115 115 115);
border: none;
background: none;
:root:not(.dark) nav button[type="button"] kbd {
color: rgba(0, 0, 0, 0.6) !important;
}
/* First separator should have less top margin */
[data-sidebar] [data-separator]:first-of-type {
margin-top: 12px;
/* ============================================
Custom Sidebar Styling (Turborepo-inspired)
============================================ */
/* Floating sidebar appearance - remove background */
[data-sidebar-container],
#nd-sidebar {
background: transparent !important;
background-color: transparent !important;
border: none !important;
--color-fd-muted: transparent !important;
--color-fd-card: transparent !important;
--color-fd-secondary: transparent !important;
}
/* Clean sidebar item styling */
[data-sidebar] a {
padding: 8px 12px;
margin: 1px 0;
border-radius: 6px;
font-size: 14px;
font-weight: 400;
line-height: 1.4;
transition: all 0.15s ease;
aside[data-sidebar],
aside#nd-sidebar {
background: transparent !important;
background-color: transparent !important;
border: none !important;
border-right: none !important;
}
/* Responsive sidebar positioning */
/* Mobile: Fumadocs handles drawer */
@media (min-width: 768px) and (max-width: 1024px) {
aside[data-sidebar],
aside#nd-sidebar {
left: var(--sidebar-offset) !important;
}
}
/* Desktop layout alignment */
@media (min-width: 1025px) {
[data-sidebar-container] {
margin-left: var(--sidebar-offset) !important;
}
aside[data-sidebar],
aside#nd-sidebar {
left: var(--sidebar-offset) !important;
}
/* TOC positioning - target all possible selectors */
[data-toc],
aside[data-toc],
div[data-toc],
.fd-toc,
#nd-toc,
nav[data-toc],
aside:has([role="complementary"]) {
right: var(--toc-offset) !important;
}
/* Alternative TOC container targeting */
[data-docs-page] > aside:last-child,
main ~ aside {
right: var(--toc-offset) !important;
}
}
/* Sidebar spacing - compact like turborepo */
[data-sidebar-viewport] {
padding: 0.5rem 20px 12px;
background: transparent !important;
background-color: transparent !important;
}
/* Override sidebar item styling to match Raindrop */
/* Target Link and button elements in sidebar - override Fumadocs itemVariants */
/* Exclude the small chevron-only toggle buttons */
#nd-sidebar a,
#nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) {
font-size: 0.9375rem !important; /* 15px to match Raindrop */
line-height: 1.4 !important;
padding: 0.5rem 0.75rem !important; /* More compact like Raindrop */
font-weight: 400 !important;
border-radius: 0.75rem !important; /* More rounded like Raindrop */
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
sans-serif !important;
}
/* Dark mode sidebar text */
.dark #nd-sidebar a,
.dark #nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) {
color: rgba(255, 255, 255, 0.6) !important;
}
/* Light mode sidebar text */
:root:not(.dark) #nd-sidebar a,
:root:not(.dark) #nd-sidebar button:not([aria-label*="ollapse"]):not([aria-label*="xpand"]) {
color: rgba(0, 0, 0, 0.6) !important;
}
/* Make sure chevron icons are visible and properly styled */
#nd-sidebar svg {
display: inline-block !important;
opacity: 0.6 !important;
flex-shrink: 0 !important;
width: 0.75rem !important;
height: 0.75rem !important;
}
/* Ensure the small chevron toggle buttons are visible */
#nd-sidebar button[aria-label*="ollapse"],
#nd-sidebar button[aria-label*="xpand"] {
display: flex !important;
opacity: 1 !important;
padding: 0.25rem !important;
}
/* Root-level spacing now handled by [data-sidebar-viewport] > * rule below */
/* Add tiny gap between nested items */
#nd-sidebar ul li {
margin-bottom: 0.0625rem !important;
}
#nd-sidebar ul li:last-child {
margin-bottom: 0 !important;
}
/* Section headers should be slightly larger */
[data-sidebar-viewport] [data-separator] {
font-size: 0.75rem !important;
font-weight: 600 !important;
text-transform: uppercase !important;
letter-spacing: 0.05em !important;
}
/* Override active state (NO PURPLE) */
#nd-sidebar a[data-active="true"],
#nd-sidebar button[data-active="true"],
#nd-sidebar a.bg-fd-primary\/10,
#nd-sidebar a.text-fd-primary,
#nd-sidebar a[class*="bg-fd-primary"],
#nd-sidebar a[class*="text-fd-primary"],
/* Override custom sidebar purple classes */
#nd-sidebar
a.bg-purple-50\/80,
#nd-sidebar a.text-purple-600,
#nd-sidebar a[class*="bg-purple"],
#nd-sidebar a[class*="text-purple"] {
background-image: none !important;
}
/* Dark mode active state */
.dark #nd-sidebar a[data-active="true"],
.dark #nd-sidebar button[data-active="true"],
.dark #nd-sidebar a.bg-fd-primary\/10,
.dark #nd-sidebar a.text-fd-primary,
.dark #nd-sidebar a[class*="bg-fd-primary"],
.dark #nd-sidebar a[class*="text-fd-primary"],
.dark #nd-sidebar a.bg-purple-50\/80,
.dark #nd-sidebar a.text-purple-600,
.dark #nd-sidebar a[class*="bg-purple"],
.dark #nd-sidebar a[class*="text-purple"] {
background-color: rgba(255, 255, 255, 0.15) !important;
color: rgba(255, 255, 255, 1) !important;
}
/* Light mode active state */
:root:not(.dark) #nd-sidebar a[data-active="true"],
:root:not(.dark) #nd-sidebar button[data-active="true"],
:root:not(.dark) #nd-sidebar a.bg-fd-primary\/10,
:root:not(.dark) #nd-sidebar a.text-fd-primary,
:root:not(.dark) #nd-sidebar a[class*="bg-fd-primary"],
:root:not(.dark) #nd-sidebar a[class*="text-fd-primary"],
:root:not(.dark) #nd-sidebar a.bg-purple-50\/80,
:root:not(.dark) #nd-sidebar a.text-purple-600,
:root:not(.dark) #nd-sidebar a[class*="bg-purple"],
:root:not(.dark) #nd-sidebar a[class*="text-purple"] {
background-color: rgba(0, 0, 0, 0.1) !important;
color: rgba(0, 0, 0, 1) !important;
}
/* Dark mode hover state */
.dark #nd-sidebar a:hover:not([data-active="true"]),
.dark #nd-sidebar button:hover:not([data-active="true"]) {
background-color: rgba(255, 255, 255, 0.08) !important;
}
/* Light mode hover state */
:root:not(.dark) #nd-sidebar a:hover:not([data-active="true"]),
:root:not(.dark) #nd-sidebar button:hover:not([data-active="true"]) {
background-color: rgba(0, 0, 0, 0.06) !important;
}
/* Dark mode - ensure active/selected items don't change on hover */
.dark #nd-sidebar a.bg-purple-50\/80:hover,
.dark #nd-sidebar a[class*="bg-purple"]:hover,
.dark #nd-sidebar a[data-active="true"]:hover,
.dark #nd-sidebar button[data-active="true"]:hover {
background-color: rgba(255, 255, 255, 0.15) !important;
color: rgba(255, 255, 255, 1) !important;
}
/* Light mode - ensure active/selected items don't change on hover */
:root:not(.dark) #nd-sidebar a.bg-purple-50\/80:hover,
:root:not(.dark) #nd-sidebar a[class*="bg-purple"]:hover,
:root:not(.dark) #nd-sidebar a[data-active="true"]:hover,
:root:not(.dark) #nd-sidebar button[data-active="true"]:hover {
background-color: rgba(0, 0, 0, 0.1) !important;
color: rgba(0, 0, 0, 1) !important;
}
/* Hide search, platform, and collapse button from sidebar completely */
[data-sidebar] [data-search],
[data-sidebar] .search-toggle,
#nd-sidebar [data-search],
#nd-sidebar .search-toggle,
[data-sidebar-viewport] [data-search],
[data-sidebar-viewport] button[data-search],
aside[data-sidebar] [role="button"]:has([data-search]),
aside[data-sidebar] > div > button:first-child,
#nd-sidebar > div > button:first-child,
[data-sidebar] a[href*="sim.ai"],
#nd-sidebar a[href*="sim.ai"],
[data-sidebar-viewport] a[href*="sim.ai"],
/* Hide search buttons (but NOT folder chevron buttons) */
aside[data-sidebar] > div:first-child
> button:not([aria-label="Collapse"]):not([aria-label="Expand"]),
#nd-sidebar > div:first-child > button:not([aria-label="Collapse"]):not([aria-label="Expand"]),
/* Hide sidebar collapse button (panel icon) - direct children only */
aside[data-sidebar] > button:first-of-type:not([aria-label="Collapse"]):not([aria-label="Expand"]),
[data-sidebar]
> button[type="button"]:first-of-type:not([aria-label="Collapse"]):not([aria-label="Expand"]),
button[data-collapse]:not([aria-label="Collapse"]):not([aria-label="Expand"]),
[data-sidebar-header] button,
/* Hide theme toggle from sidebar footer */
aside[data-sidebar] [data-theme-toggle],
[data-sidebar-footer],
[data-sidebar] footer,
footer button[aria-label*="heme"],
aside[data-sidebar] > div:last-child:has(button[aria-label*="heme"]),
aside[data-sidebar] button[aria-label*="heme"],
[data-sidebar] button[aria-label*="Theme"],
/* Additional theme toggle selectors */
aside[data-sidebar] > *:last-child
button,
[data-sidebar-viewport] ~ *,
aside[data-sidebar] > div:not([data-sidebar-viewport]),
/* Aggressive theme toggle hiding */
aside[data-sidebar] svg[class*="sun"],
aside[data-sidebar] svg[class*="moon"],
aside[data-sidebar] button[type="button"]:last-child,
aside button:has(svg:only-child),
[data-sidebar] div:has(> button[type="button"]:only-child:last-child),
/* Hide theme toggle and other non-content elements */
aside[data-sidebar] > *:not([data-sidebar-viewport]) {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
height: 0 !important;
max-height: 0 !important;
overflow: hidden !important;
pointer-events: none !important;
position: absolute !important;
left: -9999px !important;
}
/* Desktop only: Hide sidebar toggle buttons and nav title/logo (keep visible on mobile) */
@media (min-width: 1025px) {
[data-sidebar-container] > button,
[data-sidebar-container] [data-toggle],
aside[data-sidebar] [data-sidebar-toggle],
button[data-sidebar-toggle],
nav button[data-sidebar-toggle],
button[aria-label="Toggle Sidebar"],
button[aria-label="Collapse Sidebar"],
/* Hide nav title/logo in sidebar on desktop - target all possible locations */
aside[data-sidebar] a[href="/"],
aside[data-sidebar] a[href="/"] img,
aside[data-sidebar] > a:first-child,
aside[data-sidebar] > div > a:first-child,
aside[data-sidebar] img[alt="Sim"],
[data-sidebar-header],
[data-sidebar] [data-title],
#nd-sidebar > a:first-child,
#nd-sidebar > div:first-child > a:first-child,
#nd-sidebar img[alt="Sim"] {
display: none !important;
visibility: hidden !important;
height: 0 !important;
max-height: 0 !important;
overflow: hidden !important;
}
}
/* Extra aggressive - hide everything after the viewport */
aside[data-sidebar] [data-sidebar-viewport] ~ * {
display: none !important;
}
/* Tighter spacing for sidebar content */
[data-sidebar-viewport] > * {
margin-bottom: 0.0625rem;
}
[data-sidebar-viewport] > *:last-child {
margin-bottom: 0;
}
[data-sidebar-viewport] ul {
margin: 0;
padding: 0;
}
/* Ensure sidebar starts with content immediately */
aside[data-sidebar] > div:first-child {
padding-top: 0;
}
/* Remove all sidebar borders and backgrounds */
[data-sidebar-container],
aside[data-sidebar],
[data-sidebar],
[data-sidebar] *,
#nd-sidebar,
#nd-sidebar * {
border: none !important;
border-right: none !important;
border-left: none !important;
border-top: none !important;
border-bottom: none !important;
}
/* Override fumadocs background colors for sidebar */
.dark #nd-sidebar,
.dark [data-sidebar-container],
.dark aside[data-sidebar] {
--color-fd-muted: transparent !important;
--color-fd-secondary: transparent !important;
background: transparent !important;
background-color: transparent !important;
}
/* Force normal text flow in sidebar */
[data-sidebar],
[data-sidebar] *,
[data-sidebar-viewport],
[data-sidebar-viewport] * {
writing-mode: horizontal-tb !important;
}
/* ============================================
Code Block Styling (Improved)
============================================ */
/* Apply Geist Mono to code elements */
code,
pre,
pre code {
font-family: var(--font-geist-mono), ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
"Liberation Mono", "Courier New", monospace;
}
/* Inline code */
:not(pre) > code {
padding: 0.2em 0.4em;
border-radius: 0.25rem;
font-size: 0.875em;
font-weight: 500;
}
/* Light mode inline code */
:root:not(.dark) :not(pre) > code {
background-color: rgb(243 244 246);
color: rgb(220 38 38);
border: 1px solid rgb(229 231 235);
}
/* Dark mode inline code */
.dark :not(pre) > code {
background-color: rgb(31 41 55);
color: rgb(248 113 113);
border: 1px solid rgb(55 65 81);
}
/* Code block container improvements */
pre {
font-size: 0.875rem;
line-height: 1.7;
tab-size: 2;
-webkit-overflow-scrolling: touch;
}
pre code {
display: block;
color: rgb(71 85 105);
text-decoration: none;
width: fit-content;
min-width: 100%;
}
[data-sidebar] a[data-active="true"] {
background-color: rgba(128, 47, 255, 0.08);
color: var(--color-fd-primary);
font-weight: 500;
}
[data-sidebar] a:hover:not([data-active="true"]) {
background-color: rgb(248 250 252);
color: rgb(51 65 85);
}
/* Improve spacing between sidebar items */
[data-sidebar] nav > * + * {
margin-top: 2px;
}
/* Section group styling */
[data-sidebar] [data-folder] {
margin-bottom: 4px;
}
[data-sidebar] [data-folder] > div:first-child {
font-weight: 500;
font-size: 13px;
color: rgb(15 23 42);
padding: 6px 12px;
margin-bottom: 4px;
}
/* Clean up folder toggle buttons */
[data-sidebar] button[data-folder-toggle] {
padding: 4px 8px 4px 12px;
border-radius: 6px;
font-size: 13px;
font-weight: 500;
color: rgb(51 65 85);
}
[data-sidebar] button[data-folder-toggle]:hover {
background-color: rgb(248 250 252);
}
/* Nested item indentation */
[data-sidebar] [data-folder] a {
padding-left: 24px;
font-size: 14px;
}
/* Dark mode adjustments */
@media (prefers-color-scheme: dark) {
[data-sidebar] {
background-color: rgb(2 8 23);
}
[data-sidebar] a {
color: rgb(148 163 184);
}
[data-sidebar] a:hover:not([data-active="true"]) {
background-color: rgb(30 41 59);
color: rgb(226 232 240);
}
[data-sidebar] a[data-active="true"] {
background-color: rgba(128, 47, 255, 0.15);
color: var(--color-fd-primary);
}
[data-sidebar] .text-sm.font-medium.text-muted-foreground,
[data-sidebar] [data-separator] {
color: rgb(148 163 184);
}
[data-sidebar] [data-folder] > div:first-child {
color: rgb(226 232 240);
}
[data-sidebar] button[data-folder-toggle] {
color: rgb(148 163 184);
}
[data-sidebar] button[data-folder-toggle]:hover {
background-color: rgb(30 41 59);
}
/* Syntax highlighting adjustments for better readability */
pre code .line {
padding-left: 0;
padding-right: 0;
}
/* Custom text highlighting styles */
@@ -162,15 +477,54 @@
/* Add bottom spacing to prevent abrupt page endings */
[data-content] {
padding-top: 1.5rem !important;
padding-bottom: 4rem;
}
/* Alternative fallback for different Fumadocs versions */
main article,
.docs-page main {
padding-top: 1.5rem !important;
padding-bottom: 4rem;
}
/* ============================================
Center and Constrain Main Content Width
============================================ */
/* Main content area - center and constrain like turborepo/raindrop */
main[data-main] {
max-width: var(--spacing-fd-container, 1400px);
margin-left: auto;
margin-right: auto;
padding-top: 1rem;
padding-left: calc(var(--sidebar-offset) + var(--content-gap));
padding-right: calc(var(--toc-offset) + var(--content-gap));
order: 1 !important;
}
/* Adjust for smaller screens */
@media (max-width: 768px) {
main[data-main] {
padding-left: 1rem;
padding-right: 1rem;
}
}
/* Ensure docs page content is properly constrained */
[data-docs-page] {
max-width: 1400px;
margin-left: auto;
margin-right: auto;
padding-top: 1.5rem !important;
}
/* Override Fumadocs default content padding */
article[data-content],
div[data-content] {
padding-top: 1.5rem !important;
}
/* Remove any unwanted borders/outlines from video elements */
video {
outline: none !important;

View File

@@ -22,9 +22,15 @@ export const metadata = {
'drag and drop workflows',
'AI integrations',
'workflow canvas',
'AI development platform',
'AI Agent Workflow Builder',
'workflow orchestration',
'agent builder',
'AI workflow automation',
'visual programming',
],
authors: [{ name: 'Sim Team', url: 'https://sim.ai' }],
creator: 'Sim',
publisher: 'Sim',
category: 'Developer Tools',
classification: 'Developer Documentation',
manifest: '/favicon/site.webmanifest',
@@ -44,7 +50,7 @@ export const metadata = {
openGraph: {
type: 'website',
locale: 'en_US',
alternateLocale: ['fr_FR', 'zh_CN'],
alternateLocale: ['es_ES', 'fr_FR', 'de_DE', 'ja_JP', 'zh_CN'],
url: 'https://docs.sim.ai',
siteName: 'Sim Documentation',
title: 'Sim Documentation - Visual Workflow Builder for AI Applications',
@@ -52,11 +58,13 @@ export const metadata = {
'Comprehensive documentation for Sim - the visual workflow builder for AI applications. Create powerful AI agents, automation workflows, and data processing pipelines.',
},
twitter: {
card: 'summary',
card: 'summary_large_image',
title: 'Sim Documentation - Visual Workflow Builder for AI Applications',
description:
'Comprehensive documentation for Sim - the visual workflow builder for AI applications.',
creator: '@sim_ai',
creator: '@simdotai',
site: '@simdotai',
images: ['/og-image.png'],
},
robots: {
index: true,
@@ -72,9 +80,13 @@ export const metadata = {
alternates: {
canonical: 'https://docs.sim.ai',
languages: {
en: '/en',
fr: '/fr',
zh: '/zh',
'x-default': 'https://docs.sim.ai',
en: 'https://docs.sim.ai',
es: 'https://docs.sim.ai/es',
fr: 'https://docs.sim.ai/fr',
de: 'https://docs.sim.ai/de',
ja: 'https://docs.sim.ai/ja',
zh: 'https://docs.sim.ai/zh',
},
},
}

View File

@@ -0,0 +1,31 @@
import { getLLMText } from '@/lib/llms'
import { source } from '@/lib/source'
export const revalidate = false
export async function GET() {
try {
const pages = source.getPages().filter((page) => {
if (!page || !page.data || !page.url) return false
const pathParts = page.url.split('/').filter(Boolean)
const hasLangPrefix = pathParts[0] && ['es', 'fr', 'de', 'ja', 'zh'].includes(pathParts[0])
return !hasLangPrefix
})
const scan = pages.map((page) => getLLMText(page))
const scanned = await Promise.all(scan)
const filtered = scanned.filter((text) => text && text.length > 0)
return new Response(filtered.join('\n\n---\n\n'), {
headers: {
'Content-Type': 'text/plain; charset=utf-8',
},
})
} catch (error) {
console.error('Error generating LLM full text:', error)
return new Response('Error generating full documentation text', { status: 500 })
}
}

View File

@@ -1,11 +1,87 @@
import { getLLMText } from '@/lib/llms'
import { source } from '@/lib/source'
export const revalidate = false
export async function GET() {
const scan = source.getPages().map(getLLMText)
const scanned = await Promise.all(scan)
const baseUrl = 'https://docs.sim.ai'
return new Response(scanned.join('\n\n'))
try {
const pages = source.getPages().filter((page) => {
if (!page || !page.data || !page.url) return false
const pathParts = page.url.split('/').filter(Boolean)
const hasLangPrefix = pathParts[0] && ['es', 'fr', 'de', 'ja', 'zh'].includes(pathParts[0])
return !hasLangPrefix
})
const sections: Record<string, Array<{ title: string; url: string; description?: string }>> = {}
pages.forEach((page) => {
const pathParts = page.url.split('/').filter(Boolean)
const section =
pathParts[0] && ['en', 'es', 'fr', 'de', 'ja', 'zh'].includes(pathParts[0])
? pathParts[1] || 'root'
: pathParts[0] || 'root'
if (!sections[section]) {
sections[section] = []
}
sections[section].push({
title: page.data.title || 'Untitled',
url: `${baseUrl}${page.url}`,
description: page.data.description,
})
})
const manifest = `# Sim Documentation
> Visual Workflow Builder for AI Applications
Sim is a visual workflow builder for AI applications that lets you build AI agent workflows visually. Create powerful AI agents, automation workflows, and data processing pipelines by connecting blocks on a canvas—no coding required.
## Documentation Overview
This file provides an overview of our documentation. For full content of all pages, see ${baseUrl}/llms-full.txt
## Main Sections
${Object.entries(sections)
.map(([section, items]) => {
const sectionTitle = section
.split('-')
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ')
return `### ${sectionTitle}\n\n${items.map((item) => `- ${item.title}: ${item.url}${item.description ? `\n ${item.description}` : ''}`).join('\n')}`
})
.join('\n\n')}
## Additional Resources
- Full documentation content: ${baseUrl}/llms-full.txt
- Individual page content: ${baseUrl}/llms.mdx/[page-path]
- API documentation: ${baseUrl}/sdks/
- Tool integrations: ${baseUrl}/tools/
## Statistics
- Total pages: ${pages.length} (English only)
- Other languages available at: ${baseUrl}/[lang]/ (es, fr, de, ja, zh)
---
Generated: ${new Date().toISOString()}
Format: llms.txt v0.1.0
See: https://llmstxt.org for specification`
return new Response(manifest, {
headers: {
'Content-Type': 'text/plain; charset=utf-8',
},
})
} catch (error) {
console.error('Error generating LLM manifest:', error)
return new Response('Error generating documentation manifest', { status: 500 })
}
}

View File

@@ -9,14 +9,26 @@ export async function GET() {
User-agent: *
Allow: /
# Allow all well-behaved crawlers
# Search engine crawlers
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
# AI and LLM crawlers
User-agent: Slurp
Allow: /
User-agent: DuckDuckBot
Allow: /
User-agent: Baiduspider
Allow: /
User-agent: YandexBot
Allow: /
# AI and LLM crawlers - explicitly allowed for documentation indexing
User-agent: GPTBot
Allow: /
@@ -32,6 +44,21 @@ Allow: /
User-agent: Claude-Web
Allow: /
User-agent: Applebot
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: Diffbot
Allow: /
User-agent: FacebookBot
Allow: /
User-agent: cohere-ai
Allow: /
# Disallow admin and internal paths (if any exist)
Disallow: /.next/
Disallow: /api/internal/
@@ -41,14 +68,29 @@ Disallow: /admin/
# Allow but don't prioritize these
Allow: /api/search
Allow: /llms.txt
Allow: /llms-full.txt
Allow: /llms.mdx/
# Sitemaps
Sitemap: ${baseUrl}/sitemap.xml
# Crawl delay for aggressive bots (optional)
# Crawl-delay: 1
# Additional resources for AI indexing
# See https://github.com/AnswerDotAI/llms-txt for more info
# LLM-friendly content available at: ${baseUrl}/llms.txt`
# LLM-friendly content:
# Manifest: ${baseUrl}/llms.txt
# Full content: ${baseUrl}/llms-full.txt
# Individual pages: ${baseUrl}/llms.mdx/[page-path]
# Multi-language documentation available at:
# ${baseUrl}/en - English
# ${baseUrl}/es - Español
# ${baseUrl}/fr - Français
# ${baseUrl}/de - Deutsch
# ${baseUrl}/ja - 日本語
# ${baseUrl}/zh - 简体中文`
return new Response(robotsTxt, {
headers: {

View File

@@ -8,6 +8,14 @@ export async function GET() {
const allPages = source.getPages()
const getPriority = (url: string): string => {
if (url === '/introduction' || url === '/') return '1.0'
if (url === '/getting-started') return '0.9'
if (url.match(/^\/[^/]+$/)) return '0.8'
if (url.includes('/sdks/') || url.includes('/tools/')) return '0.7'
return '0.6'
}
const urls = allPages
.flatMap((page) => {
const urlWithoutLang = page.url.replace(/^\/[a-z]{2}\//, '/')
@@ -22,7 +30,7 @@ export async function GET() {
<loc>${url}</loc>
<lastmod>${new Date().toISOString().split('T')[0]}</lastmod>
<changefreq>weekly</changefreq>
<priority>${urlWithoutLang === '/introduction' ? '1.0' : '0.8'}</priority>
<priority>${getPriority(urlWithoutLang)}</priority>
${i18n.languages.length > 1 ? generateAlternateLinks(baseUrl, urlWithoutLang) : ''}
</url>`
})
@@ -37,6 +45,7 @@ ${urls}
return new Response(sitemap, {
headers: {
'Content-Type': 'application/xml',
'Cache-Control': 'public, max-age=3600, s-maxage=3600',
},
})
}

View File

@@ -0,0 +1,134 @@
'use client'
import { type ReactNode, useState } from 'react'
import type { PageTree } from 'fumadocs-core/server'
import { ChevronRight } from 'lucide-react'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { cn } from '@/lib/utils'
function isActive(url: string, pathname: string, nested = true): boolean {
return url === pathname || (nested && pathname.startsWith(`${url}/`))
}
export function SidebarItem({ item }: { item: PageTree.Item }) {
const pathname = usePathname()
const active = isActive(item.url, pathname, false)
return (
<li className='mb-[0.0625rem] list-none'>
<Link
href={item.url}
className={cn(
'block rounded-md px-2.5 py-1.5 font-normal text-[13px] leading-tight transition-colors',
'text-gray-600 dark:text-gray-400',
!active && 'hover:bg-gray-100/60 dark:hover:bg-gray-800/40',
active &&
'bg-purple-50/80 font-medium text-purple-600 dark:bg-purple-900/15 dark:text-purple-400'
)}
>
{item.name}
</Link>
</li>
)
}
export function SidebarFolder({
item,
level,
children,
}: {
item: PageTree.Folder
level: number
children: ReactNode
}) {
const pathname = usePathname()
const hasActiveChild = checkHasActiveChild(item, pathname)
const [open, setOpen] = useState(hasActiveChild)
return (
<li className='mb-[0.0625rem] list-none'>
{item.index ? (
<div className='flex items-center gap-0.5'>
<Link
href={item.index.url}
className={cn(
'block flex-1 rounded-md px-2.5 py-1.5 font-medium text-[13px] leading-tight transition-colors',
'text-gray-800 dark:text-gray-200',
!isActive(item.index.url, pathname, false) &&
'hover:bg-gray-100/60 dark:hover:bg-gray-800/40',
isActive(item.index.url, pathname, false) &&
'bg-purple-50/80 text-purple-600 dark:bg-purple-900/15 dark:text-purple-400'
)}
>
{item.name}
</Link>
<button
onClick={() => setOpen(!open)}
className='rounded p-1 transition-colors hover:bg-gray-100/60 dark:hover:bg-gray-800/40'
aria-label={open ? 'Collapse' : 'Expand'}
>
<ChevronRight
className={cn(
'h-3 w-3 text-gray-400 transition-transform duration-200 ease-in-out dark:text-gray-500',
open && 'rotate-90'
)}
/>
</button>
</div>
) : (
<button
onClick={() => setOpen(!open)}
className={cn(
'flex w-full items-center justify-between rounded-md px-2.5 py-1.5 text-left font-medium text-[13px] leading-tight transition-colors',
'hover:bg-gray-100/60 dark:hover:bg-gray-800/40',
'text-gray-800 dark:text-gray-200'
)}
>
<span>{item.name}</span>
<ChevronRight
className={cn(
'ml-auto h-3 w-3 flex-shrink-0 text-gray-400 transition-transform duration-200 ease-in-out dark:text-gray-500',
open && 'rotate-90'
)}
/>
</button>
)}
<div
className={cn(
'overflow-hidden transition-all duration-200 ease-in-out',
open ? 'max-h-[10000px] opacity-100' : 'max-h-0 opacity-0'
)}
>
<ul className='mt-0.5 ml-2 space-y-[0.0625rem] border-gray-200/60 border-l pl-2.5 dark:border-gray-700/60'>
{children}
</ul>
</div>
</li>
)
}
export function SidebarSeparator({ item }: { item: PageTree.Separator }) {
return (
<p className='mt-4 mb-1.5 px-2.5 font-semibold text-[10px] text-gray-500/80 uppercase tracking-wide dark:text-gray-500'>
{item.name}
</p>
)
}
function checkHasActiveChild(node: PageTree.Folder, pathname: string): boolean {
if (node.index && isActive(node.index.url, pathname)) {
return true
}
for (const child of node.children) {
if (child.type === 'page' && isActive(child.url, pathname)) {
return true
}
if (child.type === 'folder' && checkHasActiveChild(child, pathname)) {
return true
}
}
return false
}

View File

@@ -0,0 +1,67 @@
'use client'
import Image from 'next/image'
import Link from 'next/link'
import { LanguageDropdown } from '@/components/ui/language-dropdown'
import { SearchTrigger } from '@/components/ui/search-trigger'
import { ThemeToggle } from '@/components/ui/theme-toggle'
export function Navbar() {
return (
<nav
className='sticky top-0 z-50 border-border/50 border-b'
style={{
backgroundColor: 'hsla(0, 0%, 7.04%, 0.92)',
backdropFilter: 'blur(25px) saturate(180%) brightness(0.6)',
WebkitBackdropFilter: 'blur(25px) saturate(180%) brightness(0.6)',
}}
>
{/* Desktop: Single row layout */}
<div className='hidden h-16 w-full items-center lg:flex'>
<div
className='relative flex w-full items-center justify-between'
style={{
paddingLeft: 'calc(var(--sidebar-offset) + 20px)',
paddingRight: 'calc(var(--toc-offset) + 60px)',
}}
>
{/* Left cluster: logo */}
<div className='flex items-center'>
<Link href='/' className='flex min-w-[100px] items-center'>
<Image
src='/static/logo.png'
alt='Sim'
width={72}
height={28}
className='h-7 w-auto'
/>
</Link>
</div>
{/* Center cluster: search - absolutely positioned to center */}
<div className='-translate-x-1/2 absolute left-1/2 flex items-center justify-center'>
<SearchTrigger />
</div>
{/* Right cluster aligns with TOC edge */}
<div className='flex items-center gap-4'>
<Link
href='https://sim.ai'
target='_blank'
rel='noopener noreferrer'
className='rounded-xl px-3 py-2 font-normal text-[0.9375rem] text-foreground/60 leading-[1.4] transition-colors hover:bg-foreground/8 hover:text-foreground'
style={{
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
}}
>
Platform
</Link>
<LanguageDropdown />
<ThemeToggle />
</div>
</div>
</div>
</nav>
)
}

View File

@@ -88,7 +88,7 @@ export function StructuredData({
},
'query-input': 'required name=search_term_string',
},
inLanguage: ['en', 'fr', 'zh'],
inLanguage: ['en', 'es', 'fr', 'de', 'ja', 'zh'],
}
const faqStructuredData = title.toLowerCase().includes('faq') && {

View File

@@ -0,0 +1,50 @@
'use client'
import { useState } from 'react'
import { CodeBlock as FumadocsCodeBlock } from 'fumadocs-ui/components/codeblock'
import { Check, Copy } from 'lucide-react'
import { cn } from '@/lib/utils'
export function CodeBlock(props: React.ComponentProps<typeof FumadocsCodeBlock>) {
const [copied, setCopied] = useState(false)
const handleCopy = async (text: string) => {
await navigator.clipboard.writeText(text)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
}
return (
<FumadocsCodeBlock
{...props}
Actions={({ children, className }) => (
<div className={cn('empty:hidden', className)}>
{/* Custom copy button */}
<button
type='button'
aria-label={copied ? 'Copied Text' : 'Copy Text'}
onClick={(e) => {
const pre = (e.currentTarget as HTMLElement)
.closest('.nd-codeblock')
?.querySelector('pre')
if (pre) handleCopy(pre.textContent || '')
}}
className={cn(
'rounded-md p-2 transition-all',
'border border-border bg-background/80 hover:bg-muted',
'backdrop-blur-sm'
)}
>
<span className='flex items-center justify-center'>
{copied ? (
<Check size={16} className='text-green-600 dark:text-green-400' />
) : (
<Copy size={16} className='text-muted-foreground' />
)}
</span>
</button>
</div>
)}
/>
)
}

View File

@@ -0,0 +1,42 @@
'use client'
import { useState } from 'react'
import { Check, Copy } from 'lucide-react'
interface CopyPageButtonProps {
content: string
}
export function CopyPageButton({ content }: CopyPageButtonProps) {
const [copied, setCopied] = useState(false)
const handleCopy = async () => {
try {
await navigator.clipboard.writeText(content)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch (err) {
console.error('Failed to copy:', err)
}
}
return (
<button
onClick={handleCopy}
className='flex items-center gap-1.5 rounded-lg border border-border/40 bg-background px-2.5 py-1.5 text-muted-foreground/60 text-sm transition-all hover:border-border hover:bg-accent/50 hover:text-muted-foreground'
aria-label={copied ? 'Copied to clipboard' : 'Copy page content'}
>
{copied ? (
<>
<Check className='h-4 w-4' />
<span>Copied</span>
</>
) : (
<>
<Copy className='h-4 w-4' />
<span>Copy page</span>
</>
)}
</button>
)
}

View File

@@ -1,7 +1,7 @@
'use client'
import { useEffect, useState } from 'react'
import { Check, ChevronDown } from 'lucide-react'
import { Check, ChevronRight } from 'lucide-react'
import { useParams, usePathname, useRouter } from 'next/navigation'
const languages = {
@@ -82,15 +82,14 @@ export function LanguageDropdown() {
aria-haspopup='listbox'
aria-expanded={isOpen}
aria-controls='language-menu'
className='flex items-center gap-1.5 rounded-lg border border-border/30 bg-muted/40 px-2.5 py-1.5 text-sm shadow-sm backdrop-blur-sm transition-colors hover:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-ring'
className='flex items-center gap-1.5 rounded-xl px-3 py-2 font-normal text-[0.9375rem] text-foreground/60 leading-[1.4] transition-colors hover:bg-foreground/8 hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring'
style={{
fontFamily:
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
}}
>
<span className='text-sm'>{languages[currentLang as keyof typeof languages]?.flag}</span>
<span className='font-medium text-foreground'>
{languages[currentLang as keyof typeof languages]?.name}
</span>
<ChevronDown
className={`h-3 w-3 text-muted-foreground transition-transform ${isOpen ? 'rotate-180' : ''}`}
/>
<span>{languages[currentLang as keyof typeof languages]?.name}</span>
<ChevronRight className='h-3.5 w-3.5' />
</button>
{isOpen && (
@@ -99,7 +98,7 @@ export function LanguageDropdown() {
<div
id='language-menu'
role='listbox'
className='absolute top-full left-0 z-[1001] mt-1 max-h-[75vh] w-56 overflow-auto rounded-xl border border-border/50 bg-white shadow-2xl md:w-44 md:bg-background/95 md:backdrop-blur-md dark:bg-neutral-950 md:dark:bg-background/95'
className='absolute top-full right-0 z-[1001] mt-1 max-h-[75vh] w-56 overflow-auto rounded-xl border border-border/50 bg-white shadow-2xl md:w-44 md:bg-background/95 md:backdrop-blur-md dark:bg-neutral-950 md:dark:bg-background/95'
>
{Object.entries(languages).map(([code, lang]) => (
<button

View File

@@ -0,0 +1,38 @@
'use client'
import { Search } from 'lucide-react'
export function SearchTrigger() {
const handleClick = () => {
const event = new KeyboardEvent('keydown', {
key: 'k',
metaKey: true,
bubbles: true,
})
document.dispatchEvent(event)
}
return (
<button
type='button'
className='flex h-10 w-[460px] items-center gap-2 rounded-xl border border-border/50 px-3 py-2 text-sm backdrop-blur-xl transition-colors hover:border-border'
style={{
backgroundColor: 'hsla(0, 0%, 5%, 0.85)',
backdropFilter: 'blur(33px) saturate(180%)',
WebkitBackdropFilter: 'blur(33px) saturate(180%)',
color: 'rgba(255, 255, 255, 0.6)',
}}
onClick={handleClick}
>
<Search className='h-4 w-4' />
<span>Search...</span>
<kbd
className='ml-auto flex items-center gap-0.5 font-medium'
style={{ color: 'rgba(255, 255, 255, 0.6)' }}
>
<span style={{ fontSize: '15px', lineHeight: '1' }}></span>
<span style={{ fontSize: '13px', lineHeight: '1' }}>K</span>
</kbd>
</button>
)
}

View File

@@ -0,0 +1,32 @@
'use client'
import { useEffect, useState } from 'react'
import { Moon, Sun } from 'lucide-react'
import { useTheme } from 'next-themes'
export function ThemeToggle() {
const { theme, setTheme } = useTheme()
const [mounted, setMounted] = useState(false)
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return (
<button className='flex items-center justify-center rounded-md p-1 text-muted-foreground'>
<Moon className='h-4 w-4' />
</button>
)
}
return (
<button
onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
className='flex items-center justify-center rounded-md p-1 text-muted-foreground transition-colors hover:text-foreground'
aria-label='Toggle theme'
>
{theme === 'dark' ? <Moon className='h-4 w-4' /> : <Sun className='h-4 w-4' />}
</button>
)
}

View File

@@ -8,7 +8,7 @@ import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
import { Image } from '@/components/ui/image'
import { Video } from '@/components/ui/video'
The Guardrails block validates and protects your AI workflows by checking content against multiple validation types. Ensure data quality, prevent hallucinations, detect PII, and enforce format requirements before content moves through your workflow.
Der Guardrails-Block validiert und schützt Ihre KI-Workflows, indem er Inhalte anhand mehrerer Validierungstypen überprüft. Stellen Sie die Datenqualität sicher, verhindern Sie Halluzinationen, erkennen Sie personenbezogene Daten und erzwingen Sie Formatanforderungen, bevor Inhalte durch Ihren Workflow fließen.
<div className="flex justify-center">
<Image
@@ -20,201 +20,201 @@ The Guardrails block validates and protects your AI workflows by checking conten
/>
</div>
## Overview
## Übersicht
The Guardrails block enables you to:
Mit dem Guardrails-Block können Sie:
<Steps>
<Step>
<strong>Validate JSON Structure</strong>: Ensure LLM outputs are valid JSON before parsing
<strong>JSON-Struktur validieren</strong>: Stellen Sie sicher, dass LLM-Ausgaben gültiges JSON sind, bevor sie geparst werden
</Step>
<Step>
<strong>Match Regex Patterns</strong>: Verify content matches specific formats (emails, phone numbers, URLs, etc.)
<strong>Regex-Muster abgleichen</strong>: Überprüfen Sie, ob Inhalte bestimmten Formaten entsprechen (E-Mails, Telefonnummern, URLs usw.)
</Step>
<Step>
<strong>Detect Hallucinations</strong>: Use RAG + LLM scoring to validate AI outputs against knowledge base content
<strong>Halluzinationen erkennen</strong>: Nutzen Sie RAG + LLM-Scoring, um KI-Ausgaben anhand von Wissensdatenbankinhalten zu validieren
</Step>
<Step>
<strong>Detect PII</strong>: Identify and optionally mask personally identifiable information across 40+ entity types
<strong>PII erkennen</strong>: Identifizieren und optional maskieren Sie personenbezogene Daten über mehr als 40 Entitätstypen hinweg
</Step>
</Steps>
## Validation Types
## Validierungstypen
### JSON Validation
### JSON-Validierung
Validates that content is properly formatted JSON. Perfect for ensuring structured LLM outputs can be safely parsed.
Überprüft, ob Inhalte korrekt formatiertes JSON sind. Perfekt, um sicherzustellen, dass strukturierte LLM-Ausgaben sicher geparst werden können.
**Use Cases:**
- Validate JSON responses from Agent blocks before parsing
- Ensure API payloads are properly formatted
- Check structured data integrity
**Anwendungsfälle:**
- Validieren von JSON-Antworten aus Agent-Blöcken vor dem Parsen
- Sicherstellen, dass API-Payloads korrekt formatiert sind
- Überprüfen der Integrität strukturierter Daten
**Output:**
- `passed`: `true` if valid JSON, `false` otherwise
- `error`: Error message if validation fails (e.g., "Invalid JSON: Unexpected token...")
- `passed`: `true` wenn gültiges JSON, sonst `false`
- `error`: Fehlermeldung bei fehlgeschlagener Validierung (z.B. "Invalid JSON: Unexpected token...")
### Regex Validation
### Regex-Validierung
Checks if content matches a specified regular expression pattern.
Überprüft, ob Inhalte einem bestimmten regulären Ausdrucksmuster entsprechen.
**Use Cases:**
- Validate email addresses
- Check phone number formats
- Verify URLs or custom identifiers
- Enforce specific text patterns
**Anwendungsfälle:**
- Validieren von E-Mail-Adressen
- Überprüfen von Telefonnummernformaten
- Verifizieren von URLs oder benutzerdefinierten Kennungen
- Durchsetzen spezifischer Textmuster
**Configuration:**
- **Regex Pattern**: The regular expression to match against (e.g., `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` for emails)
**Konfiguration:**
- **Regex-Muster**: Der reguläre Ausdruck, der abgeglichen werden soll (z.B. `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` für E-Mails)
**Output:**
- `passed`: `true` if content matches pattern, `false` otherwise
- `error`: Error message if validation fails
- `passed`: `true` wenn der Inhalt dem Muster entspricht, `false` andernfalls
- `error`: Fehlermeldung bei fehlgeschlagener Validierung
### Hallucination Detection
### Halluzinationserkennung
Uses Retrieval-Augmented Generation (RAG) with LLM scoring to detect when AI-generated content contradicts or isn't grounded in your knowledge base.
Verwendet Retrieval-Augmented Generation (RAG) mit LLM-Bewertung, um zu erkennen, wann KI-generierte Inhalte im Widerspruch zu Ihrer Wissensdatenbank stehen oder nicht darin begründet sind.
**How It Works:**
1. Queries your knowledge base for relevant context
2. Sends both the AI output and retrieved context to an LLM
3. LLM assigns a confidence score (0-10 scale)
- **0** = Full hallucination (completely ungrounded)
- **10** = Fully grounded (completely supported by knowledge base)
4. Validation passes if score ≥ threshold (default: 3)
**Funktionsweise:**
1. Durchsucht Ihre Wissensdatenbank nach relevantem Kontext
2. Sendet sowohl die KI-Ausgabe als auch den abgerufenen Kontext an ein LLM
3. LLM weist einen Konfidenzwert zu (Skala 0-10)
- **0** = Vollständige Halluzination (völlig unbegründet)
- **10** = Vollständig fundiert (komplett durch Wissensdatenbank gestützt)
4. Validierung besteht, wenn der Wert ≥ Schwellenwert (Standard: 3)
**Configuration:**
- **Knowledge Base**: Select from your existing knowledge bases
- **Model**: Choose LLM for scoring (requires strong reasoning - GPT-4o, Claude 3.7 Sonnet recommended)
- **API Key**: Authentication for selected LLM provider (auto-hidden for hosted/Ollama models)
- **Confidence Threshold**: Minimum score to pass (0-10, default: 3)
- **Top K** (Advanced): Number of knowledge base chunks to retrieve (default: 10)
**Konfiguration:**
- **Wissensdatenbank**: Auswahl aus Ihren vorhandenen Wissensdatenbanken
- **Modell**: LLM für die Bewertung wählen (erfordert starkes Reasoning - GPT-4o, Claude 3.7 Sonnet empfohlen)
- **API-Schlüssel**: Authentifizierung für den ausgewählten LLM-Anbieter (automatisch ausgeblendet für gehostete/Ollama-Modelle)
- **Konfidenz-Schwellenwert**: Mindestwert zum Bestehen (0-10, Standard: 3)
- **Top K** (Erweitert): Anzahl der abzurufenden Wissensdatenbank-Chunks (Standard: 10)
**Output:**
- `passed`: `true` if confidence score ≥ threshold
- `score`: Confidence score (0-10)
- `reasoning`: LLM's explanation for the score
- `error`: Error message if validation fails
- `passed`: `true` wenn Konfidenzwert ≥ Schwellenwert
- `score`: Konfidenzwert (0-10)
- `reasoning`: Erklärung des LLM für den Wert
- `error`: Fehlermeldung bei fehlgeschlagener Validierung
**Use Cases:**
- Validate Agent responses against documentation
- Ensure customer support answers are factually accurate
- Verify generated content matches source material
- Quality control for RAG applications
**Anwendungsfälle:**
- Validierung von Agent-Antworten anhand der Dokumentation
- Sicherstellen, dass Kundenservice-Antworten sachlich korrekt sind
- Überprüfen, ob generierte Inhalte mit dem Quellmaterial übereinstimmen
- Qualitätskontrolle für RAG-Anwendungen
### PII Detection
### PII-Erkennung
Detects personally identifiable information using Microsoft Presidio. Supports 40+ entity types across multiple countries and languages.
Erkennt personenbezogene Daten mit Microsoft Presidio. Unterstützt über 40 Entitätstypen in mehreren Ländern und Sprachen.
<div className="mx-auto w-3/5 overflow-hidden rounded-lg">
<Video src="guardrails.mp4" width={500} height={350} />
</div>
**How It Works:**
1. Scans content for PII entities using pattern matching and NLP
2. Returns detected entities with locations and confidence scores
3. Optionally masks detected PII in the output
**Funktionsweise:**
1. Scannt Inhalte nach PII-Entitäten mittels Mustererkennung und NLP
2. Gibt erkannte Entitäten mit Positionen und Konfidenzwerten zurück
3. Maskiert optional erkannte PII in der Ausgabe
**Configuration:**
- **PII Types to Detect**: Select from grouped categories via modal selector
- **Common**: Person name, Email, Phone, Credit card, IP address, etc.
- **USA**: SSN, Driver's license, Passport, etc.
- **UK**: NHS number, National insurance number
- **Spain**: NIF, NIE, CIF
- **Italy**: Fiscal code, Driver's license, VAT code
- **Poland**: PESEL, NIP, REGON
- **Singapore**: NRIC/FIN, UEN
- **Australia**: ABN, ACN, TFN, Medicare
- **India**: Aadhaar, PAN, Passport, Voter number
- **Mode**:
- **Detect**: Only identify PII (default)
- **Mask**: Replace detected PII with masked values
- **Language**: Detection language (default: English)
**Konfiguration:**
- **Zu erkennende PII-Typen**: Auswahl aus gruppierten Kategorien über Modal-Selektor
- **Allgemein**: Personenname, E-Mail, Telefon, Kreditkarte, IP-Adresse usw.
- **USA**: SSN, Führerschein, Reisepass usw.
- **UK**: NHS-Nummer, Sozialversicherungsnummer
- **Spanien**: NIF, NIE, CIF
- **Italien**: Steuernummer, Führerschein, Umsatzsteuer-ID
- **Polen**: PESEL, NIP, REGON
- **Singapur**: NRIC/FIN, UEN
- **Australien**: ABN, ACN, TFN, Medicare
- **Indien**: Aadhaar, PAN, Reisepass, Wählernummer
- **Modus**:
- **Erkennen**: Nur PII identifizieren (Standard)
- **Maskieren**: Erkannte PII durch maskierte Werte ersetzen
- **Sprache**: Erkennungssprache (Standard: Englisch)
**Output:**
- `passed`: `false` if any selected PII types are detected
- `detectedEntities`: Array of detected PII with type, location, and confidence
- `maskedText`: Content with PII masked (only if mode = "Mask")
- `error`: Error message if validation fails
**Ausgabe:**
- `passed`: `false` wenn ausgewählte PII-Typen erkannt werden
- `detectedEntities`: Array erkannter PII mit Typ, Position und Konfidenz
- `maskedText`: Inhalt mit maskierter PII (nur wenn Modus = "Mask")
- `error`: Fehlermeldung, wenn die Validierung fehlschlägt
**Use Cases:**
- Block content containing sensitive personal information
- Mask PII before logging or storing data
- Compliance with GDPR, HIPAA, and other privacy regulations
- Sanitize user inputs before processing
**Anwendungsfälle:**
- Blockieren von Inhalten mit sensiblen persönlichen Informationen
- Maskieren von PII vor der Protokollierung oder Speicherung von Daten
- Einhaltung von DSGVO, HIPAA und anderen Datenschutzbestimmungen
- Bereinigung von Benutzereingaben vor der Verarbeitung
## Configuration
## Konfiguration
### Content to Validate
### Zu validierender Inhalt
The input content to validate. This typically comes from:
- Agent block outputs: `<agent.content>`
- Function block results: `<function.output>`
- API responses: `<api.output>`
- Any other block output
Der zu validierende Eingabeinhalt. Dieser stammt typischerweise aus:
- Ausgaben von Agent-Blöcken: `<agent.content>`
- Ergebnisse von Funktionsblöcken: `<function.output>`
- API-Antworten: `<api.output>`
- Jede andere Blockausgabe
### Validation Type
### Validierungstyp
Choose from four validation types:
- **Valid JSON**: Check if content is properly formatted JSON
- **Regex Match**: Verify content matches a regex pattern
- **Hallucination Check**: Validate against knowledge base with LLM scoring
- **PII Detection**: Detect and optionally mask personally identifiable information
Wählen Sie aus vier Validierungstypen:
- **Gültiges JSON**: Prüfen, ob der Inhalt korrekt formatiertes JSON ist
- **Regex-Übereinstimmung**: Überprüfen, ob der Inhalt einem Regex-Muster entspricht
- **Halluzinationsprüfung**: Validierung gegen Wissensdatenbank mit LLM-Bewertung
- **PII-Erkennung**: Erkennung und optional Maskierung personenbezogener Daten
## Outputs
## Ausgaben
All validation types return:
Alle Validierungstypen liefern zurück:
- **`<guardrails.passed>`**: Boolean indicating if validation passed
- **`<guardrails.validationType>`**: The type of validation performed
- **`<guardrails.input>`**: The original input that was validated
- **`<guardrails.error>`**: Error message if validation failed (optional)
- **`<guardrails.passed>`**: Boolean, der angibt, ob die Validierung erfolgreich war
- **`<guardrails.validationType>`**: Die Art der durchgeführten Validierung
- **`<guardrails.input>`**: Die ursprüngliche Eingabe, die validiert wurde
- **`<guardrails.error>`**: Fehlermeldung, wenn die Validierung fehlgeschlagen ist (optional)
Additional outputs by type:
Zusätzliche Ausgaben nach Typ:
**Hallucination Check:**
- **`<guardrails.score>`**: Confidence score (0-10)
- **`<guardrails.reasoning>`**: LLM's explanation
**Halluzinationsprüfung:**
- **`<guardrails.score>`**: Konfidenzwert (0-10)
- **`<guardrails.reasoning>`**: Erklärung des LLM
**PII Detection:**
- **`<guardrails.detectedEntities>`**: Array of detected PII entities
- **`<guardrails.maskedText>`**: Content with PII masked (if mode = "Mask")
**PII-Erkennung:**
- **`<guardrails.detectedEntities>`**: Array erkannter PII-Entitäten
- **`<guardrails.maskedText>`**: Inhalt mit maskierter PII (wenn Modus = "Mask")
## Example Use Cases
## Beispielanwendungsfälle
### Validate JSON Before Parsing
### JSON vor dem Parsen validieren
<div className="mb-4 rounded-md border p-4">
<h4 className="font-medium">Scenario: Ensure Agent output is valid JSON</h4>
<h4 className="font-medium">Szenario: Sicherstellen, dass die Agent-Ausgabe gültiges JSON ist</h4>
<ol className="list-decimal pl-5 text-sm">
<li>Agent generates structured JSON response</li>
<li>Guardrails validates JSON format</li>
<li>Condition block checks `<guardrails.passed>`</li>
<li>If passed → Parse and use data, If failedRetry or handle error</li>
<li>Agent generiert strukturierte JSON-Antwort</li>
<li>Guardrails validiert das JSON-Format</li>
<li>Bedingungsblock prüft `<guardrails.passed>`</li>
<li>Bei Erfolg → Daten parsen und verwenden, Bei FehlerWiederholen oder Fehler behandeln</li>
</ol>
</div>
### Prevent Hallucinations
### Halluzinationen verhindern
<div className="mb-4 rounded-md border p-4">
<h4 className="font-medium">Scenario: Validate customer support responses</h4>
<h4 className="font-medium">Szenario: Validierung von Kundendienstantworten</h4>
<ol className="list-decimal pl-5 text-sm">
<li>Agent generates response to customer question</li>
<li>Guardrails checks against support documentation knowledge base</li>
<li>If confidence score ≥ 3 → Send response</li>
<li>If confidence score \< 3 → Flag for human review</li>
<li>Agent generiert Antwort auf Kundenfrage</li>
<li>Guardrails prüft gegen die Wissensdatenbank der Support-Dokumentation</li>
<li>Wenn Konfidenzwert ≥ 3 → Antwort senden</li>
<li>Wenn Konfidenzwert \< 3 → Für manuelle Überprüfung markieren</li>
</ol>
</div>
### Block PII in User Inputs
### PII in Benutzereingaben blockieren
<div className="mb-4 rounded-md border p-4">
<h4 className="font-medium">Scenario: Sanitize user-submitted content</h4>
<h4 className="font-medium">Szenario: Bereinigung von benutzergenerierten Inhalten</h4>
<ol className="list-decimal pl-5 text-sm">
<li>User submits form with text content</li>
<li>Guardrails detects PII (emails, phone numbers, SSN, etc.)</li>
<li>If PII detected → Reject submission or mask sensitive data</li>
<li>If no PII → Process normally</li>
<li>Benutzer reicht Formular mit Textinhalt ein</li>
<li>Guardrails erkennt PII (E-Mails, Telefonnummern, Sozialversicherungsnummern usw.)</li>
<li>Bei erkannter PII → Einreichung ablehnen oder sensible Daten maskieren</li>
<li>Ohne PII → Normal verarbeiten</li>
</ol>
</div>
@@ -222,30 +222,29 @@ Additional outputs by type:
<Video src="guardrails-example.mp4" width={500} height={350} />
</div>
### Validate Email Format
### E-Mail-Format validieren
<div className="mb-4 rounded-md border p-4">
<h4 className="font-medium">Scenario: Check email address format</h4>
<h4 className="font-medium">Szenario: E-Mail-Adressformat überprüfen</h4>
<ol className="list-decimal pl-5 text-sm">
<li>Agent extracts email from text</li>
<li>Guardrails validates with regex pattern</li>
<li>If valid → Use email for notification</li>
<li>If invalid → Request correction</li>
<li>Agent extrahiert E-Mail aus Text</li>
<li>Guardrails validiert mit Regex-Muster</li>
<li>Bei Gültigkeit → E-Mail für Benachrichtigung verwenden</li>
<li>Bei Ungültigkeit → Korrektur anfordern</li>
</ol>
</div>
## Best Practices
- **Chain with Condition blocks**: Use `<guardrails.passed>` to branch workflow logic based on validation results
- **Use JSON validation before parsing**: Always validate JSON structure before attempting to parse LLM outputs
- **Choose appropriate PII types**: Only select the PII entity types relevant to your use case for better performance
- **Set reasonable confidence thresholds**: For hallucination detection, adjust threshold based on your accuracy requirements (higher = stricter)
- **Use strong models for hallucination detection**: GPT-4o or Claude 3.7 Sonnet provide more accurate confidence scoring
- **Mask PII for logging**: Use "Mask" mode when you need to log or store content that may contain PII
- **Test regex patterns**: Validate your regex patterns thoroughly before deploying to production
- **Monitor validation failures**: Track `<guardrails.error>` messages to identify common validation issues
- **Verkettung mit Condition-Blöcken**: Verwende `<guardrails.passed>` um Workflow-Logik basierend auf Validierungsergebnissen zu verzweigen
- **JSON-Validierung vor dem Parsen verwenden**: Validiere immer die JSON-Struktur, bevor du versuchst, LLM-Ausgaben zu parsen
- **Passende PII-Typen auswählen**: Wähle nur die PII-Entitätstypen aus, die für deinen Anwendungsfall relevant sind, um bessere Leistung zu erzielen
- **Vernünftige Konfidenz-Schwellenwerte festlegen**: Passe für die Halluzinationserkennung den Schwellenwert basierend auf deinen Genauigkeitsanforderungen an (höher = strenger)
- **Starke Modelle für Halluzinationserkennung verwenden**: GPT-4o oder Claude 3.7 Sonnet bieten genauere Konfidenz-Bewertungen
- **PII für Logging maskieren**: Verwende den "Mask"-Modus, wenn du Inhalte protokollieren oder speichern musst, die PII enthalten könnten
- **Regex-Muster testen**: Validiere deine Regex-Muster gründlich, bevor du sie in der Produktion einsetzt
- **Validierungsfehler überwachen**: Verfolge `<guardrails.error>` Nachrichten, um häufige Validierungsprobleme zu identifizieren
<Callout type="info">
Guardrails validation happens synchronously in your workflow. For hallucination detection, choose faster models (like GPT-4o-mini) if latency is critical.
Guardrails-Validierung erfolgt synchron in deinem Workflow. Für die Halluzinationserkennung solltest du schnellere Modelle (wie GPT-4o-mini) wählen, wenn Latenz kritisch ist.
</Callout>

View File

@@ -1,5 +1,5 @@
---
title: Blöcke
title: Übersicht
description: Die Bausteine deiner KI-Workflows
---

View File

@@ -1,5 +1,5 @@
---
title: Verbindungsgrundlagen
title: Grundlagen
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Verbindungsdatenstruktur
title: Datenstruktur
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Verbindungen
title: Übersicht
description: Verbinde deine Blöcke miteinander.
---

View File

@@ -1,5 +1,5 @@
---
title: Verbindungs-Tags
title: Tags
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -535,7 +535,7 @@ app.post('/sim-webhook', (req, res) => {
// Handle error...
} else {
console.log(`Workflow ${workflowId} completed: ${executionId}`);
console.log(`Cost: ${cost.total}`);
console.log(`Cost: $${cost.total}`);
// Process successful execution...
}
break;

View File

@@ -1,5 +1,5 @@
---
title: Ausführungsgrundlagen
title: Grundlagen
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Ausführung
title: Übersicht
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Python SDK
title: Python
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -748,10 +748,6 @@ Konfiguriere den Client mit Umgebungsvariablen:
</Step>
</Steps>
<Callout type="warning">
Halte deinen API-Schlüssel sicher und committe ihn niemals in die Versionskontrolle. Verwende Umgebungsvariablen oder sicheres Konfigurationsmanagement.
</Callout>
## Anforderungen
- Python 3.8+

View File

@@ -1,5 +1,5 @@
---
title: TypeScript/JavaScript SDK
title: TypeScript
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -81,7 +81,7 @@ new SimStudioClient(config: SimStudioConfig)
##### executeWorkflow()
Führen Sie einen Workflow mit optionalen Eingabedaten aus.
Führt einen Workflow mit optionalen Eingabedaten aus.
```typescript
const result = await client.executeWorkflow('workflow-id', {
@@ -99,7 +99,7 @@ const result = await client.executeWorkflow('workflow-id', {
- `selectedOutputs` (string[]): Block-Ausgaben, die im `blockName.attribute`Format gestreamt werden sollen (z.B. `["agent1.content"]`)
- `async` (boolean): Asynchron ausführen (Standard: false)
**Rückgabe:** `Promise<WorkflowExecutionResult | AsyncExecutionResult>`
**Rückgabewert:** `Promise<WorkflowExecutionResult | AsyncExecutionResult>`
Wenn `async: true`, wird sofort mit einer Task-ID zum Abfragen zurückgegeben. Andernfalls wird auf den Abschluss gewartet.
@@ -115,7 +115,7 @@ console.log('Is deployed:', status.isDeployed);
**Parameter:**
- `workflowId` (string): Die ID des Workflows
**Rückgabe:** `Promise<WorkflowStatus>`
**Rückgabewert:** `Promise<WorkflowStatus>`
##### validateWorkflow()
@@ -131,7 +131,7 @@ if (isReady) {
**Parameter:**
- `workflowId` (string): Die ID des Workflows
**Rückgabe:** `Promise<boolean>`
**Rückgabewert:** `Promise<boolean>`
##### getJobStatus()
@@ -148,7 +148,7 @@ if (status.status === 'completed') {
**Parameter:**
- `taskId` (string): Die Task-ID, die von der asynchronen Ausführung zurückgegeben wurde
**Rückgabe:** `Promise<JobStatus>`
**Rückgabewert:** `Promise<JobStatus>`
**Antwortfelder:**
- `success` (boolean): Ob die Anfrage erfolgreich war
@@ -161,7 +161,7 @@ if (status.status === 'completed') {
##### executeWithRetry()
Führt einen Workflow mit automatischer Wiederholung bei Ratenlimitfehlern unter Verwendung von exponentiellem Backoff aus.
Einen Workflow mit automatischer Wiederholung bei Rate-Limit-Fehlern unter Verwendung von exponentiellem Backoff ausführen.
```typescript
const result = await client.executeWithRetry('workflow-id', {
@@ -184,13 +184,13 @@ const result = await client.executeWithRetry('workflow-id', {
- `maxDelay` (number): Maximale Verzögerung in ms (Standard: 30000)
- `backoffMultiplier` (number): Backoff-Multiplikator (Standard: 2)
**Rückgabewert:** `Promise<WorkflowExecutionResult | AsyncExecutionResult>`
**Rückgabe:** `Promise<WorkflowExecutionResult | AsyncExecutionResult>`
Die Wiederholungslogik verwendet exponentiellen Backoff (1s → 2s → 4s → 8s...) mit ±25% Jitter, um den Thundering-Herd-Effekt zu vermeiden. Wenn die API einen `retry-after`Header bereitstellt, wird dieser stattdessen verwendet.
Die Wiederholungslogik verwendet exponentielles Backoff (1s → 2s → 4s → 8s...) mit ±25% Jitter, um den Thundering-Herd-Effekt zu vermeiden. Wenn die API einen `retry-after` Header bereitstellt, wird dieser stattdessen verwendet.
##### getRateLimitInfo()
Ruft die aktuellen Ratenlimit-Informationen aus der letzten API-Antwort ab.
Ruft die aktuellen Rate-Limit-Informationen aus der letzten API-Antwort ab.
```typescript
const rateLimitInfo = client.getRateLimitInfo();
@@ -201,7 +201,7 @@ if (rateLimitInfo) {
}
```
**Rückgabewert:** `RateLimitInfo | null`
**Rückgabe:** `RateLimitInfo | null`
##### getUsageLimits()
@@ -215,7 +215,7 @@ console.log('Current period cost:', limits.usage.currentPeriodCost);
console.log('Plan:', limits.usage.plan);
```
**Rückgabewert:** `Promise<UsageLimits>`
**Rückgabe:** `Promise<UsageLimits>`
**Antwortstruktur:**
@@ -357,8 +357,8 @@ class SimStudioError extends Error {
**Häufige Fehlercodes:**
- `UNAUTHORIZED`: Ungültiger API-Schlüssel
- `TIMEOUT`: Zeitüberschreitung der Anfrage
- `RATE_LIMIT_EXCEEDED`: Ratengrenze überschritten
- `USAGE_LIMIT_EXCEEDED`: Nutzungsgrenze überschritten
- `RATE_LIMIT_EXCEEDED`: Rate-Limit überschritten
- `USAGE_LIMIT_EXCEEDED`: Nutzungslimit überschritten
- `EXECUTION_ERROR`: Workflow-Ausführung fehlgeschlagen
## Beispiele
@@ -604,26 +604,105 @@ async function executeClientSideWorkflow() {
});
console.log('Workflow result:', result);
// Update UI with result
document.getElementById('result')!.textContent =
document.getElementById('result')!.textContent =
JSON.stringify(result.output, null, 2);
} catch (error) {
console.error('Error:', error);
}
}
// Attach to button click
document.getElementById('executeBtn')?.addEventListener('click', executeClientSideWorkflow);
```
### Datei-Upload
Datei-Objekte werden automatisch erkannt und in das Base64-Format konvertiert. Fügen Sie sie in Ihrem Input unter dem Feldnamen ein, der dem API-Trigger-Inputformat Ihres Workflows entspricht.
Das SDK konvertiert Datei-Objekte in dieses Format:
```typescript
{
type: 'file',
data: 'data:mime/type;base64,base64data',
name: 'filename',
mime: 'mime/type'
}
```
Alternativ können Sie Dateien manuell im URL-Format bereitstellen:
```typescript
{
type: 'url',
data: 'https://example.com/file.pdf',
name: 'file.pdf',
mime: 'application/pdf'
}
```
<Tabs items={['Browser', 'Node.js']}>
<Tab value="Browser">
```typescript
import { SimStudioClient } from 'simstudio-ts-sdk';
const client = new SimStudioClient({
apiKey: process.env.NEXT_PUBLIC_SIM_API_KEY!
});
// From file input
async function handleFileUpload(event: Event) {
const input = event.target as HTMLInputElement;
const files = Array.from(input.files || []);
// Include files under the field name from your API trigger's input format
const result = await client.executeWorkflow('workflow-id', {
input: {
documents: files, // Must match your workflow's "files" field name
instructions: 'Analyze these documents'
}
});
console.log('Result:', result);
}
```
</Tab>
<Tab value="Node.js">
```typescript
import { SimStudioClient } from 'simstudio-ts-sdk';
import fs from 'fs';
const client = new SimStudioClient({
apiKey: process.env.SIM_API_KEY!
});
// Read file and create File object
const fileBuffer = fs.readFileSync('./document.pdf');
const file = new File([fileBuffer], 'document.pdf', {
type: 'application/pdf'
});
// Include files under the field name from your API trigger's input format
const result = await client.executeWorkflow('workflow-id', {
input: {
documents: [file], // Must match your workflow's "files" field name
query: 'Summarize this document'
}
});
```
</Tab>
</Tabs>
<Callout type="warning">
Bei der Verwendung des SDK im Browser sollten Sie darauf achten, keine sensiblen API-Schlüssel offenzulegen. Erwägen Sie die Verwendung eines Backend-Proxys oder öffentlicher API-Schlüssel mit eingeschränkten Berechtigungen.
</Callout>
### React Hook-Beispiel
### React Hook Beispiel
Erstellen eines benutzerdefinierten React-Hooks für die Workflow-Ausführung:
Erstellen Sie einen benutzerdefinierten React-Hook für die Workflow-Ausführung:
```typescript
import { useState, useCallback } from 'react';
@@ -815,11 +894,27 @@ async function checkUsage() {
console.log(' Is limited:', limits.rateLimit.async.isLimited);
console.log('\n=== Usage ===');
console.log('Current period cost:
console.log('Current period cost: $' + limits.usage.currentPeriodCost.toFixed(2));
console.log('Limit: $' + limits.usage.limit.toFixed(2));
console.log('Plan:', limits.usage.plan);
### Streaming Workflow Execution
const percentUsed = (limits.usage.currentPeriodCost / limits.usage.limit) * 100;
console.log('Usage: ' + percentUsed.toFixed(1) + '%');
Execute workflows with real-time streaming responses:
if (percentUsed > 80) {
console.warn('⚠️ Warning: You are approaching your usage limit!');
}
} catch (error) {
console.error('Error checking usage:', error);
}
}
checkUsage();
```
### Streaming-Workflow-Ausführung
Führen Sie Workflows mit Echtzeit-Streaming-Antworten aus:
```typescript
import { SimStudioClient } from 'simstudio-ts-sdk';
@@ -830,33 +925,33 @@ const client = new SimStudioClient({
async function executeWithStreaming() {
try {
// Streaming für bestimmte Block-Ausgaben aktivieren
// Enable streaming for specific block outputs
const result = await client.executeWorkflow('workflow-id', {
input: { message: 'Count to five' },
stream: true,
selectedOutputs: ['agent1.content'] // Format blockName.attribute verwenden
selectedOutputs: ['agent1.content'] // Use blockName.attribute format
});
console.log('Workflow-Ergebnis:', result);
console.log('Workflow result:', result);
} catch (error) {
console.error('Fehler:', error);
console.error('Error:', error);
}
}
```
The streaming response follows the Server-Sent Events (SSE) format:
Die Streaming-Antwort folgt dem Server-Sent Events (SSE) Format:
```
data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"}
data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", zwei"}
data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", two"}
data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}}
data: [DONE]
```
**React Streaming Example:**
**React Streaming Beispiel:**
```typescript
import { useState, useEffect } from 'react';
@@ -869,13 +964,13 @@ function StreamingWorkflow() {
setLoading(true);
setOutput('');
// WICHTIG: Führen Sie diesen API-Aufruf von Ihrem Backend-Server aus, nicht vom Browser
// Setzen Sie niemals Ihren API-Schlüssel im Client-seitigen Code frei
// IMPORTANT: Make this API call from your backend server, not the browser
// Never expose your API key in client-side code
const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.SIM_API_KEY! // Nur serverseitige Umgebungsvariable
'X-API-Key': process.env.SIM_API_KEY! // Server-side environment variable only
},
body: JSON.stringify({
message: 'Generate a story',
@@ -907,10 +1002,10 @@ function StreamingWorkflow() {
if (parsed.chunk) {
setOutput(prev => prev + parsed.chunk);
} else if (parsed.event === 'done') {
console.log('Ausführung abgeschlossen:', parsed.metadata);
console.log('Execution complete:', parsed.metadata);
}
} catch (e) {
// Ungültiges JSON überspringen
// Skip invalid JSON
}
}
}
@@ -920,7 +1015,7 @@ function StreamingWorkflow() {
return (
<div>
<button onClick={executeStreaming} disabled={loading}>
{loading ? 'Generiere...' : 'Streaming starten'}
{loading ? 'Generating...' : 'Start Streaming'}
</button>
<div style={{ whiteSpace: 'pre-wrap' }}>{output}</div>
</div>
@@ -928,35 +1023,31 @@ function StreamingWorkflow() {
}
```
## Getting Your API Key
## API-Schlüssel erhalten
<Steps>
<Step title="Log in to Sim">
Navigate to [Sim](https://sim.ai) and log in to your account.
<Step title="Bei Sim anmelden">
Navigieren Sie zu [Sim](https://sim.ai) und melden Sie sich bei Ihrem Konto an.
</Step>
<Step title="Open your workflow">
Navigate to the workflow you want to execute programmatically.
<Step title="Öffnen Sie Ihren Workflow">
Navigieren Sie zu dem Workflow, den Sie programmatisch ausführen möchten.
</Step>
<Step title="Deploy your workflow">
Click on "Deploy" to deploy your workflow if it hasn't been deployed yet.
<Step title="Deployen Sie Ihren Workflow">
Klicken Sie auf "Deploy", um Ihren Workflow zu deployen, falls dies noch nicht geschehen ist.
</Step>
<Step title="Create or select an API key">
During the deployment process, select or create an API key.
<Step title="API-Schlüssel erstellen oder auswählen">
Wählen Sie während des Deployment-Prozesses einen API-Schlüssel aus oder erstellen Sie einen neuen.
</Step>
<Step title="Copy the API key">
Copy the API key to use in your TypeScript/JavaScript application.
<Step title="API-Schlüssel kopieren">
Kopieren Sie den API-Schlüssel zur Verwendung in Ihrer TypeScript/JavaScript-Anwendung.
</Step>
</Steps>
<Callout type="warning">
Keep your API key secure and never commit it to version control. Use environment variables or secure configuration management.
</Callout>
## Requirements
## Anforderungen
- Node.js 16+
- TypeScript 5.0+ (for TypeScript projects)
- TypeScript 5.0+ (für TypeScript-Projekte)
## License
## Lizenz
Apache-2.0

View File

@@ -207,18 +207,18 @@ Populate Clay with data from a JSON file. Enables direct communication and notif
#### Input
| Parameter | Type | Required | Description |
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `webhookURL` | string | Yes | The webhook URL to populate |
| `data` | json | Yes | The data to populate |
| `authToken` | string | Yes | Auth token for Clay webhook authentication |
| `webhookURL` | string | Ja | Die Webhook-URL, die befüllt werden soll |
| `data` | json | Ja | Die Daten, die befüllt werden sollen |
| `authToken` | string | Nein | Optionaler Auth-Token für die Clay-Webhook-Authentifizierung \(die meisten Webhooks benötigen dies nicht\) |
#### Output
| Parameter | Type | Description |
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Clay populate operation results including response data from Clay webhook |
| `data` | json | Antwortdaten vom Clay-Webhook |
| `metadata` | object | Webhook-Antwort-Metadaten |
## Notes

View File

@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="discord"
color="#E0E0E0"
color="#5865F2"
icon={true}
iconSvg={`<svg className="block-icon"
@@ -72,6 +72,7 @@ Eine Nachricht an einen Discord-Kanal senden
| `channelId` | string | Ja | Die Discord-Kanal-ID, an die die Nachricht gesendet werden soll |
| `content` | string | Nein | Der Textinhalt der Nachricht |
| `serverId` | string | Ja | Die Discord-Server-ID \(Guild-ID\) |
| `files` | file[] | Nein | Dateien, die an die Nachricht angehängt werden sollen |
#### Ausgabe

View File

@@ -23,7 +23,210 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
</svg>`}
/>
## Übersicht
Der Generic Webhook-Block ermöglicht es Ihnen, Webhooks von jedem externen Dienst zu empfangen. Dies ist ein flexibler Auslöser, der jede JSON-Nutzlast verarbeiten kann und sich daher ideal für die Integration mit Diensten eignet, die keinen dedizierten Sim-Block haben.
## Grundlegende Verwendung
### Einfacher Durchleitungsmodus
Ohne ein Eingabeformat zu definieren, leitet der Webhook den gesamten Anforderungstext unverändert weiter:
```bash
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret" \
-d '{
"message": "Test webhook trigger",
"data": {
"key": "value"
}
}'
```
Greifen Sie in nachgelagerten Blöcken auf die Daten zu mit:
- `<webhook1.message>` → "Test webhook trigger"
- `<webhook1.data.key>` → "value"
### Strukturiertes Eingabeformat (Optional)
Definieren Sie ein Eingabeschema, um typisierte Felder zu erhalten und erweiterte Funktionen wie Datei-Uploads zu aktivieren:
**Konfiguration des Eingabeformats:**
```json
[
{ "name": "message", "type": "string" },
{ "name": "priority", "type": "number" },
{ "name": "documents", "type": "files" }
]
```
**Webhook-Anfrage:**
```bash
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret" \
-d '{
"message": "Invoice submission",
"priority": 1,
"documents": [
{
"type": "file",
"data": "data:application/pdf;base64,JVBERi0xLjQK...",
"name": "invoice.pdf",
"mime": "application/pdf"
}
]
}'
```
## Datei-Uploads
### Unterstützte Dateiformate
Der Webhook unterstützt zwei Dateieingabeformate:
#### 1. Base64-kodierte Dateien
Zum direkten Hochladen von Dateiinhalten:
```json
{
"documents": [
{
"type": "file",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA...",
"name": "screenshot.png",
"mime": "image/png"
}
]
}
```
- **Maximale Größe**: 20MB pro Datei
- **Format**: Standard-Daten-URL mit Base64-Kodierung
- **Speicherung**: Dateien werden in sicheren Ausführungsspeicher hochgeladen
#### 2. URL-Referenzen
Zum Übergeben vorhandener Datei-URLs:
```json
{
"documents": [
{
"type": "url",
"data": "https://example.com/files/document.pdf",
"name": "document.pdf",
"mime": "application/pdf"
}
]
}
```
### Zugriff auf Dateien in nachgelagerten Blöcken
Dateien werden in `UserFile`Objekte mit folgenden Eigenschaften verarbeitet:
```typescript
{
id: string, // Unique file identifier
name: string, // Original filename
url: string, // Presigned URL (valid for 5 minutes)
size: number, // File size in bytes
type: string, // MIME type
key: string, // Storage key
uploadedAt: string, // ISO timestamp
expiresAt: string // ISO timestamp (5 minutes)
}
```
**Zugriff in Blöcken:**
- `<webhook1.documents[0].url>` → Download-URL
- `<webhook1.documents[0].name>` → "invoice.pdf"
- `<webhook1.documents[0].size>` → 524288
- `<webhook1.documents[0].type>` → "application/pdf"
### Vollständiges Beispiel für Datei-Upload
```bash
# Create a base64-encoded file
echo "Hello World" | base64
# SGVsbG8gV29ybGQK
# Send webhook with file
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret" \
-d '{
"subject": "Document for review",
"attachments": [
{
"type": "file",
"data": "data:text/plain;base64,SGVsbG8gV29ybGQK",
"name": "sample.txt",
"mime": "text/plain"
}
]
}'
```
## Authentifizierung
### Authentifizierung konfigurieren (optional)
In der Webhook-Konfiguration:
1. Aktiviere "Authentifizierung erforderlich"
2. Setze einen geheimen Token
3. Wähle den Header-Typ:
- **Benutzerdefinierter Header**: `X-Sim-Secret: your-token`
- **Authorization Bearer**: `Authorization: Bearer your-token`
### Verwendung der Authentifizierung
```bash
# With custom header
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret-token" \
-d '{"message": "Authenticated request"}'
# With bearer token
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-secret-token" \
-d '{"message": "Authenticated request"}'
```
## Best Practices
1. **Eingabeformat für Struktur verwenden**: Definiere ein Eingabeformat, wenn du das erwartete Schema kennst. Dies bietet:
- Typvalidierung
- Bessere Autovervollständigung im Editor
- Datei-Upload-Funktionen
2. **Authentifizierung**: Aktiviere immer die Authentifizierung für Produktions-Webhooks, um unbefugten Zugriff zu verhindern.
3. **Dateigrößenbeschränkungen**: Halte Dateien unter 20 MB. Verwende für größere Dateien stattdessen URL-Referenzen.
4. **Dateiablauf**: Heruntergeladene Dateien haben URLs mit einer Gültigkeit von 5 Minuten. Verarbeite sie umgehend oder speichere sie an anderer Stelle, wenn sie länger benötigt werden.
5. **Fehlerbehandlung**: Die Webhook-Verarbeitung erfolgt asynchron. Überprüfe die Ausführungsprotokolle auf Fehler.
6. **Testen**: Verwende die Schaltfläche "Webhook testen" im Editor, um deine Konfiguration vor der Bereitstellung zu validieren.
## Anwendungsfälle
- **Formularübermittlungen**: Empfange Daten von benutzerdefinierten Formularen mit Datei-Uploads
- **Drittanbieter-Integrationen**: Verbinde mit Diensten, die Webhooks senden (Stripe, GitHub usw.)
- **Dokumentenverarbeitung**: Akzeptiere Dokumente von externen Systemen zur Verarbeitung
- **Ereignisbenachrichtigungen**: Empfange Ereignisdaten aus verschiedenen Quellen
- **Benutzerdefinierte APIs**: Erstelle benutzerdefinierte API-Endpunkte für deine Anwendungen
## Hinweise
- Kategorie: `triggers`
- Typ: `generic_webhook`
- **Dateiunterstützung**: Verfügbar über Eingabeformat-Konfiguration
- **Maximale Dateigröße**: 20 MB pro Datei

View File

@@ -65,8 +65,9 @@ E-Mails über Gmail versenden
| `to` | string | Ja | E-Mail-Adresse des Empfängers |
| `subject` | string | Ja | Betreff der E-Mail |
| `body` | string | Ja | Inhalt der E-Mail |
| `cc` | string | Nein | CC-Empfänger \(durch Komma getrennt\) |
| `bcc` | string | Nein | BCC-Empfänger \(durch Komma getrennt\) |
| `cc` | string | Nein | CC-Empfänger (durch Komma getrennt) |
| `bcc` | string | Nein | BCC-Empfänger (durch Komma getrennt) |
| `attachments` | file[] | Nein | Dateien, die an die E-Mail angehängt werden sollen |
#### Ausgabe
@@ -86,8 +87,9 @@ E-Mail-Entwürfe in Gmail erstellen
| `to` | string | Ja | E-Mail-Adresse des Empfängers |
| `subject` | string | Ja | Betreff der E-Mail |
| `body` | string | Ja | Inhalt der E-Mail |
| `cc` | string | Nein | CC-Empfänger \(durch Komma getrennt\) |
| `bcc` | string | Nein | BCC-Empfänger \(durch Komma getrennt\) |
| `cc` | string | Nein | CC-Empfänger (durch Komma getrennt) |
| `bcc` | string | Nein | BCC-Empfänger (durch Komma getrennt) |
| `attachments` | file[] | Nein | Dateien, die an den E-Mail-Entwurf angehängt werden sollen |
#### Ausgabe

View File

@@ -85,10 +85,11 @@ Eine Datei zu Google Drive hochladen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `fileName` | string | Ja | Der Name der hochzuladenden Datei |
| `content` | string | Ja | Der Inhalt der hochzuladenden Datei |
| `mimeType` | string | Nein | Der MIME-Typ der hochzuladenden Datei |
| `file` | file | Nein | Binärdatei zum Hochladen (UserFile-Objekt) |
| `content` | string | Nein | Textinhalt zum Hochladen (verwenden Sie entweder diesen ODER file, nicht beides) |
| `mimeType` | string | Nein | Der MIME-Typ der hochzuladenden Datei (wird automatisch aus der Datei erkannt, wenn nicht angegeben) |
| `folderSelector` | string | Nein | Wählen Sie den Ordner aus, in den die Datei hochgeladen werden soll |
| `folderId` | string | Nein | Die ID des Ordners, in den die Datei hochgeladen werden soll \(interne Verwendung\) |
| `folderId` | string | Nein | Die ID des Ordners, in den die Datei hochgeladen werden soll (interne Verwendung) |
#### Ausgabe

View File

@@ -1,5 +1,5 @@
---
title: Tools
title: Übersicht
description: Leistungsstarke tools zur verbesserung ihrer agentischen workflows
---

View File

@@ -110,6 +110,7 @@ Inhalte aus einem Microsoft Teams-Chat lesen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `chatId` | string | Ja | Die ID des Chats, aus dem gelesen werden soll |
| `includeAttachments` | boolean | Nein | Nachrichtenanhänge \(gehostete Inhalte\) herunterladen und in den Speicher aufnehmen |
#### Ausgabe
@@ -119,9 +120,10 @@ Inhalte aus einem Microsoft Teams-Chat lesen
| `messageCount` | number | Anzahl der aus dem Chat abgerufenen Nachrichten |
| `chatId` | string | ID des Chats, aus dem gelesen wurde |
| `messages` | array | Array von Chat-Nachrichtenobjekten |
| `attachmentCount` | number | Gesamtzahl der gefundenen Anhänge |
| `attachmentCount` | number | Gesamtanzahl der gefundenen Anhänge |
| `attachmentTypes` | array | Arten der gefundenen Anhänge |
| `content` | string | Formatierter Inhalt der Chat-Nachrichten |
| `attachments` | file[] | Hochgeladene Anhänge zur Vereinfachung \(abgeflacht\) |
### `microsoft_teams_write_chat`
@@ -133,6 +135,7 @@ Inhalte in einem Microsoft Teams-Chat schreiben oder aktualisieren
| --------- | ---- | -------- | ----------- |
| `chatId` | string | Ja | Die ID des Chats, in den geschrieben werden soll |
| `content` | string | Ja | Der Inhalt, der in die Nachricht geschrieben werden soll |
| `files` | file[] | Nein | Dateien, die der Nachricht angehängt werden sollen |
#### Ausgabe
@@ -155,19 +158,21 @@ Inhalte aus einem Microsoft Teams-Kanal lesen
| --------- | ---- | -------- | ----------- |
| `teamId` | string | Ja | Die ID des Teams, aus dem gelesen werden soll |
| `channelId` | string | Ja | Die ID des Kanals, aus dem gelesen werden soll |
| `includeAttachments` | boolean | Nein | Nachrichtenanhänge \(gehostete Inhalte\) herunterladen und in den Speicher aufnehmen |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `success` | boolean | Erfolgsstatus des Lesevorgangs im Teams-Kanal |
| `success` | boolean | Erfolgsstatus des Teams-Kanal-Lesevorgangs |
| `messageCount` | number | Anzahl der aus dem Kanal abgerufenen Nachrichten |
| `teamId` | string | ID des Teams, aus dem gelesen wurde |
| `channelId` | string | ID des Kanals, aus dem gelesen wurde |
| `messages` | array | Array von Kanalnachrichtenobjekten |
| `messages` | array | Array von Kanal-Nachrichtenobjekten |
| `attachmentCount` | number | Gesamtanzahl der gefundenen Anhänge |
| `attachmentTypes` | array | Arten der gefundenen Anhänge |
| `content` | string | Formatierter Inhalt der Kanalnachrichten |
| `content` | string | Formatierter Inhalt der Kanal-Nachrichten |
| `attachments` | file[] | Hochgeladene Anhänge zur Vereinfachung \(abgeflacht\) |
### `microsoft_teams_write_channel`
@@ -177,9 +182,10 @@ Schreiben oder senden einer Nachricht an einen Microsoft Teams-Kanal
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `teamId` | string | Ja | Die ID des Teams, an das geschrieben werden soll |
| `channelId` | string | Ja | Die ID des Kanals, an den geschrieben werden soll |
| `content` | string | Ja | Der Inhalt, der an den Kanal gesendet werden soll |
| `teamId` | string | Ja | Die ID des Teams, in das geschrieben werden soll |
| `channelId` | string | Ja | Die ID des Kanals, in den geschrieben werden soll |
| `content` | string | Ja | Der Inhalt, der in den Kanal geschrieben werden soll |
| `files` | file[] | Nein | Dateien, die der Nachricht angehängt werden sollen |
#### Ausgabe

View File

@@ -63,9 +63,10 @@ Eine Datei auf OneDrive hochladen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `fileName` | string | Ja | Der Name der hochzuladenden Datei |
| `content` | string | Ja | Der Inhalt der hochzuladenden Datei |
| `file` | file | Nein | Die hochzuladende Datei (binär) |
| `content` | string | Nein | Der hochzuladende Textinhalt (falls keine Datei bereitgestellt wird) |
| `folderSelector` | string | Nein | Wählen Sie den Ordner aus, in den die Datei hochgeladen werden soll |
| `manualFolderId` | string | Nein | Manuell eingegebene Ordner-ID \(erweiterter Modus\) |
| `manualFolderId` | string | Nein | Manuell eingegebene Ordner-ID (erweiterter Modus) |
#### Ausgabe

View File

@@ -154,10 +154,11 @@ E-Mails über Outlook versenden
| `to` | string | Ja | E-Mail-Adresse des Empfängers |
| `subject` | string | Ja | E-Mail-Betreff |
| `body` | string | Ja | E-Mail-Inhalt |
| `replyToMessageId` | string | Nein | Nachrichten-ID für Antworten \(für Threading\) |
| `replyToMessageId` | string | Nein | Nachrichten-ID, auf die geantwortet wird \(für Threading\) |
| `conversationId` | string | Nein | Konversations-ID für Threading |
| `cc` | string | Nein | CC-Empfänger \(durch Kommas getrennt\) |
| `bcc` | string | Nein | BCC-Empfänger \(durch Kommas getrennt\) |
| `attachments` | file[] | Nein | Dateien, die an die E-Mail angehängt werden sollen |
#### Ausgabe
@@ -177,10 +178,11 @@ E-Mails mit Outlook erstellen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `to` | string | Ja | E-Mail-Adresse des Empfängers |
| `subject` | string | Ja | Betreff der E-Mail |
| `body` | string | Ja | Inhalt der E-Mail |
| `cc` | string | Nein | CC-Empfänger \(durch Komma getrennt\) |
| `bcc` | string | Nein | BCC-Empfänger \(durch Komma getrennt\) |
| `subject` | string | Ja | E-Mail-Betreff |
| `body` | string | Ja | E-Mail-Inhalt |
| `cc` | string | Nein | CC-Empfänger \(durch Kommas getrennt\) |
| `bcc` | string | Nein | BCC-Empfänger \(durch Kommas getrennt\) |
| `attachments` | file[] | Nein | Dateien, die an den E-Mail-Entwurf angehängt werden sollen |
#### Ausgabe
@@ -203,6 +205,7 @@ E-Mails aus Outlook lesen
| --------- | ---- | -------- | ----------- |
| `folder` | string | Nein | Ordner-ID, aus der E-Mails gelesen werden sollen \(Standard: Posteingang\) |
| `maxResults` | number | Nein | Maximale Anzahl der abzurufenden E-Mails \(Standard: 1, max: 10\) |
| `includeAttachments` | boolean | Nein | E-Mail-Anhänge herunterladen und einschließen |
#### Ausgabe
@@ -210,6 +213,7 @@ E-Mails aus Outlook lesen
| --------- | ---- | ----------- |
| `message` | string | Erfolgs- oder Statusmeldung |
| `results` | array | Array von E-Mail-Nachrichtenobjekten |
| `attachments` | file[] | Alle E-Mail-Anhänge, zusammengefasst aus allen E-Mails |
### `outlook_forward`

View File

@@ -139,7 +139,8 @@ Suche nach ähnlichen Vektoren in einer Qdrant-Sammlung
| `collection` | string | Ja | Sammlungsname |
| `vector` | array | Ja | Zu suchender Vektor |
| `limit` | number | Nein | Anzahl der zurückzugebenden Ergebnisse |
| `filter` | object | Nein | Filter für die Suche |
| `filter` | object | Nein | Auf die Suche anzuwendender Filter |
| `search_return_data` | string | Nein | Aus der Suche zurückzugebende Daten |
| `with_payload` | boolean | Nein | Payload in Antwort einschließen |
| `with_vector` | boolean | Nein | Vektor in Antwort einschließen |
@@ -161,7 +162,8 @@ Punkte anhand der ID aus einer Qdrant-Sammlung abrufen
| `url` | string | Ja | Qdrant-Basis-URL |
| `apiKey` | string | Nein | Qdrant-API-Schlüssel \(optional\) |
| `collection` | string | Ja | Sammlungsname |
| `ids` | array | Ja | Array von abzurufenden Punkt-IDs |
| `ids` | array | Ja | Array von Punkt-IDs zum Abrufen |
| `fetch_return_data` | string | Nein | Aus dem Abruf zurückzugebende Daten |
| `with_payload` | boolean | Nein | Payload in Antwort einschließen |
| `with_vector` | boolean | Nein | Vektor in Antwort einschließen |

View File

@@ -1,6 +1,6 @@
---
title: S3
description: S3-Dateien anzeigen
description: S3-Dateien hochladen, herunterladen, auflisten und verwalten
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
@@ -61,10 +61,35 @@ In Sim ermöglicht die S3-Integration Ihren Agenten das Abrufen und Zugreifen au
## Gebrauchsanweisung
S3 in den Workflow integrieren. Kann vorsignierte URLs für S3-Objekte erhalten. Erfordert Zugriffsschlüssel und geheimen Zugriffsschlüssel.
S3 in den Workflow integrieren. Dateien hochladen, Objekte herunterladen, Bucket-Inhalte auflisten, Objekte löschen und Objekte zwischen Buckets kopieren. Erfordert AWS-Zugriffsschlüssel und geheimen Zugriffsschlüssel.
## Tools
### `s3_put_object`
Eine Datei in einen AWS S3-Bucket hochladen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Ja | Ihre AWS-Zugriffsschlüssel-ID |
| `secretAccessKey` | string | Ja | Ihr AWS-geheimer Zugriffsschlüssel |
| `region` | string | Ja | AWS-Region (z. B. us-east-1) |
| `bucketName` | string | Ja | S3-Bucket-Name |
| `objectKey` | string | Ja | Objektschlüssel/Pfad in S3 (z. B. ordner/dateiname.ext) |
| `file` | file | Nein | Hochzuladende Datei |
| `content` | string | Nein | Hochzuladender Textinhalt (Alternative zur Datei) |
| `contentType` | string | Nein | Content-Type-Header (wird automatisch aus der Datei erkannt, wenn nicht angegeben) |
| `acl` | string | Nein | Zugriffskontrollliste (z. B. private, public-read) |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `url` | string | URL des hochgeladenen S3-Objekts |
| `metadata` | object | Upload-Metadaten einschließlich ETag und Speicherort |
### `s3_get_object`
Ein Objekt aus einem AWS S3-Bucket abrufen
@@ -73,8 +98,8 @@ Ein Objekt aus einem AWS S3-Bucket abrufen
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Ja | Ihre AWS Access Key ID |
| `secretAccessKey` | string | Ja | Ihr AWS Secret Access Key |
| `accessKeyId` | string | Ja | Ihre AWS-Zugriffsschlüssel-ID |
| `secretAccessKey` | string | Ja | Ihr AWS-geheimer Zugriffsschlüssel |
| `s3Uri` | string | Ja | S3-Objekt-URL |
#### Ausgabe
@@ -84,6 +109,73 @@ Ein Objekt aus einem AWS S3-Bucket abrufen
| `url` | string | Vorsignierte URL zum Herunterladen des S3-Objekts |
| `metadata` | object | Dateimetadaten einschließlich Typ, Größe, Name und Datum der letzten Änderung |
### `s3_list_objects`
Objekte in einem AWS S3-Bucket auflisten
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Ja | Ihre AWS Access Key ID |
| `secretAccessKey` | string | Ja | Ihr AWS Secret Access Key |
| `region` | string | Ja | AWS-Region (z.B. us-east-1) |
| `bucketName` | string | Ja | S3-Bucket-Name |
| `prefix` | string | Nein | Präfix zum Filtern von Objekten (z.B. ordner/) |
| `maxKeys` | number | Nein | Maximale Anzahl zurückzugebender Objekte (Standard: 1000) |
| `continuationToken` | string | Nein | Token für Paginierung |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `objects` | array | Liste der S3-Objekte |
### `s3_delete_object`
Ein Objekt aus einem AWS S3-Bucket löschen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Ja | Ihre AWS Access Key ID |
| `secretAccessKey` | string | Ja | Ihr AWS Secret Access Key |
| `region` | string | Ja | AWS-Region (z.B. us-east-1) |
| `bucketName` | string | Ja | S3-Bucket-Name |
| `objectKey` | string | Ja | Objekt-Schlüssel/Pfad zum Löschen |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `deleted` | boolean | Ob das Objekt erfolgreich gelöscht wurde |
| `metadata` | object | Löschmetadaten |
### `s3_copy_object`
Ein Objekt innerhalb von oder zwischen AWS S3-Buckets kopieren
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Ja | Ihre AWS Access Key ID |
| `secretAccessKey` | string | Ja | Ihr AWS Secret Access Key |
| `region` | string | Ja | AWS-Region (z.B. us-east-1) |
| `sourceBucket` | string | Ja | Name des Quell-Buckets |
| `sourceKey` | string | Ja | Quell-Objektschlüssel/-pfad |
| `destinationBucket` | string | Ja | Name des Ziel-Buckets |
| `destinationKey` | string | Ja | Ziel-Objektschlüssel/-pfad |
| `acl` | string | Nein | Zugriffskontrollliste für das kopierte Objekt (z.B. private, public-read) |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `url` | string | URL des kopierten S3-Objekts |
| `metadata` | object | Metadaten des Kopiervorgangs |
## Hinweise
- Kategorie: `tools`

View File

@@ -199,6 +199,26 @@ Ein neues Element zu einer SharePoint-Liste hinzufügen
| --------- | ---- | ----------- |
| `item` | object | Erstelltes SharePoint-Listenelement |
### `sharepoint_upload_file`
Dateien in eine SharePoint-Dokumentenbibliothek hochladen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | Nein | Die ID der SharePoint-Website |
| `driveId` | string | Nein | Die ID der Dokumentenbibliothek (Laufwerk). Wenn nicht angegeben, wird das Standardlaufwerk verwendet. |
| `folderPath` | string | Nein | Optionaler Ordnerpfad innerhalb der Dokumentenbibliothek (z.B. /Documents/Subfolder) |
| `fileName` | string | Nein | Optional: Überschreiben des hochgeladenen Dateinamens |
| `files` | file[] | Nein | Dateien, die nach SharePoint hochgeladen werden sollen |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `uploadedFiles` | array | Array von hochgeladenen Dateiobjekten |
## Hinweise
- Kategorie: `tools`

View File

@@ -78,7 +78,8 @@ Senden Sie Nachrichten an Slack-Kanäle oder Benutzer über die Slack-API. Unter
| `authMethod` | string | Nein | Authentifizierungsmethode: oauth oder bot_token |
| `botToken` | string | Nein | Bot-Token für Custom Bot |
| `channel` | string | Ja | Ziel-Slack-Kanal \(z.B. #general\) |
| `text` | string | Ja | Zu sendender Nachrichtentext \(unterstützt Slack mrkdwn-Formatierung\) |
| `text` | string | Ja | Nachrichtentext zum Senden \(unterstützt Slack mrkdwn-Formatierung\) |
| `files` | file[] | Nein | Dateien, die an die Nachricht angehängt werden sollen |
#### Ausgabe

View File

@@ -202,6 +202,28 @@ Daten in eine Supabase-Tabelle einfügen oder aktualisieren (Upsert-Operation)
| `message` | string | Statusmeldung der Operation |
| `results` | array | Array der eingefügten/aktualisierten Datensätze |
### `supabase_vector_search`
Ähnlichkeitssuche mit pgvector in einer Supabase-Tabelle durchführen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `projectId` | string | Ja | Ihre Supabase-Projekt-ID \(z.B. jdrkgepadsdopsntdlom\) |
| `functionName` | string | Ja | Der Name der PostgreSQL-Funktion, die die Vektorsuche durchführt \(z.B. match_documents\) |
| `queryEmbedding` | array | Ja | Der Abfragevektor/Embedding, nach dem ähnliche Elemente gesucht werden sollen |
| `matchThreshold` | number | Nein | Minimaler Ähnlichkeitsschwellenwert \(0-1\), typischerweise 0,7-0,9 |
| `matchCount` | number | Nein | Maximale Anzahl der zurückzugebenden Ergebnisse \(Standard: 10\) |
| `apiKey` | string | Ja | Ihr Supabase Service Role Secret Key |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `message` | string | Statusmeldung der Operation |
| `results` | array | Array von Datensätzen mit Ähnlichkeitswerten aus der Vektorsuche. Jeder Datensatz enthält ein Ähnlichkeitsfeld \(0-1\), das angibt, wie ähnlich er dem Abfragevektor ist. |
## Hinweise
- Kategorie: `tools`

View File

@@ -190,6 +190,26 @@ Senden Sie Animationen (GIFs) an Telegram-Kanäle oder Benutzer über die Telegr
| `message` | string | Erfolgs- oder Fehlermeldung |
| `data` | object | Telegram-Nachrichtendaten einschließlich optionaler Medien |
### `telegram_send_document`
Senden Sie Dokumente (PDF, ZIP, DOC, etc.) an Telegram-Kanäle oder -Nutzer über die Telegram Bot API.
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `botToken` | string | Ja | Ihr Telegram Bot API-Token |
| `chatId` | string | Ja | Ziel-Telegram-Chat-ID |
| `files` | file[] | Nein | Zu sendende Dokumentdatei \(PDF, ZIP, DOC, etc.\). Maximale Größe: 50MB |
| `caption` | string | Nein | Dokumentbeschreibung \(optional\) |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `message` | string | Erfolgs- oder Fehlermeldung |
| `data` | object | Telegram-Nachrichtendaten einschließlich Dokument |
## Hinweise
- Kategorie: `tools`

View File

@@ -59,8 +59,9 @@ Verarbeiten und analysieren Sie Bilder mit fortschrittlichen Vision-Modellen. F
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Ja | API-Schlüssel für den ausgewählten Modellanbieter |
| `imageUrl` | string | Ja | Öffentlich zugängliche Bild-URL |
| `model` | string | Nein | Zu verwendendes Vision-Modell \(gpt-4o, claude-3-opus-20240229, etc\) |
| `imageUrl` | string | Nein | Öffentlich zugängliche Bild-URL |
| `imageFile` | file | Nein | Zu analysierende Bilddatei |
| `model` | string | Nein | Zu verwendendes Vision-Modell \(gpt-4o, claude-3-opus-20240229, usw.\) |
| `prompt` | string | Nein | Benutzerdefinierte Eingabeaufforderung für die Bildanalyse |
#### Ausgabe

View File

@@ -0,0 +1,145 @@
---
title: Webflow
description: Webflow CMS-Sammlungen verwalten
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="webflow"
color="#E0E0E0"
icon={true}
iconSvg={`<svg className="block-icon"
viewBox='0 0 1080 674'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
fillRule='evenodd'
clipRule='evenodd'
d='M1080 0L735.386 673.684H411.695L555.916 394.481H549.445C430.464 548.934 252.942 650.61 -0.000488281 673.684V398.344C-0.000488281 398.344 161.813 388.787 256.938 288.776H-0.000488281V0.0053214H288.771V237.515L295.252 237.489L413.254 0.0053214H631.644V236.009L638.126 235.999L760.555 0H1080Z'
fill='#146EF5'
/>
</svg>`}
/>
{/* MANUAL-CONTENT-START:intro */}
[Webflow](https://webflow.com/) ist eine leistungsstarke visuelle Webdesign-Plattform, mit der Sie responsive Websites ohne Programmierung erstellen können. Sie kombiniert eine visuelle Design-Oberfläche mit einem robusten CMS (Content Management System), das es Ihnen ermöglicht, dynamische Inhalte für Ihre Websites zu erstellen, zu verwalten und zu veröffentlichen.
Mit Webflow können Sie:
- **Visuell gestalten**: Erstellen Sie benutzerdefinierte Websites mit einem visuellen Editor, der sauberen, semantischen HTML/CSS-Code generiert
- **Inhalte dynamisch verwalten**: Nutzen Sie das CMS, um Sammlungen strukturierter Inhalte wie Blogbeiträge, Produkte, Teammitglieder oder beliebige benutzerdefinierte Daten zu erstellen
- **Sofort veröffentlichen**: Stellen Sie Ihre Websites auf Webflows Hosting bereit oder exportieren Sie den Code für benutzerdefiniertes Hosting
- **Responsive Designs erstellen**: Bauen Sie Websites, die nahtlos auf Desktop, Tablet und Mobilgeräten funktionieren
- **Sammlungen anpassen**: Definieren Sie benutzerdefinierte Felder und Datenstrukturen für Ihre Inhaltstypen
- **Inhaltsaktualisierungen automatisieren**: Verwalten Sie Ihre CMS-Inhalte programmgesteuert über APIs
In Sim ermöglicht die Webflow-Integration Ihren Agenten, nahtlos mit Ihren Webflow-CMS-Sammlungen über API-Authentifizierung zu interagieren. Dies ermöglicht leistungsstarke Automatisierungsszenarien wie das automatische Erstellen von Blogbeiträgen aus KI-generierten Inhalten, das Aktualisieren von Produktinformationen, das Verwalten von Teammitgliederprofilen und das Abrufen von CMS-Elementen für die dynamische Inhaltsgenerierung. Ihre Agenten können vorhandene Elemente auflisten, um Ihre Inhalte zu durchsuchen, bestimmte Elemente nach ID abrufen, neue Einträge erstellen, um frische Inhalte hinzuzufügen, bestehende Elemente aktualisieren, um Informationen aktuell zu halten, und veraltete Inhalte löschen. Diese Integration überbrückt die Lücke zwischen Ihren KI-Workflows und Ihrem Webflow-CMS und ermöglicht automatisierte Inhaltsverwaltung, dynamische Website-Aktualisierungen und optimierte Inhalts-Workflows, die Ihre Websites ohne manuelles Eingreifen frisch und aktuell halten.
{/* MANUAL-CONTENT-END */}
## Gebrauchsanweisung
Integriert Webflow CMS in den Workflow. Kann Elemente in Webflow CMS-Sammlungen erstellen, abrufen, auflisten, aktualisieren oder löschen. Verwalten Sie Ihre Webflow-Inhalte programmatisch. Kann im Trigger-Modus verwendet werden, um Workflows auszulösen, wenn sich Sammlungselemente ändern oder Formulare übermittelt werden.
## Tools
### `webflow_list_items`
Alle Elemente aus einer Webflow CMS-Sammlung auflisten
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Ja | ID der Sammlung |
| `offset` | number | Nein | Offset für Paginierung \(optional\) |
| `limit` | number | Nein | Maximale Anzahl der zurückzugebenden Elemente \(optional, Standard: 100\) |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `items` | json | Array von Sammlungselementen |
| `metadata` | json | Metadaten über die Abfrage |
### `webflow_get_item`
Ein einzelnes Element aus einer Webflow CMS-Sammlung abrufen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Ja | ID der Sammlung |
| `itemId` | string | Ja | ID des abzurufenden Elements |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `item` | json | Das abgerufene Elementobjekt |
| `metadata` | json | Metadaten über das abgerufene Element |
### `webflow_create_item`
Ein neues Element in einer Webflow CMS-Sammlung erstellen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Ja | ID der Sammlung |
| `fieldData` | json | Ja | Felddaten für das neue Element als JSON-Objekt. Die Schlüssel sollten mit den Feldnamen der Sammlung übereinstimmen. |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `item` | json | Das erstellte Element-Objekt |
| `metadata` | json | Metadaten über das erstellte Element |
### `webflow_update_item`
Ein vorhandenes Element in einer Webflow CMS-Sammlung aktualisieren
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Ja | ID der Sammlung |
| `itemId` | string | Ja | ID des zu aktualisierenden Elements |
| `fieldData` | json | Ja | Zu aktualisierende Felddaten als JSON-Objekt. Nur Felder einschließen, die geändert werden sollen. |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `item` | json | Das aktualisierte Element-Objekt |
| `metadata` | json | Metadaten über das aktualisierte Element |
### `webflow_delete_item`
Ein Element aus einer Webflow CMS-Sammlung löschen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Ja | ID der Sammlung |
| `itemId` | string | Ja | ID des zu löschenden Elements |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `success` | boolean | Ob die Löschung erfolgreich war |
| `metadata` | json | Metadaten über die Löschung |
## Hinweise
- Kategorie: `tools`
- Typ: `webflow`

View File

@@ -0,0 +1,242 @@
---
title: Zep
description: Langzeitgedächtnis für KI-Agenten
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="zep"
color="#E8E8E8"
icon={true}
iconSvg={`<svg className="block-icon"
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 233 196'
>
<path
d='m231.34,108.7l-1.48-1.55h-10.26l3.59-75.86-14.8-.45-2.77,49.31c-59.6-3.24-119.33-3.24-178.92-.02l-1.73-64.96-14.8.45,2.5,91.53H2.16l-1.41,1.47c-1.55,16.23-.66,32.68,2.26,48.89h10.83l.18,1.27c.67,19.34,16.1,34.68,35.9,34.68s44.86-.92,66.12-.92,46.56.92,65.95.92,35.19-15.29,35.9-34.61l.16-1.34h11.02c2.91-16.19,3.81-32.61,2.26-48.81Zm-158.23,58.01c-17.27,0-30.25-13.78-30.25-29.78s12.99-29.78,30.25-29.78,29.62,13.94,29.62,29.94-12.35,29.62-29.62,29.62Zm86.51,0c-17.27,0-30.25-13.78-30.25-29.78s12.99-29.78,30.25-29.78,29.62,13.94,29.62,29.94-12.35,29.62-29.62,29.62Z'
fill='#FF1493'
/>
<polygon
points='111.77 22.4 93.39 49.97 93.52 50.48 185.88 38.51 190.95 27.68 114.32 36.55 117.7 31.48 117.7 31.47 138.38 .49 138.25 0 47.67 11.6 42.85 22.27 118.34 12.61 111.77 22.4'
fill='#FF1493'
/>
<path
d='m72.97,121.47c-8.67,0-15.73,6.93-15.73,15.46s7.06,15.46,15.73,15.46,15.37-6.75,15.37-15.37-6.75-15.55-15.37-15.55Z'
fill='#FF1493'
/>
<path
d='m159.48,121.47c-8.67,0-15.73,6.93-15.73,15.46s7.06,15.46,15.73,15.46,15.37-6.75,15.37-15.37-6.75-15.55-15.37-15.55Z'
fill='#FF1493'
/>
</svg>`}
/>
## Nutzungsanleitung
Integriere Zep für Langzeitgedächtnisverwaltung. Erstelle Threads, füge Nachrichten hinzu, rufe Kontext mit KI-gestützten Zusammenfassungen und Faktenextraktion ab.
## Tools
### `zep_create_thread`
Starte einen neuen Konversations-Thread in Zep
#### Input
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `threadId` | string | Ja | Eindeutige Kennung für den Thread |
| `userId` | string | Ja | Benutzer-ID, die mit dem Thread verknüpft ist |
| `apiKey` | string | Ja | Dein Zep API-Schlüssel |
#### Output
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `threadId` | string | Die Thread-ID |
| `userId` | string | Die Benutzer-ID |
| `uuid` | string | Interne UUID |
| `createdAt` | string | Erstellungszeitstempel |
| `projectUuid` | string | Projekt-UUID |
### `zep_get_threads`
Liste alle Konversations-Threads auf
#### Input
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `pageSize` | number | Nein | Anzahl der Threads, die pro Seite abgerufen werden sollen |
| `pageNumber` | number | Nein | Seitennummer für Paginierung |
| `orderBy` | string | Nein | Feld, nach dem die Ergebnisse sortiert werden sollen \(created_at, updated_at, user_id, thread_id\) |
| `asc` | boolean | Nein | Sortierrichtung: true für aufsteigend, false für absteigend |
| `apiKey` | string | Ja | Dein Zep API-Schlüssel |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `threads` | array | Array von Thread-Objekten |
| `responseCount` | number | Anzahl der Threads in dieser Antwort |
| `totalCount` | number | Gesamtanzahl der verfügbaren Threads |
### `zep_delete_thread`
Einen Konversations-Thread aus Zep löschen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `threadId` | string | Ja | Thread-ID zum Löschen |
| `apiKey` | string | Ja | Ihr Zep API-Schlüssel |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `deleted` | boolean | Ob der Thread gelöscht wurde |
### `zep_get_context`
Benutzerkontext aus einem Thread mit Zusammenfassungs- oder Basismodus abrufen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `threadId` | string | Ja | Thread-ID, aus der der Kontext abgerufen werden soll |
| `mode` | string | Nein | Kontextmodus: "summary" \(natürliche Sprache\) oder "basic" \(rohe Fakten\) |
| `minRating` | number | Nein | Mindestbewertung, nach der relevante Fakten gefiltert werden |
| `apiKey` | string | Ja | Ihr Zep API-Schlüssel |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `context` | string | Der Kontextstring \(Zusammenfassung oder Basis\) |
| `facts` | array | Extrahierte Fakten |
| `entities` | array | Extrahierte Entitäten |
| `summary` | string | Konversationszusammenfassung |
### `zep_get_messages`
Nachrichten aus einem Thread abrufen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `threadId` | string | Ja | Thread-ID, aus der Nachrichten abgerufen werden sollen |
| `limit` | number | Nein | Maximale Anzahl der zurückzugebenden Nachrichten |
| `cursor` | string | Nein | Cursor für Paginierung |
| `lastn` | number | Nein | Anzahl der neuesten Nachrichten, die zurückgegeben werden sollen \(überschreibt Limit und Cursor\) |
| `apiKey` | string | Ja | Ihr Zep API-Schlüssel |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `messages` | array | Array von Nachrichtenobjekten |
| `rowCount` | number | Anzahl der Nachrichten in dieser Antwort |
| `totalCount` | number | Gesamtanzahl der Nachrichten im Thread |
### `zep_add_messages`
Nachrichten zu einem bestehenden Thread hinzufügen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `threadId` | string | Ja | Thread-ID, zu der Nachrichten hinzugefügt werden sollen |
| `messages` | json | Ja | Array von Nachrichtenobjekten mit Rolle und Inhalt |
| `apiKey` | string | Ja | Ihr Zep API-Schlüssel |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `context` | string | Aktualisierter Kontext nach dem Hinzufügen von Nachrichten |
| `messageIds` | array | Array der hinzugefügten Nachrichten-UUIDs |
| `threadId` | string | Die Thread-ID |
### `zep_add_user`
Einen neuen Benutzer in Zep erstellen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Ja | Eindeutige Kennung für den Benutzer |
| `email` | string | Nein | E-Mail-Adresse des Benutzers |
| `firstName` | string | Nein | Vorname des Benutzers |
| `lastName` | string | Nein | Nachname des Benutzers |
| `metadata` | json | Nein | Zusätzliche Metadaten als JSON-Objekt |
| `apiKey` | string | Ja | Ihr Zep API-Schlüssel |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `userId` | string | Die Benutzer-ID |
| `email` | string | E-Mail des Benutzers |
| `firstName` | string | Vorname des Benutzers |
| `lastName` | string | Nachname des Benutzers |
| `uuid` | string | Interne UUID |
| `createdAt` | string | Erstellungszeitstempel |
| `metadata` | object | Benutzermetadaten |
### `zep_get_user`
Benutzerinformationen von Zep abrufen
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Ja | Zu abzurufende Benutzer-ID |
| `apiKey` | string | Ja | Ihr Zep API-Schlüssel |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `userId` | string | Die Benutzer-ID |
| `email` | string | E-Mail des Benutzers |
| `firstName` | string | Vorname des Benutzers |
| `lastName` | string | Nachname des Benutzers |
| `uuid` | string | Interne UUID |
| `createdAt` | string | Erstellungszeitstempel |
| `updatedAt` | string | Zeitstempel der letzten Aktualisierung |
| `metadata` | object | Benutzermetadaten |
### `zep_get_user_threads`
Alle Konversations-Threads für einen bestimmten Benutzer auflisten
#### Eingabe
| Parameter | Typ | Erforderlich | Beschreibung |
| --------- | ---- | -------- | ----------- |
| `userId` | string | Ja | Benutzer-ID, für die Threads abgerufen werden sollen |
| `limit` | number | Nein | Maximale Anzahl der zurückzugebenden Threads |
| `apiKey` | string | Ja | Ihr Zep API-Schlüssel |
#### Ausgabe
| Parameter | Typ | Beschreibung |
| --------- | ---- | ----------- |
| `threads` | array | Array von Thread-Objekten für diesen Benutzer |
| `userId` | string | Die Benutzer-ID |
## Hinweise
- Kategorie: `tools`
- Typ: `zep`

View File

@@ -1,5 +1,5 @@
---
title: Auslöser
title: Übersicht
description: Grundlegende Möglichkeiten, Sim-Workflows zu starten
---

View File

@@ -1,5 +1,5 @@
---
title: Blocks
title: Overview
description: The building components of your AI workflows
---

View File

@@ -0,0 +1,16 @@
{
"pages": [
"index",
"agent",
"api",
"condition",
"evaluator",
"function",
"guardrails",
"loop",
"parallel",
"response",
"router",
"workflow"
]
}

View File

@@ -1,5 +1,5 @@
---
title: Connection Basics
title: Basics
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Connection Data Structure
title: Data Structure
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Connections
title: Overview
description: Connect your blocks to one another.
---

View File

@@ -0,0 +1,3 @@
{
"pages": ["index", "basics", "data-structure", "tags"]
}

View File

@@ -1,5 +1,5 @@
---
title: Connection Tags
title: Tags
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Execution Basics
title: Basics
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Execution
title: Overview
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -0,0 +1,3 @@
{
"pages": ["index", "basics", "api", "logging", "costs"]
}

View File

@@ -3,7 +3,6 @@
"pages": [
"./introduction/index",
"./getting-started/index",
"---Building Workflows---",
"triggers",
"blocks",
"tools",
@@ -11,14 +10,9 @@
"mcp",
"copilot",
"knowledgebase",
"---Configuration---",
"variables",
"---Execution---",
"execution",
"---Advanced---",
"permissions",
"yaml",
"---SDKs---",
"sdks"
],
"defaultOpen": false

View File

@@ -0,0 +1,4 @@
{
"title": "SDKs",
"pages": ["python", "typescript"]
}

View File

@@ -1,5 +1,5 @@
---
title: Python SDK
title: Python
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -752,10 +752,6 @@ Configure the client using environment variables:
</Step>
</Steps>
<Callout type="warning">
Keep your API key secure and never commit it to version control. Use environment variables or secure configuration management.
</Callout>
## Requirements
- Python 3.8+

View File

@@ -1,5 +1,5 @@
---
title: TypeScript/JavaScript SDK
title: TypeScript
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -679,10 +679,6 @@ Alternatively, you can manually provide files using the URL format:
</Tab>
</Tabs>
// Attach to button click
document.getElementById('executeBtn')?.addEventListener('click', executeClientSideWorkflow);
```
<Callout type="warning">
When using the SDK in the browser, be careful not to expose sensitive API keys. Consider using a backend proxy or public API keys with limited permissions.
</Callout>
@@ -1030,10 +1026,6 @@ function StreamingWorkflow() {
</Step>
</Steps>
<Callout type="warning">
Keep your API key secure and never commit it to version control. Use environment variables or secure configuration management.
</Callout>
## Requirements
- Node.js 16+

View File

@@ -214,14 +214,14 @@ Populate Clay with data from a JSON file. Enables direct communication and notif
| --------- | ---- | -------- | ----------- |
| `webhookURL` | string | Yes | The webhook URL to populate |
| `data` | json | Yes | The data to populate |
| `authToken` | string | Yes | Auth token for Clay webhook authentication |
| `authToken` | string | No | Optional auth token for Clay webhook authentication \(most webhooks do not require this\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Operation success status |
| `output` | json | Clay populate operation results including response data from Clay webhook |
| `data` | json | Response data from Clay webhook |
| `metadata` | object | Webhook response metadata |

View File

@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="discord"
color="#E0E0E0"
color="#5865F2"
icon={true}
iconSvg={`<svg className="block-icon"
@@ -75,6 +75,7 @@ Send a message to a Discord channel
| `channelId` | string | Yes | The Discord channel ID to send the message to |
| `content` | string | No | The text content of the message |
| `serverId` | string | Yes | The Discord server ID \(guild ID\) |
| `files` | file[] | No | Files to attach to the message |
#### Output

View File

@@ -26,7 +26,208 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
## Overview
The Generic Webhook block allows you to receive webhooks from any external service. This is a flexible trigger that can handle any JSON payload, making it ideal for integrating with services that don't have a dedicated Sim block.
## Basic Usage
### Simple Passthrough Mode
Without defining an input format, the webhook passes through the entire request body as-is:
```bash
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret" \
-d '{
"message": "Test webhook trigger",
"data": {
"key": "value"
}
}'
```
Access the data in downstream blocks using:
- `<webhook1.message>` → "Test webhook trigger"
- `<webhook1.data.key>` → "value"
### Structured Input Format (Optional)
Define an input schema to get typed fields and enable advanced features like file uploads:
**Input Format Configuration:**
```json
[
{ "name": "message", "type": "string" },
{ "name": "priority", "type": "number" },
{ "name": "documents", "type": "files" }
]
```
**Webhook Request:**
```bash
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret" \
-d '{
"message": "Invoice submission",
"priority": 1,
"documents": [
{
"type": "file",
"data": "data:application/pdf;base64,JVBERi0xLjQK...",
"name": "invoice.pdf",
"mime": "application/pdf"
}
]
}'
```
## File Uploads
### Supported File Formats
The webhook supports two file input formats:
#### 1. Base64 Encoded Files
For uploading file content directly:
```json
{
"documents": [
{
"type": "file",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA...",
"name": "screenshot.png",
"mime": "image/png"
}
]
}
```
- **Max size**: 20MB per file
- **Format**: Standard data URL with base64 encoding
- **Storage**: Files are uploaded to secure execution storage
#### 2. URL References
For passing existing file URLs:
```json
{
"documents": [
{
"type": "url",
"data": "https://example.com/files/document.pdf",
"name": "document.pdf",
"mime": "application/pdf"
}
]
}
```
### Accessing Files in Downstream Blocks
Files are processed into `UserFile` objects with the following properties:
```typescript
{
id: string, // Unique file identifier
name: string, // Original filename
url: string, // Presigned URL (valid for 5 minutes)
size: number, // File size in bytes
type: string, // MIME type
key: string, // Storage key
uploadedAt: string, // ISO timestamp
expiresAt: string // ISO timestamp (5 minutes)
}
```
**Access in blocks:**
- `<webhook1.documents[0].url>` → Download URL
- `<webhook1.documents[0].name>` → "invoice.pdf"
- `<webhook1.documents[0].size>` → 524288
- `<webhook1.documents[0].type>` → "application/pdf"
### Complete File Upload Example
```bash
# Create a base64-encoded file
echo "Hello World" | base64
# SGVsbG8gV29ybGQK
# Send webhook with file
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret" \
-d '{
"subject": "Document for review",
"attachments": [
{
"type": "file",
"data": "data:text/plain;base64,SGVsbG8gV29ybGQK",
"name": "sample.txt",
"mime": "text/plain"
}
]
}'
```
## Authentication
### Configure Authentication (Optional)
In the webhook configuration:
1. Enable "Require Authentication"
2. Set a secret token
3. Choose header type:
- **Custom Header**: `X-Sim-Secret: your-token`
- **Authorization Bearer**: `Authorization: Bearer your-token`
### Using Authentication
```bash
# With custom header
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret-token" \
-d '{"message": "Authenticated request"}'
# With bearer token
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-secret-token" \
-d '{"message": "Authenticated request"}'
```
## Best Practices
1. **Use Input Format for Structure**: Define an input format when you know the expected schema. This provides:
- Type validation
- Better autocomplete in the editor
- File upload capabilities
2. **Authentication**: Always enable authentication for production webhooks to prevent unauthorized access.
3. **File Size Limits**: Keep files under 20MB. For larger files, use URL references instead.
4. **File Expiration**: Downloaded files have 5-minute expiration URLs. Process them promptly or store them elsewhere if needed longer.
5. **Error Handling**: Webhook processing is asynchronous. Check execution logs for errors.
6. **Testing**: Use the "Test Webhook" button in the editor to validate your configuration before deployment.
## Use Cases
- **Form Submissions**: Receive data from custom forms with file uploads
- **Third-Party Integrations**: Connect with services that send webhooks (Stripe, GitHub, etc.)
- **Document Processing**: Accept documents from external systems for processing
- **Event Notifications**: Receive event data from various sources
- **Custom APIs**: Build custom API endpoints for your applications
## Notes
- Category: `triggers`
- Type: `generic_webhook`
- **File Support**: Available via input format configuration
- **Max File Size**: 20MB per file

View File

@@ -70,6 +70,7 @@ Send emails using Gmail
| `body` | string | Yes | Email body content |
| `cc` | string | No | CC recipients \(comma-separated\) |
| `bcc` | string | No | BCC recipients \(comma-separated\) |
| `attachments` | file[] | No | Files to attach to the email |
#### Output
@@ -91,6 +92,7 @@ Draft emails using Gmail
| `body` | string | Yes | Email body content |
| `cc` | string | No | CC recipients \(comma-separated\) |
| `bcc` | string | No | BCC recipients \(comma-separated\) |
| `attachments` | file[] | No | Files to attach to the email draft |
#### Output

View File

@@ -88,8 +88,9 @@ Upload a file to Google Drive
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `fileName` | string | Yes | The name of the file to upload |
| `content` | string | Yes | The content of the file to upload |
| `mimeType` | string | No | The MIME type of the file to upload |
| `file` | file | No | Binary file to upload \(UserFile object\) |
| `content` | string | No | Text content to upload \(use this OR file, not both\) |
| `mimeType` | string | No | The MIME type of the file to upload \(auto-detected from file if not provided\) |
| `folderSelector` | string | No | Select the folder to upload the file to |
| `folderId` | string | No | The ID of the folder to upload the file to \(internal use\) |

View File

@@ -1,5 +1,5 @@
---
title: Tools
title: Overview
description: Powerful tools to enhance your agentic workflows
---

View File

@@ -1,5 +1,5 @@
{
"items": [
"pages": [
"index",
"airtable",
"arxiv",
@@ -66,6 +66,7 @@
"typeform",
"vision",
"wealthbox",
"webflow",
"webhook",
"whatsapp",
"wikipedia",

View File

@@ -138,6 +138,7 @@ Write or update content in a Microsoft Teams chat
| --------- | ---- | -------- | ----------- |
| `chatId` | string | Yes | The ID of the chat to write to |
| `content` | string | Yes | The content to write to the message |
| `files` | file[] | No | Files to attach to the message |
#### Output
@@ -187,6 +188,7 @@ Write or send a message to a Microsoft Teams channel
| `teamId` | string | Yes | The ID of the team to write to |
| `channelId` | string | Yes | The ID of the channel to write to |
| `content` | string | Yes | The content to write to the channel |
| `files` | file[] | No | Files to attach to the message |
#### Output

View File

@@ -66,7 +66,8 @@ Upload a file to OneDrive
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `fileName` | string | Yes | The name of the file to upload |
| `content` | string | Yes | The content of the file to upload |
| `file` | file | No | The file to upload \(binary\) |
| `content` | string | No | The text content to upload \(if no file is provided\) |
| `folderSelector` | string | No | Select the folder to upload the file to |
| `manualFolderId` | string | No | Manually entered folder ID \(advanced mode\) |

View File

@@ -161,6 +161,7 @@ Send emails using Outlook
| `conversationId` | string | No | Conversation ID for threading |
| `cc` | string | No | CC recipients \(comma-separated\) |
| `bcc` | string | No | BCC recipients \(comma-separated\) |
| `attachments` | file[] | No | Files to attach to the email |
#### Output
@@ -184,6 +185,7 @@ Draft emails using Outlook
| `body` | string | Yes | Email body content |
| `cc` | string | No | CC recipients \(comma-separated\) |
| `bcc` | string | No | BCC recipients \(comma-separated\) |
| `attachments` | file[] | No | Files to attach to the email draft |
#### Output

View File

@@ -143,6 +143,7 @@ Search for similar vectors in a Qdrant collection
| `vector` | array | Yes | Vector to search for |
| `limit` | number | No | Number of results to return |
| `filter` | object | No | Filter to apply to the search |
| `search_return_data` | string | No | Data to return from search |
| `with_payload` | boolean | No | Include payload in response |
| `with_vector` | boolean | No | Include vector in response |
@@ -165,6 +166,7 @@ Fetch points by ID from a Qdrant collection
| `apiKey` | string | No | Qdrant API key \(optional\) |
| `collection` | string | Yes | Collection name |
| `ids` | array | Yes | Array of point IDs to fetch |
| `fetch_return_data` | string | No | Data to return from fetch |
| `with_payload` | boolean | No | Include payload in response |
| `with_vector` | boolean | No | Include vector in response |

View File

@@ -1,6 +1,6 @@
---
title: S3
description: View S3 files
description: Upload, download, list, and manage S3 files
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
@@ -62,12 +62,37 @@ In Sim, the S3 integration enables your agents to retrieve and access files stor
## Usage Instructions
Integrate S3 into the workflow. Can get presigned URLs for S3 objects. Requires access key and secret access key.
Integrate S3 into the workflow. Upload files, download objects, list bucket contents, delete objects, and copy objects between buckets. Requires AWS access key and secret access key.
## Tools
### `s3_put_object`
Upload a file to an AWS S3 bucket
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Yes | Your AWS Access Key ID |
| `secretAccessKey` | string | Yes | Your AWS Secret Access Key |
| `region` | string | Yes | AWS region \(e.g., us-east-1\) |
| `bucketName` | string | Yes | S3 bucket name |
| `objectKey` | string | Yes | Object key/path in S3 \(e.g., folder/filename.ext\) |
| `file` | file | No | File to upload |
| `content` | string | No | Text content to upload \(alternative to file\) |
| `contentType` | string | No | Content-Type header \(auto-detected from file if not provided\) |
| `acl` | string | No | Access control list \(e.g., private, public-read\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `url` | string | URL of the uploaded S3 object |
| `metadata` | object | Upload metadata including ETag and location |
### `s3_get_object`
Retrieve an object from an AWS S3 bucket
@@ -87,6 +112,73 @@ Retrieve an object from an AWS S3 bucket
| `url` | string | Pre-signed URL for downloading the S3 object |
| `metadata` | object | File metadata including type, size, name, and last modified date |
### `s3_list_objects`
List objects in an AWS S3 bucket
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Yes | Your AWS Access Key ID |
| `secretAccessKey` | string | Yes | Your AWS Secret Access Key |
| `region` | string | Yes | AWS region \(e.g., us-east-1\) |
| `bucketName` | string | Yes | S3 bucket name |
| `prefix` | string | No | Prefix to filter objects \(e.g., folder/\) |
| `maxKeys` | number | No | Maximum number of objects to return \(default: 1000\) |
| `continuationToken` | string | No | Token for pagination |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `objects` | array | List of S3 objects |
### `s3_delete_object`
Delete an object from an AWS S3 bucket
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Yes | Your AWS Access Key ID |
| `secretAccessKey` | string | Yes | Your AWS Secret Access Key |
| `region` | string | Yes | AWS region \(e.g., us-east-1\) |
| `bucketName` | string | Yes | S3 bucket name |
| `objectKey` | string | Yes | Object key/path to delete |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `deleted` | boolean | Whether the object was successfully deleted |
| `metadata` | object | Deletion metadata |
### `s3_copy_object`
Copy an object within or between AWS S3 buckets
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Yes | Your AWS Access Key ID |
| `secretAccessKey` | string | Yes | Your AWS Secret Access Key |
| `region` | string | Yes | AWS region \(e.g., us-east-1\) |
| `sourceBucket` | string | Yes | Source bucket name |
| `sourceKey` | string | Yes | Source object key/path |
| `destinationBucket` | string | Yes | Destination bucket name |
| `destinationKey` | string | Yes | Destination object key/path |
| `acl` | string | No | Access control list for the copied object \(e.g., private, public-read\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `url` | string | URL of the copied S3 object |
| `metadata` | object | Copy operation metadata |
## Notes

View File

@@ -202,6 +202,26 @@ Add a new item to a SharePoint list
| --------- | ---- | ----------- |
| `item` | object | Created SharePoint list item |
### `sharepoint_upload_file`
Upload files to a SharePoint document library
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `siteId` | string | No | The ID of the SharePoint site |
| `driveId` | string | No | The ID of the document library \(drive\). If not provided, uses default drive. |
| `folderPath` | string | No | Optional folder path within the document library \(e.g., /Documents/Subfolder\) |
| `fileName` | string | No | Optional: override the uploaded file name |
| `files` | file[] | No | Files to upload to SharePoint |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `uploadedFiles` | array | Array of uploaded file objects |
## Notes

View File

@@ -82,6 +82,7 @@ Send messages to Slack channels or users through the Slack API. Supports Slack m
| `botToken` | string | No | Bot token for Custom Bot |
| `channel` | string | Yes | Target Slack channel \(e.g., #general\) |
| `text` | string | Yes | Message text to send \(supports Slack mrkdwn formatting\) |
| `files` | file[] | No | Files to attach to the message |
#### Output

View File

@@ -205,6 +205,28 @@ Insert or update data in a Supabase table (upsert operation)
| `message` | string | Operation status message |
| `results` | array | Array of upserted records |
### `supabase_vector_search`
Perform similarity search using pgvector in a Supabase table
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `projectId` | string | Yes | Your Supabase project ID \(e.g., jdrkgepadsdopsntdlom\) |
| `functionName` | string | Yes | The name of the PostgreSQL function that performs vector search \(e.g., match_documents\) |
| `queryEmbedding` | array | Yes | The query vector/embedding to search for similar items |
| `matchThreshold` | number | No | Minimum similarity threshold \(0-1\), typically 0.7-0.9 |
| `matchCount` | number | No | Maximum number of results to return \(default: 10\) |
| `apiKey` | string | Yes | Your Supabase service role secret key |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `message` | string | Operation status message |
| `results` | array | Array of records with similarity scores from the vector search. Each record includes a similarity field \(0-1\) indicating how similar it is to the query vector. |
## Notes

View File

@@ -191,6 +191,26 @@ Send animations (GIFs) to Telegram channels or users through the Telegram Bot AP
| `message` | string | Success or error message |
| `data` | object | Telegram message data including optional media |
### `telegram_send_document`
Send documents (PDF, ZIP, DOC, etc.) to Telegram channels or users through the Telegram Bot API.
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `botToken` | string | Yes | Your Telegram Bot API Token |
| `chatId` | string | Yes | Target Telegram chat ID |
| `files` | file[] | No | Document file to send \(PDF, ZIP, DOC, etc.\). Max size: 50MB |
| `caption` | string | No | Document caption \(optional\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `message` | string | Success or error message |
| `data` | object | Telegram message data including document |
## Notes

View File

@@ -62,7 +62,8 @@ Process and analyze images using advanced vision models. Capable of understandin
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | API key for the selected model provider |
| `imageUrl` | string | Yes | Publicly accessible image URL |
| `imageUrl` | string | No | Publicly accessible image URL |
| `imageFile` | file | No | Image file to analyze |
| `model` | string | No | Vision model to use \(gpt-4o, claude-3-opus-20240229, etc\) |
| `prompt` | string | No | Custom prompt for image analysis |

View File

@@ -0,0 +1,150 @@
---
title: Webflow
description: Manage Webflow CMS collections
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="webflow"
color="#E0E0E0"
icon={true}
iconSvg={`<svg className="block-icon"
viewBox='0 0 1080 674'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
fillRule='evenodd'
clipRule='evenodd'
d='M1080 0L735.386 673.684H411.695L555.916 394.481H549.445C430.464 548.934 252.942 650.61 -0.000488281 673.684V398.344C-0.000488281 398.344 161.813 388.787 256.938 288.776H-0.000488281V0.0053214H288.771V237.515L295.252 237.489L413.254 0.0053214H631.644V236.009L638.126 235.999L760.555 0H1080Z'
fill='#146EF5'
/>
</svg>`}
/>
{/* MANUAL-CONTENT-START:intro */}
[Webflow](https://webflow.com/) is a powerful visual web design platform that enables you to build responsive websites without writing code. It combines a visual design interface with a robust CMS (Content Management System) that allows you to create, manage, and publish dynamic content for your websites.
With Webflow, you can:
- **Design visually**: Create custom websites with a visual editor that generates clean, semantic HTML/CSS code
- **Manage content dynamically**: Use the CMS to create collections of structured content like blog posts, products, team members, or any custom data
- **Publish instantly**: Deploy your sites to Webflow's hosting or export the code for custom hosting
- **Create responsive designs**: Build sites that work seamlessly across desktop, tablet, and mobile devices
- **Customize collections**: Define custom fields and data structures for your content types
- **Automate content updates**: Programmatically manage your CMS content through APIs
In Sim, the Webflow integration enables your agents to seamlessly interact with your Webflow CMS collections through API authentication. This allows for powerful automation scenarios such as automatically creating blog posts from AI-generated content, updating product information, managing team member profiles, and retrieving CMS items for dynamic content generation. Your agents can list existing items to browse your content, retrieve specific items by ID, create new entries to add fresh content, update existing items to keep information current, and delete outdated content. This integration bridges the gap between your AI workflows and your Webflow CMS, enabling automated content management, dynamic website updates, and streamlined content workflows that keep your sites fresh and up-to-date without manual intervention.
{/* MANUAL-CONTENT-END */}
## Usage Instructions
Integrates Webflow CMS into the workflow. Can create, get, list, update, or delete items in Webflow CMS collections. Manage your Webflow content programmatically. Can be used in trigger mode to trigger workflows when collection items change or forms are submitted.
## Tools
### `webflow_list_items`
List all items from a Webflow CMS collection
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Yes | ID of the collection |
| `offset` | number | No | Offset for pagination \(optional\) |
| `limit` | number | No | Maximum number of items to return \(optional, default: 100\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `items` | json | Array of collection items |
| `metadata` | json | Metadata about the query |
### `webflow_get_item`
Get a single item from a Webflow CMS collection
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Yes | ID of the collection |
| `itemId` | string | Yes | ID of the item to retrieve |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `item` | json | The retrieved item object |
| `metadata` | json | Metadata about the retrieved item |
### `webflow_create_item`
Create a new item in a Webflow CMS collection
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Yes | ID of the collection |
| `fieldData` | json | Yes | Field data for the new item as a JSON object. Keys should match collection field names. |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `item` | json | The created item object |
| `metadata` | json | Metadata about the created item |
### `webflow_update_item`
Update an existing item in a Webflow CMS collection
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Yes | ID of the collection |
| `itemId` | string | Yes | ID of the item to update |
| `fieldData` | json | Yes | Field data to update as a JSON object. Only include fields you want to change. |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `item` | json | The updated item object |
| `metadata` | json | Metadata about the updated item |
### `webflow_delete_item`
Delete an item from a Webflow CMS collection
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `collectionId` | string | Yes | ID of the collection |
| `itemId` | string | Yes | ID of the item to delete |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Whether the deletion was successful |
| `metadata` | json | Metadata about the deletion |
## Notes
- Category: `tools`
- Type: `webflow`

View File

@@ -7,30 +7,30 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="zep"
color="#4F46E5"
color="#E8E8E8"
icon={true}
iconSvg={`<svg className="block-icon"
viewBox='0 0 24 24'
fill='none'
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 233 196'
>
<path
d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z'
fill='currentColor'
d='m231.34,108.7l-1.48-1.55h-10.26l3.59-75.86-14.8-.45-2.77,49.31c-59.6-3.24-119.33-3.24-178.92-.02l-1.73-64.96-14.8.45,2.5,91.53H2.16l-1.41,1.47c-1.55,16.23-.66,32.68,2.26,48.89h10.83l.18,1.27c.67,19.34,16.1,34.68,35.9,34.68s44.86-.92,66.12-.92,46.56.92,65.95.92,35.19-15.29,35.9-34.61l.16-1.34h11.02c2.91-16.19,3.81-32.61,2.26-48.81Zm-158.23,58.01c-17.27,0-30.25-13.78-30.25-29.78s12.99-29.78,30.25-29.78,29.62,13.94,29.62,29.94-12.35,29.62-29.62,29.62Zm86.51,0c-17.27,0-30.25-13.78-30.25-29.78s12.99-29.78,30.25-29.78,29.62,13.94,29.62,29.94-12.35,29.62-29.62,29.62Z'
fill='#FF1493'
/>
<polygon
points='111.77 22.4 93.39 49.97 93.52 50.48 185.88 38.51 190.95 27.68 114.32 36.55 117.7 31.48 117.7 31.47 138.38 .49 138.25 0 47.67 11.6 42.85 22.27 118.34 12.61 111.77 22.4'
fill='#FF1493'
/>
<path
d='M12 6c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm0 10c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z'
fill='currentColor'
d='m72.97,121.47c-8.67,0-15.73,6.93-15.73,15.46s7.06,15.46,15.73,15.46,15.37-6.75,15.37-15.37-6.75-15.55-15.37-15.55Z'
fill='#FF1493'
/>
<circle cx='12' cy='12' r='2' fill='currentColor' />
<path
d='M8 8h8M8 16h8'
stroke='currentColor'
strokeWidth='1.5'
strokeLinecap='round'
d='m159.48,121.47c-8.67,0-15.73,6.93-15.73,15.46s7.06,15.46,15.73,15.46,15.37-6.75,15.37-15.37-6.75-15.55-15.37-15.55Z'
fill='#FF1493'
/>
</svg>`}
/>

View File

@@ -1,5 +1,5 @@
---
title: Triggers
title: Overview
description: Core ways to start Sim workflows
---

View File

@@ -0,0 +1,3 @@
{
"pages": ["index", "api", "chat", "input-form", "manual", "schedule", "starter", "webhook"]
}

View File

@@ -1,357 +0,0 @@
---
title: Loop Block YAML Schema
description: YAML configuration reference for Loop blocks
---
## Schema Definition
```yaml
type: object
required:
- type
- name
- connections
properties:
type:
type: string
enum: [loop]
description: Block type identifier
name:
type: string
description: Display name for this loop block
inputs:
type: object
description: Optional. If omitted, defaults will be applied.
properties:
loopType:
type: string
enum: [for, forEach]
description: Type of loop to execute
default: for
iterations:
type: number
description: Number of iterations (for 'for' loops)
default: 5
minimum: 1
maximum: 1000
collection:
type: string
description: Collection to iterate over (for 'forEach' loops)
default: ""
maxConcurrency:
type: number
description: Maximum concurrent executions
default: 1
minimum: 1
maximum: 10
connections:
type: object
properties:
# Nested format (recommended)
loop:
type: object
properties:
start:
type: string
description: Target block ID to execute inside the loop
end:
type: string
description: Target block ID for loop completion (optional)
# Direct handle format (alternative)
loop-start-source:
type: string | string[]
description: Target block ID to execute inside the loop (direct format)
loop-end-source:
type: string | string[]
description: Target block ID for loop completion (direct format, optional)
error:
type: string
description: Target block ID for error handling
note: Use either the nested 'loop' format OR the direct 'loop-start-source' format, not both
```
## Connection Configuration
Loop blocks support two connection formats:
### Direct Handle Format (Alternative)
```yaml
connections:
loop-start-source: <string> # Target block ID to execute inside the loop
loop-end-source: <string> # Target block ID after loop completion (optional)
error: <string> # Target block ID for error handling (optional)
```
Both formats work identically. Use whichever you prefer.
## Child Block Configuration
Blocks inside a loop must have their `parentId` set to the loop block ID. The `extent` property is automatically set to `'parent'` and doesn't need to be specified:
```yaml
loop-1:
type: loop
name: "Process Items"
inputs:
loopType: forEach
collection: <start.items>
connections:
loop:
start: process-item
end: final-results
# Child block inside the loop
process-item:
type: agent
name: "Process Item"
parentId: loop-1 # References the loop block
inputs:
systemPrompt: "Process this item"
userPrompt: <loop.currentItem>
model: gpt-4o
apiKey: '{{OPENAI_API_KEY}}'
```
## Examples
### For Loop (Fixed Iterations)
```yaml
countdown-loop:
type: loop
name: "Countdown Loop"
inputs:
loopType: for
iterations: 5
connections:
loop:
start: countdown-agent
end: countdown-complete
countdown-agent:
type: agent
name: "Countdown Agent"
parentId: countdown-loop
inputs:
systemPrompt: "Generate a countdown message"
userPrompt: "Count down from 5. Current number: <loop.index>"
model: gpt-4o
apiKey: '{{OPENAI_API_KEY}}'
```
### ForEach Loop (Collection Processing)
```yaml
email-processor-loop:
type: loop
name: "Email Processor Loop"
inputs:
loopType: forEach
collection: <start.emails>
connections:
loop:
start: process-single-email
end: all-emails-processed
process-single-email:
type: agent
name: "Process Single Email"
parentId: email-processor-loop
inputs:
systemPrompt: "Classify and respond to this email"
userPrompt: "Email content: <loop.currentItem>"
model: gpt-4o
apiKey: '{{OPENAI_API_KEY}}'
```
### Loop with Multiple Child Blocks
```yaml
data-analysis-loop:
type: loop
name: "Data Analysis Loop"
inputs:
loopType: forEach
collection: <data-fetcher.records>
maxConcurrency: 3
connections:
loop:
start: validate-record
end: generate-report
error: handle-loop-error
validate-record:
type: function
name: "Validate Record"
parentId: data-analysis-loop
inputs:
code: |
const record = <loop.currentItem>;
const index = <loop.index>;
// Validate the record
if (!record.id || !record.data) {
throw new Error(`Invalid record at index ${index}`);
}
return {
valid: true,
recordId: record.id,
processedAt: new Date().toISOString()
};
connections:
success: analyze-record
error: record-error
analyze-record:
type: agent
name: "Analyze Record"
parentId: data-analysis-loop
inputs:
systemPrompt: "Analyze this data record and extract insights"
userPrompt: |
Record ID: <validaterecord.recordId>
Data: <loop.currentItem.data>
Position in collection: <loop.index>
model: gpt-4o
apiKey: '{{OPENAI_API_KEY}}'
connections:
success: store-analysis
store-analysis:
type: function
name: "Store Analysis"
parentId: data-analysis-loop
inputs:
code: |
const analysis = <analyzerecord.content>;
const recordId = <validaterecord.recordId>;
// Store analysis result
return {
recordId,
analysis,
completedAt: new Date().toISOString()
};
```
### Concurrent Processing Loop
```yaml
parallel-processing-loop:
type: loop
name: "Parallel Processing Loop"
inputs:
loopType: forEach
collection: <start.tasks>
maxConcurrency: 5
connections:
loop:
start: process-task
end: aggregate-results
process-task:
type: api
name: "Process Task"
parentId: parallel-processing-loop
inputs:
url: "https://api.example.com/process"
method: POST
headers:
- key: "Authorization"
value: "Bearer {{API_TOKEN}}"
body: |
{
"taskId": "<loop.currentItem.id>",
"data": "<loop.currentItem.data>"
}
connections:
success: task-completed
```
### Direct Handle Format Example
The same loop can be written using the direct handle format:
```yaml
my-loop:
type: loop
name: "Process Items"
inputs:
loopType: forEach
collection: <start.items>
connections:
loop-start-source: process-item # Direct handle format
loop-end-source: final-results # Direct handle format
error: handle-error
process-item:
type: agent
name: "Process Item"
parentId: my-loop
inputs:
systemPrompt: "Process this item"
userPrompt: <loop.currentItem>
model: gpt-4o
apiKey: '{{OPENAI_API_KEY}}'
```
### Minimal Loop Example (Using Defaults)
You can omit the `inputs` section entirely, and defaults will be applied:
```yaml
simple-loop:
type: loop
name: "Simple Loop"
# No inputs section - defaults to loopType: 'for', iterations: 5
connections:
loop-start-source: process-step
loop-end-source: complete
process-step:
type: agent
name: "Process Step"
parentId: simple-loop
inputs:
systemPrompt: "Execute step"
userPrompt: "Step <loop.index>"
model: gpt-4o
apiKey: '{{OPENAI_API_KEY}}'
```
This loop will execute 5 iterations by default.
## Loop Variables
Inside loop child blocks, these special variables are available:
```yaml
# Available in all child blocks of the loop
<loop.index> # Current iteration number (0-based)
<loop.currentItem> # Current item being processed (forEach loops)
<loop.items> # Full collection (forEach loops)
```
## Output References
After a loop completes, you can reference its aggregated results:
```yaml
# In blocks after the loop
final-processor:
inputs:
all-results: <loop-name.results> # Array of all iteration results
total-count: <loop-name.count> # Number of iterations completed
```
## Best Practices
- Set reasonable iteration limits to avoid long execution times
- Use forEach for collection processing, for loops for fixed iterations
- Consider using maxConcurrency for I/O bound operations
- Include error handling for robust loop execution
- Use descriptive names for loop child blocks
- Test with small collections first
- Monitor execution time for large collections

View File

@@ -8,213 +8,213 @@ import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
import { Image } from '@/components/ui/image'
import { Video } from '@/components/ui/video'
The Guardrails block validates and protects your AI workflows by checking content against multiple validation types. Ensure data quality, prevent hallucinations, detect PII, and enforce format requirements before content moves through your workflow.
El bloque Guardrails valida y protege tus flujos de trabajo de IA comprobando el contenido contra múltiples tipos de validación. Asegura la calidad de los datos, previene alucinaciones, detecta información personal identificable (PII) y aplica requisitos de formato antes de que el contenido avance por tu flujo de trabajo.
<div className="flex justify-center">
<Image
src="/static/blocks/guardrails.png"
alt="Guardrails Block"
alt="Bloque Guardrails"
width={500}
height={350}
className="my-6"
/>
</div>
## Overview
## Descripción general
The Guardrails block enables you to:
El bloque Guardrails te permite:
<Steps>
<Step>
<strong>Validate JSON Structure</strong>: Ensure LLM outputs are valid JSON before parsing
<strong>Validar estructura JSON</strong>: Asegura que las salidas de LLM sean JSON válido antes de analizarlas
</Step>
<Step>
<strong>Match Regex Patterns</strong>: Verify content matches specific formats (emails, phone numbers, URLs, etc.)
<strong>Coincidir con patrones Regex</strong>: Verifica que el contenido coincida con formatos específicos (correos electrónicos, números de teléfono, URLs, etc.)
</Step>
<Step>
<strong>Detect Hallucinations</strong>: Use RAG + LLM scoring to validate AI outputs against knowledge base content
<strong>Detectar alucinaciones</strong>: Utiliza puntuación RAG + LLM para validar las salidas de IA contra el contenido de la base de conocimientos
</Step>
<Step>
<strong>Detect PII</strong>: Identify and optionally mask personally identifiable information across 40+ entity types
<strong>Detectar PII</strong>: Identifica y opcionalmente enmascara información personal identificable en más de 40 tipos de entidades
</Step>
</Steps>
## Validation Types
## Tipos de validación
### JSON Validation
### Validación JSON
Validates that content is properly formatted JSON. Perfect for ensuring structured LLM outputs can be safely parsed.
Valida que el contenido tenga un formato JSON adecuado. Perfecto para garantizar que las salidas estructuradas de LLM puedan analizarse de forma segura.
**Use Cases:**
- Validate JSON responses from Agent blocks before parsing
- Ensure API payloads are properly formatted
- Check structured data integrity
**Casos de uso:**
- Validar respuestas JSON de bloques Agent antes de analizarlas
- Asegurar que las cargas útiles de API estén correctamente formateadas
- Comprobar la integridad de datos estructurados
**Output:**
- `passed`: `true` if valid JSON, `false` otherwise
- `error`: Error message if validation fails (e.g., "Invalid JSON: Unexpected token...")
- `passed`: `true` si es JSON válido, `false` en caso contrario
- `error`: Mensaje de error si la validación falla (p. ej., "JSON inválido: Token inesperado...")
### Regex Validation
### Validación Regex
Checks if content matches a specified regular expression pattern.
Comprueba si el contenido coincide con un patrón de expresión regular especificado.
**Use Cases:**
- Validate email addresses
- Check phone number formats
- Verify URLs or custom identifiers
- Enforce specific text patterns
**Casos de uso:**
- Validar direcciones de correo electrónico
- Comprobar formatos de números de teléfono
- Verificar URLs o identificadores personalizados
- Aplicar patrones de texto específicos
**Configuration:**
- **Regex Pattern**: The regular expression to match against (e.g., `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` for emails)
**Configuración:**
- **Patrón Regex**: La expresión regular para comparar (p. ej., `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$` para correos electrónicos)
**Output:**
- `passed`: `true` if content matches pattern, `false` otherwise
- `error`: Error message if validation fails
- `passed`: `true` si el contenido coincide con el patrón, `false` en caso contrario
- `error`: Mensaje de error si la validación falla
### Hallucination Detection
### Detección de alucinaciones
Uses Retrieval-Augmented Generation (RAG) with LLM scoring to detect when AI-generated content contradicts or isn't grounded in your knowledge base.
Utiliza generación aumentada por recuperación (RAG) con puntuación de LLM para detectar cuando el contenido generado por IA contradice o no está fundamentado en tu base de conocimientos.
**How It Works:**
1. Queries your knowledge base for relevant context
2. Sends both the AI output and retrieved context to an LLM
3. LLM assigns a confidence score (0-10 scale)
- **0** = Full hallucination (completely ungrounded)
- **10** = Fully grounded (completely supported by knowledge base)
4. Validation passes if score ≥ threshold (default: 3)
**Cómo funciona:**
1. Consulta tu base de conocimientos para obtener contexto relevante
2. Envía tanto la salida de la IA como el contexto recuperado a un LLM
3. El LLM asigna una puntuación de confianza (escala de 0-10)
- **0** = Alucinación completa (totalmente infundada)
- **10** = Completamente fundamentado (totalmente respaldado por la base de conocimientos)
4. La validación se aprueba si la puntuación ≥ umbral (predeterminado: 3)
**Configuration:**
- **Knowledge Base**: Select from your existing knowledge bases
- **Model**: Choose LLM for scoring (requires strong reasoning - GPT-4o, Claude 3.7 Sonnet recommended)
- **API Key**: Authentication for selected LLM provider (auto-hidden for hosted/Ollama models)
- **Confidence Threshold**: Minimum score to pass (0-10, default: 3)
- **Top K** (Advanced): Number of knowledge base chunks to retrieve (default: 10)
**Configuración:**
- **Base de conocimientos**: Selecciona entre tus bases de conocimientos existentes
- **Modelo**: Elige LLM para puntuación (requiere razonamiento sólido - se recomienda GPT-4o, Claude 3.7 Sonnet)
- **Clave API**: Autenticación para el proveedor LLM seleccionado (oculta automáticamente para modelos alojados/Ollama)
- **Umbral de confianza**: Puntuación mínima para aprobar (0-10, predeterminado: 3)
- **Top K** (Avanzado): Número de fragmentos de la base de conocimientos a recuperar (predeterminado: 10)
**Output:**
- `passed`: `true` if confidence score ≥ threshold
- `score`: Confidence score (0-10)
- `reasoning`: LLM's explanation for the score
- `error`: Error message if validation fails
- `passed`: `true` si la puntuación de confianza ≥ umbral
- `score`: Puntuación de confianza (0-10)
- `reasoning`: Explicación del LLM para la puntuación
- `error`: Mensaje de error si la validación falla
**Use Cases:**
- Validate Agent responses against documentation
- Ensure customer support answers are factually accurate
- Verify generated content matches source material
- Quality control for RAG applications
**Casos de uso:**
- Validar respuestas de agentes contra documentación
- Asegurar que las respuestas de atención al cliente sean precisas
- Verificar que el contenido generado coincida con el material de origen
- Control de calidad para aplicaciones RAG
### PII Detection
### Detección de PII
Detects personally identifiable information using Microsoft Presidio. Supports 40+ entity types across multiple countries and languages.
Detecta información de identificación personal utilizando Microsoft Presidio. Compatible con más de 40 tipos de entidades en múltiples países e idiomas.
<div className="mx-auto w-3/5 overflow-hidden rounded-lg">
<Video src="guardrails.mp4" width={500} height={350} />
</div>
**How It Works:**
1. Scans content for PII entities using pattern matching and NLP
2. Returns detected entities with locations and confidence scores
3. Optionally masks detected PII in the output
**Cómo funciona:**
1. Escanea el contenido en busca de entidades PII mediante coincidencia de patrones y PNL
2. Devuelve las entidades detectadas con ubicaciones y puntuaciones de confianza
3. Opcionalmente enmascara la PII detectada en la salida
**Configuration:**
- **PII Types to Detect**: Select from grouped categories via modal selector
- **Common**: Person name, Email, Phone, Credit card, IP address, etc.
- **USA**: SSN, Driver's license, Passport, etc.
- **UK**: NHS number, National insurance number
- **Spain**: NIF, NIE, CIF
- **Italy**: Fiscal code, Driver's license, VAT code
- **Poland**: PESEL, NIP, REGON
- **Singapore**: NRIC/FIN, UEN
**Configuración:**
- **Tipos de PII a detectar**: Seleccione de categorías agrupadas mediante selector modal
- **Común**: Nombre de persona, Email, Teléfono, Tarjeta de crédito, Dirección IP, etc.
- **EE.UU.**: SSN, Licencia de conducir, Pasaporte, etc.
- **Reino Unido**: Número NHS, Número de seguro nacional
- **España**: NIF, NIE, CIF
- **Italia**: Código fiscal, Licencia de conducir, Código de IVA
- **Polonia**: PESEL, NIP, REGON
- **Singapur**: NRIC/FIN, UEN
- **Australia**: ABN, ACN, TFN, Medicare
- **India**: Aadhaar, PAN, Passport, Voter number
- **Mode**:
- **Detect**: Only identify PII (default)
- **Mask**: Replace detected PII with masked values
- **Language**: Detection language (default: English)
- **India**: Aadhaar, PAN, Pasaporte, Número de votante
- **Modo**:
- **Detectar**: Solo identificar PII (predeterminado)
- **Enmascarar**: Reemplazar PII detectada con valores enmascarados
- **Idioma**: Idioma de detección (predeterminado: inglés)
**Output:**
- `passed`: `false` if any selected PII types are detected
- `detectedEntities`: Array of detected PII with type, location, and confidence
- `maskedText`: Content with PII masked (only if mode = "Mask")
- `error`: Error message if validation fails
**Salida:**
- `passed`: `false` si se detectan los tipos de PII seleccionados
- `detectedEntities`: Array de PII detectada con tipo, ubicación y confianza
- `maskedText`: Contenido con PII enmascarada (solo si modo = "Mask")
- `error`: Mensaje de error si la validación falla
**Use Cases:**
- Block content containing sensitive personal information
- Mask PII before logging or storing data
- Compliance with GDPR, HIPAA, and other privacy regulations
- Sanitize user inputs before processing
**Casos de uso:**
- Bloquear contenido que contiene información personal sensible
- Enmascarar PII antes de registrar o almacenar datos
- Cumplimiento con GDPR, HIPAA y otras regulaciones de privacidad
- Sanear entradas de usuario antes del procesamiento
## Configuration
## Configuración
### Content to Validate
### Contenido a validar
The input content to validate. This typically comes from:
- Agent block outputs: `<agent.content>`
- Function block results: `<function.output>`
- API responses: `<api.output>`
- Any other block output
El contenido de entrada para validar. Esto típicamente proviene de:
- Salidas de bloques de agente: `<agent.content>`
- Resultados de bloques de función: `<function.output>`
- Respuestas de API: `<api.output>`
- Cualquier otra salida de bloque
### Validation Type
### Tipo de validación
Choose from four validation types:
- **Valid JSON**: Check if content is properly formatted JSON
- **Regex Match**: Verify content matches a regex pattern
- **Hallucination Check**: Validate against knowledge base with LLM scoring
- **PII Detection**: Detect and optionally mask personally identifiable information
Elija entre cuatro tipos de validación:
- **JSON válido**: Comprobar si el contenido es JSON correctamente formateado
- **Coincidencia Regex**: Verificar si el contenido coincide con un patrón regex
- **Comprobación de alucinaciones**: Validar contra base de conocimiento con puntuación LLM
- **Detección de PII**: Detectar y opcionalmente enmascarar información de identificación personal
## Outputs
## Salidas
All validation types return:
Todos los tipos de validación devuelven:
- **`<guardrails.passed>`**: Boolean indicating if validation passed
- **`<guardrails.validationType>`**: The type of validation performed
- **`<guardrails.input>`**: The original input that was validated
- **`<guardrails.error>`**: Error message if validation failed (optional)
- **`<guardrails.passed>`**: Booleano que indica si la validación fue exitosa
- **`<guardrails.validationType>`**: El tipo de validación realizada
- **`<guardrails.input>`**: La entrada original que fue validada
- **`<guardrails.error>`**: Mensaje de error si la validación falló (opcional)
Additional outputs by type:
Salidas adicionales por tipo:
**Hallucination Check:**
- **`<guardrails.score>`**: Confidence score (0-10)
- **`<guardrails.reasoning>`**: LLM's explanation
**Verificación de alucinaciones:**
- **`<guardrails.score>`**: Puntuación de confianza (0-10)
- **`<guardrails.reasoning>`**: Explicación del LLM
**PII Detection:**
- **`<guardrails.detectedEntities>`**: Array of detected PII entities
- **`<guardrails.maskedText>`**: Content with PII masked (if mode = "Mask")
**Detección de PII:**
- **`<guardrails.detectedEntities>`**: Array de entidades PII detectadas
- **`<guardrails.maskedText>`**: Contenido con PII enmascarado (si el modo = "Mask")
## Example Use Cases
## Ejemplos de casos de uso
### Validate JSON Before Parsing
### Validar JSON antes de analizarlo
<div className="mb-4 rounded-md border p-4">
<h4 className="font-medium">Scenario: Ensure Agent output is valid JSON</h4>
<h4 className="font-medium">Escenario: Asegurar que la salida del agente sea JSON válido</h4>
<ol className="list-decimal pl-5 text-sm">
<li>Agent generates structured JSON response</li>
<li>Guardrails validates JSON format</li>
<li>Condition block checks `<guardrails.passed>`</li>
<li>If passed → Parse and use data, If failed → Retry or handle error</li>
<li>El agente genera una respuesta JSON estructurada</li>
<li>Guardrails valida el formato JSON</li>
<li>El bloque de condición verifica `<guardrails.passed>`</li>
<li>Si pasa → Analizar y usar datos, Si falla → Reintentar o manejar el error</li>
</ol>
</div>
### Prevent Hallucinations
### Prevenir alucinaciones
<div className="mb-4 rounded-md border p-4">
<h4 className="font-medium">Scenario: Validate customer support responses</h4>
<h4 className="font-medium">Escenario: Validar respuestas de atención al cliente</h4>
<ol className="list-decimal pl-5 text-sm">
<li>Agent generates response to customer question</li>
<li>Guardrails checks against support documentation knowledge base</li>
<li>If confidence score ≥ 3 → Send response</li>
<li>If confidence score \< 3 → Flag for human review</li>
<li>El agente genera una respuesta a la pregunta del cliente</li>
<li>Guardrails verifica contra la base de conocimientos de documentación de soporte</li>
<li>Si la puntuación de confianza ≥ 3 → Enviar respuesta</li>
<li>Si la puntuación de confianza \< 3 → Marcar para revisión humana</li>
</ol>
</div>
### Block PII in User Inputs
### Bloquear PII en entradas de usuario
<div className="mb-4 rounded-md border p-4">
<h4 className="font-medium">Scenario: Sanitize user-submitted content</h4>
<h4 className="font-medium">Escenario: Sanear contenido enviado por usuarios</h4>
<ol className="list-decimal pl-5 text-sm">
<li>User submits form with text content</li>
<li>Guardrails detects PII (emails, phone numbers, SSN, etc.)</li>
<li>If PII detected → Reject submission or mask sensitive data</li>
<li>If no PII → Process normally</li>
<li>El usuario envía un formulario con contenido de texto</li>
<li>Guardrails detecta PII (correos electrónicos, números de teléfono, SSN, etc.)</li>
<li>Si se detecta PII → Rechazar el envío o enmascarar datos sensibles</li>
<li>Si no hay PII → Procesar normalmente</li>
</ol>
</div>
@@ -222,30 +222,29 @@ Additional outputs by type:
<Video src="guardrails-example.mp4" width={500} height={350} />
</div>
### Validate Email Format
### Validar formato de correo electrónico
<div className="mb-4 rounded-md border p-4">
<h4 className="font-medium">Scenario: Check email address format</h4>
<h4 className="font-medium">Escenario: Comprobar el formato de dirección de correo electrónico</h4>
<ol className="list-decimal pl-5 text-sm">
<li>Agent extracts email from text</li>
<li>Guardrails validates with regex pattern</li>
<li>If valid → Use email for notification</li>
<li>If invalid → Request correction</li>
<li>El agente extrae el correo electrónico del texto</li>
<li>Guardrails valida con un patrón regex</li>
<li>Si es válido → Usar el correo electrónico para notificación</li>
<li>Si no es válidoSolicitar corrección</li>
</ol>
</div>
## Best Practices
## Mejores prácticas
- **Chain with Condition blocks**: Use `<guardrails.passed>` to branch workflow logic based on validation results
- **Use JSON validation before parsing**: Always validate JSON structure before attempting to parse LLM outputs
- **Choose appropriate PII types**: Only select the PII entity types relevant to your use case for better performance
- **Set reasonable confidence thresholds**: For hallucination detection, adjust threshold based on your accuracy requirements (higher = stricter)
- **Use strong models for hallucination detection**: GPT-4o or Claude 3.7 Sonnet provide more accurate confidence scoring
- **Mask PII for logging**: Use "Mask" mode when you need to log or store content that may contain PII
- **Test regex patterns**: Validate your regex patterns thoroughly before deploying to production
- **Monitor validation failures**: Track `<guardrails.error>` messages to identify common validation issues
- **Encadena con bloques de Condición**: Usa `<guardrails.passed>` para ramificar la lógica del flujo de trabajo según los resultados de validación
- **Usa validación JSON antes de analizar**: Siempre valida la estructura JSON antes de intentar analizar las salidas de LLM
- **Elige los tipos de PII apropiados**: Selecciona solo los tipos de entidades PII relevantes para tu caso de uso para un mejor rendimiento
- **Establece umbrales de confianza razonables**: Para la detección de alucinaciones, ajusta el umbral según tus requisitos de precisión (más alto = más estricto)
- **Usa modelos potentes para la detección de alucinaciones**: GPT-4o o Claude 3.7 Sonnet proporcionan una puntuación de confianza más precisa
- **Enmascara PII para el registro**: Usa el modo "Mask" cuando necesites registrar o almacenar contenido que pueda contener PII
- **Prueba patrones regex**: Valida tus patrones de expresiones regulares minuciosamente antes de implementarlos en producción
- **Monitorea fallos de validación**: Rastrea los mensajes `<guardrails.error>` para identificar problemas comunes de validación
<Callout type="info">
Guardrails validation happens synchronously in your workflow. For hallucination detection, choose faster models (like GPT-4o-mini) if latency is critical.
La validación de Guardrails ocurre de forma sincrónica en tu flujo de trabajo. Para la detección de alucinaciones, elige modelos más rápidos (como GPT-4o-mini) si la latencia es crítica.
</Callout>

View File

@@ -1,5 +1,5 @@
---
title: Bloques
title: Descripción general
description: Los componentes de construcción de tus flujos de trabajo de IA
---

View File

@@ -1,5 +1,5 @@
---
title: Conceptos básicos de conexión
title: Conceptos básicos
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Estructura de datos de conexión
title: Estructura de datos
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Conexiones
title: Descripción general
description: Conecta tus bloques entre sí.
---

View File

@@ -1,5 +1,5 @@
---
title: Etiquetas de conexión
title: Etiquetas
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -535,7 +535,7 @@ app.post('/sim-webhook', (req, res) => {
// Handle error...
} else {
console.log(`Workflow ${workflowId} completed: ${executionId}`);
console.log(`Cost: ${cost.total}`);
console.log(`Cost: $${cost.total}`);
// Process successful execution...
}
break;

View File

@@ -1,5 +1,5 @@
---
title: Conceptos básicos de ejecución
title: Conceptos básicos
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Ejecución
title: Descripción general
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Python SDK
title: Python
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -757,10 +757,6 @@ Configura el cliente usando variables de entorno:
</Step>
</Steps>
<Callout type="warning">
Mantén tu clave API segura y nunca la incluyas en el control de versiones. Utiliza variables de entorno o gestión de configuración segura.
</Callout>
## Requisitos
- Python 3.8+

View File

@@ -1,5 +1,5 @@
---
title: TypeScript/JavaScript SDK
title: TypeScript
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -7,10 +7,10 @@ import { Card, Cards } from 'fumadocs-ui/components/card'
import { Step, Steps } from 'fumadocs-ui/components/steps'
import { Tab, Tabs } from 'fumadocs-ui/components/tabs'
El SDK oficial de TypeScript/JavaScript para Sim proporciona seguridad de tipos completa y es compatible tanto con entornos Node.js como de navegador, lo que te permite ejecutar flujos de trabajo programáticamente desde tus aplicaciones Node.js, aplicaciones web y otros entornos JavaScript.
El SDK oficial de TypeScript/JavaScript para Sim proporciona seguridad de tipos completa y es compatible tanto con entornos Node.js como con navegadores, lo que te permite ejecutar flujos de trabajo programáticamente desde tus aplicaciones Node.js, aplicaciones web y otros entornos JavaScript.
<Callout type="info">
El SDK de TypeScript proporciona seguridad de tipos completa, soporte para ejecución asíncrona, limitación automática de velocidad con retroceso exponencial y seguimiento de uso.
El SDK de TypeScript proporciona seguridad de tipos completa, soporte para ejecución asíncrona, limitación automática de tasa con retroceso exponencial y seguimiento de uso.
</Callout>
## Instalación
@@ -96,12 +96,12 @@ const result = await client.executeWorkflow('workflow-id', {
- `input` (any): Datos de entrada para pasar al flujo de trabajo
- `timeout` (number): Tiempo de espera en milisegundos (predeterminado: 30000)
- `stream` (boolean): Habilitar respuestas en streaming (predeterminado: false)
- `selectedOutputs` (string[]): Bloquear salidas para transmitir en formato `blockName.attribute` (por ejemplo, `["agent1.content"]`)
- `selectedOutputs` (string[]): Salidas de bloques para transmitir en formato `blockName.attribute` (p. ej., `["agent1.content"]`)
- `async` (boolean): Ejecutar de forma asíncrona (predeterminado: false)
**Devuelve:** `Promise<WorkflowExecutionResult | AsyncExecutionResult>`
Cuando `async: true`, devuelve inmediatamente un ID de tarea para sondeo. De lo contrario, espera a que se complete.
Cuando `async: true`, devuelve inmediatamente un ID de tarea para consultar. De lo contrario, espera hasta completarse.
##### getWorkflowStatus()
@@ -146,7 +146,7 @@ if (status.status === 'completed') {
```
**Parámetros:**
- `taskId` (string): El ID de tarea devuelto de la ejecución asíncrona
- `taskId` (string): El ID de tarea devuelto por la ejecución asíncrona
**Devuelve:** `Promise<JobStatus>`
@@ -161,7 +161,7 @@ if (status.status === 'completed') {
##### executeWithRetry()
Ejecuta un flujo de trabajo con reintento automático en errores de límite de tasa utilizando retroceso exponencial.
Ejecutar un flujo de trabajo con reintento automático en errores de límite de tasa usando retroceso exponencial.
```typescript
const result = await client.executeWithRetry('workflow-id', {
@@ -247,7 +247,7 @@ console.log('Plan:', limits.usage.plan);
##### setApiKey()
Actualiza la clave API.
Actualiza la clave de API.
```typescript
client.setApiKey('new-api-key');
@@ -501,9 +501,9 @@ Configura el cliente usando variables de entorno:
</Tab>
</Tabs>
### Integración con Express de Node.js
### Integración con Node.js Express
Integra con un servidor Express.js:
Integración con un servidor Express.js:
```typescript
import express from 'express';
@@ -582,7 +582,7 @@ export default async function handler(
}
```
### Uso del navegador
### Uso en el navegador
Uso en el navegador (con configuración CORS adecuada):
@@ -604,19 +604,98 @@ async function executeClientSideWorkflow() {
});
console.log('Workflow result:', result);
// Update UI with result
document.getElementById('result')!.textContent =
document.getElementById('result')!.textContent =
JSON.stringify(result.output, null, 2);
} catch (error) {
console.error('Error:', error);
}
}
// Attach to button click
document.getElementById('executeBtn')?.addEventListener('click', executeClientSideWorkflow);
```
### Carga de archivos
Los objetos File son detectados automáticamente y convertidos a formato base64. Inclúyelos en tu entrada bajo el nombre de campo que coincida con el formato de entrada del disparador API de tu flujo de trabajo.
El SDK convierte los objetos File a este formato:
```typescript
{
type: 'file',
data: 'data:mime/type;base64,base64data',
name: 'filename',
mime: 'mime/type'
}
```
Alternativamente, puedes proporcionar archivos manualmente usando el formato URL:
```typescript
{
type: 'url',
data: 'https://example.com/file.pdf',
name: 'file.pdf',
mime: 'application/pdf'
}
```
<Tabs items={['Browser', 'Node.js']}>
<Tab value="Browser">
```typescript
import { SimStudioClient } from 'simstudio-ts-sdk';
const client = new SimStudioClient({
apiKey: process.env.NEXT_PUBLIC_SIM_API_KEY!
});
// From file input
async function handleFileUpload(event: Event) {
const input = event.target as HTMLInputElement;
const files = Array.from(input.files || []);
// Include files under the field name from your API trigger's input format
const result = await client.executeWorkflow('workflow-id', {
input: {
documents: files, // Must match your workflow's "files" field name
instructions: 'Analyze these documents'
}
});
console.log('Result:', result);
}
```
</Tab>
<Tab value="Node.js">
```typescript
import { SimStudioClient } from 'simstudio-ts-sdk';
import fs from 'fs';
const client = new SimStudioClient({
apiKey: process.env.SIM_API_KEY!
});
// Read file and create File object
const fileBuffer = fs.readFileSync('./document.pdf');
const file = new File([fileBuffer], 'document.pdf', {
type: 'application/pdf'
});
// Include files under the field name from your API trigger's input format
const result = await client.executeWorkflow('workflow-id', {
input: {
documents: [file], // Must match your workflow's "files" field name
query: 'Summarize this document'
}
});
```
</Tab>
</Tabs>
<Callout type="warning">
Cuando uses el SDK en el navegador, ten cuidado de no exponer claves API sensibles. Considera usar un proxy de backend o claves API públicas con permisos limitados.
</Callout>
@@ -748,9 +827,9 @@ async function executeAsync() {
executeAsync();
```
### Límite de tasa y reintentos
### Limitación de tasa y reintentos
Maneja límites de tasa automáticamente con retroceso exponencial:
Maneja los límites de tasa automáticamente con retroceso exponencial:
```typescript
import { SimStudioClient, SimStudioError } from 'simstudio-ts-sdk';
@@ -788,7 +867,7 @@ async function executeWithRetryHandling() {
### Monitoreo de uso
Monitorea el uso de tu cuenta y sus límites:
Monitorea el uso y los límites de tu cuenta:
```typescript
import { SimStudioClient } from 'simstudio-ts-sdk';
@@ -814,19 +893,19 @@ async function checkUsage() {
console.log(' Resets at:', limits.rateLimit.async.resetAt);
console.log(' Is limited:', limits.rateLimit.async.isLimited);
console.log('\n=== Uso ===');
console.log('Costo del período actual: $' + limits.usage.currentPeriodCost.toFixed(2));
console.log('Límite: $' + limits.usage.limit.toFixed(2));
console.log('\n=== Usage ===');
console.log('Current period cost: $' + limits.usage.currentPeriodCost.toFixed(2));
console.log('Limit: $' + limits.usage.limit.toFixed(2));
console.log('Plan:', limits.usage.plan);
const percentUsed = (limits.usage.currentPeriodCost / limits.usage.limit) * 100;
console.log('Uso: ' + percentUsed.toFixed(1) + '%');
console.log('Usage: ' + percentUsed.toFixed(1) + '%');
if (percentUsed > 80) {
console.warn('⚠️ Advertencia: ¡Estás acercándote a tu límite de uso!');
console.warn('⚠️ Warning: You are approaching your usage limit!');
}
} catch (error) {
console.error('Error al verificar el uso:', error);
console.error('Error checking usage:', error);
}
}
@@ -846,40 +925,35 @@ const client = new SimStudioClient({
async function executeWithStreaming() {
try {
// Habilita streaming para salidas de bloques específicos
// Enable streaming for specific block outputs
const result = await client.executeWorkflow('workflow-id', {
input: { message: 'Count to five' },
stream: true,
selectedOutputs: ['agent1.content'] // Usa el formato blockName.attribute
selectedOutputs: ['agent1.content'] // Use blockName.attribute format
});
console.log('Resultado del flujo de trabajo:', result);
console.log('Workflow result:', result);
} catch (error) {
console.error('Error:', error);
}
}
```
The streaming response follows the Server-Sent Events (SSE) format:
La respuesta en streaming sigue el formato de eventos enviados por el servidor (SSE):
```
data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"}
data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", dos"}
data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", two"}
data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}}
data: [DONE]
```
**React Streaming Example:**
**Ejemplo de streaming en React:**
```
typescript
```typescript
import { useState, useEffect } from 'react';
function StreamingWorkflow() {
@@ -941,44 +1015,39 @@ function StreamingWorkflow() {
return (
<div>
<button onClick={executeStreaming} disabled={loading}>
{loading ? 'Generando...' : 'Iniciar streaming'}
{loading ? 'Generating...' : 'Start Streaming'}
</button>
<div style={{ whiteSpace: 'pre-wrap' }}>{output}</div>
</div>
);
}
```
## Getting Your API Key
## Obtener tu clave API
<Steps>
<Step title="Log in to Sim">
Navigate to [Sim](https://sim.ai) and log in to your account.
<Step title="Inicia sesión en Sim">
Navega a [Sim](https://sim.ai) e inicia sesión en tu cuenta.
</Step>
<Step title="Open your workflow">
Navigate to the workflow you want to execute programmatically.
<Step title="Abre tu flujo de trabajo">
Navega al flujo de trabajo que quieres ejecutar programáticamente.
</Step>
<Step title="Deploy your workflow">
Click on "Deploy" to deploy your workflow if it hasn't been deployed yet.
<Step title="Despliega tu flujo de trabajo">
Haz clic en "Desplegar" para desplegar tu flujo de trabajo si aún no ha sido desplegado.
</Step>
<Step title="Create or select an API key">
During the deployment process, select or create an API key.
<Step title="Crea o selecciona una clave API">
Durante el proceso de despliegue, selecciona o crea una clave API.
</Step>
<Step title="Copy the API key">
Copy the API key to use in your TypeScript/JavaScript application.
<Step title="Copia la clave API">
Copia la clave API para usarla en tu aplicación TypeScript/JavaScript.
</Step>
</Steps>
<Callout type="warning">
Keep your API key secure and never commit it to version control. Use environment variables or secure configuration management.
</Callout>
## Requirements
## Requisitos
- Node.js 16+
- TypeScript 5.0+ (for TypeScript projects)
- TypeScript 5.0+ (para proyectos TypeScript)
## License
## Licencia
Apache-2.0

View File

@@ -207,18 +207,18 @@ Poblar Clay con datos de un archivo JSON. Permite comunicación directa y notifi
#### Entrada
| Parámetro | Tipo | Requerido | Descripción |
| --------- | ---- | -------- | ----------- |
| `webhookURL` | string | Sí | La URL del webhook para poblar |
| `data` | json | Sí | Los datos para poblar |
| `authToken` | string | | Token de autenticación para la autenticación del webhook de Clay |
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | ----------- | ----------- |
| `webhookURL` | string | Sí | La URL del webhook a completar |
| `data` | json | Sí | Los datos para completar |
| `authToken` | string | No | Token de autenticación opcional para la autenticación del webhook de Clay \(la mayoría de los webhooks no requieren esto\) |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `success` | boolean | Estado de éxito de la operación |
| `output` | json | Resultados de la operación de poblado de Clay incluyendo datos de respuesta del webhook de Clay |
| `data` | json | Datos de respuesta del webhook de Clay |
| `metadata` | object | Metadatos de respuesta del webhook |
## Notas

View File

@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="discord"
color="#E0E0E0"
color="#5865F2"
icon={true}
iconSvg={`<svg className="block-icon"
@@ -67,11 +67,12 @@ Enviar un mensaje a un canal de Discord
#### Entrada
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | ----------- | ----------- |
| --------- | ---- | -------- | ----------- |
| `botToken` | string | Sí | El token del bot para autenticación |
| `channelId` | string | Sí | El ID del canal de Discord donde enviar el mensaje |
| `channelId` | string | Sí | El ID del canal de Discord al que enviar el mensaje |
| `content` | string | No | El contenido de texto del mensaje |
| `serverId` | string | Sí | El ID del servidor de Discord \(ID del guild\) |
| `files` | file[] | No | Archivos para adjuntar al mensaje |
#### Salida

View File

@@ -22,7 +22,210 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
</svg>`}
/>
## Descripción general
El bloque de Webhook Genérico te permite recibir webhooks desde cualquier servicio externo. Este es un disparador flexible que puede manejar cualquier carga útil JSON, lo que lo hace ideal para integrarse con servicios que no tienen un bloque Sim dedicado.
## Uso básico
### Modo de paso simple
Sin definir un formato de entrada, el webhook transmite todo el cuerpo de la solicitud tal como está:
```bash
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret" \
-d '{
"message": "Test webhook trigger",
"data": {
"key": "value"
}
}'
```
Accede a los datos en bloques posteriores usando:
- `<webhook1.message>` → "Test webhook trigger"
- `<webhook1.data.key>` → "value"
### Formato de entrada estructurado (opcional)
Define un esquema de entrada para obtener campos tipados y habilitar funciones avanzadas como cargas de archivos:
**Configuración del formato de entrada:**
```json
[
{ "name": "message", "type": "string" },
{ "name": "priority", "type": "number" },
{ "name": "documents", "type": "files" }
]
```
**Solicitud de webhook:**
```bash
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret" \
-d '{
"message": "Invoice submission",
"priority": 1,
"documents": [
{
"type": "file",
"data": "data:application/pdf;base64,JVBERi0xLjQK...",
"name": "invoice.pdf",
"mime": "application/pdf"
}
]
}'
```
## Cargas de archivos
### Formatos de archivo compatibles
El webhook admite dos formatos de entrada de archivos:
#### 1. Archivos codificados en Base64
Para cargar contenido de archivos directamente:
```json
{
"documents": [
{
"type": "file",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA...",
"name": "screenshot.png",
"mime": "image/png"
}
]
}
```
- **Tamaño máximo**: 20MB por archivo
- **Formato**: URL de datos estándar con codificación base64
- **Almacenamiento**: Los archivos se cargan en un almacenamiento de ejecución seguro
#### 2. Referencias URL
Para pasar URLs de archivos existentes:
```json
{
"documents": [
{
"type": "url",
"data": "https://example.com/files/document.pdf",
"name": "document.pdf",
"mime": "application/pdf"
}
]
}
```
### Acceso a archivos en bloques posteriores
Los archivos se procesan en objetos `UserFile` con las siguientes propiedades:
```typescript
{
id: string, // Unique file identifier
name: string, // Original filename
url: string, // Presigned URL (valid for 5 minutes)
size: number, // File size in bytes
type: string, // MIME type
key: string, // Storage key
uploadedAt: string, // ISO timestamp
expiresAt: string // ISO timestamp (5 minutes)
}
```
**Acceso en bloques:**
- `<webhook1.documents[0].url>` → URL de descarga
- `<webhook1.documents[0].name>` → "invoice.pdf"
- `<webhook1.documents[0].size>` → 524288
- `<webhook1.documents[0].type>` → "application/pdf"
### Ejemplo completo de carga de archivos
```bash
# Create a base64-encoded file
echo "Hello World" | base64
# SGVsbG8gV29ybGQK
# Send webhook with file
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret" \
-d '{
"subject": "Document for review",
"attachments": [
{
"type": "file",
"data": "data:text/plain;base64,SGVsbG8gV29ybGQK",
"name": "sample.txt",
"mime": "text/plain"
}
]
}'
```
## Autenticación
### Configurar autenticación (opcional)
En la configuración del webhook:
1. Habilita "Requerir autenticación"
2. Establece un token secreto
3. Elige el tipo de encabezado:
- **Encabezado personalizado**: `X-Sim-Secret: your-token`
- **Autorización Bearer**: `Authorization: Bearer your-token`
### Uso de la autenticación
```bash
# With custom header
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "X-Sim-Secret: your-secret-token" \
-d '{"message": "Authenticated request"}'
# With bearer token
curl -X POST https://sim.ai/api/webhooks/trigger/{webhook-path} \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-secret-token" \
-d '{"message": "Authenticated request"}'
```
## Mejores prácticas
1. **Usa formato de entrada para la estructura**: define un formato de entrada cuando conozcas el esquema esperado. Esto proporciona:
- Validación de tipo
- Mejor autocompletado en el editor
- Capacidades de carga de archivos
2. **Autenticación**: habilita siempre la autenticación para webhooks en producción para prevenir accesos no autorizados.
3. **Límites de tamaño de archivo**: mantén los archivos por debajo de 20MB. Para archivos más grandes, usa referencias URL en su lugar.
4. **Caducidad de archivos**: los archivos descargados tienen URLs con caducidad de 5 minutos. Procésalos rápidamente o almacénalos en otro lugar si los necesitas por más tiempo.
5. **Manejo de errores**: el procesamiento de webhooks es asíncrono. Revisa los registros de ejecución para ver errores.
6. **Pruebas**: usa el botón "Probar webhook" en el editor para validar tu configuración antes de implementarla.
## Casos de uso
- **Envíos de formularios**: recibe datos de formularios personalizados con cargas de archivos
- **Integraciones con terceros**: conéctate con servicios que envían webhooks (Stripe, GitHub, etc.)
- **Procesamiento de documentos**: acepta documentos de sistemas externos para procesamiento
- **Notificaciones de eventos**: recibe datos de eventos de varias fuentes
- **APIs personalizadas**: construye endpoints de API personalizados para tus aplicaciones
## Notas
- Categoría: `triggers`
- Tipo: `generic_webhook`
- **Soporte de archivos**: disponible a través de la configuración del formato de entrada
- **Tamaño máximo de archivo**: 20MB por archivo

View File

@@ -65,8 +65,9 @@ Enviar correos electrónicos usando Gmail
| `to` | string | Sí | Dirección de correo electrónico del destinatario |
| `subject` | string | Sí | Asunto del correo electrónico |
| `body` | string | Sí | Contenido del cuerpo del correo electrónico |
| `cc` | string | No | Destinatarios en CC \(separados por comas\) |
| `bcc` | string | No | Destinatarios en CCO \(separados por comas\) |
| `cc` | string | No | Destinatarios en CC (separados por comas) |
| `bcc` | string | No | Destinatarios en CCO (separados por comas) |
| `attachments` | file[] | No | Archivos para adjuntar al correo electrónico |
#### Salida
@@ -86,8 +87,9 @@ Crear borradores de correos electrónicos usando Gmail
| `to` | string | Sí | Dirección de correo electrónico del destinatario |
| `subject` | string | Sí | Asunto del correo electrónico |
| `body` | string | Sí | Contenido del cuerpo del correo electrónico |
| `cc` | string | No | Destinatarios en CC \(separados por comas\) |
| `bcc` | string | No | Destinatarios en CCO \(separados por comas\) |
| `cc` | string | No | Destinatarios en CC (separados por comas) |
| `bcc` | string | No | Destinatarios en CCO (separados por comas) |
| `attachments` | file[] | No | Archivos para adjuntar al borrador del correo electrónico |
#### Salida

Some files were not shown because too many files have changed in this diff Show More