feat: add theme management with light and dark modes

- Implemented a new composable `useTheme` for managing theme state.
- Added functions to read and write theme preference to local storage.
- Applied theme styles to the DOM based on user preference.
- Introduced a toggle function to switch between light and dark themes.

refactor: enhance copilot plugin functionality

- Improved request handling with sequence and document versioning.
- Refactored ghost text handling to improve clarity and efficiency.
- Updated markdown insertion logic to handle parsed content more robustly.
- Enhanced error handling and logging for better debugging.

style: update global styles for light and dark themes

- Defined CSS variables for light and dark themes to streamline styling.
- Improved overall styling consistency and responsiveness.
- Added transitions for smoother theme changes and interactions.
This commit is contained in:
2026-02-15 15:44:09 +08:00
parent 03bb21d5c6
commit 838eec30a8
205 changed files with 1868 additions and 344 deletions

View File

@@ -1,6 +1,7 @@
import os
import time
import logging
from datetime import datetime
import ollama
from dotenv import load_dotenv
@@ -58,6 +59,7 @@ async def call_ollama(prompt: str, *, tag: str = "default", temperature: float =
调用 Ollama API 并返回 content 和 thinking。
"""
start = time.perf_counter()
start_dt = datetime.now()
logger.info(
"[LLM][%s] request model=%s host=%s prompt_chars=%d temp=%.2f",
tag,
@@ -79,11 +81,25 @@ async def call_ollama(prompt: str, *, tag: str = "default", temperature: float =
)
except Exception:
elapsed_ms = (time.perf_counter() - start) * 1000
end_dt = datetime.now()
logger.info(
"[LLM][%s] call_time [%s --> %s]",
tag,
start_dt.strftime("%H:%M:%S"),
end_dt.strftime("%H:%M:%S"),
)
logger.exception("[LLM][%s] request failed after %.1fms", tag, elapsed_ms)
raise
content, thinking = _extract_message(response)
elapsed_ms = (time.perf_counter() - start) * 1000
end_dt = datetime.now()
logger.info(
"[LLM][%s] call_time [%s --> %s]",
tag,
start_dt.strftime("%H:%M:%S"),
end_dt.strftime("%H:%M:%S"),
)
logger.info(
"[LLM][%s] response in %.1fms response_type=%s content_chars=%d thinking_chars=%d",
tag,
@@ -100,6 +116,7 @@ async def call_ollama(prompt: str, *, tag: str = "default", temperature: float =
async def call_vlm_ocr(image_bytes: bytes, language: str = 'auto') -> str:
start = time.perf_counter()
start_dt = datetime.now()
logger.info(
"[VLM][ocr] request model=%s host=%s image_bytes=%d language=%s",
VLM_MODEL,
@@ -121,11 +138,23 @@ async def call_vlm_ocr(image_bytes: bytes, language: str = 'auto') -> str:
)
except Exception:
elapsed_ms = (time.perf_counter() - start) * 1000
end_dt = datetime.now()
logger.info(
"[VLM][ocr] call_time [%s --> %s]",
start_dt.strftime("%H:%M:%S"),
end_dt.strftime("%H:%M:%S"),
)
logger.exception("[VLM][ocr] request failed after %.1fms", elapsed_ms)
raise
content, thinking = _extract_message(response)
elapsed_ms = (time.perf_counter() - start) * 1000
end_dt = datetime.now()
logger.info(
"[VLM][ocr] call_time [%s --> %s]",
start_dt.strftime("%H:%M:%S"),
end_dt.strftime("%H:%M:%S"),
)
logger.info(
"[VLM][ocr] response in %.1fms response_type=%s content_chars=%d thinking_chars=%d",
elapsed_ms,