diff --git a/api/controllers/service_api/app/annotation.py b/api/controllers/service_api/app/annotation.py index ef254ca357..c22190cbc9 100644 --- a/api/controllers/service_api/app/annotation.py +++ b/api/controllers/service_api/app/annotation.py @@ -185,4 +185,4 @@ class AnnotationUpdateDeleteApi(Resource): def delete(self, app_model: App, annotation_id: str): """Delete an annotation.""" AppAnnotationService.delete_app_annotation(app_model.id, annotation_id) - return {"result": "success"}, 204 + return "", 204 diff --git a/api/controllers/service_api/app/conversation.py b/api/controllers/service_api/app/conversation.py index 8e29c9ff0f..edbf011656 100644 --- a/api/controllers/service_api/app/conversation.py +++ b/api/controllers/service_api/app/conversation.py @@ -14,7 +14,6 @@ from controllers.service_api.wraps import FetchUserArg, WhereisUserArg, validate from core.app.entities.app_invoke_entities import InvokeFrom from extensions.ext_database import db from fields.conversation_fields import ( - ConversationDelete, ConversationInfiniteScrollPagination, SimpleConversation, ) @@ -163,7 +162,7 @@ class ConversationDetailApi(Resource): ConversationService.delete(app_model, conversation_id, end_user) except services.errors.conversation.ConversationNotExistsError: raise NotFound("Conversation Not Exists.") - return ConversationDelete(result="success").model_dump(mode="json"), 204 + return "", 204 @service_api_ns.route("/conversations//name") diff --git a/api/controllers/service_api/app/workflow.py b/api/controllers/service_api/app/workflow.py index b2148f4fa1..35dd22c801 100644 --- a/api/controllers/service_api/app/workflow.py +++ b/api/controllers/service_api/app/workflow.py @@ -132,6 +132,8 @@ class WorkflowRunDetailApi(Resource): app_id=app_model.id, run_id=workflow_run_id, ) + if not workflow_run: + raise NotFound("Workflow run not found.") return workflow_run diff --git a/api/migrations/versions/2026_02_26_1336-e288952f2994_add_partial_indexes_on_conversations_.py b/api/migrations/versions/2026_02_26_1336-e288952f2994_add_partial_indexes_on_conversations_.py new file mode 100644 index 0000000000..ed794178b3 --- /dev/null +++ b/api/migrations/versions/2026_02_26_1336-e288952f2994_add_partial_indexes_on_conversations_.py @@ -0,0 +1,37 @@ +"""add partial indexes on conversations for app_id with created_at and updated_at + +Revision ID: e288952f2994 +Revises: fce013ca180e +Create Date: 2026-02-26 13:36:45.928922 + +""" +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision = 'e288952f2994' +down_revision = 'fce013ca180e' +branch_labels = None +depends_on = None + + +def upgrade(): + with op.batch_alter_table('conversations', schema=None) as batch_op: + batch_op.create_index( + 'conversation_app_created_at_idx', + ['app_id', sa.literal_column('created_at DESC')], + unique=False, + postgresql_where=sa.text('is_deleted IS false'), + ) + batch_op.create_index( + 'conversation_app_updated_at_idx', + ['app_id', sa.literal_column('updated_at DESC')], + unique=False, + postgresql_where=sa.text('is_deleted IS false'), + ) + + +def downgrade(): + with op.batch_alter_table('conversations', schema=None) as batch_op: + batch_op.drop_index('conversation_app_updated_at_idx') + batch_op.drop_index('conversation_app_created_at_idx') diff --git a/api/models/model.py b/api/models/model.py index a5bca06666..2bf80edb80 100644 --- a/api/models/model.py +++ b/api/models/model.py @@ -711,6 +711,18 @@ class Conversation(Base): __table_args__ = ( sa.PrimaryKeyConstraint("id", name="conversation_pkey"), sa.Index("conversation_app_from_user_idx", "app_id", "from_source", "from_end_user_id"), + sa.Index( + "conversation_app_created_at_idx", + "app_id", + sa.text("created_at DESC"), + postgresql_where=sa.text("is_deleted IS false"), + ), + sa.Index( + "conversation_app_updated_at_idx", + "app_id", + sa.text("updated_at DESC"), + postgresql_where=sa.text("is_deleted IS false"), + ), ) id: Mapped[str] = mapped_column(StringUUID, default=lambda: str(uuid4())) diff --git a/web/app/components/header/account-setting/model-provider-page/atoms.ts b/web/app/components/header/account-setting/model-provider-page/atoms.ts index d0f5a3b3e3..66737c5eb2 100644 --- a/web/app/components/header/account-setting/model-provider-page/atoms.ts +++ b/web/app/components/header/account-setting/model-provider-page/atoms.ts @@ -2,63 +2,34 @@ import { atom, useAtomValue, useSetAtom } from 'jotai' import { selectAtom } from 'jotai/utils' import { useCallback, useMemo } from 'react' -const modelProviderListExpandedAtom = atom>({}) - -const setModelProviderListExpandedAtom = atom( - null, - (get, set, params: { providerName: string, expanded: boolean }) => { - const { providerName, expanded } = params - const current = get(modelProviderListExpandedAtom) - - if (expanded) { - if (current[providerName]) - return - - set(modelProviderListExpandedAtom, { - ...current, - [providerName]: true, - }) - return - } - - if (!current[providerName]) - return - - const next = { ...current } - delete next[providerName] - set(modelProviderListExpandedAtom, next) - }, -) - -const resetModelProviderListExpandedAtom = atom( - null, - (_get, set) => { - set(modelProviderListExpandedAtom, {}) - }, -) +const expandedAtom = atom>({}) export function useModelProviderListExpanded(providerName: string) { - const selectedAtom = useMemo( - () => selectAtom(modelProviderListExpandedAtom, state => state[providerName] ?? false), - [providerName], + return useAtomValue( + useMemo( + () => selectAtom(expandedAtom, s => !!s[providerName]), + [providerName], + ), ) - return useAtomValue(selectedAtom) } export function useSetModelProviderListExpanded(providerName: string) { - const setExpanded = useSetAtom(setModelProviderListExpandedAtom) - return useCallback((expanded: boolean) => { - setExpanded({ providerName, expanded }) - }, [providerName, setExpanded]) + const set = useSetAtom(expandedAtom) + return useCallback( + (expanded: boolean) => set(prev => ({ ...prev, [providerName]: expanded })), + [providerName, set], + ) } export function useExpandModelProviderList() { - const setExpanded = useSetAtom(setModelProviderListExpandedAtom) - return useCallback((providerName: string) => { - setExpanded({ providerName, expanded: true }) - }, [setExpanded]) + const set = useSetAtom(expandedAtom) + return useCallback( + (providerName: string) => set(prev => ({ ...prev, [providerName]: true })), + [set], + ) } export function useResetModelProviderListExpanded() { - return useSetAtom(resetModelProviderListExpandedAtom) + const set = useSetAtom(expandedAtom) + return useCallback(() => set({}), [set]) }