Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
46e760a
feat: add model download utility, update gitignore, and refactor CLI …
professorczh Apr 15, 2026
e0becc9
Merge upstream/master: Adapt to new LLMConfigManager and protect loca…
professorczh Apr 15, 2026
9b80d16
feat: implement voice style analysis API and LLM configuration manage…
professorczh Apr 15, 2026
5c7cb9b
feat: implement theme management system with multi-mode support and i…
professorczh Apr 15, 2026
5dccc58
feat: implement LLM control API, Gemini provider, and onboarding setu…
professorczh Apr 15, 2026
5e0b7ac
Merge upstream architecture: Dynamic LLM profiles & BlackGold UI with…
professorczh Apr 15, 2026
f06526a
Add missing settings components to complete UI implementation
professorczh Apr 15, 2026
9209fab
Fix: Add timeout_seconds and other missing fields to Settings class
professorczh Apr 15, 2026
49edcfb
Merge upstream master: Full architecture alignment, Prompt Plaza inte…
professorczh Apr 15, 2026
e3fc58b
feat: implement global LLM and embedding configuration panel with dra…
professorczh Apr 15, 2026
e69e72c
feat: implement LLM control workbench API and frontend infrastructure…
professorczh Apr 15, 2026
95b9688
chore: preserve theme fixes before merging upstream changes
professorczh Apr 17, 2026
1d37c30
merge: massive upstream update with visual sovereignty and navigation…
professorczh Apr 17, 2026
eb3fc46
feat: integrate Gemini AI provider, add novel onboarding wizard, and …
professorczh Apr 29, 2026
f47225c
Merge updates from upstream (v1.0.4) and resolve conflicts
professorczh Apr 29, 2026
d4ccc9b
feat: implement LLM control service with multi-provider support, Vert…
professorczh May 2, 2026
2de5385
feat: implement theme management system with store, global styles, an…
professorczh May 2, 2026
2d6045b
fix: remove deprecated configuration module
professorczh May 2, 2026
326c74b
feat: add NovelSetupGuide component for user onboarding flow
professorczh May 2, 2026
bdbc1d3
fix: address code review issues from CodeRabbit (GCP/UI/DB)
professorczh May 2, 2026
0608942
feat: add Vertex AI provider, implement LLM control API endpoints, an…
professorczh May 2, 2026
e4ebe46
feat: implement Vertex AI provider, SQLite connection migrations, and…
professorczh May 2, 2026
a7e501b
feat: implement Vertex AI provider for infrastructure integration
professorczh May 2, 2026
f8ed1b0
feat: add utility script to download models from ModelScope
professorczh May 2, 2026
45ad52a
feat: implement Vertex AI provider for infrastructure integration
professorczh May 2, 2026
605bb25
feat: add NovelSetupGuide component for onboarding flow
professorczh May 2, 2026
0ae0068
Merge upstream/master: Adopt SSE architecture, retain local proxy and…
professorczh May 15, 2026
3973e09
feat: implement dashboard stats sidebar and backend services for worl…
professorczh May 17, 2026
1ba1651
Merge upstream/master: Synchronize latest upstream features and fix c…
professorczh May 17, 2026
3429c5a
fix: resolve TS build errors in StatsSidebar and restore functional S…
professorczh May 17, 2026
30bd51b
fix: auto approve mode state sync and wizard button overflow
professorczh May 17, 2026
993d1d8
Merge branch 'upstream/master' into master
professorczh May 17, 2026
0126833
feat: clean orphaned triples, fix worldbuilding labels, forbid self-i…
professorczh May 18, 2026
fc8af1e
merge: pull latest upstream changes including rewrite counter, deadlo…
professorczh May 18, 2026
34591c6
feat: add novel duplication and reset utilities with comprehensive se…
professorczh May 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
.env
.env.*
!.env.example
README-LOCAL.md
README_local.md

# ── Python ──
__pycache__/
Expand Down Expand Up @@ -92,6 +94,10 @@ data/llm_configs.json
# ── 日志 ──
logs/

# ── 本地大模型与助手沙盒 ──
models/
scratch/

# ── PyInstaller 打包产物(根目录) ──
plotpilot.spec
plotpilot.lock
Expand All @@ -110,6 +116,7 @@ base_library.zip
# ── 内嵌 Python(保留 zip 原始包,解压目录不入库) ──
/tools/python_embed/
/tools/plotpilot/
/tools/aitext/
# tools/python-*.zip # ← 保留!Python embed 原始包(~15MB),入库供用户直接用

# ── 临时 / 无关文件 ──
Expand Down
28 changes: 27 additions & 1 deletion application/ai/llm_control_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

logger = logging.getLogger(__name__)

LLMProtocol = Literal['openai', 'anthropic', 'gemini']
LLMProtocol = Literal['openai', 'anthropic', 'gemini', 'vertex-ai']


class LLMPreset(BaseModel):
Expand Down Expand Up @@ -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]:
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)
21 changes: 12 additions & 9 deletions application/analyst/services/state_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
chapter_state_payload_to_domain,
empty_chapter_state,
parse_chapter_state_llm_response,
ChapterStateLlmPayload,
)
from application.ai.structured_json_pipeline import structured_json_generate

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -37,23 +39,24 @@ async def extract_chapter_state(self, content: str) -> ChapterState:
system_prompt, user_prompt = self._build_extraction_prompt(content)
prompt = Prompt(system=system_prompt, user=user_prompt)

# 配置 LLM
# 配置 LLM 并强制指定 JSON schema
config = GenerationConfig(
model=os.getenv("WRITING_MODEL", ""),
max_tokens=4096,
temperature=0.3
temperature=0.3,
response_format=ChapterStateLlmPayload,
)

# 调用 LLM 生成
result = await self.llm_service.generate(prompt=prompt, config=config)
raw_response = result.content
logger.debug(f"StateExtractor LLM raw response (first 500 chars): {raw_response[:500]}")
payload = await structured_json_generate(
llm=self.llm_service,
prompt=prompt,
config=config,
schema_model=ChapterStateLlmPayload,
)

payload, errors = parse_chapter_state_llm_response(raw_response)
if payload is None:
logger.warning(
"StateExtractor: LLM 输出未通过契约校验: %s",
"; ".join(errors) if errors else "unknown",
"StateExtractor: LLM 输出结构化生成失败,返回安全空值。"
)
chapter_state = empty_chapter_state()
else:
Expand Down
Loading