Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
aa99db6
fix(subflows): tag dropdown + resolution logic (#2949)
icecrasher321 Jan 23, 2026
f765b83
chore(deps): bump posthog-js to 1.334.1 (#2948)
waleedlatif1 Jan 23, 2026
1b309b5
fix(idempotency): add conflict target to atomicallyClaimDb query + re…
icecrasher321 Jan 23, 2026
7f22628
improvement(kb): add document filtering, select all, and React Query …
waleedlatif1 Jan 23, 2026
1467862
improvement(logs): trace span, details (#2952)
emir-karabeg Jan 23, 2026
9b72b52
feat(blog): v0.5 release post (#2953)
waleedlatif1 Jan 23, 2026
64efeaa
feat(admin): add credits endpoint to issue credits to users (#2954)
waleedlatif1 Jan 23, 2026
efef91e
improvement(copilot): fast mode, subagent tool responses and allow pr…
Sg312 Jan 23, 2026
7f4edc8
fix(billing): handle missing userStats and prevent crashes (#2956)
waleedlatif1 Jan 23, 2026
6464cfa
fix(logs): refresh logic to refresh logs details (#2958)
emir-karabeg Jan 24, 2026
f44594c
fix(security): add authentication and input validation to API routes …
waleedlatif1 Jan 24, 2026
f0ee67f
improvement(helm): add internal ingress support and same-host path co…
waleedlatif1 Jan 24, 2026
428781c
feat(blog): enterprise post (#2961)
waleedlatif1 Jan 24, 2026
b913cff
fix(envvars): resolution standardized (#2957)
icecrasher321 Jan 24, 2026
2329468
fix(copilot): mask credentials fix (#2963)
Sg312 Jan 24, 2026
12100e6
improvement(webhooks): remove dead code (#2965)
icecrasher321 Jan 24, 2026
0f9b6ad
fix(preview): subblock values (#2969)
emir-karabeg Jan 24, 2026
211a7ac
fix(child-workflow): nested spans handoff (#2966)
icecrasher321 Jan 24, 2026
48adaa0
fix(security): restrict API key access on internal-only routes (#2964)
waleedlatif1 Jan 24, 2026
9c3e663
fix(copilot): update copilot chat title (#2968)
Sg312 Jan 24, 2026
8574e6c
fix(hitl): fix condition blocks after hitl (#2967)
Sg312 Jan 24, 2026
8429040
fix(notes): ghost edges (#2970)
icecrasher321 Jan 24, 2026
fc7f56e
improvement(docs): loop and parallel var reference syntax (#2975)
icecrasher321 Jan 24, 2026
6868325
fix(blog): slash actions description (#2976)
icecrasher321 Jan 24, 2026
3bbf7f5
fix(auth): copilot routes (#2977)
Sg312 Jan 24, 2026
9f91694
fix(copilot): fix edit summary for loops/parallels (#2978)
Sg312 Jan 24, 2026
4d84465
fix(integrations): hide from tool bar (#2544)
Sg312 Jan 24, 2026
c7db48e
fix(landing): ui (#2979)
emir-karabeg Jan 24, 2026
841cb63
fix(edge-validation): race condition on collaborative add (#2980)
icecrasher321 Jan 24, 2026
bcf6dc8
fix(variables): boolean type support and input improvements (#2981)
waleedlatif1 Jan 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 42 additions & 8 deletions apps/docs/content/docs/en/blocks/loop.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,44 @@ Choose between four types of loops:
3. Drag other blocks inside the loop container
4. Connect the blocks as needed

### Accessing Results
### Referencing Loop Data

After a loop completes, you can access aggregated results:
There's an important distinction between referencing loop data from **inside** vs **outside** the loop:

- **`<loop.results>`**: Array of results from all loop iterations
<Tabs items={['Inside the Loop', 'Outside the Loop']}>
<Tab>
**Inside the loop**, use `<loop.>` references to access the current iteration context:

- **`<loop.index>`**: Current iteration number (0-based)
- **`<loop.currentItem>`**: Current item being processed (forEach only)
- **`<loop.items>`**: Full collection being iterated (forEach only)

```
// Inside a Function block within the loop
const idx = <loop.index>; // 0, 1, 2, ...
const item = <loop.currentItem>; // Current item
```

<Callout type="info">
These references are only available for blocks **inside** the loop container. They give you access to the current iteration's context.
</Callout>
</Tab>
<Tab>
**Outside the loop** (after it completes), reference the loop block by its name to access aggregated results:

- **`<LoopBlockName.results>`**: Array of results from all iterations

```
// If your loop block is named "Process Items"
const allResults = <processitems.results>;
// Returns: [result1, result2, result3, ...]
```

<Callout type="info">
After the loop completes, use the loop's block name (not `loop.`) to access the collected results. The block name is normalized (lowercase, no spaces).
</Callout>
</Tab>
</Tabs>

## Example Use Cases

Expand Down Expand Up @@ -184,28 +217,29 @@ Variables (i=0) → Loop (While i<10) → Agent (Process) → Variables (i++)
</ul>
</Tab>
<Tab>
Available **inside** the loop only:
<ul className="list-disc space-y-2 pl-6">
<li>
<strong>loop.currentItem</strong>: Current item being processed
<strong>{"<loop.index>"}</strong>: Current iteration number (0-based)
</li>
<li>
<strong>loop.index</strong>: Current iteration number (0-based)
<strong>{"<loop.currentItem>"}</strong>: Current item being processed (forEach only)
</li>
<li>
<strong>loop.items</strong>: Full collection (forEach loops)
<strong>{"<loop.items>"}</strong>: Full collection (forEach only)
</li>
</ul>
</Tab>
<Tab>
<ul className="list-disc space-y-2 pl-6">
<li>
<strong>loop.results</strong>: Array of all iteration results
<strong>{"<blockname.results>"}</strong>: Array of all iteration results (accessed via block name)
</li>
<li>
<strong>Structure</strong>: Results maintain iteration order
</li>
<li>
<strong>Access</strong>: Available in blocks after the loop
<strong>Access</strong>: Available in blocks after the loop completes
</li>
</ul>
</Tab>
Expand Down
56 changes: 45 additions & 11 deletions apps/docs/content/docs/en/blocks/parallel.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,44 @@ Choose between two types of parallel execution:
3. Drag a single block inside the parallel container
4. Connect the block as needed

### Accessing Results
### Referencing Parallel Data

After a parallel block completes, you can access aggregated results:
There's an important distinction between referencing parallel data from **inside** vs **outside** the parallel block:

- **`<parallel.results>`**: Array of results from all parallel instances
<Tabs items={['Inside the Parallel', 'Outside the Parallel']}>
<Tab>
**Inside the parallel**, use `<parallel.>` references to access the current instance context:

- **`<parallel.index>`**: Current instance number (0-based)
- **`<parallel.currentItem>`**: Item for this instance (collection-based only)
- **`<parallel.items>`**: Full collection being distributed (collection-based only)

```
// Inside a Function block within the parallel
const idx = <parallel.index>; // 0, 1, 2, ...
const item = <parallel.currentItem>; // This instance's item
```

<Callout type="info">
These references are only available for blocks **inside** the parallel container. They give you access to the current instance's context.
</Callout>
</Tab>
<Tab>
**Outside the parallel** (after it completes), reference the parallel block by its name to access aggregated results:

- **`<ParallelBlockName.results>`**: Array of results from all instances

```
// If your parallel block is named "Process Tasks"
const allResults = <processtasks.results>;
// Returns: [result1, result2, result3, ...]
```

<Callout type="info">
After the parallel completes, use the parallel's block name (not `parallel.`) to access the collected results. The block name is normalized (lowercase, no spaces).
</Callout>
</Tab>
</Tabs>

## Example Use Cases

Expand All @@ -98,11 +131,11 @@ Parallel (["gpt-4o", "claude-3.7-sonnet", "gemini-2.5-pro"]) → Agent → Evalu

### Result Aggregation

Results from all parallel instances are automatically collected:
Results from all parallel instances are automatically collected and accessible via the block name:

```javascript
// In a Function block after the parallel
const allResults = input.parallel.results;
// In a Function block after a parallel named "Process Tasks"
const allResults = <processtasks.results>;
// Returns: [result1, result2, result3, ...]
```

Expand Down Expand Up @@ -158,25 +191,26 @@ Understanding when to use each:
</ul>
</Tab>
<Tab>
Available **inside** the parallel only:
<ul className="list-disc space-y-2 pl-6">
<li>
<strong>parallel.currentItem</strong>: Item for this instance
<strong>{"<parallel.index>"}</strong>: Instance number (0-based)
</li>
<li>
<strong>parallel.index</strong>: Instance number (0-based)
<strong>{"<parallel.currentItem>"}</strong>: Item for this instance (collection-based only)
</li>
<li>
<strong>parallel.items</strong>: Full collection (collection-based)
<strong>{"<parallel.items>"}</strong>: Full collection (collection-based only)
</li>
</ul>
</Tab>
<Tab>
<ul className="list-disc space-y-2 pl-6">
<li>
<strong>parallel.results</strong>: Array of all instance results
<strong>{"<blockname.results>"}</strong>: Array of all instance results (accessed via block name)
</li>
<li>
<strong>Access</strong>: Available in blocks after the parallel
<strong>Access</strong>: Available in blocks after the parallel completes
</li>
</ul>
</Tab>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default function StatusIndicator() {
href={statusUrl}
target='_blank'
rel='noopener noreferrer'
className={`flex items-center gap-[6px] whitespace-nowrap text-[12px] transition-colors ${STATUS_COLORS[status]}`}
className={`flex min-w-[165px] items-center gap-[6px] whitespace-nowrap text-[12px] transition-colors ${STATUS_COLORS[status]}`}
aria-label={`System status: ${message}`}
>
<StatusDotIcon status={status} className='h-[6px] w-[6px]' aria-hidden='true' />
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/(landing)/components/hero/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export { LandingLoopNode } from './landing-canvas/landing-block/landing-loop-nod
export { LandingNode } from './landing-canvas/landing-block/landing-node'
export type { LoopBlockProps } from './landing-canvas/landing-block/loop-block'
export { LoopBlock } from './landing-canvas/landing-block/loop-block'
export type { TagProps } from './landing-canvas/landing-block/tag'
export { Tag } from './landing-canvas/landing-block/tag'
export type { SubBlockRowProps, TagProps } from './landing-canvas/landing-block/tag'
export { SubBlockRow, Tag } from './landing-canvas/landing-block/tag'
export type {
LandingBlockNode,
LandingCanvasProps,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react'
import { BookIcon } from 'lucide-react'
import {
Tag,
type TagProps,
SubBlockRow,
type SubBlockRowProps,
} from '@/app/(landing)/components/hero/components/landing-canvas/landing-block/tag'

/**
* Data structure for a landing card component
* Matches the workflow block structure from the application
*/
export interface LandingCardData {
/** Icon element to display in the card header */
Expand All @@ -15,8 +15,8 @@ export interface LandingCardData {
color: string | '#f6f6f6'
/** Name/title of the card */
name: string
/** Optional tags to display at the bottom of the card */
tags?: TagProps[]
/** Optional subblock rows to display below the header */
tags?: SubBlockRowProps[]
}

/**
Expand All @@ -28,7 +28,8 @@ export interface LandingBlockProps extends LandingCardData {
}

/**
* Landing block component that displays a card with icon, name, and optional tags
* Landing block component that displays a card with icon, name, and optional subblock rows
* Styled to match the application's workflow blocks
* @param props - Component properties including icon, color, name, tags, and className
* @returns A styled block card component
*/
Expand All @@ -39,33 +40,37 @@ export const LandingBlock = React.memo(function LandingBlock({
tags,
className,
}: LandingBlockProps) {
const hasContentBelowHeader = tags && tags.length > 0

return (
<div
className={`z-10 flex w-64 flex-col items-start gap-3 rounded-[14px] border border-[#E5E5E5] bg-[#FEFEFE] p-3 ${className ?? ''}`}
style={{
boxShadow: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
}}
className={`z-10 flex w-[250px] flex-col rounded-[8px] border border-[#E5E5E5] bg-white ${className ?? ''}`}
>
<div className='flex w-full items-center justify-between'>
<div className='flex items-center gap-2.5'>
{/* Header - matches workflow-block.tsx header styling */}
<div
className={`flex items-center justify-between p-[8px] ${hasContentBelowHeader ? 'border-[#E5E5E5] border-b' : ''}`}
>
<div className='flex min-w-0 flex-1 items-center gap-[10px]'>
<div
className='flex h-6 w-6 items-center justify-center rounded-[8px] text-white'
style={{ backgroundColor: color as string }}
className='flex h-[24px] w-[24px] flex-shrink-0 items-center justify-center rounded-[6px]'
style={{ background: color as string }}
>
{icon}
</div>
<p className='text-base text-card-foreground'>{name}</p>
<span className='truncate font-medium text-[#171717] text-[16px]' title={name}>
{name}
</span>
</div>
<BookIcon className='h-4 w-4 text-muted-foreground' />
</div>

{tags && tags.length > 0 ? (
<div className='flex flex-wrap gap-2'>
{/* Content - SubBlock Rows matching workflow-block.tsx */}
{hasContentBelowHeader && (
<div className='flex flex-col gap-[8px] p-[8px]'>
{tags.map((tag) => (
<Tag key={tag.label} icon={tag.icon} label={tag.label} />
<SubBlockRow key={tag.label} icon={tag.icon} label={tag.label} />
))}
</div>
) : null}
)}
</div>
)
})
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ import {
type LandingCardData,
} from '@/app/(landing)/components/hero/components/landing-canvas/landing-block/landing-block'

/**
* Handle Y offset from block top - matches HANDLE_POSITIONS.DEFAULT_Y_OFFSET
*/
const HANDLE_Y_OFFSET = 20

/**
* React Flow node component for the landing canvas
* Includes CSS animations and connection handles
* Styled to match the application's workflow blocks
* @param props - Component properties containing node data
* @returns A React Flow compatible node component
*/
Expand Down Expand Up @@ -41,15 +46,15 @@ export const LandingNode = React.memo(function LandingNode({ data }: { data: Lan
type='target'
position={Position.Left}
style={{
width: '12px',
height: '12px',
background: '#FEFEFE',
border: '1px solid #E5E5E5',
borderRadius: '50%',
top: '50%',
left: '-20px',
width: '7px',
height: '20px',
background: '#D1D1D1',
border: 'none',
borderRadius: '2px 0 0 2px',
top: `${HANDLE_Y_OFFSET}px`,
left: '-7px',
transform: 'translateY(-50%)',
zIndex: 2,
zIndex: 10,
}}
isConnectable={false}
/>
Expand All @@ -59,15 +64,15 @@ export const LandingNode = React.memo(function LandingNode({ data }: { data: Lan
type='source'
position={Position.Right}
style={{
width: '12px',
height: '12px',
background: '#FEFEFE',
border: '1px solid #E5E5E5',
borderRadius: '50%',
top: '50%',
right: '-20px',
width: '7px',
height: '20px',
background: '#D1D1D1',
border: 'none',
borderRadius: '0 2px 2px 0',
top: `${HANDLE_Y_OFFSET}px`,
right: '-7px',
transform: 'translateY(-50%)',
zIndex: 2,
zIndex: 10,
}}
isConnectable={false}
/>
Expand Down
Loading
Loading