Skip to content

Commit b1abd72

Browse files
Merge branch 'staging' into feat/wf-log-block
Resolve conflicts in /api/logs and /api/logs/[id] by adopting staging's new contract pattern (parseRequest, fetchLogDetail, cursor pagination) and re-applying checkSessionOrInternalAuth on top so the Logs block tools can call these routes from the executor. Update tools/logs and the Logs block to match the new API: - /api/logs returns { data, nextCursor }; drop offset/page/total - /api/logs/[id] now requires ?workspaceId=... query - Drop the details='basic'|'full' knob (gone from staging) - Add cursor, sortBy, sortOrder subblocks - Use WorkflowLogSummary / WorkflowLogDetail types from contract
2 parents 338d695 + 9eeb1b2 commit b1abd72

381 files changed

Lines changed: 53991 additions & 7663 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test-build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,15 @@ jobs:
9090
9191
echo "✅ All feature flags are properly configured"
9292
93-
- name: Check subblock ID stability
93+
- name: Check block registry invariants
9494
run: |
9595
if [ "${{ github.event_name }}" = "pull_request" ]; then
9696
BASE_REF="origin/${{ github.base_ref }}"
9797
git fetch --depth=1 origin "${{ github.base_ref }}" 2>/dev/null || true
9898
else
9999
BASE_REF="HEAD~1"
100100
fi
101-
bun run apps/sim/scripts/check-subblock-id-stability.ts "$BASE_REF"
101+
bun run apps/sim/scripts/check-block-registry.ts "$BASE_REF"
102102
103103
- name: Lint code
104104
run: bun run lint:check

apps/docs/content/docs/en/tools/image_generator.mdx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ In Sim, the DALL-E integration enables your agents to generate images programmat
2929

3030
## Usage Instructions
3131

32-
Integrate Image Generator into the workflow. Can generate images using DALL-E 3 or GPT Image.
32+
Integrate Image Generator into the workflow. Can generate images using DALL-E 3, GPT Image 1, or GPT Image 2.
3333

3434

3535

@@ -43,12 +43,14 @@ Generate images using OpenAI
4343

4444
| Parameter | Type | Required | Description |
4545
| --------- | ---- | -------- | ----------- |
46-
| `model` | string | Yes | The model to use \(gpt-image-1 or dall-e-3\) |
46+
| `model` | string | Yes | The model to use \(dall-e-3, gpt-image-1, or gpt-image-2\) |
4747
| `prompt` | string | Yes | A text description of the desired image |
48-
| `size` | string | Yes | The size of the generated images \(1024x1024, 1024x1792, or 1792x1024\) |
49-
| `quality` | string | No | The quality of the image \(standard or hd\) |
50-
| `style` | string | No | The style of the image \(vivid or natural\) |
51-
| `background` | string | No | The background color, only for gpt-image-1 |
48+
| `size` | string | Yes | Image size. dall-e-3: 1024x1024, 1024x1792, or 1792x1024. gpt-image-1: auto, 1024x1024, 1536x1024, or 1024x1536. gpt-image-2: auto or any size with edges ≤3840px and multiples of 16 \(e.g. 1024x1024, 1536x1024, 1024x1536, 2560x1440, 3840x2160\). |
49+
| `quality` | string | No | Quality. dall-e-3: standard\|hd. gpt-image-1/gpt-image-2: auto\|low\|medium\|high |
50+
| `style` | string | No | The style of the image \(vivid or natural\), only for dall-e-3 |
51+
| `background` | string | No | Background. gpt-image-1: auto\|transparent\|opaque. gpt-image-2: auto\|opaque \(transparent not supported\) |
52+
| `outputFormat` | string | No | Output image format \(png, jpeg, webp\), only for gpt-image-1 and gpt-image-2 |
53+
| `moderation` | string | No | Moderation level \(auto or low\), only for gpt-image-1 and gpt-image-2 |
5254
| `n` | number | No | The number of images to generate \(1-10\) |
5355
| `apiKey` | string | Yes | Your OpenAI API key |
5456

apps/docs/content/docs/en/tools/knowledge.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ Search for similar content in a knowledge base using vector similarity
4949
| `tagValue` | string | No | No description |
5050
| `rerankerEnabled` | boolean | No | Whether to apply Cohere reranking to vector search results |
5151
| `rerankerModel` | string | No | Cohere rerank model to use \(one of: rerank-v4.0-pro, rerank-v4.0-fast, rerank-v3.5\) |
52+
| `rerankerInputCount` | number | No | Number of vector results sent to the Cohere reranker \(1–100\). Defaults to topK × 4 capped at 100. |
53+
| `apiKey` | string | No | Cohere API key for reranker \(self-hosted deployments only\) |
5254
| `tagFilters` | string | No | No description |
5355

5456
#### Output

apps/docs/content/docs/en/tools/mem0.mdx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,9 @@ Add memories to Mem0 for persistent storage and retrieval
5050

5151
| Parameter | Type | Description |
5252
| --------- | ---- | ----------- |
53-
| `ids` | array | Array of memory IDs that were created |
54-
| `memories` | array | Array of memory objects that were created |
55-
|`id` | string | Unique identifier for the memory |
56-
|`memory` | string | The content of the memory |
57-
|`event` | string | Event type indicating operation performed \(ADD, UPDATE, DELETE, NOOP\) |
58-
|`metadata` | json | Custom metadata associated with the memory |
53+
| `message` | string | Status message for the queued memory processing job |
54+
| `status` | string | Processing status returned by Mem0 |
55+
| `event_id` | string | Event ID for polling memory processing status |
5956

6057
### `mem0_search_memories`
6158

@@ -102,6 +99,7 @@ Retrieve memories from Mem0 by ID or filter criteria
10299
| `startDate` | string | No | Start date for filtering by created_at \(e.g., "2024-01-15"\) |
103100
| `endDate` | string | No | End date for filtering by created_at \(e.g., "2024-12-31"\) |
104101
| `limit` | number | No | Maximum number of results to return \(e.g., 10, 50, 100\) |
102+
| `page` | number | No | Page number to retrieve for paginated list results |
105103
| `apiKey` | string | Yes | Your Mem0 API key |
106104

107105
#### Output
@@ -120,10 +118,9 @@ Retrieve memories from Mem0 by ID or filter criteria
120118
|`categories` | json | Auto-assigned categories for the memory |
121119
|`created_at` | string | ISO 8601 timestamp when the memory was created |
122120
|`updated_at` | string | ISO 8601 timestamp when the memory was last updated |
123-
|`owner` | string | Owner of the memory |
124-
|`organization` | string | Organization associated with the memory |
125-
|`immutable` | boolean | Whether the memory can be modified |
126-
|`expiration_date` | string | Expiration date after which memory is not retrieved |
127121
| `ids` | array | Array of memory IDs that were retrieved |
122+
| `count` | number | Total number of memories matching the filters |
123+
| `next` | string | URL for the next page of results |
124+
| `previous` | string | URL for the previous page of results |
128125

129126

apps/docs/content/docs/en/tools/stt.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ Transcribe audio and video files to text using leading AI providers. Supports mu
120120
| --------- | ---- | -------- | ----------- |
121121
| `provider` | string | Yes | STT provider \(elevenlabs\) |
122122
| `apiKey` | string | Yes | ElevenLabs API key |
123-
| `model` | string | No | ElevenLabs model to use \(scribe_v1, scribe_v1_experimental\) |
123+
| `model` | string | No | ElevenLabs model to use \(scribe_v2\) |
124124
| `audioFile` | file | No | Audio or video file to transcribe \(e.g., MP3, WAV, M4A, WEBM\) |
125125
| `audioFileReference` | file | No | Reference to audio/video file from previous blocks |
126126
| `audioUrl` | string | No | URL to audio or video file |

apps/docs/content/docs/en/triggers/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"servicenow",
4040
"slack",
4141
"stripe",
42+
"table",
4243
"telegram",
4344
"twilio_voice",
4445
"typeform",
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
title: Table
3+
description: Available Table triggers for automating workflows
4+
---
5+
6+
import { BlockInfoCard } from "@/components/ui/block-info-card"
7+
8+
<BlockInfoCard
9+
type="table"
10+
color="#10B981"
11+
/>
12+
13+
Table provides 1 trigger for automating workflows based on events.
14+
15+
## Triggers
16+
17+
### Table Trigger
18+
19+
Triggers when rows are inserted or updated in a table
20+
21+
#### Configuration
22+
23+
| Parameter | Type | Required | Description |
24+
| --------- | ---- | -------- | ----------- |
25+
| `tableSelector` | table-selector | Yes | The table to monitor. |
26+
| `manualTableId` | string | Yes | The table to monitor. |
27+
| `eventType` | string | Yes | The type of event to trigger on. |
28+
| `watchColumns` | string | No | Only fire when these columns change. Leave empty to fire on any update. |
29+
| `includeHeaders` | boolean | No | When enabled, each row is returned as a key-value object mapped to column names. |
30+
31+
#### Output
32+
33+
| Parameter | Type | Description |
34+
| --------- | ---- | ----------- |
35+
| `row` | json | Row data mapped to column names \(when header mapping is enabled\) |
36+
| `rawRow` | json | Raw row data object |
37+
| `previousRow` | json | Previous row data before the update \(null for inserts\) |
38+
| `changedColumns` | json | List of column names that changed \(empty for inserts\) |
39+
| `rowId` | string | The unique row ID |
40+
| `headers` | json | Column names from the table schema |
41+
| `rowNumber` | number | The position of the row in the table |
42+
| `tableId` | string | The table ID |
43+
| `tableName` | string | The table name |
44+
| `timestamp` | string | Event timestamp in ISO format |
45+

apps/realtime/src/handlers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { setupConnectionHandlers } from '@/handlers/connection'
22
import { setupOperationsHandlers } from '@/handlers/operations'
33
import { setupPresenceHandlers } from '@/handlers/presence'
44
import { setupSubblocksHandlers } from '@/handlers/subblocks'
5+
import { setupTableHandlers } from '@/handlers/tables'
56
import { setupVariablesHandlers } from '@/handlers/variables'
67
import { setupWorkflowHandlers } from '@/handlers/workflow'
78
import type { AuthenticatedSocket } from '@/middleware/auth'
@@ -13,5 +14,6 @@ export function setupAllHandlers(socket: AuthenticatedSocket, roomManager: IRoom
1314
setupSubblocksHandlers(socket, roomManager)
1415
setupVariablesHandlers(socket, roomManager)
1516
setupPresenceHandlers(socket, roomManager)
17+
setupTableHandlers(socket, roomManager)
1618
setupConnectionHandlers(socket, roomManager)
1719
}

apps/realtime/src/handlers/operations.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from '@sim/realtime-protocol/constants'
1111
import { WorkflowOperationSchema } from '@sim/realtime-protocol/schemas'
1212
import { generateId } from '@sim/utils/id'
13+
import { assertWorkflowMutable, WorkflowLockedError } from '@sim/workflow-authz'
1314
import { ZodError } from 'zod'
1415
import { persistWorkflowOperation } from '@/database/operations'
1516
import type { AuthenticatedSocket } from '@/middleware/auth'
@@ -139,6 +140,24 @@ export function setupOperationsHandlers(socket: AuthenticatedSocket, roomManager
139140
}
140141
}
141142

143+
try {
144+
await assertWorkflowMutable(workflowId)
145+
} catch (error) {
146+
if (error instanceof WorkflowLockedError) {
147+
emitOperationError(
148+
{
149+
type: 'WORKFLOW_LOCKED',
150+
message: error.message,
151+
operation,
152+
target,
153+
},
154+
{ error: error.message, retryable: false }
155+
)
156+
return
157+
}
158+
throw error
159+
}
160+
142161
// Broadcast first for position updates to minimize latency, then persist
143162
// For other operations, persist first for consistency
144163
if (isPositionUpdate) {

apps/realtime/src/handlers/subblocks.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { db } from '@sim/db'
22
import { workflow, workflowBlocks } from '@sim/db/schema'
33
import { createLogger } from '@sim/logger'
44
import { SUBBLOCK_OPERATIONS } from '@sim/realtime-protocol/constants'
5+
import { assertWorkflowMutable, WorkflowLockedError } from '@sim/workflow-authz'
56
import { and, eq } from 'drizzle-orm'
67
import type { AuthenticatedSocket } from '@/middleware/auth'
78
import { checkRolePermission } from '@/middleware/permissions'
@@ -151,6 +152,28 @@ export function setupSubblocksHandlers(socket: AuthenticatedSocket, roomManager:
151152
return
152153
}
153154

155+
try {
156+
await assertWorkflowMutable(workflowId)
157+
} catch (error) {
158+
if (error instanceof WorkflowLockedError) {
159+
socket.emit('operation-forbidden', {
160+
type: 'WORKFLOW_LOCKED',
161+
message: error.message,
162+
operation: SUBBLOCK_OPERATIONS.UPDATE,
163+
target: 'subblock',
164+
})
165+
if (operationId) {
166+
socket.emit('operation-failed', {
167+
operationId,
168+
error: error.message,
169+
retryable: false,
170+
})
171+
}
172+
return
173+
}
174+
throw error
175+
}
176+
154177
// Update user activity
155178
await roomManager.updateUserActivity(workflowId, socket.id, { lastActivity: Date.now() })
156179

@@ -231,6 +254,22 @@ async function flushSubblockUpdate(
231254
return
232255
}
233256

257+
try {
258+
await assertWorkflowMutable(workflowId)
259+
} catch (error) {
260+
if (error instanceof WorkflowLockedError) {
261+
pending.opToSocket.forEach((socketId, opId) => {
262+
io.to(socketId).emit('operation-failed', {
263+
operationId: opId,
264+
error: error.message,
265+
retryable: false,
266+
})
267+
})
268+
return
269+
}
270+
throw error
271+
}
272+
234273
let updateSuccessful = false
235274
let blockLocked = false
236275
await db.transaction(async (tx) => {

0 commit comments

Comments
 (0)