chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
@@ -0,0 +1,77 @@
import { toError } from '@sim/utils/errors'
import type { ExecutionContext, ToolCallResult } from '@/lib/copilot/request/types'
import { performDeleteCredential, performUpdateCredential } from '@/lib/credentials/orchestration'
export function executeManageCredential(
rawParams: Record<string, unknown>,
context: ExecutionContext
): Promise<ToolCallResult> {
const params = rawParams as {
operation: string
credentialId?: string
credentialIds?: string[]
displayName?: string
}
const { operation, displayName } = params
return (async () => {
try {
if (!context?.userId) {
return { success: false, error: 'Authentication required' }
}
switch (operation) {
case 'rename': {
const credentialId = params.credentialId
if (!credentialId) return { success: false, error: 'credentialId is required for rename' }
if (!displayName) return { success: false, error: 'displayName is required for rename' }
const result = await performUpdateCredential({
credentialId,
userId: context.userId,
displayName,
allowedTypes: ['oauth'],
})
if (!result.success) {
return { success: false, error: result.error || 'Failed to rename credential' }
}
return { success: true, output: { credentialId, displayName } }
}
case 'delete': {
const ids: string[] =
params.credentialIds ?? (params.credentialId ? [params.credentialId] : [])
if (ids.length === 0)
return { success: false, error: 'credentialId or credentialIds is required for delete' }
const deleted: string[] = []
const failed: string[] = []
for (const id of ids) {
const result = await performDeleteCredential({
credentialId: id,
userId: context.userId,
allowedTypes: ['oauth'],
reason: 'copilot_delete',
})
if (!result.success) {
failed.push(id)
continue
}
deleted.push(id)
}
return {
success: deleted.length > 0,
output: { deleted, failed },
}
}
default:
return {
success: false,
error: `Unknown operation: ${operation}. Use "rename" or "delete".`,
}
}
} catch (error) {
return { success: false, error: toError(error).message }
}
})()
}
@@ -0,0 +1,286 @@
import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { createLogger } from '@sim/logger'
import { getErrorMessage, toError } from '@sim/utils/errors'
import type { ExecutionContext, ToolCallResult } from '@/lib/copilot/request/types'
import { captureServerEvent } from '@/lib/posthog/server'
import {
deleteCustomTool,
getCustomToolById,
listCustomTools,
upsertCustomTools,
} from '@/lib/workflows/custom-tools/operations'
const logger = createLogger('CopilotToolExecutor')
type ManageCustomToolOperation = 'add' | 'edit' | 'delete' | 'list'
interface ManageCustomToolSchema {
type: 'function'
function: {
name: string
description?: string
parameters: Record<string, unknown>
}
}
interface ManageCustomToolParams {
operation?: string
toolId?: string
toolIds?: string[]
schema?: ManageCustomToolSchema
code?: string
title?: string
workspaceId?: string
}
export async function executeManageCustomTool(
rawParams: Record<string, unknown>,
context: ExecutionContext
): Promise<ToolCallResult> {
const params = rawParams as ManageCustomToolParams
const operation = String(params.operation || '').toLowerCase() as ManageCustomToolOperation
const workspaceId = params.workspaceId || context.workspaceId
if (!operation) {
return { success: false, error: "Missing required 'operation' argument" }
}
const writeOps: string[] = ['add', 'edit', 'delete']
if (
writeOps.includes(operation) &&
context.userPermission &&
context.userPermission !== 'write' &&
context.userPermission !== 'admin'
) {
return {
success: false,
error: `Permission denied: '${operation}' on manage_custom_tool requires write access. You have '${context.userPermission}' permission.`,
}
}
try {
if (operation === 'list') {
const toolsForUser = await listCustomTools({
userId: context.userId,
workspaceId,
})
return {
success: true,
output: {
success: true,
operation,
tools: toolsForUser,
count: toolsForUser.length,
},
}
}
if (operation === 'add') {
if (!workspaceId) {
return {
success: false,
error: "workspaceId is required for operation 'add'",
}
}
if (!params.schema || !params.code) {
return {
success: false,
error: "Both 'schema' and 'code' are required for operation 'add'",
}
}
const title = params.title || params.schema.function?.name
if (!title) {
return { success: false, error: "Missing tool title or schema.function.name for 'add'" }
}
const resultTools = await upsertCustomTools({
tools: [{ title, schema: params.schema, code: params.code }],
workspaceId,
userId: context.userId,
})
const created = resultTools.find((tool) => tool.title === title)
recordAudit({
workspaceId,
actorId: context.userId,
action: AuditAction.CUSTOM_TOOL_CREATED,
resourceType: AuditResourceType.CUSTOM_TOOL,
resourceId: created?.id,
resourceName: title,
description: `Created custom tool "${title}"`,
metadata: { source: 'tool_input' },
})
if (created?.id) {
captureServerEvent(
context.userId,
'custom_tool_saved',
{
tool_id: created.id,
workspace_id: workspaceId,
tool_name: title,
source: 'tool_input',
},
{ groups: { workspace: workspaceId } }
)
}
return {
success: true,
output: {
success: true,
operation,
toolId: created?.id,
title,
message: `Created custom tool "${title}"`,
},
}
}
if (operation === 'edit') {
if (!workspaceId) {
return {
success: false,
error: "workspaceId is required for operation 'edit'",
}
}
if (!params.toolId) {
return { success: false, error: "'toolId' is required for operation 'edit'" }
}
if (!params.schema && !params.code) {
return {
success: false,
error: "At least one of 'schema' or 'code' is required for operation 'edit'",
}
}
const existing = await getCustomToolById({
toolId: params.toolId,
userId: context.userId,
workspaceId,
})
if (!existing) {
return { success: false, error: `Custom tool not found: ${params.toolId}` }
}
const mergedSchema = params.schema || (existing.schema as ManageCustomToolSchema)
const mergedCode = params.code || existing.code
const title = params.title || mergedSchema.function?.name || existing.title
await upsertCustomTools({
tools: [{ id: params.toolId, title, schema: mergedSchema, code: mergedCode }],
workspaceId,
userId: context.userId,
})
recordAudit({
workspaceId,
actorId: context.userId,
action: AuditAction.CUSTOM_TOOL_UPDATED,
resourceType: AuditResourceType.CUSTOM_TOOL,
resourceId: params.toolId,
resourceName: title,
description: `Updated custom tool "${title}"`,
metadata: { source: 'tool_input' },
})
captureServerEvent(
context.userId,
'custom_tool_saved',
{
tool_id: params.toolId,
workspace_id: workspaceId,
tool_name: title,
source: 'tool_input',
},
{ groups: { workspace: workspaceId } }
)
return {
success: true,
output: {
success: true,
operation,
toolId: params.toolId,
title,
message: `Updated custom tool "${title}"`,
},
}
}
if (operation === 'delete') {
const toolIds: string[] = params.toolIds ?? (params.toolId ? [params.toolId] : [])
if (toolIds.length === 0) {
return { success: false, error: "'toolId' or 'toolIds' is required for operation 'delete'" }
}
const deleted: string[] = []
const notFound: string[] = []
for (const toolId of toolIds) {
const result = await deleteCustomTool({
toolId,
userId: context.userId,
workspaceId,
})
if (result) {
deleted.push(toolId)
} else {
notFound.push(toolId)
}
}
for (const toolId of deleted) {
recordAudit({
workspaceId: workspaceId ?? null,
actorId: context.userId,
action: AuditAction.CUSTOM_TOOL_DELETED,
resourceType: AuditResourceType.CUSTOM_TOOL,
resourceId: toolId,
description: 'Deleted custom tool',
metadata: { source: 'tool_input' },
})
if (workspaceId) {
captureServerEvent(
context.userId,
'custom_tool_deleted',
{ tool_id: toolId, workspace_id: workspaceId, source: 'tool_input' },
{ groups: { workspace: workspaceId } }
)
}
}
return {
success: deleted.length > 0,
output: {
success: deleted.length > 0,
operation,
deleted,
notFound,
message: `Deleted ${deleted.length} custom tool(s)`,
},
}
}
return {
success: false,
error: `Unsupported operation for manage_custom_tool: ${operation}`,
}
} catch (error) {
logger.error(
context.messageId
? `manage_custom_tool execution failed [messageId:${context.messageId}]`
: 'manage_custom_tool execution failed',
{
operation,
workspaceId,
userId: context.userId,
error: toError(error).message,
}
)
return {
success: false,
error: getErrorMessage(error, 'Failed to manage custom tool'),
}
}
}
@@ -0,0 +1,205 @@
import { db } from '@sim/db'
import { mcpServers } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage, toError } from '@sim/utils/errors'
import { and, eq, isNull } from 'drizzle-orm'
import type { ExecutionContext, ToolCallResult } from '@/lib/copilot/request/types'
import {
performCreateMcpServer,
performDeleteMcpServer,
performUpdateMcpServer,
} from '@/lib/mcp/orchestration'
const logger = createLogger('CopilotToolExecutor')
type ManageMcpToolOperation = 'add' | 'edit' | 'delete' | 'list'
interface ManageMcpToolConfig {
name?: string
transport?: string
url?: string
headers?: Record<string, string>
timeout?: number
enabled?: boolean
}
interface ManageMcpToolParams {
operation?: string
serverId?: string
config?: ManageMcpToolConfig
}
export async function executeManageMcpTool(
rawParams: Record<string, unknown>,
context: ExecutionContext
): Promise<ToolCallResult> {
const params = rawParams as ManageMcpToolParams
const operation = String(params.operation || '').toLowerCase() as ManageMcpToolOperation
const workspaceId = context.workspaceId
if (!operation) {
return { success: false, error: "Missing required 'operation' argument" }
}
if (!workspaceId) {
return { success: false, error: 'workspaceId is required' }
}
const writeOps: string[] = ['add', 'edit', 'delete']
if (
writeOps.includes(operation) &&
context.userPermission &&
context.userPermission !== 'write' &&
context.userPermission !== 'admin'
) {
return {
success: false,
error: `Permission denied: '${operation}' on manage_mcp_tool requires write access. You have '${context.userPermission}' permission.`,
}
}
try {
if (operation === 'list') {
const servers = await db
.select()
.from(mcpServers)
.where(and(eq(mcpServers.workspaceId, workspaceId), isNull(mcpServers.deletedAt)))
return {
success: true,
output: {
success: true,
operation,
servers: servers.map((s) => ({
id: s.id,
name: s.name,
url: s.url,
transport: s.transport,
enabled: s.enabled,
connectionStatus: s.connectionStatus,
})),
count: servers.length,
},
}
}
if (operation === 'add') {
const config = params.config
if (!config?.name || !config?.url) {
return { success: false, error: "config.name and config.url are required for 'add'" }
}
const result = await performCreateMcpServer({
workspaceId,
userId: context.userId,
name: config.name,
description: '',
transport: config.transport || 'streamable-http',
url: config.url,
headers: config.headers,
timeout: config.timeout,
retries: 3,
enabled: config.enabled,
source: 'tool_input',
})
if (!result.success || !result.serverId) {
return {
success: false,
error: result.error || `Failed to add MCP server "${config.name}"`,
}
}
return {
success: true,
output: {
success: true,
operation,
serverId: result.serverId,
name: config.name,
message: result.updated
? `Updated existing MCP server "${config.name}"`
: `Added MCP server "${config.name}"`,
},
}
}
if (operation === 'edit') {
if (!params.serverId) {
return { success: false, error: "'serverId' is required for 'edit'" }
}
const config = params.config
if (!config) {
return { success: false, error: "'config' is required for 'edit'" }
}
const result = await performUpdateMcpServer({
workspaceId,
userId: context.userId,
serverId: params.serverId,
name: config.name,
transport: config.transport,
url: config.url,
headers: config.headers,
timeout: config.timeout,
enabled: config.enabled,
})
if (!result.success || !result.server) {
return { success: false, error: `MCP server not found: ${params.serverId}` }
}
return {
success: true,
output: {
success: true,
operation,
serverId: params.serverId,
name: result.server.name,
message: `Updated MCP server "${result.server.name}"`,
},
}
}
if (operation === 'delete') {
if (!params.serverId) {
return { success: false, error: "'serverId' is required for 'delete'" }
}
const result = await performDeleteMcpServer({
workspaceId,
userId: context.userId,
serverId: params.serverId,
source: 'tool_input',
})
if (!result.success || !result.server) {
return { success: false, error: `MCP server not found: ${params.serverId}` }
}
return {
success: true,
output: {
success: true,
operation,
serverId: params.serverId,
message: `Deleted MCP server "${result.server.name}"`,
},
}
}
return { success: false, error: `Unsupported operation for manage_mcp_tool: ${operation}` }
} catch (error) {
logger.error(
context.messageId
? `manage_mcp_tool execution failed [messageId:${context.messageId}]`
: 'manage_mcp_tool execution failed',
{
operation,
workspaceId,
error: toError(error).message,
}
)
return {
success: false,
error: getErrorMessage(error, 'Failed to manage MCP server'),
}
}
}
@@ -0,0 +1,239 @@
import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { createLogger } from '@sim/logger'
import { getErrorMessage, toError } from '@sim/utils/errors'
import type { ExecutionContext, ToolCallResult } from '@/lib/copilot/request/types'
import { captureServerEvent } from '@/lib/posthog/server'
import { deleteSkill, listSkills, upsertSkills } from '@/lib/workflows/skills/operations'
const logger = createLogger('CopilotToolExecutor')
type ManageSkillOperation = 'add' | 'edit' | 'delete' | 'list'
interface ManageSkillParams {
operation?: string
skillId?: string
name?: string
description?: string
content?: string
}
export async function executeManageSkill(
rawParams: Record<string, unknown>,
context: ExecutionContext
): Promise<ToolCallResult> {
const params = rawParams as ManageSkillParams
const operation = String(params.operation || '').toLowerCase() as ManageSkillOperation
const workspaceId = context.workspaceId
if (!operation) {
return { success: false, error: "Missing required 'operation' argument" }
}
if (!workspaceId) {
return { success: false, error: 'workspaceId is required' }
}
const writeOps: string[] = ['add', 'edit', 'delete']
if (
writeOps.includes(operation) &&
context.userPermission &&
context.userPermission !== 'write' &&
context.userPermission !== 'admin'
) {
return {
success: false,
error: `Permission denied: '${operation}' on manage_skill requires write access. You have '${context.userPermission}' permission.`,
}
}
try {
if (operation === 'list') {
const skills = await listSkills({ workspaceId })
return {
success: true,
output: {
success: true,
operation,
skills: skills.map((s) => ({
id: s.id,
name: s.name,
description: s.description,
createdAt: s.createdAt,
})),
count: skills.length,
},
}
}
if (operation === 'add') {
if (!params.name || !params.description || !params.content) {
return {
success: false,
error: "'name', 'description', and 'content' are required for 'add'",
}
}
const { skills: resultSkills } = await upsertSkills({
skills: [{ name: params.name, description: params.description, content: params.content }],
workspaceId,
userId: context.userId,
})
const created = resultSkills.find((s) => s.name === params.name)
recordAudit({
workspaceId,
actorId: context.userId,
action: AuditAction.SKILL_CREATED,
resourceType: AuditResourceType.SKILL,
resourceId: created?.id,
resourceName: params.name,
description: `Created skill "${params.name}"`,
metadata: { source: 'tool_input' },
})
if (created?.id) {
captureServerEvent(
context.userId,
'skill_created',
{
skill_id: created.id,
skill_name: params.name,
workspace_id: workspaceId,
source: 'tool_input',
},
{ groups: { workspace: workspaceId } }
)
}
return {
success: true,
output: {
success: true,
operation,
skillId: created?.id,
name: params.name,
message: `Created skill "${params.name}"`,
},
}
}
if (operation === 'edit') {
if (!params.skillId) {
return { success: false, error: "'skillId' is required for 'edit'" }
}
if (!params.name && !params.description && !params.content) {
return {
success: false,
error: "At least one of 'name', 'description', or 'content' is required for 'edit'",
}
}
const existing = await listSkills({ workspaceId })
const found = existing.find((s) => s.id === params.skillId)
if (!found) {
return { success: false, error: `Skill not found: ${params.skillId}` }
}
await upsertSkills({
skills: [
{
id: params.skillId,
name: params.name || found.name,
description: params.description || found.description,
content: params.content || found.content,
},
],
workspaceId,
userId: context.userId,
})
const updatedName = params.name || found.name
recordAudit({
workspaceId,
actorId: context.userId,
action: AuditAction.SKILL_UPDATED,
resourceType: AuditResourceType.SKILL,
resourceId: params.skillId,
resourceName: updatedName,
description: `Updated skill "${updatedName}"`,
metadata: { source: 'tool_input' },
})
captureServerEvent(
context.userId,
'skill_updated',
{
skill_id: params.skillId,
skill_name: updatedName,
workspace_id: workspaceId,
source: 'tool_input',
},
{ groups: { workspace: workspaceId } }
)
return {
success: true,
output: {
success: true,
operation,
skillId: params.skillId,
name: params.name || found.name,
message: `Updated skill "${params.name || found.name}"`,
},
}
}
if (operation === 'delete') {
if (!params.skillId) {
return { success: false, error: "'skillId' is required for 'delete'" }
}
const deleted = await deleteSkill({ skillId: params.skillId, workspaceId })
if (!deleted) {
return { success: false, error: `Skill not found: ${params.skillId}` }
}
recordAudit({
workspaceId,
actorId: context.userId,
action: AuditAction.SKILL_DELETED,
resourceType: AuditResourceType.SKILL,
resourceId: params.skillId,
description: 'Deleted skill',
metadata: { source: 'tool_input' },
})
captureServerEvent(
context.userId,
'skill_deleted',
{ skill_id: params.skillId, workspace_id: workspaceId, source: 'tool_input' },
{ groups: { workspace: workspaceId } }
)
return {
success: true,
output: {
success: true,
operation,
skillId: params.skillId,
message: 'Deleted skill',
},
}
}
return { success: false, error: `Unsupported operation for manage_skill: ${operation}` }
} catch (error) {
logger.error(
context.messageId
? `manage_skill execution failed [messageId:${context.messageId}]`
: 'manage_skill execution failed',
{
operation,
workspaceId,
error: toError(error).message,
}
)
return {
success: false,
error: getErrorMessage(error, 'Failed to manage skill'),
}
}
}