Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 4 additions & 30 deletions apps/sim/app/workspace/providers/socket-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -368,11 +368,7 @@ export function SocketProvider({ children, user }: SocketProviderProps) {
eventHandlers.current.workflowReverted?.(data)
})

const rehydrateWorkflowStores = async (
workflowId: string,
workflowState: any,
source: 'copilot' | 'workflow-state'
) => {
const rehydrateWorkflowStores = async (workflowId: string, workflowState: any) => {
const [
{ useOperationQueueStore },
{ useWorkflowRegistry },
Expand All @@ -397,7 +393,7 @@ export function SocketProvider({ children, user }: SocketProviderProps) {
.getState()
.operations.some((op: any) => op.workflowId === workflowId && op.status !== 'confirmed')
if (hasPending) {
logger.info(`Skipping ${source} rehydration due to pending operations in queue`)
logger.info('Skipping rehydration due to pending operations in queue')
return false
}

Expand Down Expand Up @@ -426,32 +422,10 @@ export function SocketProvider({ children, user }: SocketProviderProps) {
},
}))

logger.info(`Successfully rehydrated stores from ${source}`)
logger.info('Successfully rehydrated workflow stores')
return true
}

socketInstance.on('copilot-workflow-edit', async (data) => {
logger.info(
`Copilot edited workflow ${data.workflowId} - rehydrating stores from database`
)

try {
const response = await fetch(`/api/workflows/${data.workflowId}`)
if (response.ok) {
const responseData = await response.json()
const workflowData = responseData.data

if (workflowData?.state) {
await rehydrateWorkflowStores(data.workflowId, workflowData.state, 'copilot')
}
} else {
logger.error('Failed to fetch fresh workflow state:', response.statusText)
}
} catch (error) {
logger.error('Failed to rehydrate stores after copilot edit:', error)
}
})

socketInstance.on('operation-confirmed', (data) => {
logger.debug('Operation confirmed', { operationId: data.operationId })
eventHandlers.current.operationConfirmed?.(data)
Expand Down Expand Up @@ -522,7 +496,7 @@ export function SocketProvider({ children, user }: SocketProviderProps) {

if (workflowData?.state) {
try {
await rehydrateWorkflowStores(workflowData.id, workflowData.state, 'workflow-state')
await rehydrateWorkflowStores(workflowData.id, workflowData.state)
} catch (error) {
logger.error('Error rehydrating workflow state:', error)
}
Expand Down
23 changes: 0 additions & 23 deletions apps/sim/socket/rooms/memory-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,27 +234,4 @@ export class MemoryRoomManager implements IRoomManager {

logger.info(`Notified ${room.users.size} users about workflow update: ${workflowId}`)
}

async handleCopilotWorkflowEdit(workflowId: string, description?: string): Promise<void> {
logger.info(`Handling copilot workflow edit notification for ${workflowId}`)

const room = this.workflowRooms.get(workflowId)
if (!room) {
logger.debug(`No active room found for copilot workflow edit ${workflowId}`)
return
}

const timestamp = Date.now()

this._io.to(workflowId).emit('copilot-workflow-edit', {
workflowId,
description,
message: 'Copilot has edited the workflow - rehydrating from database',
timestamp,
})

room.lastModified = timestamp

logger.info(`Notified ${room.users.size} users about copilot workflow edit: ${workflowId}`)
}
}
24 changes: 0 additions & 24 deletions apps/sim/socket/rooms/redis-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,28 +407,4 @@ export class RedisRoomManager implements IRoomManager {
const userCount = await this.getUniqueUserCount(workflowId)
logger.info(`Notified ${userCount} users about workflow update: ${workflowId}`)
}

async handleCopilotWorkflowEdit(workflowId: string, description?: string): Promise<void> {
logger.info(`Handling copilot workflow edit notification for ${workflowId}`)

const hasRoom = await this.hasWorkflowRoom(workflowId)
if (!hasRoom) {
logger.debug(`No active room found for copilot workflow edit ${workflowId}`)
return
}

const timestamp = Date.now()

this._io.to(workflowId).emit('copilot-workflow-edit', {
workflowId,
description,
message: 'Copilot has edited the workflow - rehydrating from database',
timestamp,
})

await this.updateRoomLastModified(workflowId)

const userCount = await this.getUniqueUserCount(workflowId)
logger.info(`Notified ${userCount} users about copilot workflow edit: ${workflowId}`)
}
}
5 changes: 0 additions & 5 deletions apps/sim/socket/rooms/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,4 @@ export interface IRoomManager {
* Handle workflow update - notify users
*/
handleWorkflowUpdate(workflowId: string): Promise<void>

/**
* Handle copilot workflow edit - notify users to rehydrate
*/
handleCopilotWorkflowEdit(workflowId: string, description?: string): Promise<void>
}
14 changes: 0 additions & 14 deletions apps/sim/socket/routes/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,6 @@ export function createHttpHandler(roomManager: IRoomManager, logger: Logger) {
return
}

// Handle copilot workflow edit notifications from the main API
if (req.method === 'POST' && req.url === '/api/copilot-workflow-edit') {
try {
const body = await readRequestBody(req)
const { workflowId, description } = JSON.parse(body)
await roomManager.handleCopilotWorkflowEdit(workflowId, description)
sendSuccess(res)
} catch (error) {
logger.error('Error handling copilot workflow edit notification:', error)
sendError(res, 'Failed to process copilot edit notification')
}
return
}

// Handle workflow revert notifications from the main API
if (req.method === 'POST' && req.url === '/api/workflow-reverted') {
try {
Expand Down
13 changes: 10 additions & 3 deletions docker-compose.local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ services:
- DATABASE_URL=postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@db:5432/${POSTGRES_DB:-simstudio}
- BETTER_AUTH_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-your_auth_secret_here}
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-your_encryption_key_here}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-dev-secret-at-least-32-characters-long}
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-dev-encryption-key-at-least-32-chars}
- API_ENCRYPTION_KEY=${API_ENCRYPTION_KEY:-}
- INTERNAL_API_SECRET=${INTERNAL_API_SECRET:-dev-internal-api-secret-min-32-chars}
- REDIS_URL=${REDIS_URL:-}
- COPILOT_API_KEY=${COPILOT_API_KEY}
- SIM_AGENT_API_URL=${SIM_AGENT_API_URL}
- OLLAMA_URL=${OLLAMA_URL:-http://localhost:11434}
- SOCKET_SERVER_URL=${SOCKET_SERVER_URL:-http://realtime:3002}
- NEXT_PUBLIC_SOCKET_URL=${NEXT_PUBLIC_SOCKET_URL:-http://localhost:3002}
depends_on:
db:
Expand All @@ -39,10 +43,13 @@ services:
context: .
dockerfile: docker/realtime.Dockerfile
environment:
- NODE_ENV=development
- DATABASE_URL=postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@db:5432/${POSTGRES_DB:-simstudio}
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
- BETTER_AUTH_URL=${BETTER_AUTH_URL:-http://localhost:3000}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-your_auth_secret_here}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-dev-secret-at-least-32-characters-long}
- INTERNAL_API_SECRET=${INTERNAL_API_SECRET:-dev-internal-api-secret-min-32-chars}
- REDIS_URL=${REDIS_URL:-}
depends_on:
db:
condition: service_healthy
Expand Down
14 changes: 10 additions & 4 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ services:
- DATABASE_URL=postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@db:5432/${POSTGRES_DB:-simstudio}
- BETTER_AUTH_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-your_auth_secret_here}
- ENCRYPTION_KEY=${ENCRYPTION_KEY:-your_encryption_key_here}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
- API_ENCRYPTION_KEY=${API_ENCRYPTION_KEY:-}
- INTERNAL_API_SECRET=${INTERNAL_API_SECRET}
- REDIS_URL=${REDIS_URL:-}
- COPILOT_API_KEY=${COPILOT_API_KEY}
- SIM_AGENT_API_URL=${SIM_AGENT_API_URL}
- OLLAMA_URL=${OLLAMA_URL:-http://localhost:11434}
- SOCKET_SERVER_URL=${SOCKET_SERVER_URL:-http://localhost:3002}
- SOCKET_SERVER_URL=${SOCKET_SERVER_URL:-http://realtime:3002}
- NEXT_PUBLIC_SOCKET_URL=${NEXT_PUBLIC_SOCKET_URL:-http://localhost:3002}
depends_on:
db:
Expand All @@ -44,10 +47,13 @@ services:
limits:
memory: 1G
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@db:5432/${POSTGRES_DB:-simstudio}
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000}
- BETTER_AUTH_URL=${BETTER_AUTH_URL:-http://localhost:3000}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET:-your_auth_secret_here}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- INTERNAL_API_SECRET=${INTERNAL_API_SECRET}
- REDIS_URL=${REDIS_URL:-}
depends_on:
db:
condition: service_healthy
Expand Down