From 3405c27ef680056dddd20aa0933376b44934d85b Mon Sep 17 00:00:00 2001 From: marko-kraemer Date: Sun, 27 Jul 2025 01:22:56 +0200 Subject: [PATCH] wip --- ...26223759_move_agent_fields_to_metadata.sql | 31 ++++++++++++++++ ..._reverse_move_agent_fields_to_metadata.sql | 36 +++++++++++++++++++ frontend/.env.example | 9 ----- .../[projectId]/thread/[threadId]/page.tsx | 8 ++--- .../components/agents/agent-builder-chat.tsx | 5 +-- .../src/components/agents/agent-preview.tsx | 10 ++---- .../src/hooks/react-query/agents/utils.ts | 2 +- .../use-knowledge-base-queries.ts | 22 ++++++++++++ .../react-query/threads/use-agent-run.ts | 2 +- .../src/hooks/react-query/threads/utils.ts | 1 + frontend/src/lib/api-enhanced.ts | 1 - 11 files changed, 99 insertions(+), 28 deletions(-) create mode 100644 backend/supabase/migrations/20250726223759_move_agent_fields_to_metadata.sql create mode 100644 backend/supabase/migrations/20250726224819_reverse_move_agent_fields_to_metadata.sql delete mode 100644 frontend/.env.example diff --git a/backend/supabase/migrations/20250726223759_move_agent_fields_to_metadata.sql b/backend/supabase/migrations/20250726223759_move_agent_fields_to_metadata.sql new file mode 100644 index 00000000..0199e7f6 --- /dev/null +++ b/backend/supabase/migrations/20250726223759_move_agent_fields_to_metadata.sql @@ -0,0 +1,31 @@ +-- Migration: Move agent_id and agent_version_id from dedicated columns to metadata +-- This improves storage efficiency by only storing agent info for assistant messages where it's relevant + +BEGIN; + +-- Step 1: Update existing messages to move agent info to metadata +-- Only update messages that have agent_id or agent_version_id set +UPDATE messages +SET metadata = jsonb_set( + jsonb_set( + COALESCE(metadata, '{}'::jsonb), + '{agent_id}', + to_jsonb(agent_id) + ), + '{agent_version_id}', + to_jsonb(agent_version_id) +) +WHERE agent_id IS NOT NULL OR agent_version_id IS NOT NULL; + +-- Step 2: Drop indexes on the columns we're about to remove +DROP INDEX IF EXISTS idx_messages_agent_id; +DROP INDEX IF EXISTS idx_messages_agent_version_id; + +-- Step 3: Drop the dedicated agent columns +ALTER TABLE messages DROP COLUMN IF EXISTS agent_id; +ALTER TABLE messages DROP COLUMN IF EXISTS agent_version_id; + +-- Step 4: Add comment explaining the new structure +COMMENT ON COLUMN messages.metadata IS 'JSONB metadata including agent_id and agent_version_id for assistant messages, and other message-specific data'; + +COMMIT; \ No newline at end of file diff --git a/backend/supabase/migrations/20250726224819_reverse_move_agent_fields_to_metadata.sql b/backend/supabase/migrations/20250726224819_reverse_move_agent_fields_to_metadata.sql new file mode 100644 index 00000000..cc5ca836 --- /dev/null +++ b/backend/supabase/migrations/20250726224819_reverse_move_agent_fields_to_metadata.sql @@ -0,0 +1,36 @@ +-- Reverse Migration: Move agent_id and agent_version_id back from metadata to dedicated columns +-- This reverses the changes made in 20250726223759_move_agent_fields_to_metadata.sql + +BEGIN; + +-- Step 1: Add back the dedicated agent columns with proper foreign key constraints +ALTER TABLE messages ADD COLUMN IF NOT EXISTS agent_id UUID REFERENCES agents(agent_id) ON DELETE SET NULL; +ALTER TABLE messages ADD COLUMN IF NOT EXISTS agent_version_id UUID REFERENCES agent_versions(version_id) ON DELETE SET NULL; + +-- Step 2: Extract agent info from metadata and populate the dedicated columns +-- Only update messages that have agent info in metadata +UPDATE messages +SET + agent_id = CASE + WHEN metadata ? 'agent_id' THEN (metadata->>'agent_id')::UUID + ELSE NULL + END, + agent_version_id = CASE + WHEN metadata ? 'agent_version_id' THEN (metadata->>'agent_version_id')::UUID + ELSE NULL + END +WHERE metadata ? 'agent_id' OR metadata ? 'agent_version_id'; + +-- Step 3: Remove agent fields from metadata +UPDATE messages +SET metadata = metadata - 'agent_id' - 'agent_version_id' +WHERE metadata ? 'agent_id' OR metadata ? 'agent_version_id'; + +-- Step 4: Recreate the indexes on the agent columns +CREATE INDEX IF NOT EXISTS idx_messages_agent_id ON messages(agent_id); +CREATE INDEX IF NOT EXISTS idx_messages_agent_version_id ON messages(agent_version_id); + +-- Step 5: Update the comment to reflect the original structure +COMMENT ON COLUMN messages.metadata IS 'JSONB metadata for message-specific data (agent info stored in dedicated columns)'; + +COMMIT; \ No newline at end of file diff --git a/frontend/.env.example b/frontend/.env.example deleted file mode 100644 index dc147102..00000000 --- a/frontend/.env.example +++ /dev/null @@ -1,9 +0,0 @@ -NEXT_PUBLIC_ENV_MODE="LOCAL" #production, or staging -NEXT_PUBLIC_SUPABASE_URL="" -NEXT_PUBLIC_SUPABASE_ANON_KEY="" -NEXT_PUBLIC_BACKEND_URL="" -NEXT_PUBLIC_URL="" -NEXT_PUBLIC_GOOGLE_CLIENT_ID="" -OPENAI_API_KEY="" - -EDGE_CONFIG="https://edge-config.vercel.com/REDACTED?token=REDACTED" diff --git a/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx b/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx index abdcb3c2..c2fa6e4b 100644 --- a/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx +++ b/frontend/src/app/(dashboard)/projects/[projectId]/thread/[threadId]/page.tsx @@ -129,9 +129,9 @@ export default function ThreadPage({ const agent = threadAgentData?.agent; const workflowId = threadQuery.data?.metadata?.workflow_id; - // Set initial selected agent from thread data (most recently used agent) + // Set initial selected agent from thread data useEffect(() => { - if (threadAgentData?.agent && !selectedAgentId && threadAgentData.source === 'recent') { + if (threadAgentData?.agent && !selectedAgentId) { setSelectedAgentId(threadAgentData.agent.agent_id); } }, [threadAgentData, selectedAgentId]); @@ -282,10 +282,10 @@ export default function ThreadPage({ const agentPromise = startAgentMutation.mutateAsync({ threadId, - options: selectedAgentId ? { + options: { ...options, agent_id: selectedAgentId - } : options + } }); const results = await Promise.allSettled([messagePromise, agentPromise]); diff --git a/frontend/src/components/agents/agent-builder-chat.tsx b/frontend/src/components/agents/agent-builder-chat.tsx index 562cb4dd..610204e5 100644 --- a/frontend/src/components/agents/agent-builder-chat.tsx +++ b/frontend/src/components/agents/agent-builder-chat.tsx @@ -312,10 +312,7 @@ export const AgentBuilderChat = React.memo(function AgentBuilderChat({ const agentPromise = startAgentMutation.mutateAsync({ threadId, - options: { - ...options, - agent_id: agentId - } + options }); const results = await Promise.allSettled([messagePromise, agentPromise]); diff --git a/frontend/src/components/agents/agent-preview.tsx b/frontend/src/components/agents/agent-preview.tsx index 9c012b48..85654666 100644 --- a/frontend/src/components/agents/agent-preview.tsx +++ b/frontend/src/components/agents/agent-preview.tsx @@ -213,10 +213,7 @@ export const AgentPreview = ({ agent, agentMetadata }: AgentPreviewProps) => { try { const agentResult = await startAgentMutation.mutateAsync({ threadId: result.thread_id, - options: { - ...options, - agent_id: agent.agent_id - } + options }); console.log('[PREVIEW] Agent started manually:', agentResult); setAgentRunId(agentResult.agent_run_id); @@ -283,10 +280,7 @@ export const AgentPreview = ({ agent, agentMetadata }: AgentPreviewProps) => { const agentPromise = startAgentMutation.mutateAsync({ threadId, - options: { - ...options, - agent_id: agent.agent_id - } + options }); const results = await Promise.allSettled([messagePromise, agentPromise]); diff --git a/frontend/src/hooks/react-query/agents/utils.ts b/frontend/src/hooks/react-query/agents/utils.ts index 345d930b..03ba9ba8 100644 --- a/frontend/src/hooks/react-query/agents/utils.ts +++ b/frontend/src/hooks/react-query/agents/utils.ts @@ -74,7 +74,7 @@ export type AgentsParams = { export type ThreadAgentResponse = { agent: Agent | null; - source: 'recent' | 'none' | 'missing'; + source: 'thread' | 'default' | 'none' | 'missing'; message: string; }; diff --git a/frontend/src/hooks/react-query/knowledge-base/use-knowledge-base-queries.ts b/frontend/src/hooks/react-query/knowledge-base/use-knowledge-base-queries.ts index 00852560..f509cd0c 100644 --- a/frontend/src/hooks/react-query/knowledge-base/use-knowledge-base-queries.ts +++ b/frontend/src/hooks/react-query/knowledge-base/use-knowledge-base-queries.ts @@ -77,6 +77,28 @@ export function useKnowledgeBaseEntry(entryId: string) { }); } +export function useKnowledgeBaseContext(threadId: string, maxTokens = 4000) { + const { getHeaders } = useAuthHeaders(); + + return useQuery({ + queryKey: knowledgeBaseKeys.context(threadId), + queryFn: async () => { + const headers = await getHeaders(); + const url = new URL(`${API_URL}/knowledge-base/threads/${threadId}/context`); + url.searchParams.set('max_tokens', maxTokens.toString()); + + const response = await fetch(url.toString(), { headers }); + + if (!response.ok) { + const error = await response.text(); + throw new Error(error || 'Failed to fetch knowledge base context'); + } + + return await response.json(); + }, + enabled: !!threadId, + }); +} export function useCreateKnowledgeBaseEntry() { const queryClient = useQueryClient(); diff --git a/frontend/src/hooks/react-query/threads/use-agent-run.ts b/frontend/src/hooks/react-query/threads/use-agent-run.ts index 38c9fd47..c09ed9f1 100644 --- a/frontend/src/hooks/react-query/threads/use-agent-run.ts +++ b/frontend/src/hooks/react-query/threads/use-agent-run.ts @@ -24,7 +24,7 @@ export const useStartAgentMutation = () => enable_thinking?: boolean; reasoning_effort?: string; stream?: boolean; - agent_id?: string; // Optional again + agent_id?: string; }; }) => startAgent(threadId, options), { diff --git a/frontend/src/hooks/react-query/threads/utils.ts b/frontend/src/hooks/react-query/threads/utils.ts index a723b2b7..8279a1e9 100644 --- a/frontend/src/hooks/react-query/threads/utils.ts +++ b/frontend/src/hooks/react-query/threads/utils.ts @@ -14,6 +14,7 @@ export type Thread = { workflow_name?: string; workflow_run_name?: string; is_workflow_execution?: boolean; + agent_id?: string; is_agent_builder?: boolean; [key: string]: any; }; diff --git a/frontend/src/lib/api-enhanced.ts b/frontend/src/lib/api-enhanced.ts index ba9b5bab..2e42f6e4 100644 --- a/frontend/src/lib/api-enhanced.ts +++ b/frontend/src/lib/api-enhanced.ts @@ -321,7 +321,6 @@ export const agentApi = { enable_thinking?: boolean; reasoning_effort?: string; stream?: boolean; - agent_id?: string; // Optional again } ): Promise<{ agent_run_id: string } | null> { const result = await backendApi.post(