chore(backup): 保存新版预审开发前的代码与文档基线
verify / test-and-build (push) Canceled after 0s

This commit is contained in:
2026-09-28 16:34:10 +08:00
parent b10093f9d8
commit 4d5a420671
37 changed files with 3890 additions and 10 deletions
+20 -5
View File
@@ -10,7 +10,7 @@ from typing import Literal
import httpx
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, ConfigDict, Field
from pydantic import BaseModel, ConfigDict, Field, field_validator
from graph.agent import agent_manager
@@ -31,6 +31,15 @@ class ModelResult(BaseModel):
requirement_response: str = Field(min_length=1, max_length=5000)
experience_proposal: "ExperienceProposal | None" = None
@field_validator("requirement_response", mode="before")
@classmethod
def normalize_requirement_response(cls, value):
if isinstance(value, dict):
return ";".join(f"{key}:{item}" for key, item in value.items())
if isinstance(value, list):
return ";".join(str(item) for item in value)
return value
class ExperienceProposal(BaseModel):
model_config = ConfigDict(extra="forbid")
@@ -49,16 +58,21 @@ ModelResult.model_rebuild()
def configuration():
endpoint = os.getenv("XINGBANG_LOCAL_MODEL_URL", "")
if not endpoint:
return {"available": False, "reason": "未配置内网模型,语义核查未执行"}
return {"available": False, "reason": "未配置受信模型,语义核查未执行"}
url = urlparse(endpoint)
allowed = url.hostname == "localhost"
official_deepseek = (
url.scheme == "https"
and url.hostname == "api.deepseek.com"
and url.port in (None, 443)
)
allowed = url.hostname == "localhost" or official_deepseek
try:
address = ipaddress.ip_address(url.hostname or "")
allowed = address.is_loopback or any(address in ipaddress.ip_network(net) for net in ("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16") if address.version == 4)
except ValueError:
pass
if url.scheme not in ("http", "https") or not allowed or url.username or url.password or url.query or url.fragment:
raise ValueError("模型须为已批准的内网地址,不允许凭据或参数嵌入 URL")
raise ValueError("模型须为已批准的内网地址或 DeepSeek 官方 HTTPS 地址,不允许凭据或参数嵌入 URL")
return {"available": True, "endpoint": endpoint, "name": os.getenv("XINGBANG_LOCAL_MODEL_NAME", "local-model")}
@@ -69,7 +83,8 @@ PROMPT = """你是兴邦项目核查助手,必须通过受限工具读取本
输出一个JSON对象,只含 findings 和 requirement_response。findings 每项字段为 code(稳定英文码)、title、result
(pass/issue/unknown/not_applicable)、evidence_ids(真实证据ID数组)、fields(标准字段数组)、suggested_action。
没有依据不得判定pass/issue。缺失资料标unknown,证据只能引用冻结快照。不得引用其他项目经验中的客户信息。
requirement_response逐项说明是否完成用户要求,无法验证要明确说明。不要Markdown围栏。"""
requirement_response必须是一个普通字符串,不得输出对象或数组;逐项说明是否完成用户要求,无法验证要明确说明。
示例顶层结构:{"findings": [], "requirement_response": "已读取授权事实并完成核查。"}。不要Markdown围栏。"""
def invoke(skill, snapshot, checks, rules, requirement, experiences, model_config, budget, cancelled=lambda: False, feedback=None):