diff --git a/.env.example b/.env.example index 0068b2e4a..93302ff2e 100644 --- a/.env.example +++ b/.env.example @@ -29,6 +29,16 @@ EMBEDDING_MODEL_PATH=./.models/bge-small-zh-v1.5 # GPU acceleration for local model (true/false) EMBEDDING_USE_GPU=true +# ── GCP Vertex AI 企业级配置 ── +# [重要] 1. 项目 ID 必须与你的 ADC 凭据关联的项目一致 +# [重要] 2. 建议区域设为 global,以获得预览版模型 (如 3.1 Flash) 的最佳兼容性 +GOOGLE_CLOUD_PROJECT= +GOOGLE_CLOUD_LOCATION=global +GOOGLE_CLOUD_API_KEY= +# 核心认证路径:执行 gcloud auth application-default login 后生成的 JSON 路径 +GOOGLE_APPLICATION_CREDENTIALS= +GOOGLE_GENAI_USE_VERTEXAI=true + # ── Vector Store Configuration ── VECTOR_STORE_TYPE=chromadb diff --git a/.gitignore b/.gitignore index 54ae1e4b0..23d888505 100644 --- a/.gitignore +++ b/.gitignore @@ -92,25 +92,13 @@ data/llm_configs.json # ── 日志 ── logs/ -# ── PyInstaller 打包产物(根目录) ── -aitext.spec -aitext.lock -aitext.exe -aitext.pkg -Analysis-*.toc -COLLECT-*.toc -EXE-*.toc -PKG-*.toc -PYZ-*.toc -warn-*.txt -xref-*.html -localpycs/ -base_library.zip +# ── 本地大模型与助手沙盒 ── +models/ +scratch/ # ── 内嵌 Python(保留 zip 原始包,解压目录不入库) ── /tools/python_embed/ /tools/aitext/ -# tools/python-*.zip # ← 保留!Python embed 原始包(~15MB),入库供用户直接用 # ── 临时 / 无关文件 ── =++Contribution Value Roster++= diff --git a/application/ai/llm_control_service.py b/application/ai/llm_control_service.py index dee87f7e0..bd4c0afb4 100644 --- a/application/ai/llm_control_service.py +++ b/application/ai/llm_control_service.py @@ -17,7 +17,7 @@ logger = logging.getLogger(__name__) -LLMProtocol = Literal['openai', 'anthropic', 'gemini'] +LLMProtocol = Literal['openai', 'anthropic', 'gemini', 'vertex-ai'] class LLMPreset(BaseModel): @@ -257,6 +257,15 @@ def get_presets(self) -> List[LLMPreset]: description='方舟 OpenAI-compatible 接口;模型名以方舟控制台 Endpoint 为准。', tags=['domestic', 'preset'], ), + LLMPreset( + key='vertex-ai-official', + label='Vertex AI / Google Cloud 官方', + protocol='vertex-ai', + default_base_url='', + default_model='gemini-1.5-flash', + description='GCP Vertex AI 企业版接口。需配置 GOOGLE_APPLICATION_CREDENTIALS 或通过 extra_body 传 project_id。', + tags=['official', 'enterprise'], + ), ] def get_preset_map(self) -> Dict[str, LLMPreset]: @@ -524,6 +533,14 @@ def _build_initial_config(self) -> LLMControlConfig: base_url='https://generativelanguage.googleapis.com/v1beta', model='', ), + LLMProfile( + id='vertex-ai-official-default', + name='Vertex AI / GCP', + preset_key='vertex-ai-official', + protocol='vertex-ai', + base_url='', + model='gemini-1.5-flash', + ), ] active_profile_id = profiles[0].id @@ -566,5 +583,14 @@ def _build_initial_config(self) -> LLMControlConfig: 'model': (os.getenv('ARK_MODEL') or '').strip(), }) active_profile_id = profiles[0].id + elif os.getenv('GCP_PROJECT_ID') or os.getenv('GOOGLE_APPLICATION_CREDENTIALS'): + profiles[3] = profiles[3].model_copy(update={ + 'model': (os.getenv('GCP_MODEL') or '').strip() or profiles[3].model, + 'extra_body': { + 'project_id': (os.getenv('GCP_PROJECT_ID') or '').strip(), + 'region': (os.getenv('GCP_REGION') or '').strip() or 'us-central1' + } + }) + active_profile_id = profiles[3].id return LLMControlConfig(version=1, active_profile_id=active_profile_id, profiles=profiles) diff --git a/cli.py b/cli.py index c8d47afe3..aa9f5e16b 100644 --- a/cli.py +++ b/cli.py @@ -21,7 +21,6 @@ def main(args=None): if parsed_args.command == 'serve': import uvicorn - from .interfaces.main import app _port = parsed_args.port _host = parsed_args.host @@ -71,7 +70,7 @@ def _port_in_use(p): print(f"[aitext] 警告:端口 {_port} 仍被占用,启动可能失败") uvicorn.run( - app, + "interfaces.main:app", host=_host, port=_port, reload=parsed_args.reload diff --git a/frontend/index.html b/frontend/index.html index 947afe94b..fb31b6c0b 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -22,6 +22,11 @@ href="https://fonts.loli.net/css2?family=Noto+Sans+SC:wght@400;500;600;700&display=swap" rel="stylesheet" /> + + PlotPilot · 墨枢 | 作者的领航员