refactor: config_views 单入口 + 0语义统一 + FakeAI 收敛(清理单#1#2#3)

- #3 六个消费视图 resolver 收拢 app/platform/config_views(单一定义点):
  resolve_email/push/ai_settings ← 各服务文件, resolve_contact_flags/
  context_seed_map ← conversation, name_to_region_extras ← manager
  __init__ 内联取值(or None 语义原样)——函数体逐字搬入,服务层 import 之,
  旧定义删;Phase 3 编辑器/试金石与该模块对接
- #2 限流 0 语义统一: conn_limiter.try_acquire 的 limit 与 chat_rest 的
  rate_limit_per_hour 取值同款——0 或负 = 回退出厂默认(与姊妹键一致),
  原 conn_limiter 0=全拒改为回退;chat_rest 取值抽 _resolve_rate_limit
  纯函数供锚定
- #1 FakeAI 收敛进 conftest(超集: extract/evaluate/eval_calls),四份拷贝
  删(test_lead_email_trigger/test_cc_integration/test_channel_hygiene/
  test_lead_push_wiring——计划记三份,grep 实有四份;push_wiring 经
  evaluate 参数注入原本地固定返回值,断言零改动)

全量 558 passed(554 + 新增 4: 单入口/内联等价/两处 0 语义)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-13 11:45:42 +08:00
parent acf5777ff2
commit 71e11c317f
15 changed files with 310 additions and 254 deletions
+45
View File
@@ -86,6 +86,51 @@ def _reset_platform_auth():
_reset_for_test()
# ---- Phase 2 Task 10: FakeAI 公共确定性桩(清理单 #1) --------------------------
# 收敛自四份拷贝(test_lead_email_trigger / test_cc_integration /
# test_channel_hygiene / test_lead_push_wiring,接口取超集: 前两份全量,
# hygiene/push_wiring 只用 extract 传入——evaluate=None 即它们原固定返回)。
class FakeAI:
"""替代 GLM 的确定性桩: 构造参数即每轮返回值。
- extract: dict 或 list——第 N 轮客户消息取 seq[N-1](messages 为
[u,a,u,a...] 全量历史),越界取末位;
- evaluate: dict 或 None——None = 出厂 pending 默认;子类可覆写
extract_info/evaluate 做捕获或定向注毒(既有 RecAI 用法);
- eval_calls: evaluate 被调计数(结束守卫轮次断言用)。
"""
def __init__(self, extract=None, evaluate=None):
self._extract_seq = extract if isinstance(extract, list) else [extract or {}]
self._evaluate = evaluate or {}
self.eval_calls = 0
async def chat(self, messages, context=""):
return "ok reply"
async def stream_chat(self, messages, context=""):
for token in ("ok ", "reply"):
yield token
async def extract_info(self, messages, existing_info):
# 第 N 轮客户消息 → seq[N-1](messages 为 [u,a,u,a...] 全量历史)
idx = min(max(len(messages) // 2 - 1, 0), len(self._extract_seq) - 1)
return self._extract_seq[idx]
async def evaluate(self, profile, recent_messages):
self.eval_calls += 1
result = dict(self._evaluate)
result.setdefault("intent_level", "pending")
result.setdefault("reasoning", "")
result.setdefault("contact_info", {})
result.setdefault("info_sufficient", False)
if result["intent_level"] not in ("interested", "not_interested", "pending"):
result["intent_level"] = "pending"
return result
@pytest.fixture
def jiancai_runtime():
"""直连测试用的 jiancai TenantRuntime(Task 6: manager 的 runtime 必填)。