Compare commits

...

22 Commits

Author SHA1 Message Date
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
277 changed files with 20628 additions and 3070 deletions

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,7 @@ 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 { source } from '@/lib/source'
export const dynamic = 'force-dynamic'
@@ -22,31 +23,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 +170,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}
@@ -82,7 +196,12 @@ export default async function Page(props: { params: Promise<{ slug?: string[]; l
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX components={defaultMdxComponents} />
<MDX
components={{
...defaultMdxComponents,
CodeBlock,
}}
/>
</DocsBody>
</DocsPage>
</>
@@ -128,8 +247,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 +273,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,426 @@
: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)));
--toc-offset: var(--edge-gutter);
/* 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;
}
[data-toc] {
margin-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 +462,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-[2000px] 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='grid w-full grid-cols-[auto_1fr_auto] items-center'
style={{
paddingLeft: 'calc(var(--sidebar-offset) + 20px)',
paddingRight: 'calc(var(--toc-offset) + 20px)',
}}
>
{/* Left cluster: translate by sidebar delta to align with sidebar edge */}
<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 */}
<div className='flex flex-1 items-center justify-center'>
<SearchTrigger />
</div>
{/* Right cluster aligns with TOC edge using the same right gutter */}
<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

@@ -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-[500px] 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

@@ -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

@@ -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'
@@ -1043,10 +1043,6 @@ function StreamingWorkflow() {
</Step>
</Steps>
<Callout type="warning">
Halten Sie Ihren API-Schlüssel sicher und committen Sie ihn niemals in die Versionskontrolle. Verwenden Sie Umgebungsvariablen oder sicheres Konfigurationsmanagement.
</Callout>
## Anforderungen
- Node.js 16+

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

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

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

@@ -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'
@@ -1026,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

@@ -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

@@ -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",

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

@@ -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

@@ -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

@@ -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: SDK de TypeScript/JavaScript
title: TypeScript
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -1043,10 +1043,6 @@ function StreamingWorkflow() {
</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 segura de configuración.
</Callout>
## Requisitos
- Node.js 16+

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

View File

@@ -1,5 +1,5 @@
---
title: Herramientas
title: Descripción general
description: Herramientas potentes para mejorar tus flujos de trabajo agénticos
---

View File

@@ -1,6 +1,6 @@
---
title: S3
description: Ver archivos S3
description: Subir, descargar, listar y gestionar archivos S3
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
@@ -61,20 +61,45 @@ En Sim, la integración con S3 permite a tus agentes recuperar y acceder a archi
## Instrucciones de uso
Integrar S3 en el flujo de trabajo. Puede obtener URLs prefirmadas para objetos S3. Requiere clave de acceso y clave de acceso secreta.
Integra S3 en el flujo de trabajo. Sube archivos, descarga objetos, lista contenidos de buckets, elimina objetos y copia objetos entre buckets. Requiere clave de acceso AWS y clave de acceso secreta.
## Herramientas
### `s3_get_object`
### `s3_put_object`
Recuperar un objeto de un bucket de AWS S3
Subir un archivo a un bucket de AWS S3
#### Entrada
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | ---------- | ----------- |
| `accessKeyId` | string | Sí | Tu ID de clave de acceso de AWS |
| `secretAccessKey` | string | Sí | Tu clave de acceso secreta de AWS |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Sí | Tu ID de clave de acceso AWS |
| `secretAccessKey` | string | Sí | Tu clave de acceso secreta AWS |
| `region` | string | Sí | Región AWS (ej., us-east-1) |
| `bucketName` | string | Sí | Nombre del bucket S3 |
| `objectKey` | string | Sí | Clave/ruta del objeto en S3 (ej., carpeta/archivo.ext) |
| `file` | file | No | Archivo para subir |
| `content` | string | No | Contenido de texto para subir (alternativa al archivo) |
| `contentType` | string | No | Cabecera Content-Type (autodetectada del archivo si no se proporciona) |
| `acl` | string | No | Lista de control de acceso (ej., private, public-read) |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `url` | string | URL del objeto S3 subido |
| `metadata` | object | Metadatos de subida incluyendo ETag y ubicación |
### `s3_get_object`
Recuperar un objeto de un bucket AWS S3
#### Entrada
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Sí | Tu ID de clave de acceso AWS |
| `secretAccessKey` | string | Sí | Tu clave de acceso secreta AWS |
| `s3Uri` | string | Sí | URL del objeto S3 |
#### Salida
@@ -84,6 +109,73 @@ Recuperar un objeto de un bucket de AWS S3
| `url` | string | URL prefirmada para descargar el objeto S3 |
| `metadata` | object | Metadatos del archivo incluyendo tipo, tamaño, nombre y fecha de última modificación |
### `s3_list_objects`
Listar objetos en un bucket de AWS S3
#### Entrada
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | ---------- | ----------- |
| `accessKeyId` | string | Sí | Tu ID de clave de acceso de AWS |
| `secretAccessKey` | string | Sí | Tu clave de acceso secreta de AWS |
| `region` | string | Sí | Región de AWS (p. ej., us-east-1) |
| `bucketName` | string | Sí | Nombre del bucket S3 |
| `prefix` | string | No | Prefijo para filtrar objetos (p. ej., carpeta/) |
| `maxKeys` | number | No | Número máximo de objetos a devolver (predeterminado: 1000) |
| `continuationToken` | string | No | Token para paginación |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `objects` | array | Lista de objetos S3 |
### `s3_delete_object`
Eliminar un objeto de un bucket de AWS S3
#### Entrada
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | ---------- | ----------- |
| `accessKeyId` | string | Sí | Tu ID de clave de acceso de AWS |
| `secretAccessKey` | string | Sí | Tu clave de acceso secreta de AWS |
| `region` | string | Sí | Región de AWS (p. ej., us-east-1) |
| `bucketName` | string | Sí | Nombre del bucket S3 |
| `objectKey` | string | Sí | Clave/ruta del objeto a eliminar |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `deleted` | boolean | Indica si el objeto fue eliminado correctamente |
| `metadata` | object | Metadatos de la eliminación |
### `s3_copy_object`
Copiar un objeto dentro de o entre buckets de AWS S3
#### Entrada
| Parámetro | Tipo | Obligatorio | Descripción |
| --------- | ---- | ---------- | ----------- |
| `accessKeyId` | string | Sí | Tu ID de clave de acceso de AWS |
| `secretAccessKey` | string | Sí | Tu clave de acceso secreta de AWS |
| `region` | string | Sí | Región de AWS (p. ej., us-east-1) |
| `sourceBucket` | string | Sí | Nombre del bucket de origen |
| `sourceKey` | string | Sí | Clave/ruta del objeto de origen |
| `destinationBucket` | string | Sí | Nombre del bucket de destino |
| `destinationKey` | string | Sí | Clave/ruta del objeto de destino |
| `acl` | string | No | Lista de control de acceso para el objeto copiado (p. ej., private, public-read) |
#### Salida
| Parámetro | Tipo | Descripción |
| --------- | ---- | ----------- |
| `url` | string | URL del objeto S3 copiado |
| `metadata` | object | Metadatos de la operación de copia |
## Notas
- Categoría: `tools`

View File

@@ -1,5 +1,5 @@
---
title: Disparadores
title: Descripción general
description: Formas principales de iniciar flujos de trabajo de Sim
---

View File

@@ -1,5 +1,5 @@
---
title: Blocs
title: Aperçu
description: Les composants de construction de vos flux de travail IA
---

View File

@@ -1,5 +1,5 @@
---
title: Principes de base des connexions
title: Principes de base
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Structure de données de connexion
title: Structure de données
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Connexions
title: Aperçu
description: Connectez vos blocs les uns aux autres.
---

View File

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

View File

@@ -1,5 +1,5 @@
---
title: Principes de base de l'exécution
title: Principes de base
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: Exécution
title: Aperçu
---
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 @@ Configurez le client en utilisant des variables d'environnement :
</Step>
</Steps>
<Callout type="warning">
Gardez votre clé API sécurisée et ne la soumettez jamais au contrôle de version. Utilisez des variables d'environnement ou une gestion de configuration sécurisée.
</Callout>
## Prérequis
- Python 3.8+

View File

@@ -1,5 +1,5 @@
---
title: SDK TypeScript/JavaScript
title: TypeScript
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -1043,10 +1043,6 @@ function StreamingWorkflow() {
</Step>
</Steps>
<Callout type="warning">
Gardez votre clé API en sécurité et ne la publiez jamais dans un système de contrôle de version. Utilisez des variables d'environnement ou une gestion sécurisée de configuration.
</Callout>
## Prérequis
- Node.js 16+

View File

@@ -62,12 +62,13 @@ Envoyer des e-mails via Gmail
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | -------- | ----------- |
| --------- | ---- | ---------- | ----------- |
| `to` | chaîne | Oui | Adresse e-mail du destinataire |
| `subject` | chaîne | Oui | Objet de l'e-mail |
| `body` | chaîne | Oui | Contenu du corps de l'e-mail |
| `cc` | chaîne | Non | Destinataires en CC \(séparés par des virgules\) |
| `bcc` | chaîne | Non | Destinataires en BCC \(séparés par des virgules\) |
| `attachments` | fichier[] | Non | Fichiers à joindre à l'e-mail |
#### Sortie
@@ -83,12 +84,13 @@ Créer des brouillons d'e-mails avec Gmail
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | -------- | ----------- |
| --------- | ---- | ---------- | ----------- |
| `to` | chaîne | Oui | Adresse e-mail du destinataire |
| `subject` | chaîne | Oui | Objet de l'e-mail |
| `body` | chaîne | Oui | Contenu du corps de l'e-mail |
| `cc` | chaîne | Non | Destinataires en CC \(séparés par des virgules\) |
| `bcc` | chaîne | Non | Destinataires en BCC \(séparés par des virgules\) |
| `attachments` | fichier[] | Non | Fichiers à joindre au brouillon d'e-mail |
#### Sortie

View File

@@ -1,5 +1,5 @@
---
title: Outils
title: Aperçu
description: Des outils puissants pour améliorer vos flux de travail agentiques
---

View File

@@ -1,6 +1,6 @@
---
title: S3
description: Afficher les fichiers S3
description: Téléverser, télécharger, lister et gérer les fichiers S3
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
@@ -61,10 +61,35 @@ Dans Sim, l'intégration S3 permet à vos agents de récupérer et d'accéder au
## Instructions d'utilisation
Intégrer S3 dans le flux de travail. Peut obtenir des URL présignées pour les objets S3. Nécessite une clé d'accès et une clé d'accès secrète.
Intégrez S3 dans le flux de travail. Téléversez des fichiers, téléchargez des objets, listez le contenu des buckets, supprimez des objets et copiez des objets entre buckets. Nécessite une clé d'accès AWS et une clé d'accès secrète AWS.
## Outils
### `s3_put_object`
Téléverser un fichier vers un bucket AWS S3
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Oui | Votre ID de clé d'accès AWS |
| `secretAccessKey` | string | Oui | Votre clé d'accès secrète AWS |
| `region` | string | Oui | Région AWS (ex. : us-east-1) |
| `bucketName` | string | Oui | Nom du bucket S3 |
| `objectKey` | string | Oui | Clé/chemin de l'objet dans S3 (ex. : dossier/nomfichier.ext) |
| `file` | file | Non | Fichier à téléverser |
| `content` | string | Non | Contenu textuel à téléverser (alternative au fichier) |
| `contentType` | string | Non | En-tête Content-Type (détecté automatiquement à partir du fichier si non fourni) |
| `acl` | string | Non | Liste de contrôle d'accès (ex. : private, public-read) |
#### Sortie
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `url` | string | URL de l'objet S3 téléversé |
| `metadata` | object | Métadonnées de téléversement incluant ETag et emplacement |
### `s3_get_object`
Récupérer un objet depuis un bucket AWS S3
@@ -72,10 +97,10 @@ Récupérer un objet depuis un bucket AWS S3
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `accessKeyId` | chaîne | Oui | Votre ID de clé d'accès AWS |
| `secretAccessKey` | chaîne | Oui | Votre clé d'accès secrète AWS |
| `s3Uri` | chaîne | Oui | URL de l'objet S3 |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | Oui | Votre ID de clé d'accès AWS |
| `secretAccessKey` | string | Oui | Votre clé d'accès secrète AWS |
| `s3Uri` | string | Oui | URL de l'objet S3 |
#### Sortie
@@ -84,6 +109,73 @@ Récupérer un objet depuis un bucket AWS S3
| `url` | chaîne | URL présignée pour télécharger l'objet S3 |
| `metadata` | objet | Métadonnées du fichier incluant le type, la taille, le nom et la date de dernière modification |
### `s3_list_objects`
Lister les objets dans un bucket AWS S3
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `accessKeyId` | chaîne | Oui | Votre ID de clé d'accès AWS |
| `secretAccessKey` | chaîne | Oui | Votre clé d'accès secrète AWS |
| `region` | chaîne | Oui | Région AWS (par ex., us-east-1) |
| `bucketName` | chaîne | Oui | Nom du bucket S3 |
| `prefix` | chaîne | Non | Préfixe pour filtrer les objets (par ex., dossier/) |
| `maxKeys` | nombre | Non | Nombre maximum d'objets à retourner (par défaut : 1000) |
| `continuationToken` | chaîne | Non | Jeton pour la pagination |
#### Sortie
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `objects` | tableau | Liste des objets S3 |
### `s3_delete_object`
Supprimer un objet d'un bucket AWS S3
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `accessKeyId` | chaîne | Oui | Votre ID de clé d'accès AWS |
| `secretAccessKey` | chaîne | Oui | Votre clé d'accès secrète AWS |
| `region` | chaîne | Oui | Région AWS (par ex., us-east-1) |
| `bucketName` | chaîne | Oui | Nom du bucket S3 |
| `objectKey` | chaîne | Oui | Clé/chemin de l'objet à supprimer |
#### Sortie
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `deleted` | booléen | Indique si l'objet a été supprimé avec succès |
| `metadata` | objet | Métadonnées de suppression |
### `s3_copy_object`
Copier un objet au sein d'un même bucket AWS S3 ou entre différents buckets
#### Entrée
| Paramètre | Type | Obligatoire | Description |
| --------- | ---- | ---------- | ----------- |
| `accessKeyId` | chaîne | Oui | Votre ID de clé d'accès AWS |
| `secretAccessKey` | chaîne | Oui | Votre clé d'accès secrète AWS |
| `region` | chaîne | Oui | Région AWS (par ex., us-east-1) |
| `sourceBucket` | chaîne | Oui | Nom du bucket source |
| `sourceKey` | chaîne | Oui | Clé/chemin de l'objet source |
| `destinationBucket` | chaîne | Oui | Nom du bucket de destination |
| `destinationKey` | chaîne | Oui | Clé/chemin de l'objet de destination |
| `acl` | chaîne | Non | Liste de contrôle d'accès pour l'objet copié (par ex., private, public-read) |
#### Sortie
| Paramètre | Type | Description |
| --------- | ---- | ----------- |
| `url` | chaîne | URL de l'objet S3 copié |
| `metadata` | objet | Métadonnées de l'opération de copie |
## Remarques
- Catégorie : `tools`

View File

@@ -1,5 +1,5 @@
---
title: Déclencheurs
title: Aperçu
description: Méthodes principales pour démarrer les workflows Sim
---

View File

@@ -1,5 +1,5 @@
---
title: ブロック
title: 概要
description: AIワークフローの構成要素
---

View File

@@ -1,5 +1,5 @@
---
title: 接続の基本
title: 基本
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: 接続データ構造
title: データ構造
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: 接続
title: 概要
description: ブロック同士を接続します。
---

View File

@@ -1,5 +1,5 @@
---
title: 接続タグ
title: タグ
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: 実行の基本
title: 基本
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: 実行
title: 概要
---
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 @@ if __name__ == '__main__':
</Step>
</Steps>
<Callout type="warning">
APIキーを安全に保管し、決してバージョン管理にコミットしないでください。環境変数や安全な設定管理を使用してください。
</Callout>
## 要件
- Python 3.8+

View File

@@ -1,5 +1,5 @@
---
title: TypeScript/JavaScript SDK
title: TypeScript
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -1043,14 +1043,10 @@ function StreamingWorkflow() {
</Step>
</Steps>
<Callout type="warning">
APIキーは安全に保管し、バージョン管理システムにコミットしないでください。環境変数や安全な設定管理を使用してください。
</Callout>
## 要件
- Node.js 16以上
- TypeScript 5.0以上TypeScriptプロジェクトの場合
- Node.js 16+
- TypeScript 5.0+TypeScriptプロジェクト
## ライセンス

View File

@@ -64,9 +64,10 @@ Gmailを使用してメールを送信する
| --------- | ---- | -------- | ----------- |
| `to` | string | はい | 受信者のメールアドレス |
| `subject` | string | はい | メールの件名 |
| `body` | string | はい | メール本文 |
| `body` | string | はい | メール本文の内容 |
| `cc` | string | いいえ | CCの受信者カンマ区切り |
| `bcc` | string | いいえ | BCCの受信者カンマ区切り |
| `attachments` | file[] | いいえ | メールに添付するファイル |
#### 出力
@@ -85,9 +86,10 @@ Gmailを使用してメールの下書きを作成する
| --------- | ---- | -------- | ----------- |
| `to` | string | はい | 受信者のメールアドレス |
| `subject` | string | はい | メールの件名 |
| `body` | string | はい | メール本文 |
| `body` | string | はい | メール本文の内容 |
| `cc` | string | いいえ | CCの受信者カンマ区切り |
| `bcc` | string | いいえ | BCCの受信者カンマ区切り |
| `attachments` | file[] | いいえ | メール下書きに添付するファイル |
#### 出力

View File

@@ -1,5 +1,5 @@
---
title: ツール
title: 概要
description: エージェントワークフローを強化するパワフルなツール
---

View File

@@ -1,6 +1,6 @@
---
title: S3
description: S3ファイルを表示
description: S3ファイルのアップロード、ダウンロード、一覧表示、管理
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
@@ -61,10 +61,35 @@ Simでは、S3統合によりエージェントがAmazon S3バケットに保存
## 使用手順
S3をワークフローに統合します。S3オブジェクトの署名付きURLを取得できます。アクセスキーとシークレットアクセスキーが必要です。
S3をワークフローに統合します。ファイルのアップロード、オブジェクトのダウンロード、バケットの内容一覧表示、オブジェクトの削除、バケット間でのオブジェクトのコピーが可能です。AWSアクセスキーとシークレットアクセスキーが必要です。
## ツール
### `s3_put_object`
AWS S3バケットにファイルをアップロードする
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | はい | AWSアクセスキーID |
| `secretAccessKey` | string | はい | AWSシークレットアクセスキー |
| `region` | string | はい | AWSリージョンus-east-1 |
| `bucketName` | string | はい | S3バケット名 |
| `objectKey` | string | はい | S3内のオブジェクトキー/パスfolder/filename.ext |
| `file` | file | いいえ | アップロードするファイル |
| `content` | string | いいえ | アップロードするテキストコンテンツ(ファイルの代わり) |
| `contentType` | string | いいえ | Content-Typeヘッダー指定がない場合はファイルから自動検出 |
| `acl` | string | いいえ | アクセスコントロールリストprivate, public-read |
#### 出力
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `url` | string | アップロードされたS3オブジェクトのURL |
| `metadata` | object | ETagと場所を含むアップロードメタデータ |
### `s3_get_object`
AWS S3バケットからオブジェクトを取得する
@@ -73,8 +98,8 @@ AWS S3バケットからオブジェクトを取得する
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | はい | AWS アクセスキーID |
| `secretAccessKey` | string | はい | AWS シークレットアクセスキー |
| `accessKeyId` | string | はい | AWSアクセスキーID |
| `secretAccessKey` | string | はい | AWSシークレットアクセスキー |
| `s3Uri` | string | はい | S3オブジェクトURL |
#### 出力
@@ -84,7 +109,74 @@ AWS S3バケットからオブジェクトを取得する
| `url` | string | S3オブジェクトをダウンロードするための署名付きURL |
| `metadata` | object | タイプ、サイズ、名前、最終更新日を含むファイルメタデータ |
### `s3_list_objects`
AWS S3バケット内のオブジェクトを一覧表示する
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | はい | AWS アクセスキーID |
| `secretAccessKey` | string | はい | AWS シークレットアクセスキー |
| `region` | string | はい | AWSリージョンus-east-1 |
| `bucketName` | string | はい | S3バケット名 |
| `prefix` | string | いいえ | オブジェクトをフィルタリングするプレフィックスfolder/ |
| `maxKeys` | number | いいえ | 返すオブジェクトの最大数デフォルト1000 |
| `continuationToken` | string | いいえ | ページネーション用トークン |
#### 出力
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `objects` | array | S3オブジェクトのリスト |
### `s3_delete_object`
AWS S3バケットからオブジェクトを削除する
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | はい | AWS アクセスキーID |
| `secretAccessKey` | string | はい | AWS シークレットアクセスキー |
| `region` | string | はい | AWSリージョンus-east-1 |
| `bucketName` | string | はい | S3バケット名 |
| `objectKey` | string | はい | 削除するオブジェクトのキー/パス |
#### 出力
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `deleted` | boolean | オブジェクトが正常に削除されたかどうか |
| `metadata` | object | 削除メタデータ |
### `s3_copy_object`
AWS S3バケット内または異なるバケット間でオブジェクトをコピーする
#### 入力
| パラメータ | 型 | 必須 | 説明 |
| --------- | ---- | -------- | ----------- |
| `accessKeyId` | string | はい | AWS アクセスキーID |
| `secretAccessKey` | string | はい | AWS シークレットアクセスキー |
| `region` | string | はい | AWSリージョンus-east-1 |
| `sourceBucket` | string | はい | ソースバケット名 |
| `sourceKey` | string | はい | ソースオブジェクトのキー/パス |
| `destinationBucket` | string | はい | 宛先バケット名 |
| `destinationKey` | string | はい | 宛先オブジェクトのキー/パス |
| `acl` | string | いいえ | コピーされたオブジェクトのアクセス制御リストprivate、public-read |
#### 出力
| パラメータ | 型 | 説明 |
| --------- | ---- | ----------- |
| `url` | string | コピーされたS3オブジェクトのURL |
| `metadata` | object | コピー操作のメタデータ |
## 注意事項
- カテゴリ: `tools`
- カテゴリ: `tools`
- タイプ: `s3`

View File

@@ -1,5 +1,5 @@
---
title: トリガー
title: 概要
description: Simワークフローを開始する主要な方法
---

View File

@@ -1,5 +1,5 @@
---
title: 模块
title: 概览
description: 构建 AI 工作流的组件
---

View File

@@ -1,5 +1,5 @@
---
title: 连接基础
title: 基础
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: 连接数据结构
title: 数据结构
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: 连接
title: 概览
description: 将您的模块相互连接。
---

View File

@@ -1,5 +1,5 @@
---
title: 连接标签
title: 标签
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: 执行基础
title: 基础
---
import { Callout } from 'fumadocs-ui/components/callout'

View File

@@ -1,5 +1,5 @@
---
title: 执行
title: 概览
---
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,11 +757,7 @@ if __name__ == '__main__':
</Step>
</Steps>
<Callout type="warning">
请确保您的 API 密钥安全,切勿将其提交到版本控制中。请使用环境变量或安全的配置管理工具。
</Callout>
## 要求
## 系统要求
- Python 3.8+
- requests >= 2.25.0

View File

@@ -1,5 +1,5 @@
---
title: TypeScript/JavaScript SDK
title: TypeScript
---
import { Callout } from 'fumadocs-ui/components/callout'
@@ -1043,10 +1043,6 @@ function StreamingWorkflow() {
</Step>
</Steps>
<Callout type="warning">
请确保您的 API 密钥安全,切勿将其提交到版本控制中。使用环境变量或安全配置管理。
</Callout>
## 要求
- Node.js 16+

View File

@@ -60,13 +60,14 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
#### 输入
| 参数 | 类型 | 必需 | 描述 |
| 参数 | 类型 | 是否必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `to` | 字符串 | 是 | 收件人电子邮件地址 |
| `subject` | 字符串 | 是 | 邮件主题 |
| `body` | 字符串 | 是 | 邮件正文内容 |
| `cc` | 字符串 | 否 | 抄送收件人(逗号分隔) |
| `bcc` | 字符串 | 否 | 密送收件人(逗号分隔) |
| `to` | string | 是 | 收件人电子邮件地址 |
| `subject` | string | 是 | 电子邮件主题 |
| `body` | string | 是 | 电子邮件正文内容 |
| `cc` | string | 否 | 抄送收件人(逗号分隔) |
| `bcc` | string | 否 | 密送收件人(逗号分隔) |
| `attachments` | file[] | 否 | 附加到电子邮件的文件 |
#### 输出
@@ -81,13 +82,14 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
#### 输入
| 参数 | 类型 | 必需 | 描述 |
| 参数 | 类型 | 是否必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `to` | 字符串 | 是 | 收件人电子邮件地址 |
| `subject` | 字符串 | 是 | 邮件主题 |
| `body` | 字符串 | 是 | 邮件正文内容 |
| `cc` | 字符串 | 否 | 抄送收件人(逗号分隔) |
| `bcc` | 字符串 | 否 | 密送收件人(逗号分隔) |
| `to` | string | 是 | 收件人电子邮件地址 |
| `subject` | string | 是 | 电子邮件主题 |
| `body` | string | 是 | 电子邮件正文内容 |
| `cc` | string | 否 | 抄送收件人(逗号分隔) |
| `bcc` | string | 否 | 密送收件人(逗号分隔) |
| `attachments` | file[] | 否 | 附加到电子邮件草稿的文件 |
#### 输出

View File

@@ -1,5 +1,5 @@
---
title: 工具
title: 概览
description: 强大的工具,助力提升您的代理工作流程
---

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