Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
2d2448f
fix build error
icecrasher321 Apr 3, 2026
1fc84b8
improvement(mothership): new agent loop (#3920)
Sg312 Apr 4, 2026
e2de4d2
Force redeploy
Sg312 Apr 4, 2026
b6e1df4
feat(motheship): add docx support
Sg312 Apr 4, 2026
acc00df
feat(mothership): append
Sg312 Apr 4, 2026
cac100a
Add deps
Sg312 Apr 4, 2026
0d09d11
improvement(mothership): docs
Sg312 Apr 4, 2026
0b3f3ed
File types
Sg312 Apr 5, 2026
0a41b8b
Add client retry logic
Sg312 Apr 5, 2026
d85775e
Fix stream reconnect
Sg312 Apr 5, 2026
b74cf28
Eager tool streaming
Sg312 Apr 6, 2026
87ff68c
Fix client side tools
Sg312 Apr 6, 2026
4ee6fa8
Security
Sg312 Apr 6, 2026
33433b1
Fix shell var injection
Sg312 Apr 6, 2026
ca2afaa
Remove auto injected tasks
Sg312 Apr 6, 2026
8dfbe8a
Fix 10mb tool response limit
Sg312 Apr 6, 2026
c29941e
Fix trailing leak
Sg312 Apr 6, 2026
2da0cbe
Remove dead tools
Sg312 Apr 7, 2026
c52d633
file/folder tools
Sg312 Apr 7, 2026
0dd1ee0
Folder tools
Sg312 Apr 7, 2026
d25632c
Hide function code inline
Sg312 Apr 7, 2026
5c47c1f
Dont show internal tool result reads
Sg312 Apr 7, 2026
ebc030b
Fix spacing
Sg312 Apr 7, 2026
c31ae46
Auth vfs
Sg312 Apr 7, 2026
a6fbb51
Empty folders should show in vfs
Sg312 Apr 7, 2026
1a18ebb
Fix run workflow
Sg312 Apr 7, 2026
674695e
change to node runtime
icecrasher321 Apr 7, 2026
75d5d13
revert back to bun runtime
icecrasher321 Apr 7, 2026
ed2dad0
Fix
Sg312 Apr 7, 2026
2b799f3
Appends
Sg312 Apr 8, 2026
5b22f1f
Remove debug logs
Sg312 Apr 8, 2026
5be55d2
Patch
Sg312 Apr 8, 2026
89f8842
Fix patch tool
Sg312 Apr 8, 2026
3893afd
Temp
Sg312 Apr 8, 2026
ce1f00c
Checkpoint
Sg312 Apr 8, 2026
fd4fa1c
File writes
Sg312 Apr 8, 2026
d22f367
Fix
Sg312 Apr 9, 2026
b49d67e
Remove tool truncation limits
Sg312 Apr 9, 2026
f2fcfe7
Bad hook
Sg312 Apr 9, 2026
817833c
replace react markdown with streamdown
icecrasher321 Apr 9, 2026
2ba4228
Checkpoitn
Sg312 Apr 9, 2026
81ac66f
fix code block
icecrasher321 Apr 9, 2026
2abf6ac
Merge branch 'dev' of github.com:simstudioai/sim into dev
icecrasher321 Apr 9, 2026
a738a6d
fix stream persistence
icecrasher321 Apr 9, 2026
69d69ee
temp
Sg312 Apr 9, 2026
d25c243
Fix file tools
Sg312 Apr 9, 2026
6f04c48
tool joining
Sg312 Apr 9, 2026
b1caeb0
cleanup subagent + streaming issues
icecrasher321 Apr 9, 2026
c77f204
streamed text change
icecrasher321 Apr 9, 2026
e610df6
Merge branch 'dev' of github.com:simstudioai/sim into dev
icecrasher321 Apr 9, 2026
fe5baf7
Tool display intetns
Sg312 Apr 9, 2026
f0d3819
Fix dev
Sg312 Apr 9, 2026
0638604
Fix tests
Sg312 Apr 9, 2026
9da574a
Fix dev
Sg312 Apr 9, 2026
649ee9c
Speed up dev ci
Sg312 Apr 9, 2026
3ef87e5
Add req id
Sg312 Apr 9, 2026
2d2f782
Fix persistence
Sg312 Apr 9, 2026
485dce7
Tool call names
Sg312 Apr 10, 2026
f509e33
fix payload accesses
icecrasher321 Apr 10, 2026
e321e99
Merge branch 'dev' of github.com:simstudioai/sim into dev
icecrasher321 Apr 10, 2026
8f3c8e4
Fix name
Sg312 Apr 10, 2026
7835df4
fix snapshot crash bug
icecrasher321 Apr 10, 2026
24abd87
Merge branch 'dev' of github.com:simstudioai/sim into dev
icecrasher321 Apr 10, 2026
9272b15
fix
Sg312 Apr 10, 2026
3252736
Fix
Sg312 Apr 10, 2026
c61cbb0
Merge branch 'staging' into dev
icecrasher321 Apr 10, 2026
33d1342
remove worker code
icecrasher321 Apr 10, 2026
c026ce7
Clickable resources
Sg312 Apr 10, 2026
5b94db6
Options ordering
Sg312 Apr 10, 2026
2156f49
Folder vfs
Sg312 Apr 10, 2026
c74c4a9
Restore and mass delete tools
Sg312 Apr 10, 2026
ca361a3
Fix
Sg312 Apr 10, 2026
949601c
lint
icecrasher321 Apr 10, 2026
91301df
Update request tracing and skills and handlers
Sg312 Apr 10, 2026
734a4d1
Fix editable
Sg312 Apr 10, 2026
e2b4eb3
fix type error
icecrasher321 Apr 10, 2026
386d0aa
Html code
Sg312 Apr 10, 2026
3690dc2
fix(chat): make inline code inherit parent font size in markdown headers
waleedlatif1 Apr 10, 2026
da28f8a
improved autolayout
icecrasher321 Apr 10, 2026
ac84c62
Merge branch 'dev' of github.com:simstudioai/sim into dev
icecrasher321 Apr 10, 2026
09f06cb
durable stream for files
icecrasher321 Apr 10, 2026
d11d3df
one more fix
icecrasher321 Apr 10, 2026
22cd5e4
POSSIBLE BREAKAGE: SCROLLING
Sg312 Apr 10, 2026
0f6c16d
Fixes
Sg312 Apr 10, 2026
6fe2be8
Fixes
Sg312 Apr 10, 2026
7c08cc0
Merge remote-tracking branch 'origin/staging' into dev
TheodoreSpeaks Apr 11, 2026
227d73d
Lint fix
TheodoreSpeaks Apr 11, 2026
5f7b98d
fix(resource): fix resource view disappearing on ats (#4103)
TheodoreSpeaks Apr 11, 2026
72e3c69
Fixes
Sg312 Apr 11, 2026
cce740d
feat(mothership): add execution logs as a resource type
waleedlatif1 Apr 11, 2026
d55d18a
Fix perf and message queueing
Sg312 Apr 11, 2026
ce6db00
Fix abort
Sg312 Apr 11, 2026
833f132
fix(ui): dont delete resource on clearing from context, set resource …
TheodoreSpeaks Apr 11, 2026
8c9903f
improvement(mothership): structure sim side typing
icecrasher321 Apr 12, 2026
977061c
Merge branch 'dev' of github.com:simstudioai/sim into dev
icecrasher321 Apr 12, 2026
90c8947
address comments
icecrasher321 Apr 12, 2026
a3ac741
Merge branch 'staging' into dev
icecrasher321 Apr 12, 2026
b2b10e2
reactive text editor tweaks
icecrasher321 Apr 12, 2026
df15ebd
Fix file read and tool call name persistence bug
Sg312 Apr 13, 2026
054c415
Fix code stream + create file opening resource
Sg312 Apr 13, 2026
3e21899
fix use chat race + headless trace issues
icecrasher321 Apr 13, 2026
1dc9e89
Merge branch 'dev' of github.com:simstudioai/sim into dev
icecrasher321 Apr 13, 2026
b087aba
Fix type issue
icecrasher321 Apr 13, 2026
d273a41
Fix mothership block req lifecycle
Sg312 Apr 13, 2026
7635586
Fix build
Sg312 Apr 13, 2026
7e8e77b
Move copy reqid
Sg312 Apr 13, 2026
ebf3ece
Fix
Sg312 Apr 13, 2026
4345c6c
fix(ui): fix resource tag transition from home to task (#4132)
TheodoreSpeaks Apr 13, 2026
f6309c6
Fix persistence
Sg312 Apr 13, 2026
82a8aa5
Merge staging into dev
Sg312 Apr 14, 2026
72eed27
Clean code, fix bugs
Sg312 Apr 14, 2026
fee6ac5
Fix
Sg312 Apr 14, 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
114 changes: 15 additions & 99 deletions apps/sim/app/api/workflows/[id]/deployments/[version]/revert/route.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { db, workflow, workflowDeploymentVersion } from '@sim/db'
import { createLogger } from '@sim/logger'
import { and, eq } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { env } from '@/lib/core/config/env'
import { generateRequestId } from '@/lib/core/utils/request'
import { captureServerEvent } from '@/lib/posthog/server'
import { saveWorkflowToNormalizedTables } from '@/lib/workflows/persistence/utils'
import { performRevertToVersion } from '@/lib/workflows/orchestration'
import { validateWorkflowPermissions } from '@/lib/workflows/utils'
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'

Expand Down Expand Up @@ -37,105 +32,26 @@ export async function POST(
return createErrorResponse('Invalid version', 400)
}

let stateRow: { state: any } | null = null
if (version === 'active') {
const [row] = await db
.select({ state: workflowDeploymentVersion.state })
.from(workflowDeploymentVersion)
.where(
and(
eq(workflowDeploymentVersion.workflowId, id),
eq(workflowDeploymentVersion.isActive, true)
)
)
.limit(1)
stateRow = row || null
} else {
const [row] = await db
.select({ state: workflowDeploymentVersion.state })
.from(workflowDeploymentVersion)
.where(
and(
eq(workflowDeploymentVersion.workflowId, id),
eq(workflowDeploymentVersion.version, versionSelector as number)
)
)
.limit(1)
stateRow = row || null
}

if (!stateRow?.state) {
return createErrorResponse('Deployment version not found', 404)
}

const deployedState = stateRow.state
if (!deployedState.blocks || !deployedState.edges) {
return createErrorResponse('Invalid deployed state structure', 500)
}

const saveResult = await saveWorkflowToNormalizedTables(id, {
blocks: deployedState.blocks,
edges: deployedState.edges,
loops: deployedState.loops || {},
parallels: deployedState.parallels || {},
lastSaved: Date.now(),
})

if (!saveResult.success) {
return createErrorResponse(saveResult.error || 'Failed to save deployed state', 500)
}

await db
.update(workflow)
.set({ lastSynced: new Date(), updatedAt: new Date() })
.where(eq(workflow.id, id))

try {
const socketServerUrl = env.SOCKET_SERVER_URL || 'http://localhost:3002'
await fetch(`${socketServerUrl}/api/workflow-reverted`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': env.INTERNAL_API_SECRET,
},
body: JSON.stringify({ workflowId: id, timestamp: Date.now() }),
})
} catch (e) {
logger.error('Error sending workflow reverted event to socket server', e)
}

captureServerEvent(
session!.user.id,
'workflow_deployment_reverted',
{
workflow_id: id,
workspace_id: workflowRecord?.workspaceId ?? '',
version,
},
workflowRecord?.workspaceId
? { groups: { workspace: workflowRecord.workspaceId } }
: undefined
)

recordAudit({
workspaceId: workflowRecord?.workspaceId ?? null,
actorId: session!.user.id,
action: AuditAction.WORKFLOW_DEPLOYMENT_REVERTED,
resourceType: AuditResourceType.WORKFLOW,
resourceId: id,
const result = await performRevertToVersion({
workflowId: id,
version: version === 'active' ? 'active' : (versionSelector as number),
userId: session!.user.id,
workflow: (workflowRecord ?? {}) as Record<string, unknown>,
request,
actorName: session!.user.name ?? undefined,
actorEmail: session!.user.email ?? undefined,
resourceName: workflowRecord?.name ?? undefined,
description: `Reverted workflow to deployment version ${version}`,
metadata: {
targetVersion: version,
},
request,
})

if (!result.success) {
return createErrorResponse(
result.error || 'Failed to revert',
result.errorCode === 'not_found' ? 404 : 500
)
}

return createSuccessResponse({
message: 'Reverted to deployment version',
lastSaved: Date.now(),
lastSaved: result.lastSaved,
})
} catch (error: any) {
logger.error('Error reverting to deployment version', error)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMemo } from 'react'
import { PillsRing } from '@/components/emcn'
import { FunctionExecute, WorkspaceFile } from '@/lib/copilot/generated/tool-catalog-v1'
import { WorkspaceFile } from '@/lib/copilot/generated/tool-catalog-v1'
import type { ToolCallStatus } from '../../../../types'
import { getToolIcon } from '../../utils'

Expand Down Expand Up @@ -56,42 +56,6 @@ function StatusIcon({ status, toolName }: { status: ToolCallStatus; toolName: st
return <CircleCheck className='h-[15px] w-[15px] text-[var(--text-tertiary)]' />
}

const LANG_ALIASES: Record<string, string> = {
javascript: 'javascript',
python: 'python',
shell: 'bash',
bash: 'bash',
}

function extractFunctionExecutePreview(raw: string): { code: string; lang: string } | null {
if (!raw) return null
const langMatch = raw.match(/"language"\s*:\s*"(\w+)"/)
const lang = langMatch ? (LANG_ALIASES[langMatch[1]] ?? langMatch[1]) : 'javascript'

const codeStart = raw.indexOf('"code"')
if (codeStart === -1) return null
const colonIdx = raw.indexOf(':', codeStart + 6)
if (colonIdx === -1) return null
const quoteIdx = raw.indexOf('"', colonIdx + 1)
if (quoteIdx === -1) return null

let value = raw.slice(quoteIdx + 1)
if (value.endsWith('"}') || value.endsWith('"\n}')) {
value = value.replace(/"\s*\}?\s*$/, '')
}
if (value.endsWith('"')) {
value = value.slice(0, -1)
}

const code = value
.replace(/\\n/g, '\n')
.replace(/\\t/g, '\t')
.replace(/\\"/g, '"')
.replace(/\\\\/g, '\\')

return code.length > 0 ? { code, lang } : null
}

interface ToolCallItemProps {
toolName: string
displayTitle: string
Expand Down Expand Up @@ -128,14 +92,6 @@ export function ToolCallItem({ toolName, displayTitle, status, streamingArgs }:
.replace(/\\\\/g, '\\')
return `${verb} ${unescaped}`
}, [toolName, streamingArgs])
const extracted = useMemo(() => {
if (toolName !== FunctionExecute.id || !streamingArgs) return null
return extractFunctionExecutePreview(streamingArgs)
}, [toolName, streamingArgs])
const markdown = useMemo(
() => (extracted ? `\`\`\`${extracted.lang}\n${extracted.code}\n\`\`\`` : null),
[extracted]
)

return (
<div className='flex items-center gap-[8px] pl-[24px]'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
WorkspaceFile,
} from '@/lib/copilot/generated/tool-catalog-v1'
import { resolveToolDisplay } from '@/lib/copilot/tools/client/store-utils'
import { ClientToolCallState } from '@/lib/copilot/tools/client/tool-display-registry'
import { ClientToolCallState } from '@/lib/copilot/tools/client/tool-call-state'
import type { ContentBlock, MothershipResource, OptionItem, ToolCallData } from '../../types'
import { SUBAGENT_LABELS, TOOL_UI_METADATA } from '../../types'
import type { AgentGroupItem } from './components'
Expand Down Expand Up @@ -94,8 +94,7 @@ function mapToolStatusToClientState(

function getOverrideDisplayTitle(tc: NonNullable<ContentBlock['toolCall']>): string | undefined {
if (tc.name === ReadTool.id || tc.name === 'respond' || tc.name.endsWith('_respond')) {
return resolveToolDisplay(tc.name, mapToolStatusToClientState(tc.status), tc.id, tc.params)
?.text
return resolveToolDisplay(tc.name, mapToolStatusToClientState(tc.status), tc.params)?.text
}
return undefined
}
Expand Down
24 changes: 10 additions & 14 deletions apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,6 @@ function resolveStreamingToolDisplayTitle(name: string, streamingArgs: string):
type StreamToolUI = {
hidden?: boolean
title?: string
phaseLabel?: string
clientExecutable?: boolean
}

Expand Down Expand Up @@ -597,10 +596,16 @@ function getToolUI(ui?: MothershipStreamV1ToolUI): StreamToolUI | undefined {
return undefined
}

const title =
typeof ui.title === 'string'
? ui.title
: typeof ui.phaseLabel === 'string'
? ui.phaseLabel
: undefined

return {
...(typeof ui.hidden === 'boolean' ? { hidden: ui.hidden } : {}),
...(typeof ui.title === 'string' ? { title: ui.title } : {}),
...(typeof ui.phaseLabel === 'string' ? { phaseLabel: ui.phaseLabel } : {}),
...(title ? { title } : {}),
...(typeof ui.clientExecutable === 'boolean' ? { clientExecutable: ui.clientExecutable } : {}),
}
}
Expand Down Expand Up @@ -1934,8 +1939,7 @@ export function useChat(
}
const ui = getToolUI(payload.ui)
if (ui?.hidden) break
let displayTitle = ui?.title || ui?.phaseLabel
const phaseLabel = ui?.phaseLabel
let displayTitle = ui?.title
const args = payload.arguments as Record<string, unknown> | undefined

displayTitle = resolveToolDisplayTitle(name, args) ?? displayTitle
Expand Down Expand Up @@ -1966,7 +1970,6 @@ export function useChat(
name,
status: 'executing',
displayTitle,
phaseLabel,
params: args,
calledBy: activeSubagent,
},
Expand All @@ -1980,7 +1983,6 @@ export function useChat(
if (tc) {
tc.name = name
if (displayTitle) tc.displayTitle = displayTitle
if (phaseLabel) tc.phaseLabel = phaseLabel
if (args) tc.params = args
}
}
Expand Down Expand Up @@ -2525,13 +2527,7 @@ export function useChat(
const isCancelled =
block.toolCall.status === 'executing' || block.toolCall.status === 'cancelled'
const displayTitle = isCancelled ? 'Stopped by user' : block.toolCall.displayTitle
const display =
displayTitle || block.toolCall.phaseLabel
? {
...(displayTitle ? { title: displayTitle } : {}),
...(block.toolCall.phaseLabel ? { phaseLabel: block.toolCall.phaseLabel } : {}),
}
: undefined
const display = displayTitle ? { title: displayTitle } : undefined
return {
type: block.type,
content: block.content,
Expand Down
Loading
Loading