diff --git a/apps/sim/app/api/copilot/api-keys/generate/route.ts b/apps/sim/app/api/copilot/api-keys/generate/route.ts index 755ee7ee0a..c88f309705 100644 --- a/apps/sim/app/api/copilot/api-keys/generate/route.ts +++ b/apps/sim/app/api/copilot/api-keys/generate/route.ts @@ -15,6 +15,8 @@ export async function POST(req: NextRequest) { // Move environment variable access inside the function const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT + await req.json().catch(() => ({})) + const res = await fetch(`${SIM_AGENT_API_URL}/api/validate-key/generate`, { method: 'POST', headers: { @@ -31,14 +33,14 @@ export async function POST(req: NextRequest) { ) } - const data = (await res.json().catch(() => null)) as { apiKey?: string } | null + const data = (await res.json().catch(() => null)) as { apiKey?: string; id?: string } | null if (!data?.apiKey) { return NextResponse.json({ error: 'Invalid response from Sim Agent' }, { status: 500 }) } return NextResponse.json( - { success: true, key: { id: 'new', apiKey: data.apiKey } }, + { success: true, key: { id: data?.id || 'new', apiKey: data.apiKey } }, { status: 201 } ) } catch (error) { diff --git a/apps/sim/app/api/copilot/api-keys/route.ts b/apps/sim/app/api/copilot/api-keys/route.ts index 0cbe6cafaf..3de2b0feb0 100644 --- a/apps/sim/app/api/copilot/api-keys/route.ts +++ b/apps/sim/app/api/copilot/api-keys/route.ts @@ -33,7 +33,12 @@ export async function GET(request: NextRequest) { return NextResponse.json({ error: 'Invalid response from Sim Agent' }, { status: 500 }) } - const keys = apiKeys + const keys = apiKeys.map((k) => { + const value = typeof k.apiKey === 'string' ? k.apiKey : '' + const last6 = value.slice(-6) + const displayKey = `•••••${last6}` + return { id: k.id, displayKey } + }) return NextResponse.json({ keys }, { status: 200 }) } catch (error) { diff --git a/apps/sim/app/api/copilot/execute-copilot-server-tool/route.ts b/apps/sim/app/api/copilot/execute-copilot-server-tool/route.ts index d356162857..333e5bed43 100644 --- a/apps/sim/app/api/copilot/execute-copilot-server-tool/route.ts +++ b/apps/sim/app/api/copilot/execute-copilot-server-tool/route.ts @@ -34,7 +34,7 @@ export async function POST(req: NextRequest) { const { toolName, payload } = ExecuteSchema.parse(body) logger.info(`[${tracker.requestId}] Executing server tool`, { toolName }) - const result = await routeExecution(toolName, payload) + const result = await routeExecution(toolName, payload, { userId }) try { const resultPreview = JSON.stringify(result).slice(0, 300) diff --git a/apps/sim/app/api/copilot/tools/mark-complete/route.ts b/apps/sim/app/api/copilot/tools/mark-complete/route.ts index 17b00b741f..601a652d0a 100644 --- a/apps/sim/app/api/copilot/tools/mark-complete/route.ts +++ b/apps/sim/app/api/copilot/tools/mark-complete/route.ts @@ -13,10 +13,8 @@ import { SIM_AGENT_API_URL_DEFAULT } from '@/lib/sim-agent/constants' const logger = createLogger('CopilotMarkToolCompleteAPI') -// Sim Agent API configuration const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT -// Schema for mark-complete request const MarkCompleteSchema = z.object({ id: z.string(), name: z.string(), diff --git a/apps/sim/app/api/yaml/autolayout/route.ts b/apps/sim/app/api/yaml/autolayout/route.ts index ecc7b730f0..cef54c59fa 100644 --- a/apps/sim/app/api/yaml/autolayout/route.ts +++ b/apps/sim/app/api/yaml/autolayout/route.ts @@ -18,7 +18,6 @@ import { const logger = createLogger('YamlAutoLayoutAPI') -// Sim Agent API configuration const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT const AutoLayoutRequestSchema = z.object({ diff --git a/apps/sim/app/api/yaml/diff/create/route.ts b/apps/sim/app/api/yaml/diff/create/route.ts index 81148c6520..907dd89540 100644 --- a/apps/sim/app/api/yaml/diff/create/route.ts +++ b/apps/sim/app/api/yaml/diff/create/route.ts @@ -19,7 +19,6 @@ import { const logger = createLogger('YamlDiffCreateAPI') -// Sim Agent API configuration const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT const CreateDiffRequestSchema = z.object({ diff --git a/apps/sim/app/api/yaml/diff/merge/route.ts b/apps/sim/app/api/yaml/diff/merge/route.ts index 4990e46bdb..6d741a4622 100644 --- a/apps/sim/app/api/yaml/diff/merge/route.ts +++ b/apps/sim/app/api/yaml/diff/merge/route.ts @@ -18,7 +18,6 @@ import { const logger = createLogger('YamlDiffMergeAPI') -// Sim Agent API configuration const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT const MergeDiffRequestSchema = z.object({ diff --git a/apps/sim/app/api/yaml/generate/route.ts b/apps/sim/app/api/yaml/generate/route.ts index df84ffb61d..19566707d2 100644 --- a/apps/sim/app/api/yaml/generate/route.ts +++ b/apps/sim/app/api/yaml/generate/route.ts @@ -11,7 +11,6 @@ import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/w const logger = createLogger('YamlGenerateAPI') -// Sim Agent API configuration const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT const GenerateRequestSchema = z.object({ diff --git a/apps/sim/app/api/yaml/health/route.ts b/apps/sim/app/api/yaml/health/route.ts index 260565b230..0784df3a08 100644 --- a/apps/sim/app/api/yaml/health/route.ts +++ b/apps/sim/app/api/yaml/health/route.ts @@ -6,7 +6,6 @@ import { generateRequestId } from '@/lib/utils' const logger = createLogger('YamlHealthAPI') -// Sim Agent API configuration const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT export async function GET() { diff --git a/apps/sim/app/api/yaml/parse/route.ts b/apps/sim/app/api/yaml/parse/route.ts index fec4b5deaa..a3d162960d 100644 --- a/apps/sim/app/api/yaml/parse/route.ts +++ b/apps/sim/app/api/yaml/parse/route.ts @@ -11,7 +11,6 @@ import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/w const logger = createLogger('YamlParseAPI') -// Sim Agent API configuration const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT const ParseRequestSchema = z.object({ diff --git a/apps/sim/app/api/yaml/to-workflow/route.ts b/apps/sim/app/api/yaml/to-workflow/route.ts index a31a50bca9..262c197583 100644 --- a/apps/sim/app/api/yaml/to-workflow/route.ts +++ b/apps/sim/app/api/yaml/to-workflow/route.ts @@ -11,7 +11,6 @@ import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/w const logger = createLogger('YamlToWorkflowAPI') -// Sim Agent API configuration const SIM_AGENT_API_URL = env.SIM_AGENT_API_URL || SIM_AGENT_API_URL_DEFAULT const ConvertRequestSchema = z.object({ diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/copilot/copilot.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/copilot/copilot.tsx index 918a380d07..cc9c37118c 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/copilot/copilot.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/copilot/copilot.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useState } from 'react' -import { Check, Copy, Eye, EyeOff, Plus, Search } from 'lucide-react' +import { Check, Copy, Plus, Search } from 'lucide-react' import { AlertDialog, AlertDialogAction, @@ -13,10 +13,6 @@ import { Input, Label, Skeleton, - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, } from '@/components/ui' import { createLogger } from '@/lib/logs/console/logger' @@ -24,44 +20,36 @@ const logger = createLogger('CopilotSettings') interface CopilotKey { id: string - apiKey: string + displayKey: string } export function Copilot() { const [keys, setKeys] = useState([]) const [isLoading, setIsLoading] = useState(true) - const [visible, setVisible] = useState>({}) const [searchTerm, setSearchTerm] = useState('') // Create flow state const [showNewKeyDialog, setShowNewKeyDialog] = useState(false) - const [newKey, setNewKey] = useState(null) - const [copiedKeyIds, setCopiedKeyIds] = useState>({}) + const [newKey, setNewKey] = useState(null) + const [isCreatingKey] = useState(false) const [newKeyCopySuccess, setNewKeyCopySuccess] = useState(false) // Delete flow state const [deleteKey, setDeleteKey] = useState(null) const [showDeleteDialog, setShowDeleteDialog] = useState(false) - // Filter keys based on search term + // Filter keys based on search term (by masked display value) const filteredKeys = keys.filter((key) => - key.apiKey.toLowerCase().includes(searchTerm.toLowerCase()) + key.displayKey.toLowerCase().includes(searchTerm.toLowerCase()) ) - const maskedValue = useCallback((value: string, show: boolean) => { - if (show) return value - if (!value) return '' - const last6 = value.slice(-6) - return `•••••${last6}` - }, []) - const fetchKeys = useCallback(async () => { try { setIsLoading(true) const res = await fetch('/api/copilot/api-keys') if (!res.ok) throw new Error(`Failed to fetch: ${res.status}`) const data = await res.json() - setKeys(Array.isArray(data.keys) ? data.keys : []) + setKeys(Array.isArray(data.keys) ? (data.keys as CopilotKey[]) : []) } catch (error) { logger.error('Failed to fetch copilot keys', { error }) setKeys([]) @@ -83,11 +71,11 @@ export function Copilot() { throw new Error(body.error || 'Failed to generate API key') } const data = await res.json() - // Show the new key dialog with the API key (only shown once) - if (data?.key) { - setNewKey(data.key) + if (data?.key?.apiKey) { + setNewKey(data.key.apiKey) setShowNewKeyDialog(true) } + await fetchKeys() } catch (error) { logger.error('Failed to generate copilot API key', { error }) @@ -117,12 +105,7 @@ export function Copilot() { const onCopy = async (value: string, keyId?: string) => { try { await navigator.clipboard.writeText(value) - if (keyId) { - setCopiedKeyIds((prev) => ({ ...prev, [keyId]: true })) - setTimeout(() => { - setCopiedKeyIds((prev) => ({ ...prev, [keyId]: false })) - }, 1500) - } else { + if (!keyId) { setNewKeyCopySuccess(true) setTimeout(() => setNewKeyCopySuccess(false), 1500) } @@ -166,77 +149,32 @@ export function Copilot() { ) : (
- {filteredKeys.map((k) => { - const isVisible = !!visible[k.id] - const value = maskedValue(k.apiKey, isVisible) - return ( -
- -
-
-
- {value} -
-
- - - - - - {isVisible ? 'Hide' : 'Reveal'} - - - - - - - - - Copy - - -
+ {filteredKeys.map((k) => ( +
+ +
+
+
+ {k.displayKey}
- -
+ +
- ) - })} +
+ ))} {/* Show message when search has no results but there are keys */} {searchTerm.trim() && filteredKeys.length === 0 && keys.length > 0 && (
@@ -265,7 +203,7 @@ export function Copilot() { disabled={isLoading} > - Generate Key + Create Key )} @@ -285,24 +223,23 @@ export function Copilot() { > - New Copilot API Key + Your API key has been created - Copy it now and store it securely. + This is the only time you will see your API key.{' '} + Copy it now and store it securely. {newKey && (
- - {newKey.apiKey} - + {newKey}