diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 469ce8aa0ff..565c53e5609 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -537,7 +537,7 @@ This visibility system ensures clean user interfaces while maintaining full flex ### Guidelines & Best Practices -- **Code Style:** Follow the project's ESLint and Prettier configurations. Use meaningful variable names and small, focused functions. +- **Code Style:** Follow the project's Biome configurations. Use meaningful variable names and small, focused functions. - **Documentation:** Clearly document the purpose, inputs, outputs, and any special behavior for your block/tool. - **Error Handling:** Implement robust error handling and provide user-friendly error messages. - **Parameter Visibility:** Always specify the appropriate visibility level for each parameter to ensure proper UI behavior and LLM integration. diff --git a/apps/docs/content/docs/tools/file.mdx b/apps/docs/content/docs/tools/file.mdx index f7afb49c4e9..88a3fecf8eb 100644 --- a/apps/docs/content/docs/tools/file.mdx +++ b/apps/docs/content/docs/tools/file.mdx @@ -50,7 +50,7 @@ The File Parser tool is particularly useful for scenarios where your agents need ## Usage Instructions -Upload and extract contents from structured file formats including PDFs, CSV spreadsheets, and Word documents (DOCX). Upload files directly. Specialized parsers extract text and metadata from each format. You can upload multiple files at once and access them individually or as a combined document. +Upload and extract contents from structured file formats including PDFs, CSV spreadsheets, and Word documents (DOCX). You can either provide a URL to a file or upload files directly. Specialized parsers extract text and metadata from each format. You can upload multiple files at once and access them individually or as a combined document. diff --git a/apps/docs/content/docs/tools/hunter.mdx b/apps/docs/content/docs/tools/hunter.mdx index 6ac7e166f25..f7f2c17fa29 100644 --- a/apps/docs/content/docs/tools/hunter.mdx +++ b/apps/docs/content/docs/tools/hunter.mdx @@ -38,6 +38,7 @@ With Hunter.io, you can: In Sim, the Hunter.io integration enables your agents to programmatically search for and verify email addresses, discover companies, and enrich contact data using Hunter.io’s API. This allows you to automate lead generation, contact enrichment, and email verification directly within your workflows. Your agents can leverage Hunter.io’s tools to streamline outreach, keep your CRM up-to-date, and power intelligent automation scenarios for sales, recruiting, and more. {/* MANUAL-CONTENT-END */} + ## Usage Instructions Search for email addresses, verify their deliverability, discover companies, and enrich contact data using Hunter.io's powerful email finding capabilities. diff --git a/apps/docs/content/docs/tools/knowledge.mdx b/apps/docs/content/docs/tools/knowledge.mdx index b42ce28fb9e..5a1b4e6b354 100644 --- a/apps/docs/content/docs/tools/knowledge.mdx +++ b/apps/docs/content/docs/tools/knowledge.mdx @@ -64,7 +64,7 @@ Search for similar content in a knowledge base using vector similarity | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `knowledgeBaseId` | string | Yes | ID of the knowledge base to search in | -| `query` | string | Yes | Search query text | +| `query` | string | No | Search query text \(optional when using tag filters\) | | `topK` | number | No | Number of most similar results to return \(1-100\) | | `tagFilters` | any | No | Array of tag filters with tagName and tagValue properties | diff --git a/apps/docs/content/docs/tools/mistral_parse.mdx b/apps/docs/content/docs/tools/mistral_parse.mdx index eb4700322ff..dbd5a0f72fc 100644 --- a/apps/docs/content/docs/tools/mistral_parse.mdx +++ b/apps/docs/content/docs/tools/mistral_parse.mdx @@ -79,7 +79,7 @@ The Mistral Parse tool is particularly useful for scenarios where your agents ne ## Usage Instructions -Extract text and structure from PDF documents using Mistral's OCR API. Configure processing options and get the content in your preferred format. For URLs, they must be publicly accessible and point to a valid PDF file. Note: Google Drive, Dropbox, and other cloud storage links are not supported; use a direct download URL from a web server instead. +Extract text and structure from PDF documents using Mistral's OCR API. Either enter a URL to a PDF document or upload a PDF file directly. Configure processing options and get the content in your preferred format. For URLs, they must be publicly accessible and point to a valid PDF file. Note: Google Drive, Dropbox, and other cloud storage links are not supported; use a direct download URL from a web server instead. diff --git a/apps/docs/content/docs/tools/outlook.mdx b/apps/docs/content/docs/tools/outlook.mdx index 6e1873b6462..1aefc7e0777 100644 --- a/apps/docs/content/docs/tools/outlook.mdx +++ b/apps/docs/content/docs/tools/outlook.mdx @@ -158,6 +158,10 @@ Send emails using Outlook | `to` | string | Yes | Recipient email address | | `subject` | string | Yes | Email subject | | `body` | string | Yes | Email body content | +| `replyToMessageId` | string | No | Message ID to reply to \(for threading\) | +| `conversationId` | string | No | Conversation ID for threading | +| `cc` | string | No | CC recipients \(comma-separated\) | +| `bcc` | string | No | BCC recipients \(comma-separated\) | #### Output diff --git a/apps/sim/app/(auth)/layout.tsx b/apps/sim/app/(auth)/layout.tsx index 76a3726817d..3d1f4bcb30e 100644 --- a/apps/sim/app/(auth)/layout.tsx +++ b/apps/sim/app/(auth)/layout.tsx @@ -2,9 +2,12 @@ import Image from 'next/image' import Link from 'next/link' +import { useBrandConfig } from '@/lib/branding/branding' import { GridPattern } from '@/app/(landing)/components/grid-pattern' export default function AuthLayout({ children }: { children: React.ReactNode }) { + const brand = useBrandConfig() + return (
{/* Background pattern */} @@ -21,7 +24,17 @@ export default function AuthLayout({ children }: { children: React.ReactNode })
- Sim Logo + {brand.logoUrl ? ( + {`${brand.name} + ) : ( + {`${brand.name} + )}
diff --git a/apps/sim/app/(landing)/components/nav-client.tsx b/apps/sim/app/(landing)/components/nav-client.tsx index 6bc96ea1cc0..e312b7e09d9 100644 --- a/apps/sim/app/(landing)/components/nav-client.tsx +++ b/apps/sim/app/(landing)/components/nav-client.tsx @@ -15,6 +15,7 @@ import { SheetTitle, SheetTrigger, } from '@/components/ui/sheet' +import { useBrandConfig } from '@/lib/branding/branding' import { usePrefetchOnHover } from '@/app/(landing)/utils/prefetch' // --- Framer Motion Variants --- @@ -165,6 +166,7 @@ export default function NavClient({ const [isMobile, setIsMobile] = useState(initialIsMobile ?? false) const [isSheetOpen, setIsSheetOpen] = useState(false) const _router = useRouter() + const brand = useBrandConfig() useEffect(() => { setMounted(true) @@ -199,7 +201,17 @@ export default function NavClient({
- Sim Logo + {brand.logoUrl ? ( + {`${brand.name} + ) : ( + {`${brand.name} + )}
diff --git a/apps/sim/app/api/auth/oauth/connections/route.ts b/apps/sim/app/api/auth/oauth/connections/route.ts index b174564c3ab..6bcb0c6b20f 100644 --- a/apps/sim/app/api/auth/oauth/connections/route.ts +++ b/apps/sim/app/api/auth/oauth/connections/route.ts @@ -6,8 +6,6 @@ import { createLogger } from '@/lib/logs/console/logger' import { db } from '@/db' import { account, user } from '@/db/schema' -export const dynamic = 'force-dynamic' - const logger = createLogger('OAuthConnectionsAPI') interface GoogleIdToken { diff --git a/apps/sim/app/api/billing/route.ts b/apps/sim/app/api/billing/route.ts index bf92abd8fab..6769fee05a5 100644 --- a/apps/sim/app/api/billing/route.ts +++ b/apps/sim/app/api/billing/route.ts @@ -9,8 +9,6 @@ import { member } from '@/db/schema' const logger = createLogger('UnifiedBillingAPI') -export const dynamic = 'force-dynamic' - /** * Unified Billing Endpoint */ diff --git a/apps/sim/app/api/files/serve/[...path]/route.ts b/apps/sim/app/api/files/serve/[...path]/route.ts index c0c8973e0b2..4b18b7cf600 100644 --- a/apps/sim/app/api/files/serve/[...path]/route.ts +++ b/apps/sim/app/api/files/serve/[...path]/route.ts @@ -13,8 +13,6 @@ import { getContentType, } from '@/app/api/files/utils' -export const dynamic = 'force-dynamic' - const logger = createLogger('FilesServeAPI') async function streamToBuffer(readableStream: NodeJS.ReadableStream): Promise { diff --git a/apps/sim/app/api/folders/[id]/route.ts b/apps/sim/app/api/folders/[id]/route.ts index 06ce831139a..a686fca0bef 100644 --- a/apps/sim/app/api/folders/[id]/route.ts +++ b/apps/sim/app/api/folders/[id]/route.ts @@ -2,9 +2,6 @@ import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' - -export const dynamic = 'force-dynamic' - import { getUserEntityPermissions } from '@/lib/permissions/utils' import { db } from '@/db' import { workflow, workflowFolder } from '@/db/schema' diff --git a/apps/sim/app/api/folders/route.ts b/apps/sim/app/api/folders/route.ts index c713b5a11cd..0451870cbd1 100644 --- a/apps/sim/app/api/folders/route.ts +++ b/apps/sim/app/api/folders/route.ts @@ -8,8 +8,6 @@ import { workflowFolder } from '@/db/schema' const logger = createLogger('FoldersAPI') -export const dynamic = 'force-dynamic' - // GET - Fetch folders for a workspace export async function GET(request: NextRequest) { try { diff --git a/apps/sim/app/api/logs/route.ts b/apps/sim/app/api/logs/route.ts index d4832681676..ff3fd92bf70 100644 --- a/apps/sim/app/api/logs/route.ts +++ b/apps/sim/app/api/logs/route.ts @@ -41,7 +41,6 @@ function extractBlockExecutionsFromTraceSpans(traceSpans: any[]): any[] { return blockExecutions } -export const dynamic = 'force-dynamic' export const revalidate = 0 const QueryParamsSchema = z.object({ diff --git a/apps/sim/app/api/organizations/[id]/route.ts b/apps/sim/app/api/organizations/[id]/route.ts index b7e9314b9d6..2096e2a1579 100644 --- a/apps/sim/app/api/organizations/[id]/route.ts +++ b/apps/sim/app/api/organizations/[id]/route.ts @@ -7,9 +7,6 @@ import { updateOrganizationSeats, } from '@/lib/billing/validation/seat-management' import { createLogger } from '@/lib/logs/console/logger' - -export const dynamic = 'force-dynamic' - import { db } from '@/db' import { member, organization } from '@/db/schema' diff --git a/apps/sim/app/api/organizations/[id]/workspaces/route.ts b/apps/sim/app/api/organizations/[id]/workspaces/route.ts index 3393b60127f..8fb95ce81be 100644 --- a/apps/sim/app/api/organizations/[id]/workspaces/route.ts +++ b/apps/sim/app/api/organizations/[id]/workspaces/route.ts @@ -7,8 +7,6 @@ import { member, permissions, user, workspace } from '@/db/schema' const logger = createLogger('OrganizationWorkspacesAPI') -export const dynamic = 'force-dynamic' - /** * GET /api/organizations/[id]/workspaces * Get workspaces related to the organization with optional filtering diff --git a/apps/sim/app/api/templates/[id]/route.ts b/apps/sim/app/api/templates/[id]/route.ts index 8a4a4e181bc..df7f32a85a4 100644 --- a/apps/sim/app/api/templates/[id]/route.ts +++ b/apps/sim/app/api/templates/[id]/route.ts @@ -7,7 +7,6 @@ import { templates } from '@/db/schema' const logger = createLogger('TemplateByIdAPI') -export const dynamic = 'force-dynamic' export const revalidate = 0 // GET /api/templates/[id] - Retrieve a single template by ID diff --git a/apps/sim/app/api/templates/route.ts b/apps/sim/app/api/templates/route.ts index 9d87d8a7b5e..9e84092a81a 100644 --- a/apps/sim/app/api/templates/route.ts +++ b/apps/sim/app/api/templates/route.ts @@ -9,7 +9,6 @@ import { templateStars, templates, workflow } from '@/db/schema' const logger = createLogger('TemplatesAPI') -export const dynamic = 'force-dynamic' export const revalidate = 0 // Function to sanitize sensitive data from workflow state diff --git a/apps/sim/app/api/users/me/settings/route.ts b/apps/sim/app/api/users/me/settings/route.ts index 25c20a2e64e..0cf028fd9e2 100644 --- a/apps/sim/app/api/users/me/settings/route.ts +++ b/apps/sim/app/api/users/me/settings/route.ts @@ -4,9 +4,6 @@ import { NextResponse } from 'next/server' import { z } from 'zod' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' - -export const dynamic = 'force-dynamic' - import { db } from '@/db' import { settings } from '@/db/schema' diff --git a/apps/sim/app/api/workspaces/route.ts b/apps/sim/app/api/workspaces/route.ts index 55e53c2145c..ce15c76218d 100644 --- a/apps/sim/app/api/workspaces/route.ts +++ b/apps/sim/app/api/workspaces/route.ts @@ -3,9 +3,6 @@ import { and, desc, eq, isNull } from 'drizzle-orm' import { NextResponse } from 'next/server' import { getSession } from '@/lib/auth' import { createLogger } from '@/lib/logs/console/logger' - -export const dynamic = 'force-dynamic' - import { db } from '@/db' import { permissions, workflow, workflowBlocks, workspace } from '@/db/schema' diff --git a/apps/sim/app/layout.tsx b/apps/sim/app/layout.tsx index 06e9f2d919b..07ef379bb35 100644 --- a/apps/sim/app/layout.tsx +++ b/apps/sim/app/layout.tsx @@ -1,8 +1,10 @@ import { Analytics } from '@vercel/analytics/next' import { SpeedInsights } from '@vercel/speed-insights/next' -import { GeistSans } from 'geist/font/sans' import type { Metadata, Viewport } from 'next' import { PublicEnvScript } from 'next-runtime-env' +import { BrandedLayout } from '@/components/branded-layout' +import { generateBrandedMetadata, generateStructuredData } from '@/lib/branding/metadata' +import { env } from '@/lib/env' import { isHosted } from '@/lib/environment' import { createLogger } from '@/lib/logs/console/logger' import { getAssetUrl } from '@/lib/utils' @@ -51,149 +53,20 @@ export const viewport: Viewport = { userScalable: false, } -export const metadata: Metadata = { - title: { - template: '', - default: 'Sim', - }, - description: - 'Build and deploy AI agents using our Figma-like canvas. Build, write evals, and deploy AI agent workflows that automate workflows and streamline your business processes.', - applicationName: 'Sim', - authors: [{ name: 'Sim' }], - generator: 'Next.js', - keywords: [ - 'AI agent', - 'AI agent builder', - 'AI agent workflow', - 'AI workflow automation', - 'visual workflow editor', - 'AI agents', - 'workflow canvas', - 'intelligent automation', - 'AI tools', - 'workflow designer', - 'artificial intelligence', - 'business automation', - 'AI agent workflows', - 'visual programming', - ], - referrer: 'origin-when-cross-origin', - creator: 'Sim', - publisher: 'Sim', - metadataBase: new URL('https://sim.ai'), - alternates: { - canonical: '/', - languages: { - 'en-US': '/en-US', - }, - }, - robots: { - index: true, - follow: true, - googleBot: { - index: true, - follow: true, - 'max-image-preview': 'large', - 'max-video-preview': -1, - 'max-snippet': -1, - }, - }, - openGraph: { - type: 'website', - locale: 'en_US', - url: 'https://sim.ai', - title: 'Sim', - description: - 'Build and deploy AI agents using our Figma-like canvas. Build, write evals, and deploy AI agent workflows that automate workflows and streamline your business processes.', - siteName: 'Sim', - images: [ - { - url: getAssetUrl('social/facebook.png'), - width: 1200, - height: 630, - alt: 'Sim', - }, - ], - }, - twitter: { - card: 'summary_large_image', - title: 'Sim', - description: - 'Build and deploy AI agents using our Figma-like canvas. Build, write evals, and deploy AI agent workflows that automate workflows and streamline your business processes.', - images: [getAssetUrl('social/twitter.png')], - creator: '@simstudioai', - site: '@simstudioai', - }, - manifest: '/favicon/site.webmanifest', - icons: { - icon: [ - { url: '/favicon/favicon-16x16.png', sizes: '16x16', type: 'image/png' }, - { url: '/favicon/favicon-32x32.png', sizes: '32x32', type: 'image/png' }, - { - url: '/favicon/favicon-192x192.png', - sizes: '192x192', - type: 'image/png', - }, - { - url: '/favicon/favicon-512x512.png', - sizes: '512x512', - type: 'image/png', - }, - { url: '/sim.png', sizes: 'any', type: 'image/png' }, - ], - apple: '/favicon/apple-touch-icon.png', - shortcut: '/favicon/favicon.ico', - }, - appleWebApp: { - capable: true, - statusBarStyle: 'default', - title: 'Sim', - }, - formatDetection: { - telephone: false, - }, - category: 'technology', - other: { - 'apple-mobile-web-app-capable': 'yes', - 'mobile-web-app-capable': 'yes', - 'msapplication-TileColor': '#ffffff', - 'msapplication-config': '/favicon/browserconfig.xml', - }, -} +// Generate dynamic metadata based on brand configuration +export const metadata: Metadata = generateBrandedMetadata() export default function RootLayout({ children }: { children: React.ReactNode }) { + const structuredData = generateStructuredData() + return ( - + {/* Structured Data for SEO */}