improvement(db): reduce connection saturation and egress hotspots (#4594)

* improvement(db): reduce connection saturation and egress hotspots

* fix(vfs): preserve native content type in copilot SQL projection

* fix(vfs): guard jsonb_array_elements against non-array contentBlocks
This commit is contained in:
Waleed
2026-05-13 23:39:59 -07:00
committed by GitHub
parent 104949bdc2
commit b5dba82ac9
5 changed files with 32 additions and 13 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ const socketDb = drizzle(
prepare: false,
idle_timeout: 10,
connect_timeout: 20,
max: 30,
max: 15,
onnotice: () => {},
}),
{ schema }
@@ -2,7 +2,7 @@ import { db } from '@sim/db'
import { mcpServers, workflow, workflowBlocks } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { and, eq, isNull } from 'drizzle-orm'
import { and, eq, inArray, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { mcpServerIdParamsSchema } from '@/lib/api/contracts/mcp'
import { validationErrorResponse } from '@/lib/api/server'
@@ -77,13 +77,11 @@ async function syncToolSchemasToWorkflows(
subBlocks: workflowBlocks.subBlocks,
})
.from(workflowBlocks)
.where(eq(workflowBlocks.type, 'agent'))
.where(and(eq(workflowBlocks.type, 'agent'), inArray(workflowBlocks.workflowId, workflowIds)))
const updatedWorkflowIds = new Set<string>()
for (const block of agentBlocks) {
if (!workflowIds.includes(block.workflowId)) continue
const subBlocks = block.subBlocks as Record<string, unknown> | null
if (!subBlocks) continue
+4 -4
View File
@@ -2,7 +2,7 @@ import { db } from '@sim/db'
import { workflow, workflowBlocks } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { eq } from 'drizzle-orm'
import { and, eq, inArray } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { withMcpAuth } from '@/lib/mcp/middleware'
@@ -33,13 +33,13 @@ export const GET = withRouteHandler(
const agentBlocks = await db
.select({ workflowId: workflowBlocks.workflowId, subBlocks: workflowBlocks.subBlocks })
.from(workflowBlocks)
.where(eq(workflowBlocks.type, 'agent'))
.where(
and(eq(workflowBlocks.type, 'agent'), inArray(workflowBlocks.workflowId, workflowIds))
)
const storedTools: StoredMcpTool[] = []
for (const block of agentBlocks) {
if (!workflowMap.has(block.workflowId)) continue
const subBlocks = block.subBlocks as Record<string, unknown> | null
if (!subBlocks) continue
+24 -3
View File
@@ -17,7 +17,7 @@ import {
} from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { and, desc, eq, isNotNull, isNull, ne } from 'drizzle-orm'
import { and, desc, eq, isNotNull, isNull, ne, sql } from 'drizzle-orm'
import { listApiKeys } from '@/lib/api-key/service'
import { buildWorkspaceMd, type WorkspaceMdData } from '@/lib/copilot/chat/workspace-context'
import { extractDocumentStyle } from '@/lib/copilot/vfs/document-style'
@@ -1157,7 +1157,27 @@ export class WorkspaceVFS {
.select({
id: copilotChats.id,
title: copilotChats.title,
messages: copilotChats.messages,
messageCount: sql<number>`COALESCE(jsonb_array_length(${copilotChats.messages}), 0)`,
messages: sql<unknown[]>`COALESCE((
SELECT jsonb_agg(
jsonb_build_object(
'role', m->>'role',
'content', m->'content',
'contentBlocks', COALESCE((
SELECT jsonb_agg(jsonb_build_object('type', 'text', 'content', b->'content'))
FROM jsonb_array_elements(
CASE WHEN jsonb_typeof(m->'contentBlocks') = 'array'
THEN m->'contentBlocks'
ELSE '[]'::jsonb
END
) AS b
WHERE b->>'type' = 'text'
), '[]'::jsonb)
)
)
FROM jsonb_array_elements(${copilotChats.messages}) AS m
WHERE m->>'role' IN ('user', 'assistant')
), '[]'::jsonb)`,
createdAt: copilotChats.createdAt,
updatedAt: copilotChats.updatedAt,
})
@@ -1177,13 +1197,14 @@ export class WorkspaceVFS {
const safeName = sanitizeName(title)
const prefix = `tasks/${safeName}/`
const messages = Array.isArray(task.messages) ? task.messages : []
const messageCount = Number(task.messageCount) || 0
this.files.set(
`${prefix}session.md`,
serializeTaskSession({
id: task.id,
title,
messageCount: messages.length,
messageCount,
createdAt: task.createdAt,
updatedAt: task.updatedAt,
})
+1 -1
View File
@@ -11,7 +11,7 @@ const postgresClient = postgres(connectionString, {
prepare: false,
idle_timeout: 20,
connect_timeout: 30,
max: 30,
max: 15,
onnotice: () => {},
})