diff --git a/backend/api.py b/backend/api.py index 994560ca..3a3bbde3 100644 --- a/backend/api.py +++ b/backend/api.py @@ -28,7 +28,6 @@ from flags import api as feature_flags_api from services import transcription as transcription_api import sys from services import email_api -from feedback import api as feedback_api from triggers import api as triggers_api from triggers.endpoints.workflows import router as workflows_router @@ -188,8 +187,6 @@ api_router.include_router(workflows_router, prefix="/workflows") from pipedream import api as pipedream_api api_router.include_router(pipedream_api.router) -api_router.include_router(feedback_api.router) - @api_router.get("/health") async def health_check(): logger.info("Health check endpoint called") diff --git a/backend/feedback/api.py b/backend/feedback/api.py deleted file mode 100644 index 33ceb60a..00000000 --- a/backend/feedback/api.py +++ /dev/null @@ -1,40 +0,0 @@ -from pydantic import BaseModel, Field -from fastapi import APIRouter, Depends, HTTPException -from services.supabase import DBConnection -from utils.auth_utils import get_current_user_id_from_jwt, verify_thread_access - -router = APIRouter(prefix="/feedback", tags=["feedback"]) - -class FeedbackRequest(BaseModel): - message_id: str = Field(..., description="ID of the message that is being rated") - is_good: bool = Field(..., description="True for good response, False for bad response") - feedback: str | None = Field(None, description="Optional free-form text feedback from the user") - -db = DBConnection() -@router.post("/") -async def submit_feedback(request: FeedbackRequest, user_id: str = Depends(get_current_user_id_from_jwt)): - try: - client = await db.client - thread = await client.table('messages').select('thread_id').eq('message_id', request.message_id).single().execute() - - if not thread.data: - raise HTTPException(status_code=404, detail="Message not found") - - thread_id = thread.data['thread_id'] - - await verify_thread_access(client, thread_id, user_id) - - feedback_data = { - 'message_id': request.message_id, - 'is_good': request.is_good, - 'feedback': request.feedback - } - - feedback_result = await client.table('feedback').upsert(feedback_data, on_conflict='message_id').execute() - - if not feedback_result.data: - raise HTTPException(status_code=500, detail="Failed to submit feedback") - - return {"success": True} - except Exception as e: - raise HTTPException(status_code=500, detail=str(e)) diff --git a/backend/supabase/migrations/20250703190154_feedback.sql b/backend/supabase/migrations/20250703190154_feedback.sql deleted file mode 100644 index 8788ad11..00000000 --- a/backend/supabase/migrations/20250703190154_feedback.sql +++ /dev/null @@ -1,66 +0,0 @@ -create table "public"."feedback" ( - "id" uuid not null default gen_random_uuid(), - "created_at" timestamp with time zone not null default now(), - "is_good" boolean not null, - "message_id" uuid, - "feedback" text -); - - -alter table "public"."feedback" enable row level security; - -CREATE UNIQUE INDEX feedback_message_id_key ON public.feedback USING btree (message_id); - -CREATE UNIQUE INDEX feedback_pkey ON public.feedback USING btree (id); - -alter table "public"."feedback" add constraint "feedback_pkey" PRIMARY KEY using index "feedback_pkey"; - -alter table "public"."feedback" add constraint "feedback_message_id_fkey" FOREIGN KEY (message_id) REFERENCES messages(message_id) not valid; - -alter table "public"."feedback" validate constraint "feedback_message_id_fkey"; - -alter table "public"."feedback" add constraint "feedback_message_id_key" UNIQUE using index "feedback_message_id_key"; - -grant delete on table "public"."feedback" to "anon"; - -grant insert on table "public"."feedback" to "anon"; - -grant references on table "public"."feedback" to "anon"; - -grant select on table "public"."feedback" to "anon"; - -grant trigger on table "public"."feedback" to "anon"; - -grant truncate on table "public"."feedback" to "anon"; - -grant update on table "public"."feedback" to "anon"; - -grant delete on table "public"."feedback" to "authenticated"; - -grant insert on table "public"."feedback" to "authenticated"; - -grant references on table "public"."feedback" to "authenticated"; - -grant select on table "public"."feedback" to "authenticated"; - -grant trigger on table "public"."feedback" to "authenticated"; - -grant truncate on table "public"."feedback" to "authenticated"; - -grant update on table "public"."feedback" to "authenticated"; - -grant delete on table "public"."feedback" to "service_role"; - -grant insert on table "public"."feedback" to "service_role"; - -grant references on table "public"."feedback" to "service_role"; - -grant select on table "public"."feedback" to "service_role"; - -grant trigger on table "public"."feedback" to "service_role"; - -grant truncate on table "public"."feedback" to "service_role"; - -grant update on table "public"."feedback" to "service_role"; - - diff --git a/backend/supabase/migrations/20250703191627_feedback_policy.sql b/backend/supabase/migrations/20250703191627_feedback_policy.sql deleted file mode 100644 index aff7f418..00000000 --- a/backend/supabase/migrations/20250703191627_feedback_policy.sql +++ /dev/null @@ -1,9 +0,0 @@ -create policy "Authenticated read feedback" -on "public"."feedback" -as permissive -for select -to authenticated -using (true); - - - diff --git a/backend/supabase/migrations/20250703211655_feedback_cascade.sql b/backend/supabase/migrations/20250703211655_feedback_cascade.sql deleted file mode 100644 index dc0ee05b..00000000 --- a/backend/supabase/migrations/20250703211655_feedback_cascade.sql +++ /dev/null @@ -1,498 +0,0 @@ -drop trigger if exists "trigger_agent_kb_entries_calculate_tokens" on "public"."agent_knowledge_base_entries"; - -drop trigger if exists "trigger_agent_kb_entries_updated_at" on "public"."agent_knowledge_base_entries"; - -drop trigger if exists "update_agent_triggers_updated_at" on "public"."agent_triggers"; - -drop trigger if exists "update_custom_trigger_providers_updated_at" on "public"."custom_trigger_providers"; - -drop trigger if exists "update_oauth_installations_updated_at" on "public"."oauth_installations"; - -drop policy "agent_kb_jobs_user_access" on "public"."agent_kb_file_processing_jobs"; - -drop policy "agent_kb_entries_user_access" on "public"."agent_knowledge_base_entries"; - -drop policy "agent_kb_usage_log_user_access" on "public"."agent_knowledge_base_usage_log"; - -drop policy "agent_triggers_delete_policy" on "public"."agent_triggers"; - -drop policy "agent_triggers_insert_policy" on "public"."agent_triggers"; - -drop policy "agent_triggers_select_policy" on "public"."agent_triggers"; - -drop policy "agent_triggers_update_policy" on "public"."agent_triggers"; - -drop policy "custom_trigger_providers_delete_policy" on "public"."custom_trigger_providers"; - -drop policy "custom_trigger_providers_insert_policy" on "public"."custom_trigger_providers"; - -drop policy "custom_trigger_providers_select_policy" on "public"."custom_trigger_providers"; - -drop policy "custom_trigger_providers_update_policy" on "public"."custom_trigger_providers"; - -drop policy "oauth_installations_delete_policy" on "public"."oauth_installations"; - -drop policy "oauth_installations_insert_policy" on "public"."oauth_installations"; - -drop policy "oauth_installations_select_policy" on "public"."oauth_installations"; - -drop policy "oauth_installations_update_policy" on "public"."oauth_installations"; - -drop policy "trigger_events_insert_policy" on "public"."trigger_events"; - -drop policy "trigger_events_select_policy" on "public"."trigger_events"; - -revoke delete on table "public"."agent_kb_file_processing_jobs" from "anon"; - -revoke insert on table "public"."agent_kb_file_processing_jobs" from "anon"; - -revoke references on table "public"."agent_kb_file_processing_jobs" from "anon"; - -revoke select on table "public"."agent_kb_file_processing_jobs" from "anon"; - -revoke trigger on table "public"."agent_kb_file_processing_jobs" from "anon"; - -revoke truncate on table "public"."agent_kb_file_processing_jobs" from "anon"; - -revoke update on table "public"."agent_kb_file_processing_jobs" from "anon"; - -revoke delete on table "public"."agent_kb_file_processing_jobs" from "authenticated"; - -revoke insert on table "public"."agent_kb_file_processing_jobs" from "authenticated"; - -revoke references on table "public"."agent_kb_file_processing_jobs" from "authenticated"; - -revoke select on table "public"."agent_kb_file_processing_jobs" from "authenticated"; - -revoke trigger on table "public"."agent_kb_file_processing_jobs" from "authenticated"; - -revoke truncate on table "public"."agent_kb_file_processing_jobs" from "authenticated"; - -revoke update on table "public"."agent_kb_file_processing_jobs" from "authenticated"; - -revoke delete on table "public"."agent_kb_file_processing_jobs" from "service_role"; - -revoke insert on table "public"."agent_kb_file_processing_jobs" from "service_role"; - -revoke references on table "public"."agent_kb_file_processing_jobs" from "service_role"; - -revoke select on table "public"."agent_kb_file_processing_jobs" from "service_role"; - -revoke trigger on table "public"."agent_kb_file_processing_jobs" from "service_role"; - -revoke truncate on table "public"."agent_kb_file_processing_jobs" from "service_role"; - -revoke update on table "public"."agent_kb_file_processing_jobs" from "service_role"; - -revoke delete on table "public"."agent_knowledge_base_entries" from "anon"; - -revoke insert on table "public"."agent_knowledge_base_entries" from "anon"; - -revoke references on table "public"."agent_knowledge_base_entries" from "anon"; - -revoke select on table "public"."agent_knowledge_base_entries" from "anon"; - -revoke trigger on table "public"."agent_knowledge_base_entries" from "anon"; - -revoke truncate on table "public"."agent_knowledge_base_entries" from "anon"; - -revoke update on table "public"."agent_knowledge_base_entries" from "anon"; - -revoke delete on table "public"."agent_knowledge_base_entries" from "authenticated"; - -revoke insert on table "public"."agent_knowledge_base_entries" from "authenticated"; - -revoke references on table "public"."agent_knowledge_base_entries" from "authenticated"; - -revoke select on table "public"."agent_knowledge_base_entries" from "authenticated"; - -revoke trigger on table "public"."agent_knowledge_base_entries" from "authenticated"; - -revoke truncate on table "public"."agent_knowledge_base_entries" from "authenticated"; - -revoke update on table "public"."agent_knowledge_base_entries" from "authenticated"; - -revoke delete on table "public"."agent_knowledge_base_entries" from "service_role"; - -revoke insert on table "public"."agent_knowledge_base_entries" from "service_role"; - -revoke references on table "public"."agent_knowledge_base_entries" from "service_role"; - -revoke select on table "public"."agent_knowledge_base_entries" from "service_role"; - -revoke trigger on table "public"."agent_knowledge_base_entries" from "service_role"; - -revoke truncate on table "public"."agent_knowledge_base_entries" from "service_role"; - -revoke update on table "public"."agent_knowledge_base_entries" from "service_role"; - -revoke delete on table "public"."agent_knowledge_base_usage_log" from "anon"; - -revoke insert on table "public"."agent_knowledge_base_usage_log" from "anon"; - -revoke references on table "public"."agent_knowledge_base_usage_log" from "anon"; - -revoke select on table "public"."agent_knowledge_base_usage_log" from "anon"; - -revoke trigger on table "public"."agent_knowledge_base_usage_log" from "anon"; - -revoke truncate on table "public"."agent_knowledge_base_usage_log" from "anon"; - -revoke update on table "public"."agent_knowledge_base_usage_log" from "anon"; - -revoke delete on table "public"."agent_knowledge_base_usage_log" from "authenticated"; - -revoke insert on table "public"."agent_knowledge_base_usage_log" from "authenticated"; - -revoke references on table "public"."agent_knowledge_base_usage_log" from "authenticated"; - -revoke select on table "public"."agent_knowledge_base_usage_log" from "authenticated"; - -revoke trigger on table "public"."agent_knowledge_base_usage_log" from "authenticated"; - -revoke truncate on table "public"."agent_knowledge_base_usage_log" from "authenticated"; - -revoke update on table "public"."agent_knowledge_base_usage_log" from "authenticated"; - -revoke delete on table "public"."agent_knowledge_base_usage_log" from "service_role"; - -revoke insert on table "public"."agent_knowledge_base_usage_log" from "service_role"; - -revoke references on table "public"."agent_knowledge_base_usage_log" from "service_role"; - -revoke select on table "public"."agent_knowledge_base_usage_log" from "service_role"; - -revoke trigger on table "public"."agent_knowledge_base_usage_log" from "service_role"; - -revoke truncate on table "public"."agent_knowledge_base_usage_log" from "service_role"; - -revoke update on table "public"."agent_knowledge_base_usage_log" from "service_role"; - -revoke delete on table "public"."agent_triggers" from "anon"; - -revoke insert on table "public"."agent_triggers" from "anon"; - -revoke references on table "public"."agent_triggers" from "anon"; - -revoke select on table "public"."agent_triggers" from "anon"; - -revoke trigger on table "public"."agent_triggers" from "anon"; - -revoke truncate on table "public"."agent_triggers" from "anon"; - -revoke update on table "public"."agent_triggers" from "anon"; - -revoke delete on table "public"."agent_triggers" from "authenticated"; - -revoke insert on table "public"."agent_triggers" from "authenticated"; - -revoke references on table "public"."agent_triggers" from "authenticated"; - -revoke select on table "public"."agent_triggers" from "authenticated"; - -revoke trigger on table "public"."agent_triggers" from "authenticated"; - -revoke truncate on table "public"."agent_triggers" from "authenticated"; - -revoke update on table "public"."agent_triggers" from "authenticated"; - -revoke delete on table "public"."agent_triggers" from "service_role"; - -revoke insert on table "public"."agent_triggers" from "service_role"; - -revoke references on table "public"."agent_triggers" from "service_role"; - -revoke select on table "public"."agent_triggers" from "service_role"; - -revoke trigger on table "public"."agent_triggers" from "service_role"; - -revoke truncate on table "public"."agent_triggers" from "service_role"; - -revoke update on table "public"."agent_triggers" from "service_role"; - -revoke delete on table "public"."custom_trigger_providers" from "anon"; - -revoke insert on table "public"."custom_trigger_providers" from "anon"; - -revoke references on table "public"."custom_trigger_providers" from "anon"; - -revoke select on table "public"."custom_trigger_providers" from "anon"; - -revoke trigger on table "public"."custom_trigger_providers" from "anon"; - -revoke truncate on table "public"."custom_trigger_providers" from "anon"; - -revoke update on table "public"."custom_trigger_providers" from "anon"; - -revoke delete on table "public"."custom_trigger_providers" from "authenticated"; - -revoke insert on table "public"."custom_trigger_providers" from "authenticated"; - -revoke references on table "public"."custom_trigger_providers" from "authenticated"; - -revoke select on table "public"."custom_trigger_providers" from "authenticated"; - -revoke trigger on table "public"."custom_trigger_providers" from "authenticated"; - -revoke truncate on table "public"."custom_trigger_providers" from "authenticated"; - -revoke update on table "public"."custom_trigger_providers" from "authenticated"; - -revoke delete on table "public"."custom_trigger_providers" from "service_role"; - -revoke insert on table "public"."custom_trigger_providers" from "service_role"; - -revoke references on table "public"."custom_trigger_providers" from "service_role"; - -revoke select on table "public"."custom_trigger_providers" from "service_role"; - -revoke trigger on table "public"."custom_trigger_providers" from "service_role"; - -revoke truncate on table "public"."custom_trigger_providers" from "service_role"; - -revoke update on table "public"."custom_trigger_providers" from "service_role"; - -revoke delete on table "public"."oauth_installations" from "anon"; - -revoke insert on table "public"."oauth_installations" from "anon"; - -revoke references on table "public"."oauth_installations" from "anon"; - -revoke select on table "public"."oauth_installations" from "anon"; - -revoke trigger on table "public"."oauth_installations" from "anon"; - -revoke truncate on table "public"."oauth_installations" from "anon"; - -revoke update on table "public"."oauth_installations" from "anon"; - -revoke delete on table "public"."oauth_installations" from "authenticated"; - -revoke insert on table "public"."oauth_installations" from "authenticated"; - -revoke references on table "public"."oauth_installations" from "authenticated"; - -revoke select on table "public"."oauth_installations" from "authenticated"; - -revoke trigger on table "public"."oauth_installations" from "authenticated"; - -revoke truncate on table "public"."oauth_installations" from "authenticated"; - -revoke update on table "public"."oauth_installations" from "authenticated"; - -revoke delete on table "public"."oauth_installations" from "service_role"; - -revoke insert on table "public"."oauth_installations" from "service_role"; - -revoke references on table "public"."oauth_installations" from "service_role"; - -revoke select on table "public"."oauth_installations" from "service_role"; - -revoke trigger on table "public"."oauth_installations" from "service_role"; - -revoke truncate on table "public"."oauth_installations" from "service_role"; - -revoke update on table "public"."oauth_installations" from "service_role"; - -revoke delete on table "public"."trigger_events" from "anon"; - -revoke insert on table "public"."trigger_events" from "anon"; - -revoke references on table "public"."trigger_events" from "anon"; - -revoke select on table "public"."trigger_events" from "anon"; - -revoke trigger on table "public"."trigger_events" from "anon"; - -revoke truncate on table "public"."trigger_events" from "anon"; - -revoke update on table "public"."trigger_events" from "anon"; - -revoke delete on table "public"."trigger_events" from "authenticated"; - -revoke insert on table "public"."trigger_events" from "authenticated"; - -revoke references on table "public"."trigger_events" from "authenticated"; - -revoke select on table "public"."trigger_events" from "authenticated"; - -revoke trigger on table "public"."trigger_events" from "authenticated"; - -revoke truncate on table "public"."trigger_events" from "authenticated"; - -revoke update on table "public"."trigger_events" from "authenticated"; - -revoke delete on table "public"."trigger_events" from "service_role"; - -revoke insert on table "public"."trigger_events" from "service_role"; - -revoke references on table "public"."trigger_events" from "service_role"; - -revoke select on table "public"."trigger_events" from "service_role"; - -revoke trigger on table "public"."trigger_events" from "service_role"; - -revoke truncate on table "public"."trigger_events" from "service_role"; - -revoke update on table "public"."trigger_events" from "service_role"; - -alter table "public"."agent_kb_file_processing_jobs" drop constraint "agent_kb_file_processing_jobs_account_id_fkey"; - -alter table "public"."agent_kb_file_processing_jobs" drop constraint "agent_kb_file_processing_jobs_agent_id_fkey"; - -alter table "public"."agent_kb_file_processing_jobs" drop constraint "agent_kb_file_processing_jobs_job_type_check"; - -alter table "public"."agent_kb_file_processing_jobs" drop constraint "agent_kb_file_processing_jobs_status_check"; - -alter table "public"."agent_knowledge_base_entries" drop constraint "agent_kb_entries_content_not_empty"; - -alter table "public"."agent_knowledge_base_entries" drop constraint "agent_kb_entries_valid_usage_context"; - -alter table "public"."agent_knowledge_base_entries" drop constraint "agent_knowledge_base_entries_account_id_fkey"; - -alter table "public"."agent_knowledge_base_entries" drop constraint "agent_knowledge_base_entries_agent_id_fkey"; - -alter table "public"."agent_knowledge_base_entries" drop constraint "agent_knowledge_base_entries_extracted_from_zip_id_fkey"; - -alter table "public"."agent_knowledge_base_entries" drop constraint "agent_knowledge_base_entries_source_type_check"; - -alter table "public"."agent_knowledge_base_usage_log" drop constraint "agent_knowledge_base_usage_log_agent_id_fkey"; - -alter table "public"."agent_knowledge_base_usage_log" drop constraint "agent_knowledge_base_usage_log_entry_id_fkey"; - -alter table "public"."agent_triggers" drop constraint "agent_triggers_agent_id_fkey"; - -alter table "public"."custom_trigger_providers" drop constraint "custom_trigger_providers_created_by_fkey"; - -alter table "public"."oauth_installations" drop constraint "oauth_installations_trigger_id_fkey"; - -alter table "public"."trigger_events" drop constraint "trigger_events_agent_id_fkey"; - -alter table "public"."trigger_events" drop constraint "trigger_events_trigger_id_fkey"; - -drop function if exists "public"."calculate_agent_kb_entry_tokens"(); - -drop function if exists "public"."create_agent_kb_processing_job"(p_agent_id uuid, p_account_id uuid, p_job_type character varying, p_source_info jsonb); - -drop function if exists "public"."get_agent_kb_processing_jobs"(p_agent_id uuid, p_limit integer); - -drop function if exists "public"."get_agent_knowledge_base"(p_agent_id uuid, p_include_inactive boolean); - -drop function if exists "public"."get_agent_knowledge_base_context"(p_agent_id uuid, p_max_tokens integer); - -drop function if exists "public"."get_combined_knowledge_base_context"(p_thread_id uuid, p_agent_id uuid, p_max_tokens integer); - -drop function if exists "public"."update_agent_kb_entry_timestamp"(); - -drop function if exists "public"."update_agent_kb_job_status"(p_job_id uuid, p_status character varying, p_result_info jsonb, p_entries_created integer, p_total_files integer, p_error_message text); - -alter table "public"."agent_kb_file_processing_jobs" drop constraint "agent_kb_file_processing_jobs_pkey"; - -alter table "public"."agent_knowledge_base_entries" drop constraint "agent_knowledge_base_entries_pkey"; - -alter table "public"."agent_knowledge_base_usage_log" drop constraint "agent_knowledge_base_usage_log_pkey"; - -alter table "public"."agent_triggers" drop constraint "agent_triggers_pkey"; - -alter table "public"."custom_trigger_providers" drop constraint "custom_trigger_providers_pkey"; - -alter table "public"."oauth_installations" drop constraint "oauth_installations_pkey"; - -alter table "public"."trigger_events" drop constraint "trigger_events_pkey"; - -drop index if exists "public"."agent_kb_file_processing_jobs_pkey"; - -drop index if exists "public"."agent_knowledge_base_entries_pkey"; - -drop index if exists "public"."agent_knowledge_base_usage_log_pkey"; - -drop index if exists "public"."agent_triggers_pkey"; - -drop index if exists "public"."custom_trigger_providers_pkey"; - -drop index if exists "public"."idx_agent_kb_entries_account_id"; - -drop index if exists "public"."idx_agent_kb_entries_agent_id"; - -drop index if exists "public"."idx_agent_kb_entries_created_at"; - -drop index if exists "public"."idx_agent_kb_entries_extracted_from_zip"; - -drop index if exists "public"."idx_agent_kb_entries_is_active"; - -drop index if exists "public"."idx_agent_kb_entries_source_type"; - -drop index if exists "public"."idx_agent_kb_entries_usage_context"; - -drop index if exists "public"."idx_agent_kb_jobs_agent_id"; - -drop index if exists "public"."idx_agent_kb_jobs_created_at"; - -drop index if exists "public"."idx_agent_kb_jobs_status"; - -drop index if exists "public"."idx_agent_kb_usage_agent_id"; - -drop index if exists "public"."idx_agent_kb_usage_entry_id"; - -drop index if exists "public"."idx_agent_kb_usage_used_at"; - -drop index if exists "public"."idx_agent_triggers_agent_id"; - -drop index if exists "public"."idx_agent_triggers_created_at"; - -drop index if exists "public"."idx_agent_triggers_is_active"; - -drop index if exists "public"."idx_agent_triggers_trigger_type"; - -drop index if exists "public"."idx_custom_trigger_providers_is_active"; - -drop index if exists "public"."idx_custom_trigger_providers_trigger_type"; - -drop index if exists "public"."idx_oauth_installations_installed_at"; - -drop index if exists "public"."idx_oauth_installations_provider"; - -drop index if exists "public"."idx_oauth_installations_trigger_id"; - -drop index if exists "public"."idx_trigger_events_agent_id"; - -drop index if exists "public"."idx_trigger_events_success"; - -drop index if exists "public"."idx_trigger_events_timestamp"; - -drop index if exists "public"."idx_trigger_events_trigger_id"; - -drop index if exists "public"."oauth_installations_pkey"; - -drop index if exists "public"."trigger_events_pkey"; - -drop table "public"."agent_kb_file_processing_jobs"; - -drop table "public"."agent_knowledge_base_entries"; - -drop table "public"."agent_knowledge_base_usage_log"; - -drop table "public"."agent_triggers"; - -drop table "public"."custom_trigger_providers"; - -drop table "public"."oauth_installations"; - -drop table "public"."trigger_events"; - -drop type "public"."agent_trigger_type"; - -set check_function_bodies = off; - -CREATE OR REPLACE FUNCTION public.update_updated_at_column() - RETURNS trigger - LANGUAGE plpgsql -AS $function$ -BEGIN - NEW.updated_at = TIMEZONE('utc'::text, NOW()); - RETURN NEW; -END; -$function$ -; - - diff --git a/frontend/src/app/(dashboard)/projects/[projectId]/thread/_hooks/useThreadData.ts b/frontend/src/app/(dashboard)/projects/[projectId]/thread/_hooks/useThreadData.ts index 13e9ef0e..7b387633 100644 --- a/frontend/src/app/(dashboard)/projects/[projectId]/thread/_hooks/useThreadData.ts +++ b/frontend/src/app/(dashboard)/projects/[projectId]/thread/_hooks/useThreadData.ts @@ -79,7 +79,6 @@ export function useThreadData(threadId: string, projectId: string): UseThreadDat thread_id: msg.thread_id || threadId, type: (msg.type || 'system') as UnifiedMessage['type'], is_llm_message: Boolean(msg.is_llm_message), - user_feedback: msg.user_feedback ?? null, content: msg.content || '', metadata: msg.metadata || '{}', created_at: msg.created_at || new Date().toISOString(), @@ -153,7 +152,6 @@ export function useThreadData(threadId: string, projectId: string): UseThreadDat thread_id: msg.thread_id || threadId, type: (msg.type || 'system') as UnifiedMessage['type'], is_llm_message: Boolean(msg.is_llm_message), - user_feedback: msg.user_feedback ?? null, content: msg.content || '', metadata: msg.metadata || '{}', created_at: msg.created_at || new Date().toISOString(), diff --git a/frontend/src/app/(dashboard)/projects/[projectId]/thread/_types/index.ts b/frontend/src/app/(dashboard)/projects/[projectId]/thread/_types/index.ts index aa3737cb..38f2c1cf 100644 --- a/frontend/src/app/(dashboard)/projects/[projectId]/thread/_types/index.ts +++ b/frontend/src/app/(dashboard)/projects/[projectId]/thread/_types/index.ts @@ -20,7 +20,6 @@ export interface ApiMessageType extends BaseApiMessageType { metadata?: string; created_at?: string; updated_at?: string; - user_feedback?: boolean | null; } export interface StreamingToolCall { diff --git a/frontend/src/app/share/[threadId]/page.tsx b/frontend/src/app/share/[threadId]/page.tsx index 1e72c81e..a158bd18 100644 --- a/frontend/src/app/share/[threadId]/page.tsx +++ b/frontend/src/app/share/[threadId]/page.tsx @@ -48,7 +48,6 @@ interface ApiMessageType extends BaseApiMessageType { avatar?: string; avatar_color?: string; }; - user_feedback?: boolean | null; } interface StreamingToolCall { @@ -402,7 +401,6 @@ export default function ThreadPage({ updated_at: msg.updated_at || new Date().toISOString(), agent_id: (msg as any).agent_id, agents: (msg as any).agents, - user_feedback: msg.user_feedback ?? null, })); setMessages(unifiedMessages); diff --git a/frontend/src/components/thread/content/ThreadContent.tsx b/frontend/src/components/thread/content/ThreadContent.tsx index 6af0c6bf..c6c2589c 100644 --- a/frontend/src/components/thread/content/ThreadContent.tsx +++ b/frontend/src/components/thread/content/ThreadContent.tsx @@ -18,44 +18,6 @@ import { KortixLogo } from '@/components/sidebar/kortix-logo'; import { AgentLoader } from './loader'; import { parseXmlToolCalls, isNewXmlFormat, extractToolNameFromStream } from '@/components/thread/tool-views/xml-parser'; import { parseToolResult } from '@/components/thread/tool-views/tool-result-parser'; -import MessageActions from '@/components/thread/message-actions'; - -// Utility function to extract clean markdown content with formatting preserved -function extractCleanMarkdownContent(content: string): string { - if (!content) return ''; - - let processedContent = content; - - // Extract text from new format ... - const newFormatAskRegex = /[\s\S]*?[\s\S]*?([\s\S]*?)<\/parameter>[\s\S]*?<\/invoke>[\s\S]*?<\/function_calls>/gi; - const newFormatMatches = [...processedContent.matchAll(newFormatAskRegex)]; - - for (const match of newFormatMatches) { - const askText = match[1].trim(); - processedContent = processedContent.replace(match[0], askText); - } - - // Extract text from old format ... - const oldFormatAskRegex = /]*>([\s\S]*?)<\/ask>/gi; - const oldFormatMatches = [...processedContent.matchAll(oldFormatAskRegex)]; - - for (const match of oldFormatMatches) { - const askText = match[1].trim(); - processedContent = processedContent.replace(match[0], askText); - } - - // Remove remaining blocks - processedContent = processedContent.replace(/[\s\S]*?<\/function_calls>/gi, ''); - - // Remove other individual XML tool call tags (but not ask, since we handled those) - processedContent = processedContent.replace(/<(?!inform\b)([a-zA-Z\-_]+)(?:\s+[^>]*)?>(?:[\s\S]*?)<\/\1>|<(?!inform\b)([a-zA-Z\-_]+)(?:\s+[^>]*)?\/>/g, ''); - - // Clean up extra whitespace and newlines while preserving markdown structure - return processedContent - .replace(/\n\s*\n\s*\n/g, '\n\n') // Replace multiple newlines with double newlines - .replace(/^\s+|\s+$/g, '') // Trim leading/trailing whitespace - .trim(); -} // Define the set of tags whose raw XML should be hidden during streaming const HIDE_STREAMING_XML_TAGS = new Set([ @@ -447,7 +409,6 @@ export const ThreadContent: React.FC = ({ type: 'user' | 'assistant_group'; messages: UnifiedMessage[]; key: string; - processedContent?: string; }; const groupedMessages: MessageGroup[] = []; let currentGroup: MessageGroup | null = null; @@ -644,7 +605,7 @@ export const ThreadContent: React.FC = ({ } else if (group.type === 'assistant_group') { return (
-
+
{(() => { @@ -723,9 +684,6 @@ export const ThreadContent: React.FC = ({ const elements: React.ReactNode[] = []; let assistantMessageCount = 0; // Move this outside the loop - // Collect processed content for the Feedback component - const processedContentParts: string[] = []; - group.messages.forEach((message, msgIndex) => { if (message.type === 'assistant') { const parsedContent = safeJsonParse(message.content, {}); @@ -733,12 +691,6 @@ export const ThreadContent: React.FC = ({ if (!parsedContent.content) return; - // Extract clean content for copying - const cleanContent = extractCleanMarkdownContent(parsedContent.content); - if (cleanContent) { - processedContentParts.push(cleanContent); - } - const renderedContent = renderMarkdownContent( parsedContent.content, handleToolClick, @@ -761,10 +713,6 @@ export const ThreadContent: React.FC = ({ } }); - // Store the processed content for the Feedback component - const processedContent = processedContentParts.join('\n\n'); - group.processedContent = processedContent; - return elements; })()} @@ -945,34 +893,6 @@ export const ThreadContent: React.FC = ({ )}
- - {(() => { - const firstAssistant = group.messages.find(msg => msg.type === 'assistant'); - const messageId = firstAssistant?.message_id; - if (!messageId) return null; - - // Check if this group is currently streaming - const isCurrentlyStreaming = (() => { - const isLastGroup = groupIndex === finalGroupedMessages.length - 1; - const hasStreamingContent = streamingTextContent || streamingToolCall; - return isLastGroup && hasStreamingContent; - })(); - - // Don't show actions for streaming messages - if (isCurrentlyStreaming) return null; - - // Get the processed content that was stored during rendering - const processedContent = group.processedContent; - return ( -
- -
- ); - })()}
); diff --git a/frontend/src/components/thread/message-actions.tsx b/frontend/src/components/thread/message-actions.tsx deleted file mode 100644 index 0491f745..00000000 --- a/frontend/src/components/thread/message-actions.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { Dialog, DialogTitle, DialogHeader, DialogContent, DialogFooter, DialogClose } from "@/components/ui/dialog"; -import { Button } from "@/components/ui/button"; -import { ThumbsDown, ThumbsUp, Copy } from "lucide-react"; -import { memo, useState } from "react"; -import { Textarea } from "../ui/textarea"; -import { toast } from "sonner"; -import { backendApi } from '@/lib/api-client'; - -interface MessageActionsProps { - messageId: string; - initialFeedback?: boolean | null; - processedContent?: string; -} - -export default memo(function MessageActions({ messageId, initialFeedback = null, processedContent }: MessageActionsProps) { - const [open, setOpen] = useState(false); - const [submittedFeedback, setSubmittedFeedback] = useState(initialFeedback); - const [feedback, setFeedback] = useState(''); - const [isSubmitting, setIsSubmitting] = useState(false); - const [currentSelection, setCurrentSelection] = useState(null); - - const handleClick = (isGood: boolean) => { - setCurrentSelection(isGood); - setOpen(true); - }; - - const handleCopy = async () => { - try { - if (processedContent) { - await navigator.clipboard.writeText(processedContent); - toast.success('Response copied to clipboard'); - } else { - toast.error('No content to copy'); - } - } catch (error) { - console.error('Failed to copy to clipboard:', error); - toast.error('Failed to copy to clipboard'); - } - }; - - const handleSubmit = async () => { - if (currentSelection === null) return; - - setIsSubmitting(true); - - try { - const { success } = await backendApi.post('/feedback/', { - message_id: messageId, - is_good: currentSelection, - feedback: feedback.trim() || null, - }); - - if (success) { - setSubmittedFeedback(currentSelection); - toast.success('Feedback submitted - thank you!'); - setOpen(false); - setFeedback(''); - setCurrentSelection(null); - } - } catch (error) { - console.error('Failed to submit feedback:', error); - toast.error('Failed to submit feedback'); - } finally { - setIsSubmitting(false); - } - }; - - const handleOpenChange = (newOpen: boolean) => { - setOpen(newOpen); - if (!newOpen) { - setFeedback(''); - setCurrentSelection(null); - } - }; - - return ( -
- - - - - - - - - - Feedback - - - {`What was ${currentSelection === false ? 'un' : ''}satisfying about this response?`} - -