From d1465b9bed38d6cd320a45c1a6ae2c31dc7e4199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BC=A8=E7=BC=A8?= Date: Mon, 9 Dec 2024 14:44:39 +0800 Subject: [PATCH 01/11] chore: update the database types (#576) --- client/types/database.types.ts | 601 +++++++++++++++------------------ 1 file changed, 266 insertions(+), 335 deletions(-) diff --git a/client/types/database.types.ts b/client/types/database.types.ts index c134ef1c..3f183d40 100644 --- a/client/types/database.types.ts +++ b/client/types/database.types.ts @@ -34,6 +34,33 @@ export type Database = { }; public: { Tables: { + bot_approval: { + Row: { + approval_path: string | null; + approval_status: string | null; + bot_id: string | null; + created_at: string; + id: string; + task_type: string | null; + }; + Insert: { + approval_path?: string | null; + approval_status?: string | null; + bot_id?: string | null; + created_at?: string; + id?: string; + task_type?: string | null; + }; + Update: { + approval_path?: string | null; + approval_status?: string | null; + bot_id?: string | null; + created_at?: string; + id?: string; + task_type?: string | null; + }; + Relationships: []; + }; bots: { Row: { avatar: string | null; @@ -44,11 +71,15 @@ export type Database = { id: string; label: string | null; llm: string | null; + n: number | null; name: string; prompt: string | null; public: boolean | null; repo_name: string | null; starters: string[] | null; + temperature: number | null; + token_id: string | null; + top_p: number | null; uid: string | null; updated_at: string | null; }; @@ -61,11 +92,15 @@ export type Database = { id?: string; label?: string | null; llm?: string | null; + n?: number | null; name?: string; prompt?: string | null; public?: boolean | null; repo_name?: string | null; starters?: string[] | null; + temperature?: number | null; + token_id?: string | null; + top_p?: number | null; uid?: string | null; updated_at?: string | null; }; @@ -78,11 +113,15 @@ export type Database = { id?: string; label?: string | null; llm?: string | null; + n?: number | null; name?: string; prompt?: string | null; public?: boolean | null; repo_name?: string | null; starters?: string[] | null; + temperature?: number | null; + token_id?: string | null; + top_p?: number | null; uid?: string | null; updated_at?: string | null; }; @@ -158,26 +197,26 @@ export type Database = { Row: { created_at: string; id: string; - repo_name: string | null; - robot_id: string | null; owner_id: string | null; repo_id: string | null; + repo_name: string | null; + robot_id: string | null; }; Insert: { created_at?: string; id?: string; - repo_name?: string | null; - robot_id?: string | null; owner_id?: string | null; repo_id?: string | null; + repo_name?: string | null; + robot_id?: string | null; }; Update: { created_at?: string; id?: string; - repo_name?: string | null; - robot_id?: string | null; owner_id?: string | null; repo_id?: string | null; + repo_name?: string | null; + robot_id?: string | null; }; Relationships: []; }; @@ -222,6 +261,7 @@ export type Database = { }; profiles: { Row: { + agreement_accepted: boolean | null; created_at: string; id: string; name: string | null; @@ -229,9 +269,9 @@ export type Database = { picture: string | null; sid: string | null; sub: string | null; - agreement_accepted: boolean | null; }; Insert: { + agreement_accepted?: boolean | null; created_at?: string; id: string; name?: string | null; @@ -239,9 +279,9 @@ export type Database = { picture?: string | null; sid?: string | null; sub?: string | null; - agreement_accepted?: boolean | null; }; Update: { + agreement_accepted?: boolean | null; created_at?: string; id?: string; name?: string | null; @@ -249,7 +289,6 @@ export type Database = { picture?: string | null; sid?: string | null; sub?: string | null; - agreement_accepted?: boolean | null; }; Relationships: []; }; @@ -263,7 +302,7 @@ export type Database = { file_sha: string | null; id: string; metadata: Json | null; - repo_name: string | null; + repo_name: string; update_timestamp: string | null; }; Insert: { @@ -275,7 +314,7 @@ export type Database = { file_sha?: string | null; id?: string; metadata?: Json | null; - repo_name?: string | null; + repo_name: string; update_timestamp?: string | null; }; Update: { @@ -287,7 +326,7 @@ export type Database = { file_sha?: string | null; id?: string; metadata?: Json | null; - repo_name?: string | null; + repo_name?: string; update_timestamp?: string | null; }; Relationships: []; @@ -403,35 +442,95 @@ export type Database = { }; Relationships: []; }; - user_token_usage: { + user_rate_limit: { Row: { created_at: string; - id: number; + id: string; last_request: string | null; request_count: number | null; user_id: string | null; }; Insert: { created_at?: string; - id?: number; + id?: string; last_request?: string | null; request_count?: number | null; user_id?: string | null; }; Update: { created_at?: string; - id?: number; + id?: string; last_request?: string | null; request_count?: number | null; user_id?: string | null; }; Relationships: []; }; + user_token_usage: { + Row: { + bot_id: string | null; + created_at: string; + date: string | null; + id: string; + input_token: number | null; + output_token: number | null; + token_id: string | null; + total_token: number | null; + user_id: string | null; + }; + Insert: { + bot_id?: string | null; + created_at?: string; + date?: string | null; + id?: string; + input_token?: number | null; + output_token?: number | null; + token_id?: string | null; + total_token?: number | null; + user_id?: string | null; + }; + Update: { + bot_id?: string | null; + created_at?: string; + date?: string | null; + id?: string; + input_token?: number | null; + output_token?: number | null; + token_id?: string | null; + total_token?: number | null; + user_id?: string | null; + }; + Relationships: []; + }; }; Views: { [_ in never]: never; }; Functions: { + binary_quantize: + | { + Args: { + '': string; + }; + Returns: unknown; + } + | { + Args: { + '': unknown; + }; + Returns: unknown; + }; + count_rag_docs_by_sha: { + Args: { + file_sha_input: string; + }; + Returns: { + count: number; + file_sha: string; + repo_name: string; + file_path: string; + }[]; + }; execute_sql: { Args: { query: string; @@ -453,18 +552,125 @@ export type Database = { hello_message: string; }[]; }; + get_bot_stats: { + Args: { + filter_bot_id: string; + }; + Returns: { + call_cnt: number; + }[]; + }; + get_user_stats: { + Args: { + filter_user_id: string; + start_date: string; + end_date: string; + }; + Returns: { + usage_date: string; + input_tokens: number; + output_tokens: number; + total_tokens: number; + }[]; + }; + halfvec_avg: { + Args: { + '': number[]; + }; + Returns: unknown; + }; + halfvec_out: { + Args: { + '': unknown; + }; + Returns: unknown; + }; + halfvec_send: { + Args: { + '': unknown; + }; + Returns: string; + }; + halfvec_typmod_in: { + Args: { + '': unknown[]; + }; + Returns: number; + }; + hnsw_bit_support: { + Args: { + '': unknown; + }; + Returns: unknown; + }; + hnsw_halfvec_support: { + Args: { + '': unknown; + }; + Returns: unknown; + }; + hnsw_sparsevec_support: { + Args: { + '': unknown; + }; + Returns: unknown; + }; hnswhandler: { Args: { '': unknown; }; Returns: unknown; }; + ivfflat_bit_support: { + Args: { + '': unknown; + }; + Returns: unknown; + }; + ivfflat_halfvec_support: { + Args: { + '': unknown; + }; + Returns: unknown; + }; ivfflathandler: { Args: { '': unknown; }; Returns: unknown; }; + l2_norm: + | { + Args: { + '': unknown; + }; + Returns: number; + } + | { + Args: { + '': unknown; + }; + Returns: number; + }; + l2_normalize: + | { + Args: { + '': string; + }; + Returns: string; + } + | { + Args: { + '': unknown; + }; + Returns: unknown; + } + | { + Args: { + '': unknown; + }; + Returns: unknown; + }; match_embedding_docs: { Args: { query_embedding: string; @@ -491,18 +697,43 @@ export type Database = { similarity: number; }[]; }; - vector_avg: { + sparsevec_out: { Args: { - '': number[]; + '': unknown; + }; + Returns: unknown; + }; + sparsevec_send: { + Args: { + '': unknown; }; Returns: string; }; - vector_dims: { + sparsevec_typmod_in: { Args: { - '': string; + '': unknown[]; }; Returns: number; }; + vector_avg: { + Args: { + '': number[]; + }; + Returns: string; + }; + vector_dims: + | { + Args: { + '': string; + }; + Returns: number; + } + | { + Args: { + '': unknown; + }; + Returns: number; + }; vector_norm: { Args: { '': string; @@ -535,321 +766,6 @@ export type Database = { [_ in never]: never; }; }; - storage: { - Tables: { - buckets: { - Row: { - allowed_mime_types: string[] | null; - avif_autodetection: boolean | null; - created_at: string | null; - file_size_limit: number | null; - id: string; - name: string; - owner: string | null; - owner_id: string | null; - public: boolean | null; - updated_at: string | null; - }; - Insert: { - allowed_mime_types?: string[] | null; - avif_autodetection?: boolean | null; - created_at?: string | null; - file_size_limit?: number | null; - id: string; - name: string; - owner?: string | null; - owner_id?: string | null; - public?: boolean | null; - updated_at?: string | null; - }; - Update: { - allowed_mime_types?: string[] | null; - avif_autodetection?: boolean | null; - created_at?: string | null; - file_size_limit?: number | null; - id?: string; - name?: string; - owner?: string | null; - owner_id?: string | null; - public?: boolean | null; - updated_at?: string | null; - }; - Relationships: []; - }; - migrations: { - Row: { - executed_at: string | null; - hash: string; - id: number; - name: string; - }; - Insert: { - executed_at?: string | null; - hash: string; - id: number; - name: string; - }; - Update: { - executed_at?: string | null; - hash?: string; - id?: number; - name?: string; - }; - Relationships: []; - }; - objects: { - Row: { - bucket_id: string | null; - created_at: string | null; - id: string; - last_accessed_at: string | null; - metadata: Json | null; - name: string | null; - owner: string | null; - owner_id: string | null; - path_tokens: string[] | null; - updated_at: string | null; - user_metadata: Json | null; - version: string | null; - }; - Insert: { - bucket_id?: string | null; - created_at?: string | null; - id?: string; - last_accessed_at?: string | null; - metadata?: Json | null; - name?: string | null; - owner?: string | null; - owner_id?: string | null; - path_tokens?: string[] | null; - updated_at?: string | null; - user_metadata?: Json | null; - version?: string | null; - }; - Update: { - bucket_id?: string | null; - created_at?: string | null; - id?: string; - last_accessed_at?: string | null; - metadata?: Json | null; - name?: string | null; - owner?: string | null; - owner_id?: string | null; - path_tokens?: string[] | null; - updated_at?: string | null; - user_metadata?: Json | null; - version?: string | null; - }; - Relationships: [ - { - foreignKeyName: 'objects_bucketId_fkey'; - columns: ['bucket_id']; - isOneToOne: false; - referencedRelation: 'buckets'; - referencedColumns: ['id']; - }, - ]; - }; - s3_multipart_uploads: { - Row: { - bucket_id: string; - created_at: string; - id: string; - in_progress_size: number; - key: string; - owner_id: string | null; - upload_signature: string; - user_metadata: Json | null; - version: string; - }; - Insert: { - bucket_id: string; - created_at?: string; - id: string; - in_progress_size?: number; - key: string; - owner_id?: string | null; - upload_signature: string; - user_metadata?: Json | null; - version: string; - }; - Update: { - bucket_id?: string; - created_at?: string; - id?: string; - in_progress_size?: number; - key?: string; - owner_id?: string | null; - upload_signature?: string; - user_metadata?: Json | null; - version?: string; - }; - Relationships: [ - { - foreignKeyName: 's3_multipart_uploads_bucket_id_fkey'; - columns: ['bucket_id']; - isOneToOne: false; - referencedRelation: 'buckets'; - referencedColumns: ['id']; - }, - ]; - }; - s3_multipart_uploads_parts: { - Row: { - bucket_id: string; - created_at: string; - etag: string; - id: string; - key: string; - owner_id: string | null; - part_number: number; - size: number; - upload_id: string; - version: string; - }; - Insert: { - bucket_id: string; - created_at?: string; - etag: string; - id?: string; - key: string; - owner_id?: string | null; - part_number: number; - size?: number; - upload_id: string; - version: string; - }; - Update: { - bucket_id?: string; - created_at?: string; - etag?: string; - id?: string; - key?: string; - owner_id?: string | null; - part_number?: number; - size?: number; - upload_id?: string; - version?: string; - }; - Relationships: [ - { - foreignKeyName: 's3_multipart_uploads_parts_bucket_id_fkey'; - columns: ['bucket_id']; - isOneToOne: false; - referencedRelation: 'buckets'; - referencedColumns: ['id']; - }, - { - foreignKeyName: 's3_multipart_uploads_parts_upload_id_fkey'; - columns: ['upload_id']; - isOneToOne: false; - referencedRelation: 's3_multipart_uploads'; - referencedColumns: ['id']; - }, - ]; - }; - }; - Views: { - [_ in never]: never; - }; - Functions: { - can_insert_object: { - Args: { - bucketid: string; - name: string; - owner: string; - metadata: Json; - }; - Returns: undefined; - }; - extension: { - Args: { - name: string; - }; - Returns: string; - }; - filename: { - Args: { - name: string; - }; - Returns: string; - }; - foldername: { - Args: { - name: string; - }; - Returns: string[]; - }; - get_size_by_bucket: { - Args: Record; - Returns: { - size: number; - bucket_id: string; - }[]; - }; - list_multipart_uploads_with_delimiter: { - Args: { - bucket_id: string; - prefix_param: string; - delimiter_param: string; - max_keys?: number; - next_key_token?: string; - next_upload_token?: string; - }; - Returns: { - key: string; - id: string; - created_at: string; - }[]; - }; - list_objects_with_delimiter: { - Args: { - bucket_id: string; - prefix_param: string; - delimiter_param: string; - max_keys?: number; - start_after?: string; - next_token?: string; - }; - Returns: { - name: string; - id: string; - metadata: Json; - updated_at: string; - }[]; - }; - operation: { - Args: Record; - Returns: string; - }; - search: { - Args: { - prefix: string; - bucketname: string; - limits?: number; - levels?: number; - offsets?: number; - search?: string; - sortcolumn?: string; - sortorder?: string; - }; - Returns: { - name: string; - id: string; - updated_at: string; - created_at: string; - last_accessed_at: string; - metadata: Json; - }[]; - }; - }; - Enums: { - [_ in never]: never; - }; - CompositeTypes: { - [_ in never]: never; - }; - }; }; type PublicSchema = Database[Extract]; @@ -933,3 +849,18 @@ export type Enums< : PublicEnumNameOrOptions extends keyof PublicSchema['Enums'] ? PublicSchema['Enums'][PublicEnumNameOrOptions] : never; + +export type CompositeTypes< + PublicCompositeTypeNameOrOptions extends + | keyof PublicSchema['CompositeTypes'] + | { schema: keyof Database }, + CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { + schema: keyof Database; + } + ? keyof Database[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes'] + : never = never, +> = PublicCompositeTypeNameOrOptions extends { schema: keyof Database } + ? Database[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes'][CompositeTypeName] + : PublicCompositeTypeNameOrOptions extends keyof PublicSchema['CompositeTypes'] + ? PublicSchema['CompositeTypes'][PublicCompositeTypeNameOrOptions] + : never; From 57291ddae8140162e19f951be1ce62614bd9b858 Mon Sep 17 00:00:00 2001 From: yingying Date: Mon, 9 Dec 2024 17:51:02 +0800 Subject: [PATCH 02/11] refactor(install): Refactor GitHub App Installation Logic --- server/core/dao/repositoryConfigDAO.py | 130 +++++++++++++++---------- server/event_handler/intsall.py | 23 ++++- server/github_app/router.py | 46 +-------- 3 files changed, 105 insertions(+), 94 deletions(-) diff --git a/server/core/dao/repositoryConfigDAO.py b/server/core/dao/repositoryConfigDAO.py index 26151aa0..1fc1746e 100644 --- a/server/core/dao/repositoryConfigDAO.py +++ b/server/core/dao/repositoryConfigDAO.py @@ -3,7 +3,6 @@ from core.models.bot import RepoBindBotConfigVO from core.models.repository import RepositoryConfig from supabase.client import Client - from petercat_utils.db.client.supabase import get_client @@ -26,65 +25,94 @@ def create(self, data: RepositoryConfig): else: return False, {"message": "GithubRepoConfig creation failed"} except Exception as e: - print("Error: ", e) - return False, {"message": "GithubRepoConfig creation failed"} - - def query_by_owners(self, orgs: list[str]): - response = ( - self.client.table("github_repo_config") - .select("*") - .filter("owner_id", "in", f"({','.join(map(str, orgs))})") - .execute() - ) + print(f"Error: {e}") + return False, {"message": f"GithubRepoConfig creation failed: {e}"} - return response.data + def create_batch(self, data_list: List[RepositoryConfig]): + try: + records_data = [data.model_dump(exclude=["id"]) for data in data_list] + repo_config = ( + self.client.from_("github_repo_config").insert(records_data).execute() + ) + if repo_config: + return True, { + "message": "GithubRepoConfig records created successfully" + } + else: + return False, {"message": "GithubRepoConfig batch creation failed"} + except Exception as e: + print(f"Error: {e}") + return False, {"message": f"GithubRepoConfig batch creation failed: {e}"} - def update_bot_to_repos( - self, - repos: List[RepoBindBotConfigVO], - ) -> bool: - for repo in repos: - res = ( + def query_by_owners(self, orgs: List[str]): + try: + response = ( self.client.table("github_repo_config") - .update({"robot_id": repo.robot_id}) - .match({"repo_id": repo.repo_id}) + .select("*") + .filter("owner_id", "in", f"({','.join(map(str, orgs))})") .execute() ) - if not res: - raise ValueError("Failed to bind the bot.") + return response.data + except Exception as e: + print(f"Error: {e}") + return None - def get_by_repo_name(self, repo_name: str): - response = ( - self.client.table("github_repo_config") - .select("*") - .eq("repo_name", repo_name) - .execute() - ) + def update_bot_to_repos(self, repos: List[RepoBindBotConfigVO]) -> bool: + try: + for repo in repos: + res = ( + self.client.table("github_repo_config") + .update({"robot_id": repo.robot_id}) + .match({"repo_id": repo.repo_id}) + .execute() + ) + if not res: + raise ValueError("Failed to bind the bot.") + return True + except Exception as e: + print(f"Error: {e}") + return False - if not response.data or not response.data[0]: + def get_by_repo_name(self, repo_name: str): + try: + response = ( + self.client.table("github_repo_config") + .select("*") + .eq("repo_name", repo_name) + .execute() + ) + if not response.data or not response.data[0]: + return None + repo_config = response.data[0] + return RepositoryConfig(**repo_config) + except Exception as e: + print(f"Error: {e}") return None - repo_config = response.data[0] - - return RepositoryConfig(**repo_config) def get_by_bot_id(self, bot_id: str): - response = ( - self.client.table("github_repo_config") - .select("*") - .eq("robot_id", bot_id) - .execute() - ) - if not response.data or not response.data[0]: + try: + response = ( + self.client.table("github_repo_config") + .select("*") + .eq("robot_id", bot_id) + .execute() + ) + if not response.data or not response.data[0]: + return None + return [RepositoryConfig(**repo) for repo in response.data] + except Exception as e: + print(f"Error: {e}") return None - repo_configs = [RepositoryConfig(**repo) for repo in response.data] - - return repo_configs - def delete_by_repo_ids(self, repo_ids: list): - response = ( - self.client.table("github_repo_config") - .delete() - .in_("repo_id", repo_ids) - .execute() - ) - return response + def delete_by_repo_ids(self, repo_ids: List[str]): + try: + response = ( + self.client.table("github_repo_config") + .delete() + .in_("repo_id", repo_ids) + .execute() + ) + return response + except Exception as e: + print(f"Error: {e}") + return None diff --git a/server/event_handler/intsall.py b/server/event_handler/intsall.py index 7e843602..4baedb9b 100644 --- a/server/event_handler/intsall.py +++ b/server/event_handler/intsall.py @@ -1,7 +1,9 @@ -from typing import Any +from typing import Any, List from github import Github, Auth from github import GithubException from core.dao.repositoryConfigDAO import RepositoryConfigDAO +from core.models.repository import RepositoryConfig +import time class InstallEventHandler: @@ -20,12 +22,31 @@ def delete_config(self): repository_config = RepositoryConfigDAO() repository_config.delete_by_repo_ids(repo_ids) + def add_config(self): + repositories = self.event["repositories"] + owner_id = self.event["installation"]["account"]["id"] + repository_config_dao = RepositoryConfigDAO() + repository_configs: List[RepositoryConfig] = [] + for repo in repositories: + repository_config = RepositoryConfig( + owner_id=str(owner_id), + repo_name=repo["full_name"], + repo_id=str(repo["id"]), + robot_id="", + created_at=int(time.time()), + ) + repository_configs.append(repository_config) + repository_config_dao.create_batch(repository_configs) + async def execute(self): try: action = self.event["action"] if action == "deleted": self.delete_config() return {"success": True} + if action == "created": + self.add_config() + return {"success": True} except GithubException as e: print(f"处理 GitHub 请求时出错:{e}") return {"success": False, "error": str(e)} diff --git a/server/github_app/router.py b/server/github_app/router.py index 411bb676..c8443d25 100644 --- a/server/github_app/router.py +++ b/server/github_app/router.py @@ -50,48 +50,10 @@ # https://github.com/login/oauth/authorize?client_id=Iv1.c2e88b429e541264 @router.get("/app/installation/callback") def github_app_callback(code: str, installation_id: str, setup_action: str): - authorization_dao = AuthorizationDAO() - repository_config_dao = RepositoryConfigDAO() - if setup_action == "install": - if authorization_dao.exists(installation_id=installation_id): - message = (f"Installation_id {installation_id} Exists",) - return RedirectResponse( - url=f"{WEB_URL}/github/installed/{message}", status_code=302 - ) - else: - jwt = get_jwt() - access_token = get_app_installations_access_token( - installation_id=installation_id, jwt=jwt - ) - print(f"get_app_installations_access_token: {access_token}") - authorization = Authorization( - **access_token, - code=code, - installation_id=installation_id, - created_at=int(time.time()), - ) - success, message = authorization_dao.create(authorization) - installed_repositories = get_installation_repositories( - access_token=access_token["token"] - ) - for repo in installed_repositories["repositories"]: - repository_config = RepositoryConfig( - owner_id=str(repo["owner"]["id"]), - repo_name=repo["full_name"], - repo_id=str(repo["id"]), - robot_id="", - created_at=int(time.time()), - ) - repository_config_dao.create(repository_config) - - return RedirectResponse( - url=f"{WEB_URL}/github/installed?message={message}", status_code=302 - ) - # ignore others setup_action,such as deleted our app - return { - "success": False, - "message": f"Invalid setup_action value {setup_action},please delete the app first then re-install the app.", - } + return RedirectResponse( + url=f"{WEB_URL}/github/installed?installation_id={installation_id}&setup_action={setup_action}&code={code}", + status_code=302, + ) @router.post("/app/webhook") From 22e06a2d185022fec665ed3429762f1a9605dbc0 Mon Sep 17 00:00:00 2001 From: yingying Date: Tue, 10 Dec 2024 11:37:11 +0800 Subject: [PATCH 03/11] feat: add the create_batch function for the repositoryDAO --- server/core/dao/repositoryConfigDAO.py | 42 +++++++++++++++++++++----- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/server/core/dao/repositoryConfigDAO.py b/server/core/dao/repositoryConfigDAO.py index 1fc1746e..58d6fe01 100644 --- a/server/core/dao/repositoryConfigDAO.py +++ b/server/core/dao/repositoryConfigDAO.py @@ -1,4 +1,4 @@ -from typing import List +from typing import Counter, List from core.dao.BaseDAO import BaseDAO from core.models.bot import RepoBindBotConfigVO from core.models.repository import RepositoryConfig @@ -31,15 +31,41 @@ def create(self, data: RepositoryConfig): def create_batch(self, data_list: List[RepositoryConfig]): try: records_data = [data.model_dump(exclude=["id"]) for data in data_list] - repo_config = ( - self.client.from_("github_repo_config").insert(records_data).execute() + repo_ids = [data.repo_id for data in data_list] + + # 查询现有的 repo_id + response = ( + self.client.table("github_repo_config") + .select("repo_id") + .in_("repo_id", repo_ids) + .execute() ) - if repo_config: - return True, { - "message": "GithubRepoConfig records created successfully" + existing_repo_ids = ( + {record["repo_id"] for record in response.data} + if response.data + else set() + ) + + # 筛选出未存在的记录 + new_records_data = [ + data + for data in records_data + if data["repo_id"] not in existing_repo_ids + ] + + if not new_records_data: + return False, { + "message": "No new GithubRepoConfig records to insert, all repo_ids already exist" } - else: - return False, {"message": "GithubRepoConfig batch creation failed"} + + # 执行插入操作 + repo_config_result = ( + self.client.table("github_repo_config") + .insert(new_records_data) + .execute() + ) + + return repo_config_result except Exception as e: print(f"Error: {e}") return False, {"message": f"GithubRepoConfig batch creation failed: {e}"} From 52646b4ea6d329935a04ae47605f4955f1c30ad4 Mon Sep 17 00:00:00 2001 From: yingying Date: Tue, 10 Dec 2024 11:54:06 +0800 Subject: [PATCH 04/11] feat: add the InstallationEditEventHandler --- server/event_handler/intsall.py | 48 ++++++++++++++++++++++++++++++++- server/github_app/handlers.py | 8 +++--- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/server/event_handler/intsall.py b/server/event_handler/intsall.py index 4baedb9b..757fd739 100644 --- a/server/event_handler/intsall.py +++ b/server/event_handler/intsall.py @@ -6,7 +6,7 @@ import time -class InstallEventHandler: +class InstallationEventHandler: event: Any auth: Auth.AppAuth g: Github @@ -50,3 +50,49 @@ async def execute(self): except GithubException as e: print(f"处理 GitHub 请求时出错:{e}") return {"success": False, "error": str(e)} + + +class InstallationEditEventHandler: + event: Any + auth: Auth.AppAuth + g: Github + + def __init__(self, payload: Any, auth: Auth.AppAuth, installation_id: int) -> None: + self.event: Any = payload + self.auth: Auth.AppAuth = auth + self.g: Github = Github(auth=auth) + + def delete_config(self): + repositories = self.event["repositories_removed"] + repo_ids = [str(repo["id"]) for repo in repositories] + repository_config = RepositoryConfigDAO() + repository_config.delete_by_repo_ids(repo_ids) + + def add_config(self): + repositories = self.event["repositories_added"] + owner_id = self.event["installation"]["account"]["id"] + repository_config_dao = RepositoryConfigDAO() + repository_configs: List[RepositoryConfig] = [] + for repo in repositories: + repository_config = RepositoryConfig( + owner_id=str(owner_id), + repo_name=repo["full_name"], + repo_id=str(repo["id"]), + robot_id="", + created_at=int(time.time()), + ) + repository_configs.append(repository_config) + repository_config_dao.create_batch(repository_configs) + + async def execute(self): + try: + action = self.event["action"] + if action == "removed": + self.delete_config() + return {"success": True} + if action == "added": + self.add_config() + return {"success": True} + except GithubException as e: + print(f"处理 GitHub 请求时出错:{e}") + return {"success": False, "error": str(e)} diff --git a/server/github_app/handlers.py b/server/github_app/handlers.py index 3caea4ad..0581221f 100644 --- a/server/github_app/handlers.py +++ b/server/github_app/handlers.py @@ -1,6 +1,6 @@ from typing import Union -from event_handler.intsall import InstallEventHandler +from event_handler.intsall import InstallationEventHandler, InstallationEditEventHandler from petercat_utils import get_env_variable from github import Auth @@ -26,7 +26,8 @@ def get_handler( DiscussionEventHandler, DiscussionCommentEventHandler, PullRequestReviewCommentEventHandler, - InstallEventHandler, + InstallationEventHandler, + InstallationEditEventHandler, None, ]: handlers = { @@ -37,7 +38,8 @@ def get_handler( "discussion_comment": DiscussionCommentEventHandler, "pull_request_review_comment": PullRequestReviewCommentEventHandler, "pull_request_review": PullRequestReviewCommentEventHandler, - "installation": InstallEventHandler, + "installation": InstallationEventHandler, + "installation_repositories": InstallationEditEventHandler, } return ( handlers.get(event)(payload=payload, auth=auth, installation_id=installation_id) From 4dccb7597d31b9d8c8be186a761ee5ef23239e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BC=A8=E7=BC=A8?= Date: Tue, 10 Dec 2024 16:13:06 +0800 Subject: [PATCH 05/11] chore: sync the db (#582) * chore: remove useless table * chore: sync the db migration * chore: fix ci --- client/types/database.types.ts | 30 ---- .../20240911082857_remote_schema.sql | 156 +--------------- .../20240912023152_remote_schema.sql | 6 +- .../20240913114522_remote_schema.sql | 7 +- .../20241015085655_remote_schema.sql | 84 --------- .../20241015090438_remote_schema.sql | 4 - .../20241210072126_remote_schema.sql | 170 ++++++++++++++++++ server/core/dao/authorizationDAO.py | 39 ---- server/core/dao/repositoryConfigDAO.py | 2 +- server/github_app/router.py | 7 - 10 files changed, 181 insertions(+), 324 deletions(-) create mode 100644 migrations/supabase/migrations/20241210072126_remote_schema.sql delete mode 100644 server/core/dao/authorizationDAO.py diff --git a/client/types/database.types.ts b/client/types/database.types.ts index 3f183d40..20f05584 100644 --- a/client/types/database.types.ts +++ b/client/types/database.types.ts @@ -163,36 +163,6 @@ export type Database = { }; Relationships: []; }; - github_app_authorization: { - Row: { - code: string | null; - created_at: string; - expires_at: string | null; - id: number; - installation_id: string | null; - permissions: Json | null; - token: string | null; - }; - Insert: { - code?: string | null; - created_at?: string; - expires_at?: string | null; - id?: number; - installation_id?: string | null; - permissions?: Json | null; - token?: string | null; - }; - Update: { - code?: string | null; - created_at?: string; - expires_at?: string | null; - id?: number; - installation_id?: string | null; - permissions?: Json | null; - token?: string | null; - }; - Relationships: []; - }; github_repo_config: { Row: { created_at: string; diff --git a/migrations/supabase/migrations/20240911082857_remote_schema.sql b/migrations/supabase/migrations/20240911082857_remote_schema.sql index 2dc5ed68..6427a7f8 100644 --- a/migrations/supabase/migrations/20240911082857_remote_schema.sql +++ b/migrations/supabase/migrations/20240911082857_remote_schema.sql @@ -1,4 +1,3 @@ - SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; @@ -9,27 +8,16 @@ SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; - CREATE EXTENSION IF NOT EXISTS "pg_net" WITH SCHEMA "extensions"; - CREATE EXTENSION IF NOT EXISTS "pgsodium" WITH SCHEMA "pgsodium"; - COMMENT ON SCHEMA "public" IS 'standard public schema'; - CREATE EXTENSION IF NOT EXISTS "pg_graphql" WITH SCHEMA "graphql"; - CREATE EXTENSION IF NOT EXISTS "pg_stat_statements" WITH SCHEMA "extensions"; - CREATE EXTENSION IF NOT EXISTS "pgcrypto" WITH SCHEMA "extensions"; - CREATE EXTENSION IF NOT EXISTS "pgjwt" WITH SCHEMA "extensions"; - CREATE EXTENSION IF NOT EXISTS "supabase_vault" WITH SCHEMA "vault"; - CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA "extensions"; - CREATE EXTENSION IF NOT EXISTS "vector" WITH SCHEMA "public"; - CREATE OR REPLACE FUNCTION "public"."execute_sql"("query" "text") RETURNS TABLE("id" "uuid", "created_at" timestamp with time zone, "uid" character varying, "avatar" character varying, "description" character varying, "prompt" "text", "files" "text"[], "enable_img_generation" boolean, "label" character varying, "name" character varying, "starters" "text"[], "public" boolean, "updated_at" timestamp with time zone, "hello_message" "text") LANGUAGE "plpgsql" AS $$ @@ -37,9 +25,7 @@ BEGIN RETURN QUERY EXECUTE query; END; $$; - ALTER FUNCTION "public"."execute_sql"("query" "text") OWNER TO "postgres"; - CREATE OR REPLACE FUNCTION "public"."handle_new_user"() RETURNS "trigger" LANGUAGE "plpgsql" SECURITY DEFINER SET "search_path" TO 'public' @@ -50,9 +36,7 @@ begin return new; end; $$; - ALTER FUNCTION "public"."handle_new_user"() OWNER TO "postgres"; - CREATE OR REPLACE FUNCTION "public"."match_antd_doc"("query_embedding" "public"."vector", "filter" "jsonb" DEFAULT '{}'::"jsonb") RETURNS TABLE("id" "uuid", "content" "text", "metadata" "jsonb", "similarity" double precision) LANGUAGE "plpgsql" AS $$ @@ -69,9 +53,7 @@ begin order by antd_doc.embedding <=> query_embedding; end; $$; - ALTER FUNCTION "public"."match_antd_doc"("query_embedding" "public"."vector", "filter" "jsonb") OWNER TO "postgres"; - CREATE OR REPLACE FUNCTION "public"."match_antd_documents"("query_embedding" "public"."vector", "filter" "jsonb" DEFAULT '{}'::"jsonb") RETURNS TABLE("id" "uuid", "content" "text", "metadata" "jsonb", "similarity" double precision) LANGUAGE "plpgsql" AS $$ @@ -88,9 +70,7 @@ begin order by antd_documents.embedding <=> query_embedding; end; $$; - ALTER FUNCTION "public"."match_antd_documents"("query_embedding" "public"."vector", "filter" "jsonb") OWNER TO "postgres"; - CREATE OR REPLACE FUNCTION "public"."match_antd_knowledge"("query_embedding" "public"."vector", "filter" "jsonb" DEFAULT '{}'::"jsonb") RETURNS TABLE("id" "uuid", "content" "text", "metadata" "jsonb", "similarity" double precision) LANGUAGE "plpgsql" AS $$ @@ -107,9 +87,7 @@ begin order by antd_knowledge.embedding <=> query_embedding; end; $$; - ALTER FUNCTION "public"."match_antd_knowledge"("query_embedding" "public"."vector", "filter" "jsonb") OWNER TO "postgres"; - CREATE OR REPLACE FUNCTION "public"."match_docs"("query_embedding" "public"."vector", "match_count" integer DEFAULT NULL::integer, "filter" "jsonb" DEFAULT '{}'::"jsonb") RETURNS TABLE("id" bigint, "content" "text", "metadata" "jsonb", "similarity" double precision) LANGUAGE "plpgsql" AS $$ @@ -127,9 +105,7 @@ begin limit match_count; end; $$; - ALTER FUNCTION "public"."match_docs"("query_embedding" "public"."vector", "match_count" integer, "filter" "jsonb") OWNER TO "postgres"; - CREATE OR REPLACE FUNCTION "public"."match_documents"("query_embedding" "public"."vector", "filter" "jsonb" DEFAULT '{}'::"jsonb") RETURNS TABLE("id" "uuid", "content" "text", "metadata" "jsonb", "similarity" double precision) LANGUAGE "plpgsql" AS $$ @@ -146,10 +122,8 @@ begin order by documents.embedding <=> query_embedding; end; $$; - ALTER FUNCTION "public"."match_documents"("query_embedding" "public"."vector", "filter" "jsonb") OWNER TO "postgres"; - -CREATE OR REPLACE FUNCTION "public"."match_embedding_docs"("query_embedding" "public"."vector", "filter" "jsonb" DEFAULT '{}'::"jsonb") RETURNS TABLE("id" "uuid", "content" "text", "metadata" "jsonb", "embedding" "public"."vector", "similarity" double precision) +CREATE OR REPLACE FUNCTION "public"."match_rag_docs"("query_embedding" "public"."vector", "filter" "jsonb" DEFAULT '{}'::"jsonb") RETURNS TABLE("id" "uuid", "content" "text", "metadata" "jsonb", "embedding" "public"."vector", "similarity" double precision) LANGUAGE "plpgsql" AS $$ #variable_conflict use_column @@ -164,11 +138,11 @@ begin ) as similarity from rag_docs where metadata @> jsonb_extract_path(filter, 'metadata') - and repo_name = jsonb_extract_path_text(filter, 'repo_name') + and bot_id = jsonb_extract_path_text(filter, 'bot_id') order by rag_docs.embedding <=> query_embedding; end; $$; - +ALTER FUNCTION "public"."match_rag_docs"("query_embedding" "public"."vector", "filter" "jsonb") OWNER TO "postgres"; CREATE OR REPLACE FUNCTION "public"."match_text"("query_embedding" "public"."vector", "match_count" integer DEFAULT NULL::integer, "filter" "jsonb" DEFAULT '{}'::"jsonb") RETURNS TABLE("id" bigint, "content" "text", "metadata" "jsonb", "similarity" double precision) LANGUAGE "plpgsql" AS $$ @@ -186,9 +160,7 @@ begin limit match_count; end; $$; - ALTER FUNCTION "public"."match_text"("query_embedding" "public"."vector", "match_count" integer, "filter" "jsonb") OWNER TO "postgres"; - CREATE OR REPLACE FUNCTION "public"."rag_docs"("query_embedding" "public"."vector", "filter" "jsonb" DEFAULT '{}'::"jsonb", "query_repo_name" "text" DEFAULT ''::"text") RETURNS TABLE("id" "uuid", "metadata" "jsonb", "content" "text", "similarity" double precision) LANGUAGE "sql" STABLE AS $$ @@ -202,9 +174,7 @@ CREATE OR REPLACE FUNCTION "public"."rag_docs"("query_embedding" "public"."vecto and repo_name = query_repo_name order by (rag_docs.embedding <=> query_embedding) asc $$; - ALTER FUNCTION "public"."rag_docs"("query_embedding" "public"."vector", "filter" "jsonb", "query_repo_name" "text") OWNER TO "postgres"; - CREATE OR REPLACE FUNCTION "public"."update_timestamp_function"() RETURNS "trigger" LANGUAGE "plpgsql" AS $$ @@ -213,13 +183,9 @@ BEGIN RETURN NEW; END; $$; - ALTER FUNCTION "public"."update_timestamp_function"() OWNER TO "postgres"; - SET default_tablespace = ''; - SET default_table_access_method = "heap"; - CREATE TABLE IF NOT EXISTS "public"."bots" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, @@ -238,11 +204,8 @@ CREATE TABLE IF NOT EXISTS "public"."bots" ( "repo_name" "text", "token_id" "text" DEFAULT '''''::text'::"text" ); - ALTER TABLE "public"."bots" OWNER TO "postgres"; - COMMENT ON TABLE "public"."bots" IS 'bots list'; - CREATE TABLE IF NOT EXISTS "public"."git_issue_tasks" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, @@ -254,9 +217,7 @@ CREATE TABLE IF NOT EXISTS "public"."git_issue_tasks" ( "bot_id" character varying, "page_index" numeric ); - ALTER TABLE "public"."git_issue_tasks" OWNER TO "postgres"; - CREATE TABLE IF NOT EXISTS "public"."github_app_authorization" ( "id" bigint NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, @@ -266,11 +227,8 @@ CREATE TABLE IF NOT EXISTS "public"."github_app_authorization" ( "permissions" "json", "code" character varying ); - ALTER TABLE "public"."github_app_authorization" OWNER TO "postgres"; - COMMENT ON TABLE "public"."github_app_authorization" IS 'Authorizations of Github App'; - ALTER TABLE "public"."github_app_authorization" ALTER COLUMN "id" ADD GENERATED BY DEFAULT AS IDENTITY ( SEQUENCE NAME "public"."github_app_authorization_id_seq" START WITH 1 @@ -279,16 +237,13 @@ ALTER TABLE "public"."github_app_authorization" ALTER COLUMN "id" ADD GENERATED NO MAXVALUE CACHE 1 ); - CREATE TABLE IF NOT EXISTS "public"."github_repo_config" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, "repo_name" character varying, "robot_id" character varying ); - ALTER TABLE "public"."github_repo_config" OWNER TO "postgres"; - CREATE TABLE IF NOT EXISTS "public"."llm_tokens" ( "id" bigint NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, @@ -301,9 +256,7 @@ CREATE TABLE IF NOT EXISTS "public"."llm_tokens" ( "encrypted_token" "text", "user_id" "text" ); - ALTER TABLE "public"."llm_tokens" OWNER TO "postgres"; - ALTER TABLE "public"."llm_tokens" ALTER COLUMN "id" ADD GENERATED BY DEFAULT AS IDENTITY ( SEQUENCE NAME "public"."llm_tokens_id_seq" START WITH 1 @@ -312,7 +265,6 @@ ALTER TABLE "public"."llm_tokens" ALTER COLUMN "id" ADD GENERATED BY DEFAULT AS NO MAXVALUE CACHE 1 ); - CREATE TABLE IF NOT EXISTS "public"."profiles" ( "id" character varying NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, @@ -320,12 +272,9 @@ CREATE TABLE IF NOT EXISTS "public"."profiles" ( "name" character varying, "picture" character varying, "sid" character varying, - "sub" character varying, - "agreement_accepted" boolean DEFAULT false; + "sub" character varying ); - ALTER TABLE "public"."profiles" OWNER TO "postgres"; - CREATE TABLE IF NOT EXISTS "public"."rag_docs" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "content" "text", @@ -338,9 +287,7 @@ CREATE TABLE IF NOT EXISTS "public"."rag_docs" ( "bot_id" character varying, "update_timestamp" timestamp with time zone ); - ALTER TABLE "public"."rag_docs" OWNER TO "postgres"; - CREATE TABLE IF NOT EXISTS "public"."rag_issues" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "update_timestamp" timestamp with time zone DEFAULT "now"() NOT NULL, @@ -352,9 +299,7 @@ CREATE TABLE IF NOT EXISTS "public"."rag_issues" ( "bot_id" character varying, "comment_id" character varying ); - ALTER TABLE "public"."rag_issues" OWNER TO "postgres"; - CREATE TABLE IF NOT EXISTS "public"."rag_tasks" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, @@ -369,9 +314,7 @@ CREATE TABLE IF NOT EXISTS "public"."rag_tasks" ( "bot_id" character varying, "page_index" numeric ); - ALTER TABLE "public"."rag_tasks" OWNER TO "postgres"; - CREATE TABLE IF NOT EXISTS "public"."user_llm_tokens" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, @@ -381,9 +324,7 @@ CREATE TABLE IF NOT EXISTS "public"."user_llm_tokens" ( "encrypted_token" "text", "sanitized_token" "text" ); - ALTER TABLE "public"."user_llm_tokens" OWNER TO "postgres"; - CREATE TABLE IF NOT EXISTS "public"."user_token_usage" ( "id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL, "created_at" timestamp with time zone DEFAULT "now"() NOT NULL, @@ -395,353 +336,272 @@ CREATE TABLE IF NOT EXISTS "public"."user_token_usage" ( "token_id" "text", "total_token" bigint ); - ALTER TABLE "public"."user_token_usage" OWNER TO "postgres"; - COMMENT ON TABLE "public"."user_token_usage" IS 'token usage of people'; - ALTER TABLE ONLY "public"."bots" ADD CONSTRAINT "bots_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."git_issue_tasks" ADD CONSTRAINT "git_issue_tasks_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."github_app_authorization" ADD CONSTRAINT "github_app_authorization_installation_id_key" UNIQUE ("installation_id"); - ALTER TABLE ONLY "public"."github_app_authorization" ADD CONSTRAINT "github_app_authorization_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."github_repo_config" ADD CONSTRAINT "github_repo_config_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."rag_issues" ADD CONSTRAINT "issue_docs_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."llm_tokens" ADD CONSTRAINT "llm_tokens_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."profiles" ADD CONSTRAINT "profile_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."rag_docs" ADD CONSTRAINT "rag_docs_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."rag_tasks" ADD CONSTRAINT "rag_tasks_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."user_llm_tokens" ADD CONSTRAINT "user_llm_tokens_pkey" PRIMARY KEY ("id"); - ALTER TABLE ONLY "public"."user_token_usage" ADD CONSTRAINT "user_token_usage_pkey" PRIMARY KEY ("id"); - CREATE OR REPLACE TRIGGER "update_timestamp_trigger" BEFORE INSERT OR UPDATE ON "public"."rag_docs" FOR EACH ROW EXECUTE FUNCTION "public"."update_timestamp_function"(); - CREATE POLICY "Enable read access for all users" ON "public"."llm_tokens" FOR SELECT USING (true); - ALTER PUBLICATION "supabase_realtime" OWNER TO "postgres"; - GRANT USAGE ON SCHEMA "public" TO "postgres"; GRANT USAGE ON SCHEMA "public" TO "anon"; GRANT USAGE ON SCHEMA "public" TO "authenticated"; GRANT USAGE ON SCHEMA "public" TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_in"("cstring", "oid", integer) TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_in"("cstring", "oid", integer) TO "anon"; GRANT ALL ON FUNCTION "public"."vector_in"("cstring", "oid", integer) TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_in"("cstring", "oid", integer) TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_out"("public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_out"("public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_out"("public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_out"("public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_recv"("internal", "oid", integer) TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_recv"("internal", "oid", integer) TO "anon"; GRANT ALL ON FUNCTION "public"."vector_recv"("internal", "oid", integer) TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_recv"("internal", "oid", integer) TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_send"("public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_send"("public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_send"("public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_send"("public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_typmod_in"("cstring"[]) TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_typmod_in"("cstring"[]) TO "anon"; GRANT ALL ON FUNCTION "public"."vector_typmod_in"("cstring"[]) TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_typmod_in"("cstring"[]) TO "service_role"; - GRANT ALL ON FUNCTION "public"."array_to_vector"(real[], integer, boolean) TO "postgres"; GRANT ALL ON FUNCTION "public"."array_to_vector"(real[], integer, boolean) TO "anon"; GRANT ALL ON FUNCTION "public"."array_to_vector"(real[], integer, boolean) TO "authenticated"; GRANT ALL ON FUNCTION "public"."array_to_vector"(real[], integer, boolean) TO "service_role"; - GRANT ALL ON FUNCTION "public"."array_to_vector"(double precision[], integer, boolean) TO "postgres"; GRANT ALL ON FUNCTION "public"."array_to_vector"(double precision[], integer, boolean) TO "anon"; GRANT ALL ON FUNCTION "public"."array_to_vector"(double precision[], integer, boolean) TO "authenticated"; GRANT ALL ON FUNCTION "public"."array_to_vector"(double precision[], integer, boolean) TO "service_role"; - GRANT ALL ON FUNCTION "public"."array_to_vector"(integer[], integer, boolean) TO "postgres"; GRANT ALL ON FUNCTION "public"."array_to_vector"(integer[], integer, boolean) TO "anon"; GRANT ALL ON FUNCTION "public"."array_to_vector"(integer[], integer, boolean) TO "authenticated"; GRANT ALL ON FUNCTION "public"."array_to_vector"(integer[], integer, boolean) TO "service_role"; - GRANT ALL ON FUNCTION "public"."array_to_vector"(numeric[], integer, boolean) TO "postgres"; GRANT ALL ON FUNCTION "public"."array_to_vector"(numeric[], integer, boolean) TO "anon"; GRANT ALL ON FUNCTION "public"."array_to_vector"(numeric[], integer, boolean) TO "authenticated"; GRANT ALL ON FUNCTION "public"."array_to_vector"(numeric[], integer, boolean) TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_to_float4"("public"."vector", integer, boolean) TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_to_float4"("public"."vector", integer, boolean) TO "anon"; GRANT ALL ON FUNCTION "public"."vector_to_float4"("public"."vector", integer, boolean) TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_to_float4"("public"."vector", integer, boolean) TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector"("public"."vector", integer, boolean) TO "postgres"; GRANT ALL ON FUNCTION "public"."vector"("public"."vector", integer, boolean) TO "anon"; GRANT ALL ON FUNCTION "public"."vector"("public"."vector", integer, boolean) TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector"("public"."vector", integer, boolean) TO "service_role"; - GRANT ALL ON FUNCTION "public"."cosine_distance"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."cosine_distance"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."cosine_distance"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."cosine_distance"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."execute_sql"("query" "text") TO "anon"; GRANT ALL ON FUNCTION "public"."execute_sql"("query" "text") TO "authenticated"; GRANT ALL ON FUNCTION "public"."execute_sql"("query" "text") TO "service_role"; - GRANT ALL ON FUNCTION "public"."handle_new_user"() TO "anon"; GRANT ALL ON FUNCTION "public"."handle_new_user"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."handle_new_user"() TO "service_role"; - GRANT ALL ON FUNCTION "public"."hnswhandler"("internal") TO "postgres"; GRANT ALL ON FUNCTION "public"."hnswhandler"("internal") TO "anon"; GRANT ALL ON FUNCTION "public"."hnswhandler"("internal") TO "authenticated"; GRANT ALL ON FUNCTION "public"."hnswhandler"("internal") TO "service_role"; - GRANT ALL ON FUNCTION "public"."inner_product"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."inner_product"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."inner_product"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."inner_product"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."ivfflathandler"("internal") TO "postgres"; GRANT ALL ON FUNCTION "public"."ivfflathandler"("internal") TO "anon"; GRANT ALL ON FUNCTION "public"."ivfflathandler"("internal") TO "authenticated"; GRANT ALL ON FUNCTION "public"."ivfflathandler"("internal") TO "service_role"; - GRANT ALL ON FUNCTION "public"."l1_distance"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."l1_distance"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."l1_distance"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."l1_distance"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."l2_distance"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."l2_distance"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."l2_distance"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."l2_distance"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."match_antd_doc"("query_embedding" "public"."vector", "filter" "jsonb") TO "anon"; GRANT ALL ON FUNCTION "public"."match_antd_doc"("query_embedding" "public"."vector", "filter" "jsonb") TO "authenticated"; GRANT ALL ON FUNCTION "public"."match_antd_doc"("query_embedding" "public"."vector", "filter" "jsonb") TO "service_role"; - GRANT ALL ON FUNCTION "public"."match_antd_documents"("query_embedding" "public"."vector", "filter" "jsonb") TO "anon"; GRANT ALL ON FUNCTION "public"."match_antd_documents"("query_embedding" "public"."vector", "filter" "jsonb") TO "authenticated"; GRANT ALL ON FUNCTION "public"."match_antd_documents"("query_embedding" "public"."vector", "filter" "jsonb") TO "service_role"; - GRANT ALL ON FUNCTION "public"."match_antd_knowledge"("query_embedding" "public"."vector", "filter" "jsonb") TO "anon"; GRANT ALL ON FUNCTION "public"."match_antd_knowledge"("query_embedding" "public"."vector", "filter" "jsonb") TO "authenticated"; GRANT ALL ON FUNCTION "public"."match_antd_knowledge"("query_embedding" "public"."vector", "filter" "jsonb") TO "service_role"; - GRANT ALL ON FUNCTION "public"."match_docs"("query_embedding" "public"."vector", "match_count" integer, "filter" "jsonb") TO "anon"; GRANT ALL ON FUNCTION "public"."match_docs"("query_embedding" "public"."vector", "match_count" integer, "filter" "jsonb") TO "authenticated"; GRANT ALL ON FUNCTION "public"."match_docs"("query_embedding" "public"."vector", "match_count" integer, "filter" "jsonb") TO "service_role"; - GRANT ALL ON FUNCTION "public"."match_documents"("query_embedding" "public"."vector", "filter" "jsonb") TO "anon"; GRANT ALL ON FUNCTION "public"."match_documents"("query_embedding" "public"."vector", "filter" "jsonb") TO "authenticated"; GRANT ALL ON FUNCTION "public"."match_documents"("query_embedding" "public"."vector", "filter" "jsonb") TO "service_role"; - +GRANT ALL ON FUNCTION "public"."match_rag_docs"("query_embedding" "public"."vector", "filter" "jsonb") TO "anon"; +GRANT ALL ON FUNCTION "public"."match_rag_docs"("query_embedding" "public"."vector", "filter" "jsonb") TO "authenticated"; +GRANT ALL ON FUNCTION "public"."match_rag_docs"("query_embedding" "public"."vector", "filter" "jsonb") TO "service_role"; GRANT ALL ON FUNCTION "public"."match_text"("query_embedding" "public"."vector", "match_count" integer, "filter" "jsonb") TO "anon"; GRANT ALL ON FUNCTION "public"."match_text"("query_embedding" "public"."vector", "match_count" integer, "filter" "jsonb") TO "authenticated"; GRANT ALL ON FUNCTION "public"."match_text"("query_embedding" "public"."vector", "match_count" integer, "filter" "jsonb") TO "service_role"; - GRANT ALL ON FUNCTION "public"."rag_docs"("query_embedding" "public"."vector", "filter" "jsonb", "query_repo_name" "text") TO "anon"; GRANT ALL ON FUNCTION "public"."rag_docs"("query_embedding" "public"."vector", "filter" "jsonb", "query_repo_name" "text") TO "authenticated"; GRANT ALL ON FUNCTION "public"."rag_docs"("query_embedding" "public"."vector", "filter" "jsonb", "query_repo_name" "text") TO "service_role"; - GRANT ALL ON FUNCTION "public"."update_timestamp_function"() TO "anon"; GRANT ALL ON FUNCTION "public"."update_timestamp_function"() TO "authenticated"; GRANT ALL ON FUNCTION "public"."update_timestamp_function"() TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_accum"(double precision[], "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_accum"(double precision[], "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_accum"(double precision[], "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_accum"(double precision[], "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_add"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_add"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_add"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_add"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_avg"(double precision[]) TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_avg"(double precision[]) TO "anon"; GRANT ALL ON FUNCTION "public"."vector_avg"(double precision[]) TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_avg"(double precision[]) TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_cmp"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_cmp"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_cmp"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_cmp"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_combine"(double precision[], double precision[]) TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_combine"(double precision[], double precision[]) TO "anon"; GRANT ALL ON FUNCTION "public"."vector_combine"(double precision[], double precision[]) TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_combine"(double precision[], double precision[]) TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_dims"("public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_dims"("public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_dims"("public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_dims"("public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_eq"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_eq"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_eq"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_eq"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_ge"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_ge"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_ge"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_ge"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_gt"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_gt"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_gt"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_gt"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_l2_squared_distance"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_l2_squared_distance"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_l2_squared_distance"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_l2_squared_distance"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_le"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_le"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_le"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_le"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_lt"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_lt"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_lt"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_lt"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_mul"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_mul"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_mul"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_mul"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_ne"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_ne"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_ne"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_ne"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_negative_inner_product"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_negative_inner_product"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_negative_inner_product"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_negative_inner_product"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_norm"("public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_norm"("public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_norm"("public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_norm"("public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_spherical_distance"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_spherical_distance"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_spherical_distance"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_spherical_distance"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."vector_sub"("public"."vector", "public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."vector_sub"("public"."vector", "public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."vector_sub"("public"."vector", "public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."vector_sub"("public"."vector", "public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."avg"("public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."avg"("public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."avg"("public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."avg"("public"."vector") TO "service_role"; - GRANT ALL ON FUNCTION "public"."sum"("public"."vector") TO "postgres"; GRANT ALL ON FUNCTION "public"."sum"("public"."vector") TO "anon"; GRANT ALL ON FUNCTION "public"."sum"("public"."vector") TO "authenticated"; GRANT ALL ON FUNCTION "public"."sum"("public"."vector") TO "service_role"; - GRANT ALL ON TABLE "public"."bots" TO "anon"; GRANT ALL ON TABLE "public"."bots" TO "authenticated"; GRANT ALL ON TABLE "public"."bots" TO "service_role"; - GRANT ALL ON TABLE "public"."git_issue_tasks" TO "anon"; GRANT ALL ON TABLE "public"."git_issue_tasks" TO "authenticated"; GRANT ALL ON TABLE "public"."git_issue_tasks" TO "service_role"; - GRANT ALL ON TABLE "public"."github_app_authorization" TO "anon"; GRANT ALL ON TABLE "public"."github_app_authorization" TO "authenticated"; GRANT ALL ON TABLE "public"."github_app_authorization" TO "service_role"; - GRANT ALL ON SEQUENCE "public"."github_app_authorization_id_seq" TO "anon"; GRANT ALL ON SEQUENCE "public"."github_app_authorization_id_seq" TO "authenticated"; GRANT ALL ON SEQUENCE "public"."github_app_authorization_id_seq" TO "service_role"; - GRANT ALL ON TABLE "public"."github_repo_config" TO "anon"; GRANT ALL ON TABLE "public"."github_repo_config" TO "authenticated"; GRANT ALL ON TABLE "public"."github_repo_config" TO "service_role"; - GRANT ALL ON TABLE "public"."llm_tokens" TO "anon"; GRANT ALL ON TABLE "public"."llm_tokens" TO "authenticated"; GRANT ALL ON TABLE "public"."llm_tokens" TO "service_role"; - GRANT ALL ON SEQUENCE "public"."llm_tokens_id_seq" TO "anon"; GRANT ALL ON SEQUENCE "public"."llm_tokens_id_seq" TO "authenticated"; GRANT ALL ON SEQUENCE "public"."llm_tokens_id_seq" TO "service_role"; - GRANT ALL ON TABLE "public"."profiles" TO "anon"; GRANT ALL ON TABLE "public"."profiles" TO "authenticated"; GRANT ALL ON TABLE "public"."profiles" TO "service_role"; - GRANT ALL ON TABLE "public"."rag_docs" TO "anon"; GRANT ALL ON TABLE "public"."rag_docs" TO "authenticated"; GRANT ALL ON TABLE "public"."rag_docs" TO "service_role"; - GRANT ALL ON TABLE "public"."rag_issues" TO "anon"; GRANT ALL ON TABLE "public"."rag_issues" TO "authenticated"; GRANT ALL ON TABLE "public"."rag_issues" TO "service_role"; - GRANT ALL ON TABLE "public"."rag_tasks" TO "anon"; GRANT ALL ON TABLE "public"."rag_tasks" TO "authenticated"; GRANT ALL ON TABLE "public"."rag_tasks" TO "service_role"; - GRANT ALL ON TABLE "public"."user_llm_tokens" TO "anon"; GRANT ALL ON TABLE "public"."user_llm_tokens" TO "authenticated"; GRANT ALL ON TABLE "public"."user_llm_tokens" TO "service_role"; - GRANT ALL ON TABLE "public"."user_token_usage" TO "anon"; GRANT ALL ON TABLE "public"."user_token_usage" TO "authenticated"; GRANT ALL ON TABLE "public"."user_token_usage" TO "service_role"; - ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "postgres"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "anon"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "authenticated"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON SEQUENCES TO "service_role"; - ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "postgres"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "anon"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "authenticated"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON FUNCTIONS TO "service_role"; - ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "postgres"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "anon"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "authenticated"; ALTER DEFAULT PRIVILEGES FOR ROLE "postgres" IN SCHEMA "public" GRANT ALL ON TABLES TO "service_role"; - RESET ALL; - -- -- Dumped schema changes for auth and storage --- - +--; diff --git a/migrations/supabase/migrations/20240912023152_remote_schema.sql b/migrations/supabase/migrations/20240912023152_remote_schema.sql index d51bfe06..2abc90f9 100644 --- a/migrations/supabase/migrations/20240912023152_remote_schema.sql +++ b/migrations/supabase/migrations/20240912023152_remote_schema.sql @@ -1,5 +1,4 @@ set check_function_bodies = off; - CREATE OR REPLACE FUNCTION public.get_user_stats(filter_user_id text, start_date date, end_date date) RETURNS TABLE(usage_date date, input_tokens bigint, output_tokens bigint, total_tokens bigint) LANGUAGE plpgsql @@ -17,7 +16,4 @@ BEGIN AND u.date <= end_date GROUP BY u.date; END; -$function$ -; - - +$function$; diff --git a/migrations/supabase/migrations/20240913114522_remote_schema.sql b/migrations/supabase/migrations/20240913114522_remote_schema.sql index 3d17702f..24e868b3 100644 --- a/migrations/supabase/migrations/20240913114522_remote_schema.sql +++ b/migrations/supabase/migrations/20240913114522_remote_schema.sql @@ -1,7 +1,5 @@ alter table "public"."bots" alter column "token_id" set default ''::text; - set check_function_bodies = off; - CREATE OR REPLACE FUNCTION public.get_bot_stats(filter_bot_id text) RETURNS TABLE(call_cnt bigint) LANGUAGE plpgsql @@ -14,7 +12,4 @@ BEGIN WHERE u.bot_id = filter_bot_id -- 使用别名来引用参数 GROUP BY u.bot_id; END; -$function$ -; - - +$function$; diff --git a/migrations/supabase/migrations/20241015085655_remote_schema.sql b/migrations/supabase/migrations/20241015085655_remote_schema.sql index 2d4fab98..20cd0568 100644 --- a/migrations/supabase/migrations/20241015085655_remote_schema.sql +++ b/migrations/supabase/migrations/20241015085655_remote_schema.sql @@ -1,9 +1,6 @@ drop function if exists "public"."match_docs"(query_embedding vector, match_count integer, filter jsonb); - drop function if exists "public"."match_documents"(query_embedding vector, filter jsonb); - drop function if exists "public"."match_text"(query_embedding vector, match_count integer, filter jsonb); - create table "public"."bot_approval" ( "id" uuid not null default gen_random_uuid(), "created_at" timestamp with time zone not null default now(), @@ -12,16 +9,12 @@ create table "public"."bot_approval" ( "approval_path" character varying, "approval_status" character varying default ''::character varying ); - - create table "public"."github_app_installations" ( "id" bigint generated by default as identity not null, "created_at" timestamp with time zone not null default now(), "owner_name" text, "repo_name" text ); - - create table "public"."user_rate_limit" ( "id" uuid not null default gen_random_uuid(), "created_at" timestamp with time zone not null default now(), @@ -29,154 +22,77 @@ create table "public"."user_rate_limit" ( "last_request" timestamp without time zone, "request_count" bigint ); - - alter table "public"."user_rate_limit" enable row level security; - alter table "public"."bots" alter column "llm" set default ''::character varying; - alter table "public"."bots" alter column "token_id" drop default; - alter table "public"."github_repo_config" add column "owner_id" character varying; - alter table "public"."github_repo_config" add column "repo_id" character varying; - CREATE UNIQUE INDEX "bot_ approval_pkey" ON public.bot_approval USING btree (id); - CREATE UNIQUE INDEX github_app_installations_pkey ON public.github_app_installations USING btree (id); - CREATE UNIQUE INDEX user_rate_limit_pkey ON public.user_rate_limit USING btree (id); - alter table "public"."bot_approval" add constraint "bot_ approval_pkey" PRIMARY KEY using index "bot_ approval_pkey"; - alter table "public"."github_app_installations" add constraint "github_app_installations_pkey" PRIMARY KEY using index "github_app_installations_pkey"; - alter table "public"."user_rate_limit" add constraint "user_rate_limit_pkey" PRIMARY KEY using index "user_rate_limit_pkey"; - grant delete on table "public"."bot_approval" to "anon"; - grant insert on table "public"."bot_approval" to "anon"; - grant references on table "public"."bot_approval" to "anon"; - grant select on table "public"."bot_approval" to "anon"; - grant trigger on table "public"."bot_approval" to "anon"; - grant truncate on table "public"."bot_approval" to "anon"; - grant update on table "public"."bot_approval" to "anon"; - grant delete on table "public"."bot_approval" to "authenticated"; - grant insert on table "public"."bot_approval" to "authenticated"; - grant references on table "public"."bot_approval" to "authenticated"; - grant select on table "public"."bot_approval" to "authenticated"; - grant trigger on table "public"."bot_approval" to "authenticated"; - grant truncate on table "public"."bot_approval" to "authenticated"; - grant update on table "public"."bot_approval" to "authenticated"; - grant delete on table "public"."bot_approval" to "service_role"; - grant insert on table "public"."bot_approval" to "service_role"; - grant references on table "public"."bot_approval" to "service_role"; - grant select on table "public"."bot_approval" to "service_role"; - grant trigger on table "public"."bot_approval" to "service_role"; - grant truncate on table "public"."bot_approval" to "service_role"; - grant update on table "public"."bot_approval" to "service_role"; - grant delete on table "public"."github_app_installations" to "anon"; - grant insert on table "public"."github_app_installations" to "anon"; - grant references on table "public"."github_app_installations" to "anon"; - grant select on table "public"."github_app_installations" to "anon"; - grant trigger on table "public"."github_app_installations" to "anon"; - grant truncate on table "public"."github_app_installations" to "anon"; - grant update on table "public"."github_app_installations" to "anon"; - grant delete on table "public"."github_app_installations" to "authenticated"; - grant insert on table "public"."github_app_installations" to "authenticated"; - grant references on table "public"."github_app_installations" to "authenticated"; - grant select on table "public"."github_app_installations" to "authenticated"; - grant trigger on table "public"."github_app_installations" to "authenticated"; - grant truncate on table "public"."github_app_installations" to "authenticated"; - grant update on table "public"."github_app_installations" to "authenticated"; - grant delete on table "public"."github_app_installations" to "service_role"; - grant insert on table "public"."github_app_installations" to "service_role"; - grant references on table "public"."github_app_installations" to "service_role"; - grant select on table "public"."github_app_installations" to "service_role"; - grant trigger on table "public"."github_app_installations" to "service_role"; - grant truncate on table "public"."github_app_installations" to "service_role"; - grant update on table "public"."github_app_installations" to "service_role"; - grant delete on table "public"."user_rate_limit" to "anon"; - grant insert on table "public"."user_rate_limit" to "anon"; - grant references on table "public"."user_rate_limit" to "anon"; - grant select on table "public"."user_rate_limit" to "anon"; - grant trigger on table "public"."user_rate_limit" to "anon"; - grant truncate on table "public"."user_rate_limit" to "anon"; - grant update on table "public"."user_rate_limit" to "anon"; - grant delete on table "public"."user_rate_limit" to "authenticated"; - grant insert on table "public"."user_rate_limit" to "authenticated"; - grant references on table "public"."user_rate_limit" to "authenticated"; - grant select on table "public"."user_rate_limit" to "authenticated"; - grant trigger on table "public"."user_rate_limit" to "authenticated"; - grant truncate on table "public"."user_rate_limit" to "authenticated"; - grant update on table "public"."user_rate_limit" to "authenticated"; - grant delete on table "public"."user_rate_limit" to "service_role"; - grant insert on table "public"."user_rate_limit" to "service_role"; - grant references on table "public"."user_rate_limit" to "service_role"; - grant select on table "public"."user_rate_limit" to "service_role"; - grant trigger on table "public"."user_rate_limit" to "service_role"; - grant truncate on table "public"."user_rate_limit" to "service_role"; - grant update on table "public"."user_rate_limit" to "service_role"; - - diff --git a/migrations/supabase/migrations/20241015090438_remote_schema.sql b/migrations/supabase/migrations/20241015090438_remote_schema.sql index 91a860a9..3c9e5bbc 100644 --- a/migrations/supabase/migrations/20241015090438_remote_schema.sql +++ b/migrations/supabase/migrations/20241015090438_remote_schema.sql @@ -1,7 +1,3 @@ drop function if exists "public"."match_antd_doc"(query_embedding vector, filter jsonb); - drop function if exists "public"."match_antd_documents"(query_embedding vector, filter jsonb); - drop function if exists "public"."match_antd_knowledge"(query_embedding vector, filter jsonb); - - diff --git a/migrations/supabase/migrations/20241210072126_remote_schema.sql b/migrations/supabase/migrations/20241210072126_remote_schema.sql new file mode 100644 index 00000000..691a9bd7 --- /dev/null +++ b/migrations/supabase/migrations/20241210072126_remote_schema.sql @@ -0,0 +1,170 @@ +revoke delete on table "public"."github_app_authorization" from "anon"; + +revoke insert on table "public"."github_app_authorization" from "anon"; + +revoke references on table "public"."github_app_authorization" from "anon"; + +revoke select on table "public"."github_app_authorization" from "anon"; + +revoke trigger on table "public"."github_app_authorization" from "anon"; + +revoke truncate on table "public"."github_app_authorization" from "anon"; + +revoke update on table "public"."github_app_authorization" from "anon"; + +revoke delete on table "public"."github_app_authorization" from "authenticated"; + +revoke insert on table "public"."github_app_authorization" from "authenticated"; + +revoke references on table "public"."github_app_authorization" from "authenticated"; + +revoke select on table "public"."github_app_authorization" from "authenticated"; + +revoke trigger on table "public"."github_app_authorization" from "authenticated"; + +revoke truncate on table "public"."github_app_authorization" from "authenticated"; + +revoke update on table "public"."github_app_authorization" from "authenticated"; + +revoke delete on table "public"."github_app_authorization" from "service_role"; + +revoke insert on table "public"."github_app_authorization" from "service_role"; + +revoke references on table "public"."github_app_authorization" from "service_role"; + +revoke select on table "public"."github_app_authorization" from "service_role"; + +revoke trigger on table "public"."github_app_authorization" from "service_role"; + +revoke truncate on table "public"."github_app_authorization" from "service_role"; + +revoke update on table "public"."github_app_authorization" from "service_role"; + +revoke delete on table "public"."github_app_installations" from "anon"; + +revoke insert on table "public"."github_app_installations" from "anon"; + +revoke references on table "public"."github_app_installations" from "anon"; + +revoke select on table "public"."github_app_installations" from "anon"; + +revoke trigger on table "public"."github_app_installations" from "anon"; + +revoke truncate on table "public"."github_app_installations" from "anon"; + +revoke update on table "public"."github_app_installations" from "anon"; + +revoke delete on table "public"."github_app_installations" from "authenticated"; + +revoke insert on table "public"."github_app_installations" from "authenticated"; + +revoke references on table "public"."github_app_installations" from "authenticated"; + +revoke select on table "public"."github_app_installations" from "authenticated"; + +revoke trigger on table "public"."github_app_installations" from "authenticated"; + +revoke truncate on table "public"."github_app_installations" from "authenticated"; + +revoke update on table "public"."github_app_installations" from "authenticated"; + +revoke delete on table "public"."github_app_installations" from "service_role"; + +revoke insert on table "public"."github_app_installations" from "service_role"; + +revoke references on table "public"."github_app_installations" from "service_role"; + +revoke select on table "public"."github_app_installations" from "service_role"; + +revoke trigger on table "public"."github_app_installations" from "service_role"; + +revoke truncate on table "public"."github_app_installations" from "service_role"; + +revoke update on table "public"."github_app_installations" from "service_role"; + +alter table "public"."github_app_authorization" drop constraint "github_app_authorization_installation_id_key"; + +drop function if exists "public"."match_rag_docs"(query_embedding vector, filter jsonb); + +alter table "public"."github_app_authorization" drop constraint "github_app_authorization_pkey"; + +alter table "public"."github_app_installations" drop constraint "github_app_installations_pkey"; + +alter table "public"."rag_docs" drop constraint "rag_docs_pkey"; + +drop index if exists "public"."github_app_authorization_installation_id_key"; + +drop index if exists "public"."github_app_authorization_pkey"; + +drop index if exists "public"."github_app_installations_pkey"; + +drop index if exists "public"."rag_docs_pkey"; + +drop table "public"."github_app_authorization"; + +drop table "public"."github_app_installations"; + +alter table "public"."bots" add column "n" smallint default '1'::smallint; + +alter table "public"."bots" add column "temperature" real default '0.2'::real; + +alter table "public"."bots" add column "top_p" real; + +alter table "public"."profiles" add column "agreement_accepted" boolean default false; + +alter table "public"."rag_docs" alter column "repo_name" set not null; + +CREATE UNIQUE INDEX rag_docs_pkey ON public.rag_docs USING btree (id, repo_name); + +alter table "public"."rag_docs" add constraint "rag_docs_pkey" PRIMARY KEY using index "rag_docs_pkey"; + +set check_function_bodies = off; + +CREATE OR REPLACE FUNCTION public.count_rag_docs_by_sha(file_sha_input text) + RETURNS TABLE(count bigint, file_sha character varying, repo_name text, file_path character varying) + LANGUAGE plpgsql +AS $function$ +BEGIN + RETURN QUERY + SELECT + COUNT(id) AS count, + r.file_sha AS file_sha, + r.repo_name AS repo_name, + r.file_path AS file_path + FROM + rag_docs r + WHERE + r.file_sha = file_sha_input + GROUP BY + r.file_sha, + r.repo_name, + r.file_path + ORDER BY + count ASC; +END; +$function$ +; + +CREATE OR REPLACE FUNCTION public.match_embedding_docs(query_embedding vector, filter jsonb DEFAULT '{}'::jsonb) + RETURNS TABLE(id uuid, content text, metadata jsonb, embedding vector, similarity double precision) + LANGUAGE plpgsql +AS $function$ +#variable_conflict use_column +begin + return query + select + id, + content, + metadata, + embedding, + 1 - (rag_docs.embedding <=> query_embedding + ) as similarity + from rag_docs + where metadata @> jsonb_extract_path(filter, 'metadata') + and repo_name = jsonb_extract_path_text(filter, 'repo_name') + order by rag_docs.embedding <=> query_embedding; +end; +$function$ +; + + diff --git a/server/core/dao/authorizationDAO.py b/server/core/dao/authorizationDAO.py deleted file mode 100644 index 871a40f2..00000000 --- a/server/core/dao/authorizationDAO.py +++ /dev/null @@ -1,39 +0,0 @@ -from supabase.client import Client - -from petercat_utils.db.client.supabase import get_client - -from core.dao.BaseDAO import BaseDAO -from core.models.authorization import Authorization - -class AuthorizationDAO(BaseDAO): - client: Client - - def __init__(self): - super().__init__() - self.client = get_client() - - def exists(self, installation_id: str) -> bool: - try: - authorization = self.client.table("github_app_authorization")\ - .select('*', count="exact")\ - .eq('installation_id', installation_id) \ - .execute() - - return bool(authorization.count) - - except Exception as e: - print("Error: ", e) - return {"message": "User creation failed"} - - def create(self, data: Authorization): - try: - authorization = self.client.from_("github_app_authorization")\ - .insert(data.model_dump())\ - .execute() - if authorization: - return True, {"message": "User created successfully"} - else: - return False, {"message": "User creation failed"} - except Exception as e: - print("Error: ", e) - return False, {"message": "User creation failed"} \ No newline at end of file diff --git a/server/core/dao/repositoryConfigDAO.py b/server/core/dao/repositoryConfigDAO.py index 58d6fe01..b9c410fe 100644 --- a/server/core/dao/repositoryConfigDAO.py +++ b/server/core/dao/repositoryConfigDAO.py @@ -1,4 +1,4 @@ -from typing import Counter, List +from typing import List from core.dao.BaseDAO import BaseDAO from core.models.bot import RepoBindBotConfigVO from core.models.repository import RepositoryConfig diff --git a/server/github_app/router.py b/server/github_app/router.py index c8443d25..01e4ea94 100644 --- a/server/github_app/router.py +++ b/server/github_app/router.py @@ -11,22 +11,15 @@ import logging from fastapi.responses import RedirectResponse -import time from github import Auth, Github from auth.get_user_info import get_user -from core.dao.authorizationDAO import AuthorizationDAO from core.dao.repositoryConfigDAO import RepositoryConfigDAO from core.models.bot import RepoBindBotRequest -from core.models.repository import RepositoryConfig -from core.models.authorization import Authorization from core.models.user import User from github_app.handlers import get_handler from github_app.purchased import PurchaseServer from github_app.utils import ( - get_app_installations_access_token, - get_installation_repositories, - get_jwt, get_private_key, ) From f96230f5bbbc466340c00e4a1426034eaa52e734 Mon Sep 17 00:00:00 2001 From: yingying Date: Thu, 12 Dec 2024 15:34:54 +0800 Subject: [PATCH 06/11] feat: add auto complete --- client/.kiwi/en/edit.ts | 4 +- client/.kiwi/ja/edit.ts | 4 +- client/.kiwi/ko/edit.ts | 4 +- client/.kiwi/zh-CN/edit.ts | 4 +- client/.kiwi/zh-TW/edit.ts | 4 +- client/app/factory/edit/page.tsx | 111 ++++++++++++++++---------- client/app/hooks/useUser.ts | 22 ++++- client/app/services/UserController.ts | 7 ++ client/app/utils/tools.ts | 9 ++- client/components/User.tsx | 9 ++- server/auth/get_user_info.py | 1 + server/auth/router.py | 92 ++++++++++++++------- 12 files changed, 178 insertions(+), 93 deletions(-) diff --git a/client/.kiwi/en/edit.ts b/client/.kiwi/en/edit.ts index 7ff3761b..f4ccb78e 100644 --- a/client/.kiwi/en/edit.ts +++ b/client/.kiwi/en/edit.ts @@ -9,10 +9,10 @@ export default { chongXinShengChengPei: 'Regenerate Configuration', ziDongShengChengPei: 'Automatically Generate Configuration', diZhiYouWu: 'Invalid Address', - qingShuRuGI: 'Please enter the GitHub project URL', + qingShuRuGI: 'Please enter or select the GitHub project name', fuZhiTOK: 'Copy Token', tOKEN: 'Token has been copied to clipboard', - gITHU: 'GitHub Project URL', + gITHU: 'GitHub project name', bangWoPeiZhiYi: 'Help me create a Q&A bot', chuCiJianMianXian: '👋🏻 Hello! Nice to meet you. Let me introduce myself: I am PeterCat, a robot for an open-source project. You can create a Q&A robot by talking to me.', diff --git a/client/.kiwi/ja/edit.ts b/client/.kiwi/ja/edit.ts index 47a082a3..36410691 100644 --- a/client/.kiwi/ja/edit.ts +++ b/client/.kiwi/ja/edit.ts @@ -9,10 +9,10 @@ export default { chongXinShengChengPei: '設定を再生成', ziDongShengChengPei: '設定を自動生成', diZhiYouWu: 'アドレスに誤りがあります', - qingShuRuGI: 'GitHubプロジェクトのアドレスを入力してください', + qingShuRuGI: 'GitHubプロジェクト名を入力または選択してください', fuZhiTOK: 'トークンをコピー', tOKEN: 'トークンがクリップボードにコピーされました', - gITHU: 'GitHubプロジェクトのアドレス', + gITHU: 'GitHubプロジェクト名', bangWoPeiZhiYi: 'Q&Aボットの設定を手伝ってください', chuCiJianMianXian: '👋🏻 こんにちは!初めまして、自己紹介させていただきます。私はPeterCatと申します。オープンソースプロジェクトのロボットです。私と対話することで、Q&Aロボットを設定できます。', diff --git a/client/.kiwi/ko/edit.ts b/client/.kiwi/ko/edit.ts index 77405ca0..53d28675 100644 --- a/client/.kiwi/ko/edit.ts +++ b/client/.kiwi/ko/edit.ts @@ -9,10 +9,10 @@ export default { chongXinShengChengPei: '구성 다시 생성', ziDongShengChengPei: '구성 자동 생성', diZhiYouWu: '주소 오류', - qingShuRuGI: 'GitHub 프로젝트 주소를 입력하십시오.', + qingShuRuGI: 'GitHub 프로젝트 이름을 입력하거나 선택하세요', fuZhiTOK: '토큰 복사', tOKEN: '토큰이 클립보드에 복사되었습니다.', - gITHU: 'GitHub 프로젝트 주소', + gITHU: 'GitHub 프로젝트 이름', bangWoPeiZhiYi: 'Q&A 봇 설정을 도와주세요.', chuCiJianMianXian: '👋🏻 안녕하세요! 처음 뵙겠습니다. 제 소개를 하겠습니다: 저는 PeterCat입니다, 오픈소스 프로젝트의 로봇입니다. 저와 대화를 통해 질의응답 로봇을 구성할 수 있습니다.', diff --git a/client/.kiwi/zh-CN/edit.ts b/client/.kiwi/zh-CN/edit.ts index 9742212f..3d376d11 100644 --- a/client/.kiwi/zh-CN/edit.ts +++ b/client/.kiwi/zh-CN/edit.ts @@ -8,10 +8,10 @@ export default { chongXinShengChengPei: '重新生成配置', ziDongShengChengPei: '自动生成配置', diZhiYouWu: '地址有误', - qingShuRuGI: '请输入 GitHub 项目地址', + qingShuRuGI: '请输入或选择 GitHub 项目名称', fuZhiTOK: '复制 Token', tOKEN: 'Token 已复制到剪贴板', - gITHU: 'Github 项目地址', + gITHU: 'Github 项目名称', bangWoPeiZhiYi: '帮我配置一个答疑机器人', chuCiJianMianXian: '👋🏻 初次见面,先自我介绍一下:我是 PeterCat,一个开源项目的机器人。你可以通过和我对话配置一个答疑机器人。', diff --git a/client/.kiwi/zh-TW/edit.ts b/client/.kiwi/zh-TW/edit.ts index 9a76b1eb..e2c0212d 100644 --- a/client/.kiwi/zh-TW/edit.ts +++ b/client/.kiwi/zh-TW/edit.ts @@ -8,10 +8,10 @@ export default { chongXinShengChengPei: '重新生成配置', ziDongShengChengPei: '自動生成配置', diZhiYouWu: '地址有誤', - qingShuRuGI: '請輸入 GitHub 項目地址', + qingShuRuGI: '請輸入或選擇 GitHub 項目名稱', fuZhiTOK: '複製 Token', tOKEN: 'Token 已複製到剪貼板', - gITHU: 'GitHub 項目地址', + gITHU: 'GitHub 項目名稱', bangWoPeiZhiYi: '幫我配置一個答疑機器人', chuCiJianMianXian: '👋🏻 初次見面,先自我介紹一下:我是 PeterCat,一個開源項目的機器人。你可以通過和我對話配置一個答疑機器人。', diff --git a/client/app/factory/edit/page.tsx b/client/app/factory/edit/page.tsx index acfe9ff4..79192e31 100644 --- a/client/app/factory/edit/page.tsx +++ b/client/app/factory/edit/page.tsx @@ -1,6 +1,6 @@ 'use client'; import I18N from '@/app/utils/I18N'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState, Key } from 'react'; import { Tabs, Tab, @@ -10,9 +10,11 @@ import { ModalBody, ModalFooter, Button, - Input, Avatar, Checkbox, + Autocomplete, + AutocompleteItem, + Input, } from '@nextui-org/react'; import Image from 'next/image'; import BotCreateFrom from '@/app/factory/edit/components/BotCreateForm'; @@ -28,20 +30,19 @@ import { } from '@/app/hooks/useBot'; import { useAgreement, useAgreementStatus } from '@/app/hooks/useAgreement'; import FullPageSkeleton from '@/components/FullPageSkeleton'; -import { isEmpty } from 'lodash'; +import { isEmpty, map, size } from 'lodash'; import { Chat } from '@petercatai/assistant'; import AIBtnIcon from '@/public/icons/AIBtnIcon'; import ChatIcon from '@/public/icons/ChatIcon'; import ConfigIcon from '@/public/icons/ConfigIcon'; import SaveIcon from '@/public/icons/SaveIcon'; import { useBot } from '@/app/contexts/BotContext'; -import useUser from '@/app/hooks/useUser'; +import { useUser, useUserRepos } from '@/app/hooks/useUser'; import Knowledge from './components/Knowledge'; import { useGlobal } from '@/app/contexts/GlobalContext'; import KnowledgeBtn from './components/KnowledgeBtn'; import { BotTaskProvider } from './components/TaskContext'; import { useSearchParams } from 'next/navigation'; -import 'react-toastify/dist/ReactToastify.css'; import { extractFullRepoNameFromGitHubUrl } from '@/app/utils/tools'; import DeployBotModal from './components/DeployBotModal'; import Markdown from '@/components/Markdown'; @@ -51,6 +52,8 @@ import AgreementJA from '../../../.kiwi/ja/agreement.md'; import AgreementKO from '../../../.kiwi/ko/agreement.md'; import AgreementZhTW from '../../../.kiwi/zh-TW/agreement.md'; +import 'react-toastify/dist/ReactToastify.css'; + const API_HOST = process.env.NEXT_PUBLIC_API_DOMAIN; enum VisibleTypeEnum { BOT_CONFIG = 'BOT_CONFIG', @@ -78,7 +81,7 @@ export default function Edit() { const [visibleType, setVisibleType] = React.useState( VisibleTypeEnum.BOT_CONFIG, ); - const [gitUrl, setGitUrl] = React.useState(''); + const [gitRepoName, setGitRepoName] = React.useState(''); const [deployModalIsOpen, setDeployModalIsOpen] = useState(false); const [agreementModalIsOpen, setAgreementModalIsOpen] = useState(false); const [agreementAccepted, setAgreementAccepted] = @@ -180,6 +183,8 @@ export default function Edit() { [id, botProfile?.id], ); + const { data: repos } = useUserRepos(!isEdit); + const botId = useMemo(() => { if (!!id && id !== 'new') { return id; @@ -323,46 +328,64 @@ export default function Edit() { )} ); - const manualConfigLabel = ( -
- {I18N.edit.page.gITHU} - {botProfile.id && ( - { - toast.success(I18N.edit.page.tOKEN); - }} - > - {/* @ts-ignore */} - - {I18N.edit.page.fuZhiTOK} - - - )} -
- ); const manualConfigContent = (
-
- { - const url = e.target.value; - setGitUrl(url); - }} - value={gitUrl || botProfile.repoName} - isDisabled={isEdit} - required - classNames={{ label: 'w-full' }} - className="mt-1 mb-6 block w-full border-gray-300 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" - /> +
+ {I18N.edit.page.gITHU} + {botProfile.id && ( + { + toast.success(I18N.edit.page.tOKEN); + }} + > + {/* @ts-ignore */} + + {I18N.edit.page.fuZhiTOK} + + + )} +
+
+ {!isEdit ? ( + { + const repoName = extractFullRepoNameFromGitHubUrl(value); + setGitRepoName(repoName || ''); + }} + onSelectionChange={(key) => { + setGitRepoName(`${key}`); + }} + allowsCustomValue + defaultInputValue={gitRepoName || botProfile.repoName} + variant="bordered" + className="mt-1 mb-6 block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" + label={I18N.edit.page.qingShuRuGI} + > + {map(repos, (item) => ( + {item.label} + ))} + + ) : ( + + )} +
{!isEdit ? (
@@ -372,7 +395,7 @@ export default function Edit() { startContent={} isLoading={createBotLoading} onClick={() => { - const repoName = extractFullRepoNameFromGitHubUrl(gitUrl); + const repoName = gitRepoName || botProfile.repoName; if (repoName) { onCreateBot({ repo_name: repoName!!, diff --git a/client/app/hooks/useUser.ts b/client/app/hooks/useUser.ts index 23357dc1..53099261 100644 --- a/client/app/hooks/useUser.ts +++ b/client/app/hooks/useUser.ts @@ -1,19 +1,33 @@ import { useUser as useAssistUser } from '@petercatai/assistant'; import { useFingerprint } from './useFingerprint'; +import { useQuery } from '@tanstack/react-query'; +import { getUserRepos } from '../services/UserController'; +import { map } from 'lodash'; const API_DOMAIN = process.env.NEXT_PUBLIC_API_DOMAIN!; -export default function useUser() { +export const useUser = () => { const { data: fingerprint } = useFingerprint(); const { user, isLoading, actions } = useAssistUser({ apiDomain: API_DOMAIN, - fingerprint: fingerprint?.visitorId! + fingerprint: fingerprint?.visitorId!, }); return { user, isLoading, actions, - status: isLoading ? "pending" : 'success', + status: isLoading ? 'pending' : 'success', }; -} +}; + +export const useUserRepos = (enabled: boolean) => { + return useQuery({ + queryKey: [`user.repos`], + queryFn: async () => getUserRepos(), + enabled, + select: (data) => + map(data.data, (item) => ({ label: item.name, key: item.name })), + retry: true, + }); +}; diff --git a/client/app/services/UserController.ts b/client/app/services/UserController.ts index a5946f63..7406e267 100644 --- a/client/app/services/UserController.ts +++ b/client/app/services/UserController.ts @@ -27,6 +27,13 @@ export async function getAgreementStatus() { return response.data; } +export async function getUserRepos() { + const response = await axios.get(`${apiDomain}/api/auth/repos`, { + withCredentials: true, + }); + return response.data; +} + export async function getAvailableLLMs() { const response = await axios.get(`${apiDomain}/api/user/llms`, { withCredentials: true, diff --git a/client/app/utils/tools.ts b/client/app/utils/tools.ts index a7df2aad..8f525ef6 100644 --- a/client/app/utils/tools.ts +++ b/client/app/utils/tools.ts @@ -13,10 +13,11 @@ export const extractParametersByTools = (content: string) => { return null; }; -export const extractFullRepoNameFromGitHubUrl = (githubUrl: string) => { +export const extractFullRepoNameFromGitHubUrl = (input: string) => { try { - const regex = /^https:\/\/github\.com\/([^\/]+)\/([^\/]+)(\/.*)?$/; - const match = githubUrl.match(regex); + // Use a regex that matches both full URLs and `username/reponame` format. + const regex = /^(?:https:\/\/github\.com\/)?([^\/]+)\/([^\/]+)(?:\/.*)?$/; + const match = input.match(regex); if (match && match[1] && match[2]) { return `${match[1]}/${match[2]}`; @@ -24,7 +25,7 @@ export const extractFullRepoNameFromGitHubUrl = (githubUrl: string) => { return null; } } catch (error) { - console.error('Error parsing GitHub URL:', error); + console.error('Error parsing input:', error); return null; } }; diff --git a/client/components/User.tsx b/client/components/User.tsx index 485501ae..0677a2b3 100644 --- a/client/components/User.tsx +++ b/client/components/User.tsx @@ -9,7 +9,7 @@ import { DropdownMenu, DropdownTrigger, } from '@nextui-org/react'; -import useUser from '../app/hooks/useUser'; +import { useUser } from '../app/hooks/useUser'; import GitHubIcon from '@/public/icons/GitHubIcon'; import Link from 'next/link'; @@ -23,13 +23,14 @@ export default function Profile() { className="min-w-[88px] px-4 h-10 inline-block transition-colors bg-[#3F3F46] text-[#FFFFFF] rounded-full leading-10 text-center" > - {I18N.components.User.dengLu} + {I18N.components.User.dengLu} + ); } const avatar = ( - + {I18N.components.User.tOKEN} - + {I18N.components.User.dengChu} diff --git a/server/auth/get_user_info.py b/server/auth/get_user_info.py index 950f916f..7b587108 100644 --- a/server/auth/get_user_info.py +++ b/server/auth/get_user_info.py @@ -11,6 +11,7 @@ AUTH0_DOMAIN = get_env_variable("AUTH0_DOMAIN") + async def getUserInfoByToken(token): userinfo_url = f"https://{AUTH0_DOMAIN}/userinfo" headers = {"authorization": f"Bearer {token}"} diff --git a/server/auth/router.py b/server/auth/router.py index bb8a2ca4..7a7a3e8b 100644 --- a/server/auth/router.py +++ b/server/auth/router.py @@ -1,3 +1,5 @@ +import json +from github import Github from core.dao.profilesDAO import ProfilesDAO from fastapi import APIRouter, Request, HTTPException, status, Depends from fastapi.responses import RedirectResponse, JSONResponse @@ -7,7 +9,12 @@ from authlib.integrations.starlette_client import OAuth from typing import Annotated, Optional -from auth.get_user_info import generateAnonymousUser, getUserInfoByToken, get_user_id +from auth.get_user_info import ( + generateAnonymousUser, + getUserAccessToken, + getUserInfoByToken, + get_user_id, +) AUTH0_DOMAIN = get_env_variable("AUTH0_DOMAIN") @@ -15,26 +22,26 @@ CLIENT_ID = get_env_variable("AUTH0_CLIENT_ID") CLIENT_SECRET = get_env_variable("AUTH0_CLIENT_SECRET") -API_URL = get_env_variable("API_URL") +API_URL = get_env_variable("API_URL") CALLBACK_URL = f"{API_URL}/api/auth/callback" LOGIN_URL = f"{API_URL}/api/auth/login" -WEB_URL = get_env_variable("WEB_URL") +WEB_URL = get_env_variable("WEB_URL") WEB_LOGIN_SUCCESS_URL = f"{WEB_URL}/user/login" MARKET_URL = f"{WEB_URL}/market" -config = Config(environ={ - "AUTH0_CLIENT_ID": CLIENT_ID, - "AUTH0_CLIENT_SECRET": CLIENT_SECRET, -}) +config = Config( + environ={ + "AUTH0_CLIENT_ID": CLIENT_ID, + "AUTH0_CLIENT_SECRET": CLIENT_SECRET, + } +) oauth = OAuth(config) oauth.register( name="auth0", - server_metadata_url=f'https://{AUTH0_DOMAIN}/.well-known/openid-configuration', - client_kwargs={ - 'scope': 'openid email profile' - } + server_metadata_url=f"https://{AUTH0_DOMAIN}/.well-known/openid-configuration", + client_kwargs={"scope": "openid email profile"}, ) router = APIRouter( @@ -43,38 +50,46 @@ responses={404: {"description": "Not found"}}, ) + async def getAnonymousUser(request: Request): clientId = request.query_params.get("clientId") if not clientId: - raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing clientId") + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail="Missing clientId" + ) token, data = await generateAnonymousUser(clientId) supabase = get_client() supabase.table("profiles").upsert(data).execute() - request.session['user'] = data + request.session["user"] = data return data + @router.get("/login") async def login(request: Request): if CLIENT_ID is None: return { "message": "enviroments CLIENT_ID and CLIENT_SECRET required.", } - redirect_response = await oauth.auth0.authorize_redirect(request, redirect_uri=CALLBACK_URL) + redirect_response = await oauth.auth0.authorize_redirect( + request, redirect_uri=CALLBACK_URL + ) return redirect_response -@router.get('/logout') + +@router.get("/logout") async def logout(request: Request): - request.session.pop('user', None) - redirect = request.query_params.get('redirect') + request.session.pop("user", None) + redirect = request.query_params.get("redirect") if redirect: - return RedirectResponse(url=f'{redirect}', status_code=302) - return { "success": True } + return RedirectResponse(url=f"{redirect}", status_code=302) + return {"success": True} + @router.get("/callback") async def callback(request: Request): auth0_token = await oauth.auth0.authorize_access_token(request) - user_info = await getUserInfoByToken(token=auth0_token['access_token']) + user_info = await getUserInfoByToken(token=auth0_token["access_token"]) if user_info: data = { @@ -86,18 +101,20 @@ async def callback(request: Request): "sid": secrets.token_urlsafe(32), "agreement_accepted": user_info.get("agreement_accepted"), } - request.session['user'] = dict(data) + request.session["user"] = dict(data) supabase = get_client() supabase.table("profiles").upsert(data).execute() - return RedirectResponse(url=f'{WEB_LOGIN_SUCCESS_URL}', status_code=302) + return RedirectResponse(url=f"{WEB_LOGIN_SUCCESS_URL}", status_code=302) + @router.get("/userinfo") async def userinfo(request: Request): - user = request.session.get('user') + user = request.session.get("user") if not user: data = await getAnonymousUser(request) - return { "data": data, "status": 200} - return { "data": user, "status": 200} + return {"data": data, "status": 200} + return {"data": user, "status": 200} + @router.get("/agreement/status") async def get_agreement_status(user_id: Optional[str] = Depends(get_user_id)): @@ -107,11 +124,14 @@ async def get_agreement_status(user_id: Optional[str] = Depends(get_user_id)): profiles_dao = ProfilesDAO() response = profiles_dao.get_agreement_status(user_id=user_id) if not response: - raise HTTPException(status_code=404, detail="User does not exist, accept failed.") + raise HTTPException( + status_code=404, detail="User does not exist, accept failed." + ) return {"success": True, "data": response} except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") + @router.post("/accept/agreement", status_code=200) async def bot_generator( request: Request, @@ -123,9 +143,27 @@ async def bot_generator( profiles_dao = ProfilesDAO() response = profiles_dao.accept_agreement(user_id=user_id) if response: - request.session['user'] = response + request.session["user"] = response return JSONResponse(content={"success": True}) else: raise HTTPException(status_code=400, detail="User update failed") except Exception as e: raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") + + +@router.get("/repos") +async def get_user_repos(user_id: Optional[str] = Depends(get_user_id)): + if not user_id: + raise HTTPException(status_code=401, detail="User not found") + try: + access_token = await getUserAccessToken(user_id=user_id) + g = Github(access_token) + user = g.get_user() + repos = user.get_repos() + + repo_names = [ + {"name": repo.full_name} for repo in repos if repo.permissions.maintain + ] + return {"data": repo_names, "status": 200} + except Exception as e: + raise HTTPException(status_code=500, detail=f"An error occurred: {str(e)}") From fa69b38fabcc272b7fc069853881b03867824e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BC=A8=E7=BC=A8?= Date: Thu, 12 Dec 2024 15:35:26 +0800 Subject: [PATCH 07/11] style: add the hover style for the bot delete button (#583) --- .../factory/edit/components/BotCreateForm.tsx | 11 +- client/app/globals.css | 6 + client/public/icons/DeleteButtonIcon.tsx | 108 ++++++++++++++++++ client/public/images/delete-button.svg | 38 ------ 4 files changed, 118 insertions(+), 45 deletions(-) create mode 100644 client/public/icons/DeleteButtonIcon.tsx delete mode 100644 client/public/images/delete-button.svg diff --git a/client/app/factory/edit/components/BotCreateForm.tsx b/client/app/factory/edit/components/BotCreateForm.tsx index 2033cd04..96da5fed 100644 --- a/client/app/factory/edit/components/BotCreateForm.tsx +++ b/client/app/factory/edit/components/BotCreateForm.tsx @@ -34,6 +34,7 @@ import { useRouter } from 'next/navigation'; import { useAvailableLLMs } from '@/app/hooks/useAvailableLLMs'; import { useTokenList } from '@/app/hooks/useToken'; import CreateButton from '@/app/user/tokens/components/CreateButton'; +import DeleteButtonIcon from '@/public/icons/DeleteButtonIcon'; const BotCreateFrom = () => { const { botProfile, setBotProfile } = useBot(); @@ -239,13 +240,9 @@ const BotCreateFrom = () => { - delete bot +
+ +
diff --git a/client/app/globals.css b/client/app/globals.css index 7fcd12ab..c8d69dc3 100644 --- a/client/app/globals.css +++ b/client/app/globals.css @@ -247,3 +247,9 @@ div.fp-watermark { } + .hover-reverse-colors:hover * { + stroke: #fff; + } + .hover-reverse-colors:hover { + fill: #DD1010; + } diff --git a/client/public/icons/DeleteButtonIcon.tsx b/client/public/icons/DeleteButtonIcon.tsx new file mode 100644 index 00000000..fcb014cf --- /dev/null +++ b/client/public/icons/DeleteButtonIcon.tsx @@ -0,0 +1,108 @@ +const DeleteButtonIcon = () => ( + + + + + + + + + + + + + + + + +); +export default DeleteButtonIcon; diff --git a/client/public/images/delete-button.svg b/client/public/images/delete-button.svg deleted file mode 100644 index 4838497e..00000000 --- a/client/public/images/delete-button.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file From dca4520301f9b792e9c3501a6d205c3b7470093a Mon Sep 17 00:00:00 2001 From: yingying Date: Thu, 12 Dec 2024 17:16:44 +0800 Subject: [PATCH 08/11] feat: enable org --- client/app/hooks/useBot.ts | 6 ++-- server/bot/router.py | 42 +++++++++++++++++--------- server/core/dao/repositoryConfigDAO.py | 16 +++++++++- server/github_app/utils.py | 13 -------- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/client/app/hooks/useBot.ts b/client/app/hooks/useBot.ts index 9232e939..bb986c80 100644 --- a/client/app/hooks/useBot.ts +++ b/client/app/hooks/useBot.ts @@ -34,7 +34,7 @@ export const useBotDetail = (id: string) => { }); }; -export const useGetBotBoundRepos =(id:string)=>{ +export const useGetBotBoundRepos = (id: string) => { return useQuery({ queryKey: [`bot.boundRepos.${id}`, id], queryFn: async () => getBotBoundRepos(id), @@ -42,7 +42,7 @@ export const useGetBotBoundRepos =(id:string)=>{ enabled: !!id, retry: false, }); -} +}; export const useBotConfig = (id: string, enabled: boolean) => { return useQuery({ @@ -153,7 +153,7 @@ export const useGetBotRagTask = ( queryKey: [`rag.task`, repoName], queryFn: async () => getRagTask(repoName), select: (data) => data, - enabled:!!repoName, + enabled: !!repoName, retry: true, refetchInterval: refetchInterval ? 3 * 1000 : undefined, }); diff --git a/server/bot/router.py b/server/bot/router.py index dad0793b..4518f28e 100644 --- a/server/bot/router.py +++ b/server/bot/router.py @@ -30,6 +30,7 @@ def get_bot_list( ), name: Optional[str] = Query(None, description="Filter bots by name"), user_id: Annotated[str | None, Depends(get_user_id)] = None, + user: Annotated[User | None, Depends(get_user)] = None, ): try: supabase = get_client() @@ -39,21 +40,35 @@ def get_bot_list( if personal == "true": if not user_id: return {"data": [], "personal": personal} - query = query.eq("uid", user_id).order("updated_at", desc=True) - if name: + + auth = Auth.Token(token=user.access_token) + g = Github(auth=auth) + github_user = g.get_user() + orgs = github_user.get_orgs() + repository_config_dao = RepositoryConfigDAO() + bots = repository_config_dao.query_by_owners( + [org.id for org in orgs] + [github_user.id] + ) + bot_ids = [bot["robot_id"] for bot in bots] + bot_ids_str = ",".join(map(str, bot_ids)) # 将 bots ID 列表转换为字符串 + or_clause = f"uid.eq.{user_id},id.in.({bot_ids_str})" + + # 添加过滤条件 query = ( - supabase.table("bots") - .select( - "id, created_at, updated_at, avatar, description, name, public, starters, uid, repo_name" - ) + query.or_(or_clause).order("updated_at", desc=True) + if not name + else query.or_(or_clause) .filter("name", "like", f"%{name}%") + .order("updated_at", desc=True) + ) + else: + query = ( + query.eq("public", True).order("updated_at", desc=True) + if not name + else query.eq("public", True) + .filter("name", "like", f"%{name}%") + .order("updated_at", desc=True) ) - - query = ( - query.eq("public", True).order("updated_at", desc=True) - if not personal or personal != "true" - else query - ) data = query.execute() if not data or not data.data: @@ -186,6 +201,7 @@ async def bot_generator( content={"success": False, "errorMessage": str(e)}, status_code=500 ) + @router.get("/git/avatar", status_code=200) async def get_git_avatar( repo_name: str, @@ -201,8 +217,6 @@ async def get_git_avatar( ) - - @router.put("/update/{id}", status_code=200) def update_bot( id: str, diff --git a/server/core/dao/repositoryConfigDAO.py b/server/core/dao/repositoryConfigDAO.py index b9c410fe..128a63f4 100644 --- a/server/core/dao/repositoryConfigDAO.py +++ b/server/core/dao/repositoryConfigDAO.py @@ -74,8 +74,22 @@ def query_by_owners(self, orgs: List[str]): try: response = ( self.client.table("github_repo_config") - .select("*") + .select("robot_id") + .filter("owner_id", "in", f"({','.join(map(str, orgs))})") + .execute() + ) + return response.data + except Exception as e: + print(f"Error: {e}") + return None + + def query_bot_id_by_owners(self, orgs: List[str]): + try: + response = ( + self.client.table("github_repo_config") + .select("robot_id") .filter("owner_id", "in", f"({','.join(map(str, orgs))})") + .filter("robot_id", "isnot", None) .execute() ) return response.data diff --git a/server/github_app/utils.py b/server/github_app/utils.py index 98e825eb..2b727fed 100644 --- a/server/github_app/utils.py +++ b/server/github_app/utils.py @@ -58,16 +58,3 @@ def get_installation_repositories(access_token: str): }, ) return resp.json() - - -def get_user_orgs(username, access_token: str): - url = f"https://api.github.com/users/{username}/orgs" - resp = requests.get( - url, - headers={ - "X-GitHub-Api-Version": "2022-11-28", - "Accept": "application/vnd.github+json", - "Authorization": f"Bearer {access_token}", - }, - ) - return resp.json() From c40bba1da6504a4890e3bc8a4abad3ec71597f2a Mon Sep 17 00:00:00 2001 From: yingying Date: Thu, 12 Dec 2024 17:23:22 +0800 Subject: [PATCH 09/11] chore: fix ci --- server/auth/router.py | 1 - 1 file changed, 1 deletion(-) diff --git a/server/auth/router.py b/server/auth/router.py index 7a7a3e8b..3d4e7305 100644 --- a/server/auth/router.py +++ b/server/auth/router.py @@ -1,4 +1,3 @@ -import json from github import Github from core.dao.profilesDAO import ProfilesDAO from fastapi import APIRouter, Request, HTTPException, status, Depends From 8b2bd31e45670ac249deffab27eadb98bdca4bff Mon Sep 17 00:00:00 2001 From: yingying Date: Thu, 12 Dec 2024 18:17:38 +0800 Subject: [PATCH 10/11] chore: fix cr --- server/bot/router.py | 16 ++++++++++------ server/bot/util.ts | 0 server/core/dao/repositoryConfigDAO.py | 3 +-- 3 files changed, 11 insertions(+), 8 deletions(-) delete mode 100644 server/bot/util.ts diff --git a/server/bot/router.py b/server/bot/router.py index 4518f28e..14fa3162 100644 --- a/server/bot/router.py +++ b/server/bot/router.py @@ -29,7 +29,6 @@ def get_bot_list( None, description="Filter bots by personal category" ), name: Optional[str] = Query(None, description="Filter bots by name"), - user_id: Annotated[str | None, Depends(get_user_id)] = None, user: Annotated[User | None, Depends(get_user)] = None, ): try: @@ -38,20 +37,25 @@ def get_bot_list( "id, created_at, updated_at, avatar, description, name, public, starters, uid, repo_name" ) if personal == "true": - if not user_id: + if not user or not user.access_token: return {"data": [], "personal": personal} - + user_id = user.id auth = Auth.Token(token=user.access_token) g = Github(auth=auth) github_user = g.get_user() orgs = github_user.get_orgs() repository_config_dao = RepositoryConfigDAO() - bots = repository_config_dao.query_by_owners( + bots = repository_config_dao.query_bot_id_by_owners( [org.id for org in orgs] + [github_user.id] ) - bot_ids = [bot["robot_id"] for bot in bots] + bot_ids = [bot["robot_id"] for bot in bots if bot["robot_id"]] bot_ids_str = ",".join(map(str, bot_ids)) # 将 bots ID 列表转换为字符串 - or_clause = f"uid.eq.{user_id},id.in.({bot_ids_str})" + + or_clause = ( + f"uid.eq.{user_id},id.in.({bot_ids_str})" + if bot_ids_str + else f"uid.eq.{user_id}" + ) # 添加过滤条件 query = ( diff --git a/server/bot/util.ts b/server/bot/util.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/server/core/dao/repositoryConfigDAO.py b/server/core/dao/repositoryConfigDAO.py index 128a63f4..e1f8f6d1 100644 --- a/server/core/dao/repositoryConfigDAO.py +++ b/server/core/dao/repositoryConfigDAO.py @@ -74,7 +74,7 @@ def query_by_owners(self, orgs: List[str]): try: response = ( self.client.table("github_repo_config") - .select("robot_id") + .select("*") .filter("owner_id", "in", f"({','.join(map(str, orgs))})") .execute() ) @@ -89,7 +89,6 @@ def query_bot_id_by_owners(self, orgs: List[str]): self.client.table("github_repo_config") .select("robot_id") .filter("owner_id", "in", f"({','.join(map(str, orgs))})") - .filter("robot_id", "isnot", None) .execute() ) return response.data From a1f80f67e8edb9e7d90bf033f8f4b2619c52bf32 Mon Sep 17 00:00:00 2001 From: yingying Date: Fri, 13 Dec 2024 16:20:09 +0800 Subject: [PATCH 11/11] refactor: fix cr --- server/bot/router.py | 48 ++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/server/bot/router.py b/server/bot/router.py index 14fa3162..00775b9e 100644 --- a/server/bot/router.py +++ b/server/bot/router.py @@ -36,48 +36,38 @@ def get_bot_list( query = supabase.table("bots").select( "id, created_at, updated_at, avatar, description, name, public, starters, uid, repo_name" ) + if personal == "true": if not user or not user.access_token: return {"data": [], "personal": personal} - user_id = user.id + auth = Auth.Token(token=user.access_token) - g = Github(auth=auth) - github_user = g.get_user() - orgs = github_user.get_orgs() + github_user = Github(auth=auth).get_user() + orgs_ids = [org.id for org in github_user.get_orgs()] + bot_ids = [] + repository_config_dao = RepositoryConfigDAO() bots = repository_config_dao.query_bot_id_by_owners( - [org.id for org in orgs] + [github_user.id] + orgs_ids + [github_user.id] ) - bot_ids = [bot["robot_id"] for bot in bots if bot["robot_id"]] - bot_ids_str = ",".join(map(str, bot_ids)) # 将 bots ID 列表转换为字符串 - or_clause = ( - f"uid.eq.{user_id},id.in.({bot_ids_str})" - if bot_ids_str - else f"uid.eq.{user_id}" - ) + if bots: + bot_ids = [bot["robot_id"] for bot in bots if bot["robot_id"]] - # 添加过滤条件 - query = ( - query.or_(or_clause).order("updated_at", desc=True) - if not name - else query.or_(or_clause) - .filter("name", "like", f"%{name}%") - .order("updated_at", desc=True) + or_clause = f"uid.eq.{user.id}" + ( + f",id.in.({','.join(map(str, bot_ids))})" if bot_ids else "" ) + query = query.or_(or_clause) else: - query = ( - query.eq("public", True).order("updated_at", desc=True) - if not name - else query.eq("public", True) - .filter("name", "like", f"%{name}%") - .order("updated_at", desc=True) - ) + query = query.eq("public", True) + if name: + query = query.filter("name", "like", f"%{name}%") + + query = query.order("updated_at", desc=True) data = query.execute() - if not data or not data.data: - return {"data": [], "personal": personal} - return {"data": data.data, "personal": personal} + + return {"data": data.data if data and data.data else [], "personal": personal} except Exception as e: return JSONResponse(