调整 workflow 执行逻辑:每个 action 完成后统一进入 LLM/规则审核,审核开始/结果可播报,审核阻断时自动暂停并给出建议 增强 chat 交互:支持执行中 Ctrl+C 中断并保存 checkpoint,后续可 resume 继续 增加运行时热更新能力:支持 set KEY=VALUE 和 load params <路径> 同步更新当前 state、config.txt 和 checkpoint 支持自定义 action 审核提示词:新增 --llm-action-analysis-prompt-file / PAM_LLM_ACTION_ANALYSIS_PROMPT_FILE 新增 prompts/action_review.txt,落地保存当前默认审核提示词,便于后续按基线调整 更新 Linux 打包脚本,将 prompts/action_review.txt 一并带入发布包 同步更新 README、流程图、todo 和打包文档,修正 --analyze-actions 语义说明与 chat 最新行为说明
46 lines
1.5 KiB
Python
46 lines
1.5 KiB
Python
"""供 CLI 和外部嵌入使用的 LLM client 工厂。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
from .base import LlmClient
|
|
from .openai_compatible import OpenAICompatibleLlmClient, load_prompt_text
|
|
from .rule_based import RuleBasedLlmClient
|
|
|
|
|
|
def build_llm_client(
|
|
*,
|
|
base_url: str | None = None,
|
|
api_key: str | None = None,
|
|
model: str | None = None,
|
|
action_analysis_prompt_path: str | None = None,
|
|
) -> LlmClient:
|
|
"""根据显式参数或环境变量构造 LLM client。"""
|
|
actual_base_url = base_url if base_url is not None else os.getenv("PAM_LLM_BASE_URL", "")
|
|
actual_api_key = api_key if api_key is not None else os.getenv("PAM_LLM_API_KEY", "")
|
|
actual_model = model if model is not None else os.getenv("PAM_LLM_MODEL", "")
|
|
actual_action_prompt_path = (
|
|
action_analysis_prompt_path
|
|
if action_analysis_prompt_path is not None
|
|
else os.getenv("PAM_LLM_ACTION_ANALYSIS_PROMPT_FILE", "")
|
|
)
|
|
|
|
if not actual_base_url and not actual_api_key and not actual_model:
|
|
return RuleBasedLlmClient()
|
|
|
|
missing = []
|
|
if not actual_base_url:
|
|
missing.append("base_url")
|
|
if not actual_model:
|
|
missing.append("model")
|
|
if missing:
|
|
raise ValueError(f"LLM 配置不完整,缺少: {', '.join(missing)}")
|
|
|
|
return OpenAICompatibleLlmClient(
|
|
base_url=actual_base_url,
|
|
api_key=actual_api_key,
|
|
model=actual_model,
|
|
action_analysis_prompt=load_prompt_text(actual_action_prompt_path),
|
|
)
|