Skip to content

Commit f6ab790

Browse files
committed
Merge branch 'staging' into dev
2 parents 79b3dd6 + 029ac9f commit f6ab790

44 files changed

Lines changed: 2155 additions & 1534 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.

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/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/sim/app/(landing)/integrations/data/integrations.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6496,7 +6496,7 @@
64966496
"slug": "image-generator",
64976497
"name": "Image Generator",
64986498
"description": "Generate images",
6499-
"longDescription": "Integrate Image Generator into the workflow. Can generate images using DALL-E 3 or GPT Image.",
6499+
"longDescription": "Integrate Image Generator into the workflow. Can generate images using DALL-E 3, GPT Image 1, or GPT Image 2.",
65006500
"bgColor": "#4D5FFF",
65016501
"iconName": "ImageIcon",
65026502
"docsUrl": "https://docs.sim.ai/tools/image_generator",
@@ -7540,7 +7540,7 @@
75407540
"operationCount": 14,
75417541
"triggers": [],
75427542
"triggerCount": 0,
7543-
"authType": "none",
7543+
"authType": "api-key",
75447544
"category": "blocks"
75457545
},
75467546
{
Lines changed: 21 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -1,183 +1,36 @@
1-
import { db } from '@sim/db'
2-
import {
3-
jobExecutionLogs,
4-
permissions,
5-
workflow,
6-
workflowDeploymentVersion,
7-
workflowExecutionLogs,
8-
} from '@sim/db/schema'
91
import { createLogger } from '@sim/logger'
10-
import { and, eq } from 'drizzle-orm'
112
import { type NextRequest, NextResponse } from 'next/server'
12-
import { logIdParamsSchema } from '@/lib/api/contracts/logs'
3+
import { getLogDetailContract } from '@/lib/api/contracts/logs'
4+
import { parseRequest } from '@/lib/api/server'
135
import { getSession } from '@/lib/auth'
14-
import { generateRequestId } from '@/lib/core/utils/request'
156
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
7+
import { fetchLogDetail } from '@/lib/logs/fetch-log-detail'
168

179
const logger = createLogger('LogDetailsByIdAPI')
1810

19-
export const revalidate = 0
20-
2111
export const GET = withRouteHandler(
22-
async (_request: NextRequest, { params }: { params: Promise<{ id: string }> }) => {
23-
const requestId = generateRequestId()
24-
25-
try {
26-
const session = await getSession()
27-
if (!session?.user?.id) {
28-
logger.warn(`[${requestId}] Unauthorized log details access attempt`)
29-
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
30-
}
31-
32-
const userId = session.user.id
33-
const { id } = logIdParamsSchema.parse(await params)
34-
35-
const rows = await db
36-
.select({
37-
id: workflowExecutionLogs.id,
38-
workflowId: workflowExecutionLogs.workflowId,
39-
executionId: workflowExecutionLogs.executionId,
40-
stateSnapshotId: workflowExecutionLogs.stateSnapshotId,
41-
deploymentVersionId: workflowExecutionLogs.deploymentVersionId,
42-
level: workflowExecutionLogs.level,
43-
status: workflowExecutionLogs.status,
44-
trigger: workflowExecutionLogs.trigger,
45-
startedAt: workflowExecutionLogs.startedAt,
46-
endedAt: workflowExecutionLogs.endedAt,
47-
totalDurationMs: workflowExecutionLogs.totalDurationMs,
48-
executionData: workflowExecutionLogs.executionData,
49-
cost: workflowExecutionLogs.cost,
50-
files: workflowExecutionLogs.files,
51-
createdAt: workflowExecutionLogs.createdAt,
52-
workflowName: workflow.name,
53-
workflowDescription: workflow.description,
54-
workflowColor: workflow.color,
55-
workflowFolderId: workflow.folderId,
56-
workflowUserId: workflow.userId,
57-
workflowWorkspaceId: workflow.workspaceId,
58-
workflowCreatedAt: workflow.createdAt,
59-
workflowUpdatedAt: workflow.updatedAt,
60-
deploymentVersion: workflowDeploymentVersion.version,
61-
deploymentVersionName: workflowDeploymentVersion.name,
62-
})
63-
.from(workflowExecutionLogs)
64-
.leftJoin(workflow, eq(workflowExecutionLogs.workflowId, workflow.id))
65-
.leftJoin(
66-
workflowDeploymentVersion,
67-
eq(workflowDeploymentVersion.id, workflowExecutionLogs.deploymentVersionId)
68-
)
69-
.innerJoin(
70-
permissions,
71-
and(
72-
eq(permissions.entityType, 'workspace'),
73-
eq(permissions.entityId, workflowExecutionLogs.workspaceId),
74-
eq(permissions.userId, userId)
75-
)
76-
)
77-
.where(eq(workflowExecutionLogs.id, id))
78-
.limit(1)
79-
80-
const log = rows[0]
81-
82-
// Fallback: check job_execution_logs
83-
if (!log) {
84-
const jobRows = await db
85-
.select({
86-
id: jobExecutionLogs.id,
87-
executionId: jobExecutionLogs.executionId,
88-
level: jobExecutionLogs.level,
89-
status: jobExecutionLogs.status,
90-
trigger: jobExecutionLogs.trigger,
91-
startedAt: jobExecutionLogs.startedAt,
92-
endedAt: jobExecutionLogs.endedAt,
93-
totalDurationMs: jobExecutionLogs.totalDurationMs,
94-
executionData: jobExecutionLogs.executionData,
95-
cost: jobExecutionLogs.cost,
96-
createdAt: jobExecutionLogs.createdAt,
97-
})
98-
.from(jobExecutionLogs)
99-
.innerJoin(
100-
permissions,
101-
and(
102-
eq(permissions.entityType, 'workspace'),
103-
eq(permissions.entityId, jobExecutionLogs.workspaceId),
104-
eq(permissions.userId, userId)
105-
)
106-
)
107-
.where(eq(jobExecutionLogs.id, id))
108-
.limit(1)
109-
110-
const jobLog = jobRows[0]
111-
if (!jobLog) {
112-
return NextResponse.json({ error: 'Not found' }, { status: 404 })
113-
}
12+
async (request: NextRequest, context: { params: Promise<{ id: string }> }) => {
13+
const session = await getSession()
14+
if (!session?.user?.id) {
15+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
16+
}
11417

115-
const execData = jobLog.executionData as Record<string, any> | null
116-
const response = {
117-
id: jobLog.id,
118-
workflowId: null,
119-
executionId: jobLog.executionId,
120-
deploymentVersionId: null,
121-
deploymentVersion: null,
122-
deploymentVersionName: null,
123-
level: jobLog.level,
124-
status: jobLog.status,
125-
duration: jobLog.totalDurationMs ? `${jobLog.totalDurationMs}ms` : null,
126-
trigger: jobLog.trigger,
127-
createdAt: jobLog.startedAt.toISOString(),
128-
workflow: null,
129-
jobTitle: (execData?.trigger?.source as string) || null,
130-
executionData: {
131-
totalDuration: jobLog.totalDurationMs,
132-
...execData,
133-
enhanced: true,
134-
},
135-
cost: jobLog.cost as any,
136-
}
18+
const parsed = await parseRequest(getLogDetailContract, request, context)
19+
if (!parsed.success) return parsed.response
13720

138-
return NextResponse.json({ data: response })
139-
}
21+
const { id } = parsed.data.params
22+
const { workspaceId } = parsed.data.query
14023

141-
const workflowSummary = log.workflowId
142-
? {
143-
id: log.workflowId,
144-
name: log.workflowName,
145-
description: log.workflowDescription,
146-
color: log.workflowColor,
147-
folderId: log.workflowFolderId,
148-
userId: log.workflowUserId,
149-
workspaceId: log.workflowWorkspaceId,
150-
createdAt: log.workflowCreatedAt,
151-
updatedAt: log.workflowUpdatedAt,
152-
}
153-
: null
24+
const data = await fetchLogDetail({
25+
userId: session.user.id,
26+
workspaceId,
27+
lookupColumn: 'id',
28+
lookupValue: id,
29+
})
15430

155-
const response = {
156-
id: log.id,
157-
workflowId: log.workflowId,
158-
executionId: log.executionId,
159-
deploymentVersionId: log.deploymentVersionId,
160-
deploymentVersion: log.deploymentVersion ?? null,
161-
deploymentVersionName: log.deploymentVersionName ?? null,
162-
level: log.level,
163-
status: log.status,
164-
duration: log.totalDurationMs ? `${log.totalDurationMs}ms` : null,
165-
trigger: log.trigger,
166-
createdAt: log.startedAt.toISOString(),
167-
files: log.files || undefined,
168-
workflow: workflowSummary,
169-
executionData: {
170-
totalDuration: log.totalDurationMs,
171-
...(log.executionData as any),
172-
enhanced: true,
173-
},
174-
cost: log.cost as any,
175-
}
31+
if (!data) return NextResponse.json({ error: 'Not found' }, { status: 404 })
17632

177-
return NextResponse.json({ data: response })
178-
} catch (error: any) {
179-
logger.error(`[${requestId}] log details fetch error`, error)
180-
return NextResponse.json({ error: error.message }, { status: 500 })
181-
}
33+
logger.debug('Fetched log detail', { id, workspaceId })
34+
return NextResponse.json({ data })
18235
}
18336
)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { createLogger } from '@sim/logger'
2+
import { type NextRequest, NextResponse } from 'next/server'
3+
import { getLogByExecutionIdContract } from '@/lib/api/contracts/logs'
4+
import { parseRequest } from '@/lib/api/server'
5+
import { getSession } from '@/lib/auth'
6+
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
7+
import { fetchLogDetail } from '@/lib/logs/fetch-log-detail'
8+
9+
const logger = createLogger('LogDetailsByExecutionAPI')
10+
11+
export const GET = withRouteHandler(
12+
async (request: NextRequest, context: { params: Promise<{ executionId: string }> }) => {
13+
const session = await getSession()
14+
if (!session?.user?.id) {
15+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
16+
}
17+
18+
const parsed = await parseRequest(getLogByExecutionIdContract, request, context)
19+
if (!parsed.success) return parsed.response
20+
21+
const { executionId } = parsed.data.params
22+
const { workspaceId } = parsed.data.query
23+
24+
const data = await fetchLogDetail({
25+
userId: session.user.id,
26+
workspaceId,
27+
lookupColumn: 'executionId',
28+
lookupValue: executionId,
29+
})
30+
31+
if (!data) return NextResponse.json({ error: 'Not found' }, { status: 404 })
32+
33+
logger.debug('Fetched log by execution id', { executionId, workspaceId })
34+
return NextResponse.json({ data })
35+
}
36+
)

0 commit comments

Comments
 (0)