diff --git a/backend/ee/onyx/db/persona.py b/backend/ee/onyx/db/persona.py index 9fab07a58..40e7bb9aa 100644 --- a/backend/ee/onyx/db/persona.py +++ b/backend/ee/onyx/db/persona.py @@ -11,6 +11,7 @@ from onyx.server.features.persona.models import PersonaSharedNotificationData def make_persona_private( persona_id: int, + creator_user_id: UUID | None, user_ids: list[UUID] | None, group_ids: list[int] | None, db_session: Session, @@ -29,15 +30,15 @@ def make_persona_private( user_ids_set = set(user_ids) for user_id in user_ids_set: db_session.add(Persona__User(persona_id=persona_id, user_id=user_id)) - - create_notification( - user_id=user_id, - notif_type=NotificationType.PERSONA_SHARED, - db_session=db_session, - additional_data=PersonaSharedNotificationData( - persona_id=persona_id, - ).model_dump(), - ) + if user_id != creator_user_id: + create_notification( + user_id=user_id, + notif_type=NotificationType.PERSONA_SHARED, + db_session=db_session, + additional_data=PersonaSharedNotificationData( + persona_id=persona_id, + ).model_dump(), + ) if group_ids: group_ids_set = set(group_ids) diff --git a/backend/onyx/agents/agent_search/basic/utils.py b/backend/onyx/agents/agent_search/basic/utils.py index 51641adbf..cc0af4a95 100644 --- a/backend/onyx/agents/agent_search/basic/utils.py +++ b/backend/onyx/agents/agent_search/basic/utils.py @@ -40,6 +40,7 @@ def process_llm_stream( # This stream will be the llm answer if no tool is chosen. When a tool is chosen, # the stream will contain AIMessageChunks with tool call information. for message in messages: + answer_piece = message.content if not isinstance(answer_piece, str): # this is only used for logging, so fine to diff --git a/backend/onyx/agents/agent_search/run_graph.py b/backend/onyx/agents/agent_search/run_graph.py index 5dea5924e..add734e1e 100644 --- a/backend/onyx/agents/agent_search/run_graph.py +++ b/backend/onyx/agents/agent_search/run_graph.py @@ -51,7 +51,6 @@ def _parse_agent_event( Parse the event into a typed object. Return None if we are not interested in the event. """ - event_type = event["event"] # We always just yield the event data, but this piece is useful for two development reasons: diff --git a/backend/onyx/background/celery/tasks/tenant_provisioning/tasks.py b/backend/onyx/background/celery/tasks/tenant_provisioning/tasks.py index cb8605b80..e182f96f6 100644 --- a/backend/onyx/background/celery/tasks/tenant_provisioning/tasks.py +++ b/backend/onyx/background/celery/tasks/tenant_provisioning/tasks.py @@ -112,7 +112,7 @@ def pre_provision_tenant() -> None: r = get_redis_client(tenant_id=ONYX_CLOUD_TENANT_ID) lock_provision: RedisLock = r.lock( - OnyxRedisLocks.PRE_PROVISION_TENANT_LOCK, + OnyxRedisLocks.CLOUD_PRE_PROVISION_TENANT_LOCK, timeout=_TENANT_PROVISIONING_SOFT_TIME_LIMIT, ) diff --git a/backend/onyx/chat/answer.py b/backend/onyx/chat/answer.py index c624b9b0e..bf3e72d59 100644 --- a/backend/onyx/chat/answer.py +++ b/backend/onyx/chat/answer.py @@ -167,7 +167,6 @@ class Answer: break processed_stream.append(packet) yield packet - self._processed_stream = processed_stream @property diff --git a/backend/onyx/configs/constants.py b/backend/onyx/configs/constants.py index d21a51881..c76710d09 100644 --- a/backend/onyx/configs/constants.py +++ b/backend/onyx/configs/constants.py @@ -334,7 +334,7 @@ class OnyxRedisLocks: CHECK_USER_FILE_FOLDER_SYNC_BEAT_LOCK = "da_lock:check_user_file_folder_sync_beat" MONITOR_BACKGROUND_PROCESSES_LOCK = "da_lock:monitor_background_processes" CHECK_AVAILABLE_TENANTS_LOCK = "da_lock:check_available_tenants" - PRE_PROVISION_TENANT_LOCK = "da_lock:pre_provision_tenant" + CLOUD_PRE_PROVISION_TENANT_LOCK = "da_lock:pre_provision_tenant" CONNECTOR_DOC_PERMISSIONS_SYNC_LOCK_PREFIX = ( "da_lock:connector_doc_permissions_sync" @@ -405,7 +405,6 @@ class OnyxCeleryTask: f"{ONYX_CLOUD_CELERY_TASK_PREFIX}_monitor_celery_pidbox" ) - # Tenant pre-provisioning UPDATE_USER_FILE_FOLDER_METADATA = "update_user_file_folder_metadata" CHECK_FOR_CONNECTOR_DELETION = "check_for_connector_deletion_task" diff --git a/backend/onyx/db/persona.py b/backend/onyx/db/persona.py index bf54ad09b..d0d7b6da8 100644 --- a/backend/onyx/db/persona.py +++ b/backend/onyx/db/persona.py @@ -3,7 +3,6 @@ from datetime import datetime from uuid import UUID from fastapi import HTTPException -from sqlalchemy import delete from sqlalchemy import exists from sqlalchemy import func from sqlalchemy import not_ @@ -168,6 +167,7 @@ def _get_persona_by_name( def make_persona_private( persona_id: int, + creator_user_id: UUID | None, user_ids: list[UUID] | None, group_ids: list[int] | None, db_session: Session, @@ -179,15 +179,15 @@ def make_persona_private( for user_uuid in user_ids: db_session.add(Persona__User(persona_id=persona_id, user_id=user_uuid)) - - create_notification( - user_id=user_uuid, - notif_type=NotificationType.PERSONA_SHARED, - db_session=db_session, - additional_data=PersonaSharedNotificationData( - persona_id=persona_id, - ).model_dump(), - ) + if user_uuid != creator_user_id: + create_notification( + user_id=user_uuid, + notif_type=NotificationType.PERSONA_SHARED, + db_session=db_session, + additional_data=PersonaSharedNotificationData( + persona_id=persona_id, + ).model_dump(), + ) db_session.commit() @@ -262,6 +262,7 @@ def create_update_persona( # Privatize Persona versioned_make_persona_private( persona_id=persona.id, + creator_user_id=user.id if user else None, user_ids=create_persona_request.users, group_ids=create_persona_request.groups, db_session=db_session, @@ -297,6 +298,7 @@ def update_persona_shared_users( # Privatize Persona versioned_make_persona_private( persona_id=persona_id, + creator_user_id=user.id if user else None, user_ids=user_ids, group_ids=None, db_session=db_session, @@ -770,8 +772,10 @@ def get_personas_by_ids( def delete_persona_by_name( persona_name: str, db_session: Session, is_default: bool = True ) -> None: - stmt = delete(Persona).where( - Persona.name == persona_name, Persona.builtin_persona == is_default + stmt = ( + update(Persona) + .where(Persona.name == persona_name, Persona.builtin_persona == is_default) + .values(deleted=True) ) db_session.execute(stmt) diff --git a/backend/onyx/server/manage/llm/api.py b/backend/onyx/server/manage/llm/api.py index 5ce350839..91373aa52 100644 --- a/backend/onyx/server/manage/llm/api.py +++ b/backend/onyx/server/manage/llm/api.py @@ -69,7 +69,8 @@ def test_llm_configuration( existing_provider = fetch_existing_llm_provider( name=test_llm_request.name, db_session=db_session ) - if existing_provider: + # if an API key is not provided, use the existing provider's API key + if existing_provider and test_api_key is None: test_api_key = existing_provider.api_key # For this "testing" workflow, we do *not* need the actual `max_input_tokens`. diff --git a/backend/onyx/server/user_documents/api.py b/backend/onyx/server/user_documents/api.py index 809510c07..731ae954c 100644 --- a/backend/onyx/server/user_documents/api.py +++ b/backend/onyx/server/user_documents/api.py @@ -90,8 +90,25 @@ def get_folders( db_session: Session = Depends(get_session), ) -> list[UserFolderSnapshot]: user_id = user.id if user else None - folders = db_session.query(UserFolder).filter(UserFolder.user_id == user_id).all() - return [UserFolderSnapshot.from_model(folder) for folder in folders] + # Get folders that belong to the user or have the RECENT_DOCS_FOLDER_ID + folders = ( + db_session.query(UserFolder) + .filter( + (UserFolder.user_id == user_id) | (UserFolder.id == RECENT_DOCS_FOLDER_ID) + ) + .all() + ) + + # For each folder, filter files to only include those belonging to the current user + result = [] + for folder in folders: + folder_snapshot = UserFolderSnapshot.from_model(folder) + folder_snapshot.files = [ + file for file in folder_snapshot.files if file.user_id == user_id + ] + result.append(folder_snapshot) + + return result @router.get("/user/folder/{folder_id}") @@ -103,13 +120,25 @@ def get_folder( user_id = user.id if user else None folder = ( db_session.query(UserFolder) - .filter(UserFolder.id == folder_id, UserFolder.user_id == user_id) + .filter( + UserFolder.id == folder_id, + ( + (UserFolder.user_id == user_id) + | (UserFolder.id == RECENT_DOCS_FOLDER_ID) + ), + ) .first() ) if not folder: raise HTTPException(status_code=404, detail="Folder not found") - return UserFolderSnapshot.from_model(folder) + folder_snapshot = UserFolderSnapshot.from_model(folder) + # Filter files to only include those belonging to the current user + folder_snapshot.files = [ + file for file in folder_snapshot.files if file.user_id == user_id + ] + + return folder_snapshot RECENT_DOCS_FOLDER_ID = -1 diff --git a/backend/shared_configs/contextvars.py b/backend/shared_configs/contextvars.py index 69eb8d33e..efd9f5174 100644 --- a/backend/shared_configs/contextvars.py +++ b/backend/shared_configs/contextvars.py @@ -27,7 +27,15 @@ ONYX_REQUEST_ID_CONTEXTVAR: contextvars.ContextVar[str | None] = contextvars.Con def get_current_tenant_id() -> str: tenant_id = CURRENT_TENANT_ID_CONTEXTVAR.get() if tenant_id is None: + import traceback + if not MULTI_TENANT: return POSTGRES_DEFAULT_SCHEMA - raise RuntimeError("Tenant ID is not set. This should never happen.") + + stack_trace = traceback.format_stack() + error_message = ( + "Tenant ID is not set. This should never happen.\nStack trace:\n" + + "".join(stack_trace) + ) + raise RuntimeError(error_message) return tenant_id diff --git a/web/package-lock.json b/web/package-lock.json index 87b6573fb..abc2e8a53 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1886,7 +1886,6 @@ }, "node_modules/@jridgewell/source-map": { "version": "0.3.6", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -2711,7 +2710,7 @@ "version": "1.51.1", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.51.1.tgz", "integrity": "sha512-nM+kEaTSAoVlXmMPH10017vn3FSiFqr/bh4fKg9vmAdMfd9SDqRZNvPSiAHADc/itWak+qPvMPZQOPwCBW7k7Q==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "dependencies": { "playwright": "1.51.1" @@ -4812,7 +4811,6 @@ }, "node_modules/@types/eslint": { "version": "9.6.1", - "dev": true, "license": "MIT", "dependencies": { "@types/estree": "*", @@ -4821,7 +4819,6 @@ }, "node_modules/@types/eslint-scope": { "version": "3.7.7", - "dev": true, "license": "MIT", "dependencies": { "@types/eslint": "*", @@ -4921,7 +4918,6 @@ }, "node_modules/@types/json-schema": { "version": "7.0.15", - "dev": true, "license": "MIT" }, "node_modules/@types/json5": { @@ -5276,7 +5272,6 @@ }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", - "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", @@ -5285,22 +5280,18 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.13.2", - "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", - "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", - "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", - "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", @@ -5310,12 +5301,10 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.13.2", - "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", - "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -5326,7 +5315,6 @@ }, "node_modules/@webassemblyjs/ieee754": { "version": "1.13.2", - "dev": true, "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" @@ -5334,7 +5322,6 @@ }, "node_modules/@webassemblyjs/leb128": { "version": "1.13.2", - "dev": true, "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" @@ -5342,12 +5329,10 @@ }, "node_modules/@webassemblyjs/utf8": { "version": "1.13.2", - "dev": true, "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", - "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -5362,7 +5347,6 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.14.1", - "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -5374,7 +5358,6 @@ }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.14.1", - "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -5385,7 +5368,6 @@ }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.14.1", - "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -5398,7 +5380,6 @@ }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.14.1", - "dev": true, "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -5407,12 +5388,10 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", - "dev": true, "license": "Apache-2.0" }, "node_modules/acorn": { @@ -5467,7 +5446,6 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -5483,7 +5461,6 @@ }, "node_modules/ajv-formats/node_modules/ajv": { "version": "8.17.1", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -5498,7 +5475,6 @@ }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/ajv-keywords": { @@ -6186,7 +6162,6 @@ }, "node_modules/buffer-from": { "version": "1.1.2", - "dev": true, "license": "MIT" }, "node_modules/busboy": { @@ -6419,7 +6394,6 @@ }, "node_modules/chrome-trace-event": { "version": "1.0.4", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0" @@ -7253,7 +7227,6 @@ }, "node_modules/enhanced-resolve": { "version": "5.18.1", - "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -7386,7 +7359,6 @@ }, "node_modules/es-module-lexer": { "version": "1.6.0", - "dev": true, "license": "MIT" }, "node_modules/es-object-atoms": { @@ -7949,7 +7921,6 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -7960,7 +7931,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -7992,7 +7962,6 @@ }, "node_modules/events": { "version": "3.3.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.x" @@ -8048,7 +8017,6 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "dev": true, "license": "MIT" }, "node_modules/fast-equals": { @@ -8094,7 +8062,6 @@ }, "node_modules/fast-uri": { "version": "3.0.6", - "dev": true, "funding": [ { "type": "github", @@ -8560,7 +8527,6 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", - "dev": true, "license": "BSD-2-Clause" }, "node_modules/glob/node_modules/brace-expansion": { @@ -8617,7 +8583,6 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "dev": true, "license": "ISC" }, "node_modules/graphemer": { @@ -10752,7 +10717,6 @@ }, "node_modules/loader-runner": { "version": "4.3.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6.11.5" @@ -11198,7 +11162,6 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "dev": true, "license": "MIT" }, "node_modules/merge2": { @@ -11755,7 +11718,6 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -11763,7 +11725,6 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -11846,7 +11807,6 @@ }, "node_modules/neo-async": { "version": "2.6.2", - "dev": true, "license": "MIT" }, "node_modules/next": { @@ -15033,7 +14993,7 @@ "version": "1.51.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz", "integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "dependencies": { "playwright-core": "1.51.1" @@ -15052,7 +15012,7 @@ "version": "1.51.1", "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz", "integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" @@ -15531,7 +15491,6 @@ }, "node_modules/randombytes": { "version": "2.1.0", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" @@ -16123,7 +16082,6 @@ }, "node_modules/require-from-string": { "version": "2.0.2", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16294,7 +16252,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "dev": true, "funding": [ { "type": "github", @@ -16383,7 +16340,6 @@ }, "node_modules/serialize-javascript": { "version": "6.0.2", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" @@ -16591,7 +16547,6 @@ }, "node_modules/source-map": { "version": "0.6.1", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -17205,7 +17160,6 @@ }, "node_modules/tapable": { "version": "2.2.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -17213,7 +17167,6 @@ }, "node_modules/terser": { "version": "5.39.0", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -17230,7 +17183,6 @@ }, "node_modules/terser-webpack-plugin": { "version": "5.3.14", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", @@ -17263,7 +17215,6 @@ }, "node_modules/terser-webpack-plugin/node_modules/ajv": { "version": "8.17.1", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -17278,7 +17229,6 @@ }, "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { "version": "5.1.0", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" @@ -17289,7 +17239,6 @@ }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -17302,12 +17251,10 @@ }, "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", @@ -17325,7 +17272,6 @@ }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -17339,12 +17285,10 @@ }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", - "dev": true, "license": "MIT" }, "node_modules/terser/node_modules/source-map-support": { "version": "0.5.21", - "dev": true, "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -18144,7 +18088,6 @@ }, "node_modules/watchpack": { "version": "2.4.2", - "dev": true, "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", @@ -18172,7 +18115,6 @@ }, "node_modules/webpack": { "version": "5.98.0", - "dev": true, "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", @@ -18315,7 +18257,6 @@ }, "node_modules/webpack/node_modules/ajv": { "version": "8.17.1", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -18330,7 +18271,6 @@ }, "node_modules/webpack/node_modules/ajv-keywords": { "version": "5.1.0", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" @@ -18341,7 +18281,6 @@ }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -18353,7 +18292,6 @@ }, "node_modules/webpack/node_modules/estraverse": { "version": "4.3.0", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -18361,12 +18299,10 @@ }, "node_modules/webpack/node_modules/json-schema-traverse": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/webpack/node_modules/schema-utils": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", diff --git a/web/src/app/admin/actions/ActionEditor.tsx b/web/src/app/admin/actions/ActionEditor.tsx index ccc6b199f..9d896f7b9 100644 --- a/web/src/app/admin/actions/ActionEditor.tsx +++ b/web/src/app/admin/actions/ActionEditor.tsx @@ -25,6 +25,7 @@ import { TooltipTrigger, } from "@/components/ui/tooltip"; import { useAuthType } from "@/lib/hooks"; +import { InfoIcon } from "lucide-react"; function parseJsonWithTrailingCommas(jsonString: string) { // Regular expression to remove trailing commas before } or ] @@ -159,25 +160,14 @@ function ActionForm({ component="div" className="mb-4 text-error text-sm" /> -