Add files via upload

This commit is contained in:
FURK4NGG
2026-05-12 13:45:20 +03:00
committed by GitHub
parent 68dd6df55a
commit b933752259
6 changed files with 7489 additions and 802 deletions
+2802 -121
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -82,8 +82,8 @@ sys.exit(1)
*)
echo "Usage:"
echo " capture-ai.sh image - Take a screenshot and start using it directly in the app"
echo " capture-ai.sh text - Start the app without an image (text mode)"
echo " capture-ai.sh cli - Run the app in terminal mode"
echo " capture-ai.sh image"
echo " capture-ai.sh text"
echo " capture-ai.sh cli"
;;
esac
+266
View File
@@ -0,0 +1,266 @@
{
"o_Toggle_Sidebar": "Show/Hide",
"o_Context_RAG": "RAG",
"o_Context_Direct": "Direct",
"o_Context_Mode": "RAG: uses summary, recent messages, code context, and relevant past chunks.\nDirect: sends only the current message and selected references.",
"o_Add_Model": "Add Model",
"o_Delete_Model": "Delete Model",
"o_Delete_Model_Confirm": "Do you want to delete this model?\n\n{model_id}",
"o_Min_Model_Title": "Model can't be deleted",
"o_Min_Model_Error": "At least one model must remain. You cannot delete the last model.",
"o_New_Chat": "New Chat",
"o_Options": "Options",
"o_Toggle_Dark_Mode": "Toggle Dark Mode",
"o_Settings": "Settings",
"o_Suggestions_Title": "Try asking something",
"o_Suggestion_1": "Tell me a joke",
"o_Suggestion_2": "Summarize this text",
"o_Suggestion_3": "Give me an idea for a project",
"o_Suggestion_4": "Explain a topic simply",
"o_Suggestion_5": "Help me write an email",
"o_Attachments": "Take photo, Attach file",
"o_Prompt_Chooser": "Prompt Chooser",
"o_PC_Copyable": "Copyable Content",
"o_PC_Apply": "Apply Changes to Files",
"o_PC_FileCreate": "Create New Files (DOCX / XLSX)",
"o_PC_WebSearch": "Web search",
"o_PC_Structured": "Structured Output",
"o_PC_Code": "Code Generation / Editing",
"o_PC_PDFText": "PDF Text",
"o_PC_PDFImage": "PDF Image",
"o_PC_PDFTextImage": "PDF Text + Image",
"o_PDF_Mode_Required": "You must select a PDF mode from the Prompt Chooser:\n- PDF Text\n- PDF Image\n- PDF Text + Image",
"o_PDF_Text_Edited": "PDF text was edited and the file was created.",
"o_PDF_Image_Edited": "PDF image was edited and converted to PDF.",
"o_PDF_Image_Block_Edited": "PDF image block was edited and the PDF was created.",
"o_PDF_Mixed_Edited": "Mixed PDF was edited and the file was created.",
"o_PDF_Convert_Failed": "PDF could not be converted to images. Check the PDF conversion setup.",
"o_PDF_Has_Text_Select_Text_Model": "This PDF contains extractable text. Please select PDF Text mode instead of PDF Image mode.",
"o_PDF_No_Images_Found": "No images were found in this PDF.",
"o_PDF_Text_Extract_Failed": "PDF text could not be extracted.\nDo not ask for the file path.\nUse OCR or PDF Image mode.",
"o_Microphone": "Dictate",
"o_Stop_Recording": "Stop Recording",
"o_Send_Button": "Send",
"o_Stop_Button": "Stop",
"o_Scroll_Left": "Scroll left",
"o_Scroll_Right": "Scroll right",
"o_Clear_Selection": "Clear selection",
"o_Image": "Image",
"o_Image_Could_Not_Be_Loaded": "Image could not be loaded:\n{path}",
"o_Zoom_Attachments": "Zoom in",
"o_Close_Attachments": "Close",
"o_Scroll_Down": "Scroll down",
"o_AI_Models": "AI Models",
"o_Chats": "Chats",
"o_Delete_Chat": "Delete chat",
"o_Delete_Chat_Confirm": "Do you want to delete this chat?\nThis action cannot be undone.",
"o_Rename": "Rename",
"o_New_Name": "New Name:",
"o_Rename_Hint": "(This will be used as the file name)",
"o_Pin": "Pin",
"o_Unpin": "Unpin",
"o_OpenRouter-Tavily_API_Key": "🔑 OpenRouter/Tavily Key",
"o_OpenRouter_API_Key": "🔑 OpenRouter API Key",
"o_Tavily_API_Key": "🔑 Tavily Key",
"o_Response_Style": "🧠 Response style",
"o_Personalization": "🎨 Personalization",
"o_Language": "🇬🇧 Language",
"o_RAG_Settings": "🧩 RAG Settings",
"o_AI_Settings": "🤖 Local AI Settings",
"o_STT_Settings": "🎙️ STT Settings",
"o_Input_Tokens": "Input tokens",
"o_Output_Tokens": "Output tokens",
"o_Total_Tokens": "Total",
"o_Copy": "Copy",
"o_Download": "Download",
"o_Image_Created": "Image created.",
"o_File_Saved": "File saved.",
"o_File_Not_Found": "File not found.",
"o_Thinking": "Thinking",
"o_Take_Photo": "Take Photo",
"o_Attach_File": "Attach File",
"o_Reference_Message": "message selected as reference",
"o_Apply": "Apply",
"o_Apply_Mode_replace": "Replacing",
"o_Apply_Mode_before": "Inserting before",
"o_Apply_Mode_after": "Inserting after",
"o_Reject": "Reject",
"o_Save": "Save",
"o_Cancel": "Cancel",
"o_Search": "Search",
"o_Web_Search_Request": "Web search request",
"o_Web_Searching": "Searching...",
"o_Web_Search_Searched": "Searched",
"o_Web_Search_Cancelled": "Web search cancelled",
"o_Web_Search_Request_With_Query": "AI wants to search the web:\n{query}",
"o_Web_Search_API_Key_Invalid": "Web search API key is invalid.",
"o_Web_Search_API_Error": "Web search API error ({status_code}).",
"o_Web_Search_Failed": "Search failed",
"o_Web_Search_Error_With_Detail": "Search failed: {error}",
"o_OK": "OK",
"o_Add": "Add",
"o_Delete": "Delete",
"o_File_Created": "File created.",
"o_File_Changed": "File modified",
"o_Cancelled": "Operation cancelled",
"o_Generation_Failed": "Failed to generate response",
"o_OpenRouter_Placeholder": "Enter OpenRouter API Key...",
"o_Tavily_Placeholder": "Enter Tavily API Key...",
"o_Response_Style_Placeholder": "Example: Speak in a friendly and humorous tone",
"o_Window_BG": "Window background",
"o_Input_BG": "Input background",
"o_User_BG": "User bubble background",
"o_User_Text": "User text color",
"o_Bot_BG": "Bot bubble background",
"o_Bot_Text": "Bot text color",
"o_Sidebar_Text": "Sidebar text color",
"o_Local_Model_Color": "Local model highlight color",
"o_Token_Usage": "Token Usage",
"o_Use_Token_Value": "Show Token Value",
"o_Token_Value": "Token Value",
"o_Token_Value_Hint": "Price per 1M tokens",
"o_Total_Token_Price": "Total Token Price",
"o_Color_Edit_Hint": "You are editing {mode_name} colors.\nUse hex format: e.g. #303643",
"o_Background_Hint": "Chat Background Image",
"o_Background_Path_Placeholder": "/file-path/photo.png",
"o_Clear": "Clear",
"o_Select_Image": "Select Image",
"o_Reset_Default": "Reset to default",
"o_RAG_Recent_Count": "Recent message count",
"o_RAG_Recent_Count_Hint": "Number of recent conversation messages sent to the model in RAG mode.",
"o_RAG_Retrieved_Count": "Relevant old message count",
"o_RAG_Retrieved_Count_Hint": "Number of relevant old chunks retrieved from previous conversation.",
"o_RAG_Summary_Every": "Summary update interval",
"o_RAG_Summary_Every_Hint": "How often the conversation summary is updated.",
"o_RAG_Memory_Chunk_Max": "Memory chunk max length",
"o_RAG_Memory_Chunk_Max_Hint": "Maximum character length of a single saved memory chunk.",
"o_RAG_Summary_Max": "Summary max length",
"o_RAG_Summary_Max_Hint": "Maximum character length of the conversation summary.",
"o_RAG_Code_Context_Max": "Code context max length",
"o_RAG_Code_Context_Max_Hint": "Maximum character length of code context sent to the model.",
"o_RAG_Use_Summary": "Use summary",
"o_RAG_Use_Summary_Hint": "Adds the conversation summary to the context when enabled.",
"o_RAG_Use_Recent": "Use recent messages",
"o_RAG_Use_Recent_Hint": "Adds recent messages to the context when enabled.",
"o_RAG_Use_Retrieval": "Use relevant old messages",
"o_RAG_Use_Retrieval_Hint": "Retrieves relevant old chunks from previous conversation when enabled.",
"o_RAG_Use_Code_Context": "Use code context",
"o_RAG_Use_Code_Context_Hint": "Adds summaries of attached code files to the context when enabled.",
"o_RAG_Recent_Attachments": "Send attachments in recent messages",
"o_RAG_Recent_Attachments_Hint": "When disabled, only text from recent messages is sent; old files/images are not resent.",
"o_Force_Language_Text": "Use UI Language for Responses",
"o_Force_Language_Hint": "AI should always respond in the selected language.",
"o_Ask_Web_Search": "Ask before web search",
"o_Ask_Web_Search_Hint": "The AI must ask for your permission before it performs a web search.",
"o_AI_Providers": "AI Providers",
"o_Selected_Provider": "Selected Provider",
"o_Add_Provider": "Add Provider",
"o_Stop_Provider": "Stop Provider",
"o_Provider_Cant_Be_Deleted": "Provider can't be deleted",
"o_Provider_Min_One_Required": "At least one provider must remain.",
"o_Delete_Provider": "Delete Provider",
"o_Delete_Provider_Confirm": "Do you want to delete this provider?\n\n{provider}",
"o_Provider_Name": "Provider Name",
"o_Enable_Provider": "Enable Provider",
"o_Enable_Provider_Hint": "Enable this AI provider for local models.",
"o_Run_Startup": "Run Startup",
"o_Run_Startup_Placeholder": "Enter a command or a script path to start the provider.",
"o_Stop_Command": "Stop Command",
"o_Stop_Command_Placeholder": "Exp: pkill -f 'ollama serve'",
"o_Custom_Error": "Custom Error Message",
"o_Custom_Error_Placeholder": "Write a custom error message that will be displayed if the provider cannot respond.",
"o_System_Prompt": "System Prompt",
"o_Online_STT_Text": "Online STT",
"o_Online_STT_Hint": "If enabled, speech-to-text is processed via OpenRouter.",
"o_Use_Desktop_Audio_Text": "Use Desktop Audio",
"o_Use_Desktop_Audio_Hint": "If enabled, system audio will be recorded instead of the microphone.",
"o_Online_STT_Model": "Online STT Model",
"o_Binary_Path": "Binary Path",
"o_Model_Path": "Model Path",
"o_Active_Chat": "Active Chat",
"o_Active_Model": "Active Model",
"o_Pending_Attachments": "Pending attachments",
"o_image": "image",
"o_file": "file",
"o_Pin_Current_Chat": "Pin Current Chat",
"o_Unpin_Current_Chat": "Unpin Current Chat",
"o_Send_Message": "Send Message",
"o_sub_Send_Message": "Type your message. Press Enter on an empty line to finish.",
"o_Empty_Message": "Empty message was not sent.",
"o_AI_Response": "Sent. Waiting for AI response...",
"o_Drag_Drop": "Enter a file path or drag and drop the file",
"o_to_Menu": "Press Enter to return to the menu...",
"o_Empty_Input": "You cannot enter an empty value.",
"o_Type_ESC": "To cancel, type “esc” on the first line and press Enter.",
"o_Press_ESC": "You can cancel the selection by pressing ESC.",
"o_Change_Chat": "Change Chat",
"o_Rename_Chat": "Chat to be renamed",
"o_New_Value": "Please enter a new value:",
"o_Chat_Rename_Fail": "The new name must be different from the current name.",
"o_AI_Model": "AI Model",
"o_Change_AI_Model": "Change AI Model",
"o_Available_Languages": "Available languages",
"o_Language_Select_Hint": "You can choose one of the language codes below.",
"o_Invalid_Language_Code": "Invalid language code. This language was not found in the config.",
"o_Saved": "Saved",
"o_Go_Back": "Go Back",
"o_Exit": "Exit",
"o_Selection": "Selection",
"o_Error": "Error",
"o_Timeout": "Timeout",
"o_Failed": "Failed",
"o_Error_With_Detail": "❌ Error:\n{error}",
"o_Config_Not_Found": "Config file not found.",
"o_Config_Read_Error": "Config could not be read: {error}",
"o_Chat_Read_Error": "Chat could not be read: {error}",
"o_OpenRouter_Key_Missing": "OpenRouter API Key not found.",
"o_Invalid_Local_Model_Format": "Invalid local model format: {model}. Expected: provider/model",
"o_Local_Provider_Not_Found": "Local provider not found: {provider}",
"o_Local_Provider_Disabled": "Local provider is disabled: {provider}",
"o_Unsupported_Local_Provider": "Unsupported local provider: {provider}",
"o_OpenRouter_API_Error": "OpenRouter API error ({status_code}): {details}",
"o_OpenRouter_Empty_Stream": "OpenRouter returned an empty stream.",
"o_Request_Timeout": "The request timed out.",
"o_Internet_Connection_Error": "Connection error. Check your internet connection.",
"o_Local_Connection_Error": "{provider} connection error.\nThe local AI server could not be reached.\nExpected address: {base_url}\nThe {provider} server may not be running.",
"o_Ollama_API_Error": "Ollama API error ({status_code}): {details}",
"o_Ollama_JSON_Parse_Error": "Ollama JSON parse error: {error}",
"o_Ollama_Empty_Response": "Ollama returned an empty response.",
"o_Script_Not_Found": "Script not found: {path}",
"o_Photo_Capture_Error": "Photo capture error: {error}",
"o_STT_Error": "STT error: {error}",
"o_No_Speech_Detected": "No speech detected.",
"o_OpenRouter_STT_Key_Missing": "open_router_key is missing",
"o_Whisper_Bin_Not_Found": "whisper_cpp_bin not found: {path}",
"o_Whisper_Model_Not_Found": "whisper_cpp_model not found: {path}",
"o_Whisper_Failed": "whisper.cpp failed",
"o_Desktop_Audio_Monitor_Not_Found": "Monitor source for desktop audio was not found.",
"o_Microphone_Source_Not_Found": "Microphone source was not found.",
"o_Desktop_Audio_Requires_PWRecord": "pw-record is required for desktop audio capture.",
"o_Microphone_Device_Not_Found": "Microphone device was not found.",
"o_Audio_Recorder_Not_Found": "pw-record or arecord was not found.",
"o_Audio_Record_Start_Failed": "Audio recording could not be started: {error}",
"o_Unknown_Error": "unknown error",
"o_Apply_Failed_Input": "❌ APPLY FAILED: {error}",
"o_Apply_No_Ops": "no ops to apply",
"o_Apply_File_Not_Found": "file not found: {path}",
"o_Apply_Find_Failed": "find failed: anchor not found in {name}",
"o_Apply_Unknown_Mode": "unknown mode: {mode}",
"o_Apply_No_Changes": "no changes produced (maybe identical content?)",
"o_Apply_Exception": "exception: {error}",
"o_Provider_Command_No_Command": "{provider}\n\nNo command is set.",
"o_Provider_Command_Timeout": "{provider}\n\nCommand timed out:\n{command}",
"o_Provider_Command_Error": "{provider}\n\n{error}",
"o_Provider_Command_Success": "{provider}\n\nCommand executed successfully.\n\n{command}",
"o_Provider_Command_Failed": "{provider}\n\nCommand failed.\n\n{command}\n\nExit code: {code}",
"o_Start_Local_Server_From_App": "Start the local server from the {provider} app.",
"o_Base_System_Prompt": "This message is a set of instructions.\nDo not respond to this message.\nOnly respond to user messages.\nOnly respond to the most recent user message.",
"o_Prompt_Copyable": "In this conversation, you may be asked to generate emails, code, commands, configuration files, or text that needs to be copied exactly.\n\nFORMAT RULE:\nIf the user's request requires generating directly copyable content (such as code, scripts, terminal commands, configuration files, etc.), use the following format:\n\ntitle\n<short and descriptive title>\ntitle\ncopy\n<code or copyable content>\ncopy\n\nRules:\n- The words 'title' and 'copy' must be on their own lines.\n- The 'title' block must appear before the code block.\n- Do not use this format if there is no code.\n- Do not use this format in normal conversational responses.\n- Only use this format when the content is genuinely meant to be copied.",
"o_Prompt_Apply": "[FILE] BLOCKS:\n- If the user has attached a file, its content is already provided in this message in the format [FILE] ... [CONTENT] ... [/CONTENT].\n- Do not ask the user to paste code or re-upload the file.\n- If changes are required, read and operate on the [CONTENT].\n- Do not request the file content again.\n- Use the path value exactly as provided in the [FILE] block.\n\nFILE MODIFICATION RULE:\n- If 'editable: true', you may suggest modifications.\n- If 'editable: false', NEVER suggest changes.\n- Do not generate an apply block for editable:false files.\n- If no changes are needed, do not generate an apply block.\n\nAPPLY (AUTOMATIC PATCH) PROTOCOL:\nIf and only if the user requests changes to an editable:true file,\nappend the following block at the END of your response:\n\napply\n[\n {\n \"path\": \"/absolute/path/to/file\",\n \"find\": \"EXACT ANCHOR TEXT FOUND IN FILE\",\n \"mode\": \"before|after|replace\",\n \"text\": \"TEXT TO INSERT OR REPLACE\"\n }\n]\napply\n\nRules:\n- The apply block must contain ONLY JSON.\n- mode must be one of: before, after, replace.\n- path MUST be an absolute path.\n- find must be a short/medium anchor that exists exactly in the file.\n\nAPPLY SUMMARY LINE RULE:\n- If you generate an apply block, NEVER use definitive/finished statements.\n- Write exactly ONE summary line before the apply block.",
"o_Prompt_File_Create": "[FILE] BLOCKS:\n- If previous assistant messages contain a [GENERATED_FILES] block, and the user refers to 'the last file', 'the file you created', etc., use those path values.\n- Do not ask the user to upload the file again.\n- If file content is already provided in a [FILE] block, do not request it again.\n\nFILE_CREATE PROTOCOL:\nIf the user wants to edit an editable:true DOCX, XLSX, or text-based file and receive it as a new file, append the following block at the END of your response:\n\nfile_create\n[\n {\n \"source_path\": \"/absolute/path/to/source.docx\",\n \"format\": \"docx\",\n \"output_name\": \"edited-file.docx\",\n \"content\": \"New file content\"\n }\n]\nfile_create\n\nRules:\n- Do not include explanations outside JSON.\n- format must be one of: docx, xlsx, txt, md.\n- For DOCX, content must be plain text.\n- For XLSX, content must be a JSON table or supported operation object.\n- The content must be a 2D JSON array whenever possible.\n- Each inner array represents one row in Excel.\n- Avoid rewriting large XLSX files row by row.\n- Do not wrap the entire table inside one row.\n- Each row must be separate.",
"o_Prompt_Web_Search": "If current or unknown information is needed, do not answer normally. Instead, return only this JSON format:\n{\"tool\":\"web_search\",\"query\":\"search query\"}\n\nRules:\n- Use this only when current information is really needed.\n- Use it for match scores, current prices, latest news, new versions, today's information, etc.\n- If web results are provided to you, answer normally using only those results.\n- When web search results are provided, include a short 'Sources' section at the end of your answer. Use the source titles and URLs exactly as provided. Do not invent sources.\n- When web search results are used, write source URLs as full https:// links.",
"o_Prompt_Structured": "When needed, provide responses in a clean, structured, and parseable format. If JSON is requested, return only valid JSON.",
"o_Prompt_Code": "When writing code, produce clean, directly usable code without unnecessary explanation. If modifying existing code, preserve the original structure as much as possible.",
"o_Prompt_PDF_Text_Only_To_DOCX_Rule": "PDF TEXT REWRITE RULE:\nThe PDF text is already provided inside [CONTENT].\nDo not request file paths.\nDo not ask the user to upload the file again.\n\nRules:\n- Do not generate images.\n- Do not use HTML, markdown, or image placeholders.\n- Output plain text only.\n- Rewrite according to the request while preserving meaning.\n- Do not invent new content.\n\nReturn ONLY in file_create DOCX format:\nfile_create\n[\n {\n \"source_path\": \"/absolute/path/to/source.pdf\",\n \"format\": \"docx\",\n \"output_name\": \"edited-document.docx\",\n \"content\": \"Final rewritten text\"\n }\n]\nfile_create",
"o_Prompt_PDF_Mixed_Text_Only_Rule": "PDF MIXED TEXT-ONLY RULE:\nThe PDF contains both text and images, but only text should be modified.\nDo not modify images.\n\nRules:\n- Rewrite text only.\n- Do not invent new content.\n- Do not modify images.\n\nReturn ONLY JSON:\n{\n \"type\": \"pdf_mixed_rewrite\",\n \"content\": \"File created.\",\n \"text_replacements\": {\n \"TEXT_BLOCK_ID\": \"new text\"\n },\n \"image_replacements\": {}\n}"
}
+266
View File
@@ -0,0 +1,266 @@
{
"o_Toggle_Sidebar": "Göster/Gizle",
"o_Context_RAG": "RAG",
"o_Context_Direct": "Direkt",
"o_Context_Mode": "RAG: özet + son mesajlar + kod bağlamı + ilgili eski konuşmalar.\nDirekt: sadece mevcut mesaj ve seçili referanslar gönderilir.",
"o_Add_Model": "Model Ekle",
"o_Delete_Model": "Modeli Sil",
"o_Delete_Model_Confirm": "Bu modeli silmek istiyor musun?\n\n{model_id}",
"o_Min_Model_Title": "Model Silinemez",
"o_Min_Model_Error": "En az 1 model kalmalı. Son modeli silemezsin.",
"o_New_Chat": "Yeni Sohbet",
"o_Options": "Seçenekler",
"o_Toggle_Dark_Mode": "Karanlık Modu Tetikle",
"o_Settings": "Ayarlar",
"o_Suggestions_Title": "Bir şey sormayı dene",
"o_Suggestion_1": "Bana bir fıkra anlat",
"o_Suggestion_2": "Bu metni özetle",
"o_Suggestion_3": "Bana bir proje fikri ver",
"o_Suggestion_4": "Bir konuyu basitçe anlat",
"o_Suggestion_5": "E-posta yazmama yardım et",
"o_Attachments": "Fotoğraf çek, Dosya ekle",
"o_Prompt_Chooser": "Girdi Seçici",
"o_PC_Copyable": "Kopyalanabilir İçerik",
"o_PC_Apply": "Dosyada Değişiklik",
"o_PC_FileCreate": "Yeni Dosya Oluştur (DOCX / XLSX)",
"o_PC_WebSearch": "Ağ araması",
"o_PC_Structured": "Yapılandırılmış Çıktı",
"o_PC_Code": "Kod Üretimi / Düzenleme",
"o_PC_PDFText": "PDF Yazı",
"o_PC_PDFImage": "PDF Resim",
"o_PC_PDFTextImage": "PDF Yazı + Resim",
"o_PDF_Mode_Required": "PDF düzenleme için Prompt Chooser içinden bir PDF modu seçmelisin:\n- PDF Yazı\n- PDF Resim\n- PDF Yazı + Resim",
"o_PDF_Text_Edited": "PDF metni düzenlendi ve dosya oluşturuldu.",
"o_PDF_Image_Edited": "PDF görseli düzenlendi ve PDF olarak oluşturuldu.",
"o_PDF_Image_Block_Edited": "PDF görsel bloğu düzenlendi ve PDF oluşturuldu.",
"o_PDF_Mixed_Edited": "Karışık PDF düzenlendi ve dosya oluşturuldu.",
"o_PDF_Convert_Failed": "PDF görsellere dönüştürülemedi. PDF dönüştürme kurulumunu kontrol et.",
"o_PDF_Has_Text_Select_Text_Model": "Bu PDF çıkarılabilir metin içeriyor. PDF Image modu yerine PDF Text modunu seç.",
"o_PDF_No_Images_Found": "Bu PDF içinde görsel bulunamadı.",
"o_PDF_Text_Extract_Failed": "PDF metni çıkarılamadı.\nDosya yolunu isteme.\nOCR veya PDF Image modunu kullan.",
"o_Microphone": "Dikte et",
"o_Stop_Recording": "Kaydı Durdur",
"o_Send_Button": "Gönder",
"o_Stop_Button": "Durdur",
"o_Scroll_Left": "Sola kaydır",
"o_Scroll_Right": "Sağa kaydır",
"o_Clear_Selection": "Seçimi temizle",
"o_Image": "Görsel",
"o_Image_Could_Not_Be_Loaded": "Görsel yüklenemedi:\n{path}",
"o_Zoom_Attachments": "Yakınlaştır",
"o_Close_Attachments": "Kapat",
"o_Scroll_Down": "Aşağı kaydır",
"o_AI_Models": "AI Modelleri",
"o_Chats": "Sohbetler",
"o_Delete_Chat": "Sohbeti Sil",
"o_Delete_Chat_Confirm": "Bu sohbeti silmek istiyor musun?\n\nBu işlem geri alınamaz.",
"o_Rename": "İsim'i Değiştir",
"o_New_Name": "Yeni İsim:",
"o_Rename_Hint": "(Dosya adı olarak kaydedilir)",
"o_Pin": "Sabitle",
"o_Unpin": "Sabiti Kaldır",
"o_OpenRouter-Tavily_API_Key": "🔑 OpenRouter/Tavily Anahtarı",
"o_OpenRouter_API_Key": "🔑 OpenRouter Anahtarı",
"o_Tavily_API_Key": "🔑 Tavily Anahtarı",
"o_Response_Style": "🧠 Cevap Tarzı",
"o_Personalization": "🎨 Kişiselleştirme",
"o_Language": "🇹🇷 Dil",
"o_RAG_Settings": "🧩 RAG Ayarları",
"o_AI_Settings": "🤖 Yerel AI Ayarları",
"o_STT_Settings": "🎙️ STT Ayarları",
"o_Input_Tokens": "Girdi token",
"o_Output_Tokens": "Çıktı token",
"o_Total_Tokens": "Toplam",
"o_Copy": "Kopyala",
"o_Download": "İndir",
"o_Image_Created": "Görsel oluşturuldu.",
"o_File_Saved": "Dosya kaydedildi.",
"o_File_Not_Found": "Dosya bulunamadı.",
"o_Thinking": "Düşünüyor",
"o_Take_Photo": "Fotoğraf Çek",
"o_Attach_File": "Belge Ekle",
"o_Reference_Message": "mesaj referans seçildi",
"o_Apply": "Uygula",
"o_Apply_Mode_replace": "Bu satırı değiştiriyorum",
"o_Apply_Mode_before": "Bu satırın öncesine ekliyorum",
"o_Apply_Mode_after": "Bu satırın sonrasına ekliyorum",
"o_Reject": "Reddet",
"o_Save": "Kaydet",
"o_Cancel": "İptal",
"o_Search": "Ara",
"o_Web_Search_Request": "Ağ araması isteği",
"o_Web_Searching": "Aranıyor...",
"o_Web_Search_Searched": "Arandı",
"o_Web_Search_Cancelled": "Ağ araması iptal edildi",
"o_Web_Search_Request_With_Query": "AI ağda arama yapmak istiyor:\n{query}",
"o_Web_Search_API_Key_Invalid": "Web arama API anahtarı geçersiz.",
"o_Web_Search_API_Error": "Web arama API hatası ({status_code}).",
"o_Web_Search_Failed": "Arama başarısız",
"o_Web_Search_Error_With_Detail": "Arama başarısız: {error}",
"o_OK": "Tamam",
"o_Add": "Ekle",
"o_Delete": "Sil",
"o_File_Created": "Dosya oluşturuldu.",
"o_File_Changed": "Dosya değiştirildi",
"o_Cancelled": "İşlem iptal edildi",
"o_Generation_Failed": "Yanıt oluşturulamadı",
"o_OpenRouter_Placeholder": "OpenRouter API Anahtarı girin...",
"o_Tavily_Placeholder": "Tavily API Anahtarı girin...",
"o_Response_Style_Placeholder": "Örn: Samimi ve esprili konuş",
"o_Window_BG": "Genel arkaplan",
"o_Input_BG": "Input arkaplan",
"o_User_BG": "Kullanıcı balon arkaplan",
"o_User_Text": "Kullanıcı yazı rengi",
"o_Bot_BG": "Bot balon arkaplan",
"o_Bot_Text": "Bot yazı rengi",
"o_Sidebar_Text": "Sidebar yazı rengi",
"o_Local_Model_Color": "Yerel model vurgulama rengi",
"o_Token_Usage": "Jeton Kullanımı",
"o_Use_Token_Value": "Token Değerini Göster",
"o_Token_Value": "Token Değeri",
"o_Token_Value_Hint": "1M token başına ücret",
"o_Total_Token_Price": "Toplam Token Ücreti",
"o_Color_Edit_Hint": "Şu anda {mode_name} renklerini düzenliyorsun.\nHex formatı kullan: örn #303643",
"o_Background_Hint": "Sohbet Arkaplan Resmi",
"o_Background_Path_Placeholder": "/dosya-yolu/resim.png",
"o_Clear": "Temizle",
"o_Select_Image": "Resim Seç",
"o_Reset_Default": "Varsayılana dön",
"o_RAG_Recent_Count": "Son mesaj sayısı",
"o_RAG_Recent_Count_Hint": "RAG modunda modele gönderilecek son konuşma mesajı sayısı.",
"o_RAG_Retrieved_Count": "İlgili eski mesaj sayısı",
"o_RAG_Retrieved_Count_Hint": "Eski konuşmalardan çekilecek alakalı parça sayısı.",
"o_RAG_Summary_Every": "Özet güncelleme aralığı",
"o_RAG_Summary_Every_Hint": "Kaç mesajda bir konuşma özeti güncellensin.",
"o_RAG_Memory_Chunk_Max": "Memory parçası maksimum uzunluğu",
"o_RAG_Memory_Chunk_Max_Hint": "Memory içine kaydedilecek tek parçanın maksimum karakter sayısı.",
"o_RAG_Summary_Max": "Özet maksimum uzunluğu",
"o_RAG_Summary_Max_Hint": "Konuşma özetinin maksimum karakter sayısı.",
"o_RAG_Code_Context_Max": "Kod bağlamı maksimum uzunluğu",
"o_RAG_Code_Context_Max_Hint": "Kod dosyası özetlerinin modele gönderilecek maksimum karakter sayısı.",
"o_RAG_Use_Summary": "Özet kullan",
"o_RAG_Use_Summary_Hint": "Açık olursa konuşma özeti bağlama eklenir.",
"o_RAG_Use_Recent": "Son mesajları kullan",
"o_RAG_Use_Recent_Hint": "Açık olursa son mesajlar bağlama eklenir.",
"o_RAG_Use_Retrieval": "Eski alakalı mesajları kullan",
"o_RAG_Use_Retrieval_Hint": "Açık olursa eski konuşmalardan alakalı parçalar çekilir.",
"o_RAG_Use_Code_Context": "Kod bağlamı kullan",
"o_RAG_Use_Code_Context_Hint": "Açık olursa eklenen kod dosyalarının özeti bağlama eklenir.",
"o_RAG_Recent_Attachments": "Son mesajlardaki dosyaları gönder",
"o_RAG_Recent_Attachments_Hint": "Kapalı olursa son mesajların sadece yazıları gider; eski dosya/resimler tekrar gönderilmez.",
"o_Force_Language_Text": "Yanıtlar için Arayüz Dilini Kullan",
"o_Force_Language_Hint": "AI her zaman seçili dilde cevap versin.",
"o_Ask_Web_Search": "Ağ aramasından önce sor",
"o_Ask_Web_Search_Hint": "AI, ağ araması yapmadan önce kullanıcıdan izin almak zorunda olsun.",
"o_AI_Providers": "AI Sağlayıcıları",
"o_Selected_Provider": "Seçili Sağlayıcı",
"o_Add_Provider": "Sağlayıcı Ekle",
"o_Stop_Provider": "Sağlayıcıyı Durdur",
"o_Provider_Cant_Be_Deleted": "Sağlayıcı silinemez",
"o_Provider_Min_One_Required": "En az bir sağlayıcı kalmalı.",
"o_Delete_Provider": "Sağlayıcıyı Sil",
"o_Delete_Provider_Confirm": "Bu sağlayıcı silinsin mi?\n\n{provider}",
"o_Provider_Name": "Sağlayıcı Adı",
"o_Enable_Provider": "Sağlayıcıyı Etkinleştir",
"o_Enable_Provider_Hint": "Bu sağlayıcıyı yerel modeller için aç.",
"o_Run_Startup": "Başlatma Komutu",
"o_Run_Startup_Placeholder": "Sağlayıcıyı başlatmak için komut veya script gir.",
"o_Stop_Command": "Durdurma Komutu",
"o_Stop_Command_Placeholder": "Örn: pkill -f 'ollama serve'",
"o_Custom_Error": "Özel Hata Mesajı",
"o_Custom_Error_Placeholder": "Sağlayıcı hata verirse gösterilecek mesajı yaz.",
"o_System_Prompt": "Sistem Mesajı",
"o_Online_STT_Text": "Çevrimiçi STT",
"o_Online_STT_Hint": "Açık ise OpenRouter üzerinden speech-to-text kullanılır.",
"o_Use_Desktop_Audio_Text": "Masaüstü Sesi Kullan",
"o_Use_Desktop_Audio_Hint": "Açık ise mikrofon yerine masaüstünde çalan ses kaydedilmeye çalışılır.",
"o_Online_STT_Model": "Çevrimiçi STT Model",
"o_Binary_Path": "Çalıştırılabilir Dosya Yolu",
"o_Model_Path": "Model Dosya Yolu",
"o_Active_Chat": "Aktif Sohbet",
"o_Active_Model": "Aktif Model",
"o_Pending_Attachments": "Bekleyen ekler",
"o_image": "görüntü",
"o_file": "dosya",
"o_Pin_Current_Chat": "Mevcut Sohbeti Sabitle",
"o_Unpin_Current_Chat": "Mevcut Sohbetin Sabitini Kaldır",
"o_Send_Message": "Mesaj Gönder",
"o_sub_Send_Message": "Mesajını yaz. Bitirmek için boş satır + Enter yap.",
"o_Empty_Message": "Boş mesaj gönderilmedi.",
"o_AI_Response": "Gönderildi. AI yanıtı bekleniyor...",
"o_Drag_Drop": "Dosya yolu girin veya dosyayı sürükleyip bırakın",
"o_to_Menu": "Menüye dönmek için Enter...",
"o_Empty_Input": "Boş veri giremezsiniz.",
"o_Type_ESC": "İptal etmek için ilk satıra esc yazıp Enter'a bas.",
"o_Press_ESC": "ESC ile seçimi iptal edebilirsiniz.",
"o_Change_Chat": "Sohbeti Değiştir",
"o_Rename_Chat": "İsmi değişecek chat",
"o_New_Value": "Yeni değeri girin:",
"o_Chat_Rename_Fail": "Yeni isim mevcut isimden farklı olmalıdır.",
"o_AI_Model": "AI Modeli",
"o_Change_AI_Model": "AI Modelini Değiştir",
"o_Available_Languages": "Kullanılabilir diller",
"o_Language_Select_Hint": "Aşağıdaki dil kodlarından birini seçebilirsiniz.",
"o_Invalid_Language_Code": "Geçersiz dil kodu. Bu dil config içinde bulunamadı.",
"o_Saved": "Kaydedildi",
"o_Go_Back": "Geri Dön",
"o_Exit": "Çıkış",
"o_Selection": "Seçim",
"o_Error": "Hata",
"o_Timeout": "Zaman Aşımı",
"o_Failed": "Başarısız",
"o_Error_With_Detail": "❌ Hata:\n{error}",
"o_Config_Not_Found": "Config dosyası bulunamadı.",
"o_Config_Read_Error": "Config okunamadı: {error}",
"o_Chat_Read_Error": "Chat okunamadı: {error}",
"o_OpenRouter_Key_Missing": "OpenRouter API Key bulunamadı.",
"o_Invalid_Local_Model_Format": "Geçersiz local model formatı: {model}. Beklenen: provider/model",
"o_Local_Provider_Not_Found": "Local provider bulunamadı: {provider}",
"o_Local_Provider_Disabled": "Local provider devre dışı: {provider}",
"o_Unsupported_Local_Provider": "Desteklenmeyen local provider: {provider}",
"o_OpenRouter_API_Error": "OpenRouter API hatası ({status_code}): {details}",
"o_OpenRouter_Empty_Stream": "OpenRouter boş stream döndürdü.",
"o_Request_Timeout": "İstek zaman aşımına uğradı (timeout).",
"o_Internet_Connection_Error": "Bağlantı hatası. İnternet bağlantınızı kontrol edin.",
"o_Local_Connection_Error": "{provider} bağlantı hatası.\nLocal AI sunucusuna ulaşılamadı.\nBeklenen adres: {base_url}\n{provider} server çalışmıyor olabilir.",
"o_Ollama_API_Error": "Ollama API hatası ({status_code}): {details}",
"o_Ollama_JSON_Parse_Error": "Ollama JSON parse hatası: {error}",
"o_Ollama_Empty_Response": "Ollama boş cevap döndürdü.",
"o_Script_Not_Found": "Script bulunamadı: {path}",
"o_Photo_Capture_Error": "Fotoğraf çekme hatası: {error}",
"o_STT_Error": "STT hata: {error}",
"o_No_Speech_Detected": "Ses algılanamadı.",
"o_OpenRouter_STT_Key_Missing": "open_router_key yok",
"o_Whisper_Bin_Not_Found": "whisper_cpp_bin bulunamadı: {path}",
"o_Whisper_Model_Not_Found": "whisper_cpp_model bulunamadı: {path}",
"o_Whisper_Failed": "whisper.cpp failed",
"o_Desktop_Audio_Monitor_Not_Found": "Masaüstü sesi için monitor source bulunamadı.",
"o_Microphone_Source_Not_Found": "Mikrofon kaynağı bulunamadı.",
"o_Desktop_Audio_Requires_PWRecord": "Masaüstü sesi kaydı için pw-record gerekli.",
"o_Microphone_Device_Not_Found": "Mikrofon cihazı bulunamadı.",
"o_Audio_Recorder_Not_Found": "pw-record veya arecord bulunamadı.",
"o_Audio_Record_Start_Failed": "Ses kaydı başlatılamadı: {error}",
"o_Unknown_Error": "Bilinmeyen hata",
"o_Apply_Failed_Input": "❌ Uygulama başarısız: {error}",
"o_Apply_No_Ops": "Uygulanacak işlem yok",
"o_Apply_File_Not_Found": "Dosya bulunamadı: {path}",
"o_Apply_Find_Failed": "Bulma başarısız: {name} içinde referans bulunamadı",
"o_Apply_Unknown_Mode": "Bilinmeyen mod: {mode}",
"o_Apply_No_Changes": "Herhangi bir değişiklik yapılmadı (içerik aynı olabilir)",
"o_Apply_Exception": "Hata oluştu: {error}",
"o_Provider_Command_No_Command": "{provider}\n\nKomut ayarlanmamış.",
"o_Provider_Command_Timeout": "{provider}\n\nKomut zaman aşımına uğradı:\n{command}",
"o_Provider_Command_Error": "{provider}\n\n{error}",
"o_Provider_Command_Success": "{provider}\n\nKomut başarıyla çalıştırıldı.\n\n{command}",
"o_Provider_Command_Failed": "{provider}\n\nKomut başarısız oldu.\n\n{command}\n\nÇıkış kodu: {code}",
"o_Start_Local_Server_From_App": "{provider} uygulamasından local server başlatın.",
"o_Base_System_Prompt": "Bu mesaj bir talimat setidir.\nBu mesaja cevap verme.\nSadece kullanıcı mesajlarına cevap ver.\nSadece en son kullanıcı mesajını yanıtla.",
"o_Prompt_Copyable": "Bu konuşmada sana zaman zaman e-posta, kod, komut, yapılandırma dosyası veya birebir kopyalanması gereken metinler yazdırılabilir.\n\nFORMAT KURALI:\nEğer kullanıcıdan gelen istekte doğrudan kopyalanabilir bir içerik (örneğin kod, script, terminal komutu, yapılandırma dosyası vb.) üretmen gerekiyorsa aşağıdaki formatı kullan:\n\ntitle\n<kısa ve açıklayıcı başlık>\ntitle\ncopy\n<kod veya kopyalanacak içerik>\ncopy\n\nKurallar:\n- 'title' ve 'copy' kelimeleri tek başına satır olmalıdır.\n- 'title' bloğu kod bloğundan önce gelmelidir.\n- Kod yoksa bu formatı kullanma.\n- Normal sohbet cevaplarında bu formatı kullanma.\n- Sadece gerçekten kopyalanabilir içerik varsa bu formatı kullan.",
"o_Prompt_Apply": "[FILE] BLOKLARI HAKKINDA:\n- Eğer kullanıcı bir dosya eklediyse, dosya içeriği bu mesaj içinde [FILE] ... [CONTENT] ... [/CONTENT] formatında ZATEN verilmiştir.\n- Bu durumda kullanıcıdan 'kodu buraya yapıştır' veya 'dosyayı paylaş' deme.\n- Değişiklik gerekiyorsa [CONTENT] içeriğini okuyarak işlem yap.\n- Dosya içeriğini tekrar isteme.\n- path alanı olarak [FILE] bloğunda verilen path değerini aynen kullan.\n\nDOSYA DEĞİŞİKLİĞİ KURALI:\n- [FILE] bloklarında 'editable: true' ise dosyada değişiklik önerebilirsin.\n- 'editable: false' olan dosyalar için ASLA dosyaya uygulanacak değişiklik isteme.\n- editable:false dosyalar için apply bloğu üretme.\n- Eğer değişiklik gerekmiyorsa apply bloğu hiç koyma.\n\nAPPLY (OTOMATİK UYGULAMA) PROTOKOLÜ:\nEğer ve sadece eğer kullanıcı 'editable: true' bir dosyada değişiklik istiyorsa,\ncevabının SONUNA aşağıdaki blok formatıyla ekle:\n\napply\n[\n {\n \"path\": \"/absolute/path/to/file\",\n \"find\": \"DOSYADA BİREBİR GEÇEN ANCHOR METİN\",\n \"mode\": \"before|after|replace\",\n \"text\": \"EKLENECEK/YERİNE GEÇECEK METİN\"\n }\n]\napply\n\nKurallar:\n- apply bloğunun içi SADECE JSON olmalı.\n- mode sadece: before, after, replace.\n- path MUTLAKA absolute path olmalı.\n- find, dosyada birebir bulunan kısa/orta bir anchor olmalı.\n\nAPPLY ÖZET SATIRI KURALI:\n- Eğer apply bloğu üretiyorsan, kesin/bitmiş ifade ASLA kullanma.\n- apply bloğundan ÖNCE sadece 1 satır özet yaz.",
"o_Prompt_File_Create": "[FILE] BLOKLARI HAKKINDA:\n- Önceki assistant mesajlarında [GENERATED_FILES] bloğu varsa, kullanıcı 'son dosya', 'oluşturduğun dosya' gibi ifadeler kullandığında bu path değerlerini kullan.\n- Kullanıcı tekrar dosya yüklemesini isteme.\n- Dosya içeriği [FILE] bloğunda verilmişse tekrar dosya isteme.\n\nFILE_CREATE PROTOKOLÜ:\nEğer kullanıcı editable:true olan DOCX, XLSX veya metin tabanlı bir dosyayı düzenleyip yeni dosya olarak almak istiyorsa, cevabının SONUNA şu formatı ekle:\n\nfile_create\n[\n {\n \"source_path\": \"/absolute/path/to/source.docx\",\n \"format\": \"docx\",\n \"output_name\": \"edited-file.docx\",\n \"content\": \"Yeni dosya içeriği\"\n }\n]\nfile_create\n\nKurallar:\n- JSON dışında açıklama koyma.\n- format sadece docx, xlsx, txt, md olabilir.\n- DOCX için content düz metin olarak verilir.\n- XLSX için content JSON tablo veya desteklenen işlem nesnesi olmalıdır.\n- Büyük XLSX dosyalarında satırları tek tek yazma.",
"o_Prompt_Web_Search": "Güncel veya bilmediğin bir bilgi gerekiyorsa normal cevap verme. Bunun yerine sadece şu JSON formatında cevap ver:\n{\"tool\":\"web_search\",\"query\":\"arama sorusu\"}\n\nKurallar:\n- Bu formatı sadece gerçekten güncel bilgi gerekiyorsa kullan.\n- Maç sonucu, güncel fiyat, son haber, yeni sürüm, bugünkü bilgi gibi konularda kullan.\n- Eğer web sonucu sana verilirse, sadece verilen sonuçlara göre kullanıcıya normal cevap ver.\n- Web arama sonuçları verildiğinde cevabın sonuna kısa bir 'Kaynaklar' bölümü ekle. Kaynak başlıklarını ve URL adreslerini sana verildiği şekilde kullan. Kaynak uydurma.\n- Web arama sonuçları kullanıldığında kaynak URL'lerini tam https:// linkleri olarak yaz.",
"o_Prompt_Structured": "Gerektiğinde cevabı düzenli, temiz ve parse edilebilir formatta ver. JSON istenirse sadece geçerli JSON üret.",
"o_Prompt_Code": "Kod yazarken doğrudan kullanılabilir, temiz ve gereksiz açıklamadan arındırılmış kod üret. Var olan kod düzenleniyorsa mevcut yapıyı mümkün olduğunca koru.",
"o_Prompt_PDF_Text_Only_To_DOCX_Rule": "PDF METİN DÖNÜŞTÜRME KURALI:\nPDF metni zaten [CONTENT] içinde verilmiştir.\nDosya yolu isteme.\nKullanıcıdan tekrar yükleme isteme.\n\nKurallar:\n- Görsel üretme.\n- HTML, markdown, image placeholder kullanma.\n- Sadece düz metin üret.\n- Metni isteğe göre düzenle ama anlamı koru.\n- Yeni içerik uydurma.\n\nSadece file_create formatında DOCX döndür:\nfile_create\n[\n {\n \"source_path\": \"/absolute/path/to/source.pdf\",\n \"format\": \"docx\",\n \"output_name\": \"edited-document.docx\",\n \"content\": \"Final metin\"\n }\n]\nfile_create",
"o_Prompt_PDF_Mixed_Text_Only_Rule": "PDF hem metin hem görsel içeriyor ancak sadece metin değiştirilecek.\nGörsellere dokunma.\n\nKurallar:\n- Sadece metinleri düzenle.\n- Yeni içerik uydurma.\n- Görselleri değiştirme.\n\nSadece JSON döndür:\n{\n \"type\": \"pdf_mixed_rewrite\",\n \"content\": \"File created.\",\n \"text_replacements\": {\n \"TEXT_BLOCK_ID\": \"new text\"\n },\n \"image_replacements\": {}\n}"
}
+252
View File
@@ -0,0 +1,252 @@
import json
import re
import math
import hashlib
from pathlib import Path
from collections import Counter
def normalize_chat_data(raw):
if isinstance(raw, list):
return {
"summary": "",
"messages": raw,
"code_context": {},
"memory_chunks": []
}
if not isinstance(raw, dict):
raw = {}
raw.setdefault("summary", "")
raw.setdefault("messages", [])
raw.setdefault("code_context", {})
raw.setdefault("memory_chunks", [])
return raw
def load_chat_data(chat_file: Path) -> dict:
try:
raw = json.loads(chat_file.read_text(encoding="utf-8")) or []
except Exception:
raw = []
return normalize_chat_data(raw)
def save_chat_data(chat_file: Path, chat_data: dict):
chat_file.write_text(
json.dumps(chat_data, ensure_ascii=False, indent=2),
encoding="utf-8"
)
def get_chat_messages(chat_data: dict) -> list:
return chat_data.get("messages", [])
def add_memory_chunk(chat_data: dict, text: str, source: str = "chat"):
text = str(text or "").strip()
if not text:
return
cid = hashlib.sha256((source + text).encode("utf-8")).hexdigest()[:16]
for item in chat_data.get("memory_chunks", []):
if item.get("id") == cid:
return
chat_data.setdefault("memory_chunks", []).append({
"id": cid,
"source": source,
"text": text[:4000]
})
def tokenize(text: str):
return re.findall(r"\w+", str(text).lower())
def cosine_similarity(a: str, b: str) -> float:
va = Counter(tokenize(a))
vb = Counter(tokenize(b))
if not va or not vb:
return 0.0
common = set(va) & set(vb)
dot = sum(va[w] * vb[w] for w in common)
na = math.sqrt(sum(v * v for v in va.values()))
nb = math.sqrt(sum(v * v for v in vb.values()))
if na == 0 or nb == 0:
return 0.0
return dot / (na * nb)
def retrieve_relevant_chunks(chat_data: dict, query: str, limit: int = 5) -> list:
scored = []
for chunk in chat_data.get("memory_chunks", []):
text = chunk.get("text", "")
score = cosine_similarity(query, text)
if score > 0:
scored.append((score, chunk))
scored.sort(key=lambda x: x[0], reverse=True)
return [chunk for score, chunk in scored[:limit]]
def summarize_code_basic(file_path: Path) -> dict:
try:
code = file_path.read_text(encoding="utf-8", errors="replace")
except Exception:
return {}
classes = []
functions = []
for line in code.splitlines():
s = line.strip()
if s.startswith("class "):
classes.append(s)
elif s.startswith("def "):
functions.append(s)
return {
"path": str(file_path),
"name": file_path.name,
"summary": f"{file_path.name}: {len(classes)} class, {len(functions)} function bulundu.",
"classes": classes[:30],
"functions": functions[:80]
}
def update_code_context_from_message(chat_data: dict, msg: dict):
files = msg.get("files") or []
if not isinstance(files, list):
return
for f in files:
if not isinstance(f, dict):
continue
p_raw = str(f.get("path") or "").strip()
if not p_raw:
continue
p = Path(p_raw)
if not p.exists() or not p.is_file():
continue
if p.suffix.lower() not in {
".py", ".js", ".ts", ".tsx", ".jsx", ".json", ".html",
".css", ".cpp", ".c", ".h", ".hpp", ".java", ".go",
".rs", ".sh", ".md", ".txt", ".yaml", ".yml"
}:
continue
ctx = summarize_code_basic(p)
if not ctx:
continue
chat_data.setdefault("code_context", {})[str(p)] = ctx
add_memory_chunk(
chat_data,
ctx["summary"] + "\nFunctions:\n" + "\n".join(ctx.get("functions", [])[:30]),
source=f"code:{p.name}"
)
def build_memory_context(chat_data: dict, user_message: str) -> str:
parts = []
summary = str(chat_data.get("summary") or "").strip()
if summary:
parts.append("Conversation summary:\n" + summary)
relevant = retrieve_relevant_chunks(chat_data, user_message, limit=5)
if relevant:
txt = "Relevant old context:\n"
for ch in relevant:
txt += f"- [{ch.get('source')}] {ch.get('text')}\n"
parts.append(txt)
code_context = chat_data.get("code_context") or {}
if isinstance(code_context, dict) and code_context:
txt = "Known code context:\n"
for path, ctx in code_context.items():
txt += f"\nFile: {ctx.get('name') or path}\n"
txt += f"{ctx.get('summary', '')}\n"
funcs = ctx.get("functions") or []
if funcs:
txt += "Functions:\n" + "\n".join(funcs[:30]) + "\n"
classes = ctx.get("classes") or []
if classes:
txt += "Classes:\n" + "\n".join(classes[:20]) + "\n"
parts.append(txt)
return "\n\n".join(parts).strip()
def should_update_summary(chat_data: dict, every: int = 20) -> bool:
messages = chat_data.get("messages", [])
real = [m for m in messages if isinstance(m, dict) and m.get("role") in ("user", "bot", "assistant")]
return len(real) > 0 and len(real) % every == 0
def make_simple_summary(chat_data: dict) -> str:
messages = chat_data.get("messages", [])
real_messages = [
m for m in messages
if isinstance(m, dict) and m.get("role") in ("user", "bot", "assistant")
]
last_items = real_messages[-20:]
parts = []
for m in last_items:
role = str(m.get("role") or "").strip()
text = str(m.get("content") or "").strip()
if not text:
continue
text = text.replace("\n", " ")
if len(text) > 300:
text = text[:300] + "..."
parts.append(f"{role}: {text}")
code_context = chat_data.get("code_context") or {}
known_files = []
if isinstance(code_context, dict):
for _path, ctx in code_context.items():
if not isinstance(ctx, dict):
continue
name = str(ctx.get("name") or "").strip()
summary = str(ctx.get("summary") or "").strip()
if name:
known_files.append(name)
if summary:
parts.append(f"code_context: {summary}")
summary = "Recent conversation summary:\n"
summary += "\n".join(parts)
if known_files:
summary += "\n\nKnown code files: " + ", ".join(known_files)
return summary[:6000]
+3856 -634
View File
File diff suppressed because it is too large Load Diff