Ver Fonte

fix(sample-kb): 归属租户改为「活跃智能体最多者优先」

第二次租户踩坑: config.json 的 key 属 launch 租户, 但浏览器
localStorage 实际登录的是拥有 7 个智能体的 local 租户 — 资料库页
仍看不到示例库。改启发式: 活跃智能体最多的租户(日常使用集中地)
> config.json key 租户(全新安装时无智能体, 走这条) > 最老租户。
存量数据已对齐。测试 +1 (busiest-tenant)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kenny67nju há 4 meses atrás
pai
commit
0569c629a2
2 ficheiros alterados com 38 adições e 4 exclusões
  1. 13 4
      agentpaas/src/agentpaas/engine/sample_kb.py
  2. 25 0
      tests/test_sample_kb.py

+ 13 - 4
agentpaas/src/agentpaas/engine/sample_kb.py

@@ -106,12 +106,21 @@ def _build_page_index_json(kb_dir: Path) -> int:
 def _resolve_desktop_tenant(db) -> str:
     """定位示例库应归属的租户。
 
-    多租户的老库里"最老的活跃租户"很可能不是桌面用户当前登录的那个
-    (实测:示例库建给了 lambda-space,而用户登录的是 launch 租户,
+    桌面老库往往积累了多个历史租户(lambda-space/launch/local…),
+    "最老租户"和 config.json 的 key 租户都可能不是浏览器实际登录的
+    那个(实测两次踩坑:示例库分别建给了 lambda-space 和 launch,
+    而浏览器 localStorage 用的是拥有 7 个智能体的 local 租户,
     「知识库」页因租户过滤显示 0 个)。优先级:
-    1. ~/.agentpaas/config.json 里 api_key 前缀对应的租户(当前登录者)
-    2. 退化:最老的活跃租户(全新安装时只有一个,语义一致)
+    1. 活跃智能体最多的租户 —— 日常使用集中地,浏览器会话最可能在这
+    2. ~/.agentpaas/config.json 里 api_key 对应的租户(全新安装的正解,
+       此时该租户也还没有智能体,1 查不到)
+    3. 退化:最老的活跃租户
     """
+    row = db.fetchone(
+        "SELECT tenant_id, COUNT(*) AS n FROM agents WHERE status = 'active' "
+        "GROUP BY tenant_id ORDER BY n DESC LIMIT 1")
+    if row:
+        return row["tenant_id"]
     try:
         with open(os.path.expanduser("~/.agentpaas/config.json"), encoding="utf-8") as f:
             api_key = (json.load(f) or {}).get("api_key", "")

+ 25 - 0
tests/test_sample_kb.py

@@ -192,3 +192,28 @@ def test_page_index_search_chinese_query(fresh_db, tmp_path):
     # 英文 query 不受影响
     hits_en = _page_index_search(kb["root_dir"], "ADT stack push pop", 3)
     assert hits_en and hits_en[0]["score"] > 0
+
+
+def test_resolve_tenant_prefers_busiest(fresh_db, tmp_path):
+    """多租户老库:示例库应归属活跃智能体最多的租户(浏览器会话所在地),
+    而非最老租户或 config.json 租户。"""
+    from agentpaas.db.models import gen_id, now_utc
+    from agentpaas.engine.sample_kb import ensure_sample_kb, SAMPLE_KB_NAME
+
+    db, tid_old = fresh_db
+    # 第二个租户,拥有 2 个活跃智能体(模拟日常使用租户)
+    tid_busy = gen_id("tn_")
+    now = now_utc()
+    db.execute("INSERT INTO tenants (id, name, plan, status, created_at) "
+               "VALUES (?, 'busy', 'free', 'active', ?)", (tid_busy, now))
+    for i in range(2):
+        db.execute(
+            "INSERT INTO agents (id, tenant_id, name, current_version, status, "
+            "created_at, updated_at) VALUES (?, ?, ?, 1, 'active', ?, ?)",
+            (gen_id("ag_"), tid_busy, f"a{i}", now, now))
+    db.commit()
+
+    ensure_sample_kb(str(tmp_path))
+    kb = db.fetchone("SELECT tenant_id FROM knowledge_bases WHERE name = ?",
+                     (SAMPLE_KB_NAME,))
+    assert kb["tenant_id"] == tid_busy, "应归属智能体最多的租户"