@hupan56/wlkj 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +117 -0
- package/package.json +1 -1
- package/templates/qoder/commands/optional/wl-insight.md +276 -276
- package/templates/qoder/commands/optional/wl-report.md +1 -1
- package/templates/qoder/commands/optional/wl-spec.md +13 -1
- package/templates/qoder/commands/optional/wl-status.md +12 -1
- package/templates/qoder/commands/wl-code.md +76 -4
- package/templates/qoder/commands/wl-commit.md +12 -1
- package/templates/qoder/commands/wl-design.md +69 -5
- package/templates/qoder/commands/wl-init.md +27 -0
- package/templates/qoder/commands/wl-prd.md +145 -4
- package/templates/qoder/commands/wl-search.md +74 -20
- package/templates/qoder/commands/wl-task.md +613 -613
- package/templates/qoder/commands/wl-test.md +16 -1
- package/templates/qoder/contracts/spec.md +4 -0
- package/templates/qoder/hooks/post-tool-use.py +41 -0
- package/templates/qoder/hooks/session-start.py +34 -66
- package/templates/qoder/scripts/capability/__pycache__/__init__.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/__pycache__/registry.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/__pycache__/registry_mcp.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/adapters/__init__.py +1 -1
- package/templates/qoder/scripts/capability/adapters/__pycache__/__init__.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/adapters/__pycache__/cli.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/adapters/__pycache__/mcp.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/adapters/__pycache__/qw.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/adapters/mcp.py +76 -100
- package/templates/qoder/scripts/capability/adapters/qw.py +295 -295
- package/templates/qoder/scripts/capability/caps/__init__.py +1 -1
- package/templates/qoder/scripts/capability/caps/__pycache__/__init__.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/caps/__pycache__/context.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/caps/__pycache__/cron.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/caps/__pycache__/identity.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/caps/__pycache__/memory.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/caps/__pycache__/notify.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/caps/__pycache__/present.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/caps/__pycache__/repo.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/caps/__pycache__/sandbox.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/capability/caps/memory.py +1 -1
- package/templates/qoder/scripts/capability/registry.py +21 -23
- package/templates/qoder/scripts/capability/registry_mcp.py +69 -5
- package/templates/qoder/scripts/capability/smoke_test_report.json +34 -20
- package/templates/qoder/scripts/deployment/setup/carriers.py +3 -1
- package/templates/qoder/scripts/deployment/setup/init_doctor.py +10 -3
- package/templates/qoder/scripts/domain/__pycache__/__init__.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/domain/integration/__init__.py +0 -0
- package/templates/qoder/scripts/domain/integration/__pycache__/__init__.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/domain/integration/__pycache__/return_to_platform.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/domain/integration/return_to_platform.py +392 -0
- package/templates/qoder/scripts/domain/integration/spec_upload.py +209 -0
- package/templates/qoder/scripts/domain/kg/build/kg_build.py +27 -3
- package/templates/qoder/scripts/domain/kg/extract/asset/__init__.py +10 -0
- package/templates/qoder/scripts/domain/kg/extract/asset/asset_tree.py +57 -0
- package/templates/qoder/scripts/domain/kg/extract/asset/discussion_importer.py +62 -0
- package/templates/qoder/scripts/domain/kg/extract/asset/prd_importer.py +146 -0
- package/templates/qoder/scripts/domain/kg/extract/asset/prototype_importer.py +64 -0
- package/templates/qoder/scripts/domain/kg/extract/asset/returns_importer.py +52 -0
- package/templates/qoder/scripts/domain/kg/extract/build_goal3.py +104 -0
- package/templates/qoder/scripts/domain/kg/extract/build_goal4.py +55 -0
- package/templates/qoder/scripts/domain/kg/extract/build_goal5.py +95 -0
- package/templates/qoder/scripts/domain/kg/extract/db/__init__.py +8 -0
- package/templates/qoder/scripts/domain/kg/extract/db/data_profile.py +22 -0
- package/templates/qoder/scripts/domain/kg/extract/db/fk_extractor.py +55 -0
- package/templates/qoder/scripts/domain/kg/extract/db/schema_extractor.py +90 -0
- package/templates/qoder/scripts/domain/kg/extract/extract.py +84 -0
- package/templates/qoder/scripts/domain/kg/extract/extract.py.bak +430 -0
- package/templates/qoder/scripts/domain/kg/extract/inference/__init__.py +9 -0
- package/templates/qoder/scripts/domain/kg/extract/inference/community_summarizer.py +206 -0
- package/templates/qoder/scripts/domain/kg/extract/inference/embed_builder.py +132 -0
- package/templates/qoder/scripts/domain/kg/extract/inference/naming_matcher.py +80 -0
- package/templates/qoder/scripts/domain/kg/extract/inference/promote.py +59 -0
- package/templates/qoder/scripts/domain/kg/extract/inference/recompute.py +93 -0
- package/templates/qoder/scripts/domain/kg/extract/inference/weak_link.py +421 -0
- package/templates/qoder/scripts/domain/kg/extract/java/__init__.py +15 -0
- package/templates/qoder/scripts/domain/kg/extract/java/_parser.py +271 -0
- package/templates/qoder/scripts/domain/kg/extract/java/all.py +145 -0
- package/templates/qoder/scripts/domain/kg/extract/java/build_java_to_pg.py +102 -0
- package/templates/qoder/scripts/domain/kg/extract/java/call_chain.py +49 -0
- package/templates/qoder/scripts/domain/kg/extract/java/class_extractor.py +141 -0
- package/templates/qoder/scripts/domain/kg/extract/java/domain_extractor.py +148 -0
- package/templates/qoder/scripts/domain/kg/extract/java/dubbo_extractor.py +33 -0
- package/templates/qoder/scripts/domain/kg/extract/java/endpoint_extractor.py +36 -0
- package/templates/qoder/scripts/domain/kg/extract/java/javadoc_extractor.py +110 -0
- package/templates/qoder/scripts/domain/kg/extract/java/llm_cn_filler.py +150 -0
- package/templates/qoder/scripts/domain/kg/extract/java/member_extractor.py +157 -0
- package/templates/qoder/scripts/domain/kg/extract/java/mybatisplus_extractor.py +34 -0
- package/templates/qoder/scripts/domain/kg/extract/java/pg_upsert.py +165 -0
- package/templates/qoder/scripts/domain/kg/extract/java/satoken_extractor.py +30 -0
- package/templates/qoder/scripts/domain/kg/extract/java/spring_extractor.py +39 -0
- package/templates/qoder/scripts/domain/kg/extract/java/validation_extractor.py +33 -0
- package/templates/qoder/scripts/domain/kg/extract/mybatis/__init__.py +9 -0
- package/templates/qoder/scripts/domain/kg/extract/mybatis/all.py +79 -0
- package/templates/qoder/scripts/domain/kg/extract/mybatis/mapper_parser.py +99 -0
- package/templates/qoder/scripts/domain/kg/extract/mybatis/relation_builder.py +69 -0
- package/templates/qoder/scripts/domain/kg/extract/mybatis/sql_extractor.py +78 -0
- package/templates/qoder/scripts/domain/kg/extract/prd/__init__.py +8 -0
- package/templates/qoder/scripts/domain/kg/extract/prd/prd_chunk_embed.py +105 -0
- package/templates/qoder/scripts/domain/kg/extract/prd/prd_llm_extract.py +153 -0
- package/templates/qoder/scripts/domain/kg/extract/prd/req_anchor.py +120 -0
- package/templates/qoder/scripts/domain/kg/graph/kg_semantic.py +4 -2
- package/templates/qoder/scripts/domain/kg/kg.py +42 -5
- package/templates/qoder/scripts/domain/kg/search/_remote.py +187 -0
- package/templates/qoder/scripts/domain/kg/search/context_pack.py +32 -2
- package/templates/qoder/scripts/domain/kg/search/search_index.py +74 -20
- package/templates/qoder/scripts/domain/kg/switch_project.py +159 -0
- package/templates/qoder/scripts/domain/kg/sync_repowiki.py +109 -0
- package/templates/qoder/scripts/domain/task/__pycache__/wlkj_panel.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/domain/task/{zentao_panel.py → wlkj_panel.py} +315 -53
- package/templates/qoder/scripts/engine/poller.py +219 -0
- package/templates/qoder/scripts/foundation/__pycache__/__init__.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/foundation/core/__pycache__/__init__.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/foundation/core/__pycache__/paths.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/foundation/integrations/active_task.py +2 -1
- package/templates/qoder/scripts/orchestration/wlkj.py +4 -0
- package/templates/qoder/scripts/protocol/__pycache__/__init__.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/protocol/mcp/zentao_mcp_server.py +1 -1
- package/templates/qoder/scripts/protocol/transports/__pycache__/__init__.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/protocol/transports/__pycache__/base.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/protocol/transports/__pycache__/cli.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/protocol/transports/__pycache__/http.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/protocol/transports/__pycache__/stdio.cpython-39.pyc +0 -0
- package/templates/qoder/scripts/protocol/transports/http.py +7 -1
- package/templates/root/AGENTS.md +9 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""
|
|
3
|
-
|
|
3
|
+
capability.registry —— 宿主发现 + Nexus Facade。
|
|
4
4
|
|
|
5
5
|
设计模式:
|
|
6
6
|
- Registry(HOST_TABLE 单一事实源,泛化 common.active_task._ENV_SESSION_KEYS)
|
|
@@ -8,7 +8,7 @@ nexus.registry —— 宿主发现 + Nexus Facade。
|
|
|
8
8
|
- Bridge(Cap 抽象 × 宿主实现 正交)
|
|
9
9
|
|
|
10
10
|
主轴: 工作流面向能力编程,不面向宿主。
|
|
11
|
-
cap =
|
|
11
|
+
cap = resolve()
|
|
12
12
|
cap.memory.recall(...) # 不管在 QoderWork 还是 CLI,同一行代码
|
|
13
13
|
"""
|
|
14
14
|
from __future__ import annotations
|
|
@@ -36,26 +36,24 @@ from .caps import (
|
|
|
36
36
|
# =============================================================================
|
|
37
37
|
|
|
38
38
|
HOST_TABLE: dict[str, dict] = {
|
|
39
|
-
# ── Qoder
|
|
39
|
+
# ── Qoder 系列(第一宿主系列,2026-07 对齐最新产品线)─────────────
|
|
40
|
+
# 主开发宿主 + 办公产品。(Qoder CLI / Cloud Agents 后续按需再加;QoderWake 架构性不接。)
|
|
41
|
+
# features = 引擎已接(非 NoOp adapter);native = 产品原生能力(仅建模,不算实现)。
|
|
42
|
+
"qoder-desktop": {
|
|
43
|
+
# Qoder 1.0 "Autonomous Development Desktop"(原 qoder-ide;Quest Window/Agent Mode 是其模式,故原 qoder-quest 合并于此)
|
|
44
|
+
"detect": ("QODER_DESKTOP", "QODER_IDE"),
|
|
45
|
+
"features": ("mcp", "memory", "cron", "present"),
|
|
46
|
+
"native": ("agent-mode", "context-engine", "vm-sandbox", "hooks", "skills", "mcp-sse"),
|
|
47
|
+
"mcp_servers": ["qoder-knowledge-graph", "qoder-zentao", "qoder-mysql", "lanhu"],
|
|
48
|
+
"note": "Qoder Desktop/IDE 1.0(主开发宿主;Quest 是其模式,非独立宿主)",
|
|
49
|
+
},
|
|
40
50
|
"qoder-work": {
|
|
51
|
+
# QoderWork:办公产品(非开发者,文档/报告/PPT/M365)。~/.qoderwork/ 投影 + qoder_show_widget 是其接入点。
|
|
41
52
|
"detect": ("QODER_SESSION_ID",),
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"features": ("mcp", "memory", "cron"),
|
|
53
|
+
"features": ("mcp", "memory", "cron", "present"),
|
|
54
|
+
"native": ("office-agent", "m365", "human-in-loop", "hooks", "show-widget"),
|
|
45
55
|
"mcp_servers": ["qoder-knowledge-graph", "qoder-zentao", "qoder-mysql", "lanhu"],
|
|
46
|
-
"note": "QoderWork
|
|
47
|
-
},
|
|
48
|
-
"qoder-ide": {
|
|
49
|
-
"detect": ("QODER_IDE",),
|
|
50
|
-
"features": ("mcp", "memory"),
|
|
51
|
-
"mcp_servers": ["qoder-knowledge-graph", "qoder-zentao", "qoder-mysql"],
|
|
52
|
-
"note": "Qoder IDE (VSCode 扩展)",
|
|
53
|
-
},
|
|
54
|
-
"qoder-quest": {
|
|
55
|
-
"detect": ("QODER_QUEST",),
|
|
56
|
-
"features": ("mcp", "memory"),
|
|
57
|
-
"mcp_servers": ["qoder-knowledge-graph", "qoder-zentao"],
|
|
58
|
-
"note": "Qoder Quest,自然语言入口",
|
|
56
|
+
"note": "QoderWork 桌面办公 Agent(非开发者;文档/PPT/M365);~/.qoderwork/ 投影入口",
|
|
59
57
|
},
|
|
60
58
|
# ── 其他宿主(通用 AI 工具)────────────────────────────────
|
|
61
59
|
"codex": {
|
|
@@ -124,7 +122,7 @@ def detect_host() -> str:
|
|
|
124
122
|
class Nexus:
|
|
125
123
|
"""宿主能力 Facade —— 聚合所有能力,对外统一入口。
|
|
126
124
|
|
|
127
|
-
工作流永远只调
|
|
125
|
+
工作流永远只调 resolve() 拿到本对象,再访问 .memory/.mcp/...,
|
|
128
126
|
不直接 import 任何 adapter(Facade 模式)。
|
|
129
127
|
"""
|
|
130
128
|
|
|
@@ -202,8 +200,8 @@ def _resolve_notify(host: str):
|
|
|
202
200
|
|
|
203
201
|
|
|
204
202
|
def _resolve_present(host: str):
|
|
205
|
-
"""L2 富展示 ——
|
|
206
|
-
if host in ("qoder-
|
|
203
|
+
"""L2 富展示 —— Qoder Desktop/Work 调 qoder_show_widget 嵌入对话; 其余 NoOp 降级表格。"""
|
|
204
|
+
if host in ("qoder-desktop", "qoder-work"):
|
|
207
205
|
try:
|
|
208
206
|
from .adapters.qw import QwPresentCap
|
|
209
207
|
return QwPresentCap()
|
|
@@ -227,7 +225,7 @@ def _resolve_mcp(host: str):
|
|
|
227
225
|
def resolve() -> Nexus:
|
|
228
226
|
"""解析当前环境,返回 Nexus Facade。
|
|
229
227
|
|
|
230
|
-
一行入口: cap =
|
|
228
|
+
一行入口: cap = resolve()
|
|
231
229
|
内部: detect_host → 按宿主装配各 Cap → 注入 NoOp 兜底。
|
|
232
230
|
工作流代码零宿主感知。
|
|
233
231
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""
|
|
3
|
-
|
|
3
|
+
capability.registry_mcp —— MCP 工具路由(tool → server → transport)。
|
|
4
4
|
|
|
5
5
|
设计模式: Registry + Strategy(配合 transports 层)
|
|
6
6
|
|
|
@@ -34,11 +34,25 @@ from protocol.transports import get_transport, Transport, NoOpTransport, ToolRes
|
|
|
34
34
|
# 未来改这里即可切换部署形态,工作流零改动。
|
|
35
35
|
# =============================================================================
|
|
36
36
|
|
|
37
|
+
# =============================================================================
|
|
38
|
+
# mcp_config.json 消费 —— 让配置文件真正生效(单一事实源)
|
|
39
|
+
# -----------------------------------------------------------------------------
|
|
40
|
+
# 历史 bug: mcp_config.json / registry_mcp_config.json 是"死配置"(全仓 0 读取),
|
|
41
|
+
# registry 用硬编码 SERVERS。改配置文件不生效。
|
|
42
|
+
# 现在: 优先读 wlinkj-workflow/mcp_config.json 的 mcpServers,读不到才 fallback。
|
|
43
|
+
# =============================================================================
|
|
44
|
+
# 配置文件中知识层 server 的别名映射(统一命名,两边都支持):
|
|
45
|
+
# mcp_config.json 里叫 "wlinkj-knowledge",本地硬编码叫 "qoder-knowledge-graph"。
|
|
46
|
+
# 让 _load_servers 把 config 的 server 也注册成 "qoder-knowledge-graph" 别名,
|
|
47
|
+
# 这样反向索引 / 显式 server 调用两边名字都能命中。
|
|
48
|
+
_KNOWLEDGE_SERVER_ALIASES = ["wlinkj-knowledge", "qoder-knowledge-graph"]
|
|
49
|
+
|
|
50
|
+
# 硬编码 fallback(配置文件读不到时兜底,保证引擎不崩)
|
|
37
51
|
SERVERS: dict[str, dict] = {
|
|
38
52
|
"qoder-knowledge-graph": {
|
|
39
|
-
"kind": "
|
|
40
|
-
"
|
|
41
|
-
"note": "
|
|
53
|
+
"kind": "http",
|
|
54
|
+
"url": "http://127.0.0.1:10010/mcp",
|
|
55
|
+
"note": "知识图谱。已改为 http 模式,指向资产平台 MCP 服务(POST /mcp JSON-RPC)",
|
|
42
56
|
},
|
|
43
57
|
"qoder-zentao": {
|
|
44
58
|
"kind": "stdio",
|
|
@@ -58,6 +72,55 @@ SERVERS: dict[str, dict] = {
|
|
|
58
72
|
}
|
|
59
73
|
|
|
60
74
|
|
|
75
|
+
def _mcp_config_path() -> Path:
|
|
76
|
+
"""定位 wlinkj-workflow/mcp_config.json(在仓库根下)。"""
|
|
77
|
+
repo = _get_repo_root()
|
|
78
|
+
# registry_mcp.py 在 .../scripts/capability/, mcp_config.json 在 wlinkj-workflow/
|
|
79
|
+
# 仓库根可能就是 wlinkj-workflow/, 或是其上层。两级查找。
|
|
80
|
+
for cand in [
|
|
81
|
+
repo / "mcp_config.json",
|
|
82
|
+
repo / "wlinkj-workflow" / "mcp_config.json",
|
|
83
|
+
repo / "registry_mcp_config.json",
|
|
84
|
+
]:
|
|
85
|
+
if cand.is_file():
|
|
86
|
+
return cand
|
|
87
|
+
return repo / "mcp_config.json"
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _load_servers() -> dict[str, dict]:
|
|
91
|
+
"""从 mcp_config.json 加载 mcpServers,合并到硬编码 SERVERS 上。
|
|
92
|
+
|
|
93
|
+
配置文件优先(改配置真生效),硬编码兜底(配置缺失也不崩)。
|
|
94
|
+
同时把知识层 server 注册多个别名(wlinkj-knowledge / qoder-knowledge-graph),
|
|
95
|
+
让引擎用任一名字都能调到。
|
|
96
|
+
"""
|
|
97
|
+
import json as _json
|
|
98
|
+
|
|
99
|
+
merged: dict[str, dict] = {k: dict(v) for k, v in SERVERS.items()}
|
|
100
|
+
try:
|
|
101
|
+
cfg_path = _mcp_config_path()
|
|
102
|
+
if not cfg_path.is_file():
|
|
103
|
+
return merged
|
|
104
|
+
with open(cfg_path, encoding="utf-8") as f:
|
|
105
|
+
cfg = _json.load(f)
|
|
106
|
+
mcp_servers = cfg.get("mcpServers") or {}
|
|
107
|
+
for name, spec in mcp_servers.items():
|
|
108
|
+
if not isinstance(spec, dict):
|
|
109
|
+
continue
|
|
110
|
+
# 剥离 _comment / _usage 等说明字段,只留 kind/url/token/env/launcher_arg/note
|
|
111
|
+
clean = {k: v for k, v in spec.items() if not k.startswith("_")}
|
|
112
|
+
# 知识层 server: 注册全部别名,都指向同一份配置
|
|
113
|
+
if name in _KNOWLEDGE_SERVER_ALIASES:
|
|
114
|
+
for alias in _KNOWLEDGE_SERVER_ALIASES:
|
|
115
|
+
merged[alias] = clean
|
|
116
|
+
else:
|
|
117
|
+
merged[name] = clean
|
|
118
|
+
except Exception:
|
|
119
|
+
# 读配置失败绝不能让引擎崩 —— 退回硬编码
|
|
120
|
+
pass
|
|
121
|
+
return merged
|
|
122
|
+
|
|
123
|
+
|
|
61
124
|
def _get_repo_root() -> Path:
|
|
62
125
|
"""从 common.paths 获取仓库根(复用既有工具,不重复造轮子)。"""
|
|
63
126
|
try:
|
|
@@ -76,7 +139,8 @@ class McpRegistry:
|
|
|
76
139
|
|
|
77
140
|
def __init__(self, repo_root: Optional[Path] = None, servers: Optional[dict] = None):
|
|
78
141
|
self._repo = repo_root or _get_repo_root()
|
|
79
|
-
|
|
142
|
+
# 默认从 mcp_config.json 加载(改配置真生效),显式传 servers 时覆盖
|
|
143
|
+
self._servers = servers if servers is not None else _load_servers()
|
|
80
144
|
self._pool: dict[str, Transport] = {}
|
|
81
145
|
self._tool_to_server: Optional[dict[str, str]] = None # 懒构建
|
|
82
146
|
self._index_lock_built = False
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
|
-
"timestamp": "2026-
|
|
2
|
+
"timestamp": "2026-07-02 11:13:44",
|
|
3
3
|
"servers": {
|
|
4
4
|
"qoder-knowledge-graph": {
|
|
5
5
|
"available": true,
|
|
6
|
-
"tools_indexed":
|
|
7
|
-
"latency_ms":
|
|
6
|
+
"tools_indexed": 35,
|
|
7
|
+
"latency_ms": 16.0,
|
|
8
8
|
"sample_tools": [
|
|
9
9
|
"search_code",
|
|
10
10
|
"search_api",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
11
|
+
"search_field",
|
|
12
|
+
"search_style",
|
|
13
13
|
"context_360"
|
|
14
14
|
],
|
|
15
|
-
"spawn_pid":
|
|
15
|
+
"spawn_pid": null,
|
|
16
16
|
"status": "PASS"
|
|
17
17
|
},
|
|
18
18
|
"qoder-zentao": {
|
|
19
19
|
"available": true,
|
|
20
20
|
"tools_indexed": 68,
|
|
21
|
-
"latency_ms":
|
|
21
|
+
"latency_ms": 1625.0,
|
|
22
22
|
"sample_tools": [
|
|
23
23
|
"check_zentao_status",
|
|
24
24
|
"get_zentao_url",
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"get_product",
|
|
27
27
|
"create_product"
|
|
28
28
|
],
|
|
29
|
-
"spawn_pid":
|
|
29
|
+
"spawn_pid": 76064,
|
|
30
30
|
"status": "PASS"
|
|
31
31
|
},
|
|
32
32
|
"qoder-mysql": {
|
|
33
33
|
"available": true,
|
|
34
34
|
"tools_indexed": 6,
|
|
35
|
-
"latency_ms":
|
|
35
|
+
"latency_ms": 500.0,
|
|
36
36
|
"sample_tools": [
|
|
37
37
|
"list_envs",
|
|
38
38
|
"query_schema",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"query_distinct",
|
|
41
41
|
"list_databases"
|
|
42
42
|
],
|
|
43
|
-
"spawn_pid":
|
|
43
|
+
"spawn_pid": 26784,
|
|
44
44
|
"status": "PASS"
|
|
45
45
|
},
|
|
46
46
|
"lanhu": {
|
|
47
47
|
"available": true,
|
|
48
48
|
"tools_indexed": 13,
|
|
49
|
-
"latency_ms":
|
|
49
|
+
"latency_ms": 4906.0,
|
|
50
50
|
"sample_tools": [
|
|
51
51
|
"lanhu_resolve_invite_link",
|
|
52
52
|
"lanhu_list_product_documents",
|
|
@@ -54,14 +54,28 @@
|
|
|
54
54
|
"lanhu_get_ai_analyze_page_result",
|
|
55
55
|
"lanhu_get_designs"
|
|
56
56
|
],
|
|
57
|
-
"spawn_pid":
|
|
57
|
+
"spawn_pid": 14148,
|
|
58
|
+
"status": "PASS"
|
|
59
|
+
},
|
|
60
|
+
"wlinkj-knowledge": {
|
|
61
|
+
"available": true,
|
|
62
|
+
"tools_indexed": 35,
|
|
63
|
+
"latency_ms": 32.0,
|
|
64
|
+
"sample_tools": [
|
|
65
|
+
"search_code",
|
|
66
|
+
"search_api",
|
|
67
|
+
"search_field",
|
|
68
|
+
"search_style",
|
|
69
|
+
"context_360"
|
|
70
|
+
],
|
|
71
|
+
"spawn_pid": null,
|
|
58
72
|
"status": "PASS"
|
|
59
73
|
}
|
|
60
74
|
},
|
|
61
75
|
"call_tool": {
|
|
62
76
|
"status": "PASS",
|
|
63
|
-
"latency_ms":
|
|
64
|
-
"text_preview": "
|
|
77
|
+
"latency_ms": 7281.0,
|
|
78
|
+
"text_preview": "{\"query\": \"保险\", \"platform\": null, \"module\": null, \"total\": 1, \"items\": [{\"type\": \"BUTTON\", \"name\": \"history\", \"label\": \"保险记录\"}]}",
|
|
65
79
|
"is_error": false
|
|
66
80
|
},
|
|
67
81
|
"memory": {
|
|
@@ -69,13 +83,13 @@
|
|
|
69
83
|
"providers": [
|
|
70
84
|
{
|
|
71
85
|
"provider": "McpMemoryProvider",
|
|
72
|
-
"available":
|
|
73
|
-
"hit":
|
|
86
|
+
"available": false,
|
|
87
|
+
"hit": false
|
|
74
88
|
},
|
|
75
89
|
{
|
|
76
90
|
"provider": "FileMemoryCap",
|
|
77
91
|
"available": true,
|
|
78
|
-
"hit":
|
|
92
|
+
"hit": true
|
|
79
93
|
},
|
|
80
94
|
{
|
|
81
95
|
"provider": "NoOpMemoryCap",
|
|
@@ -87,8 +101,8 @@
|
|
|
87
101
|
},
|
|
88
102
|
"summary": {
|
|
89
103
|
"all_pass": true,
|
|
90
|
-
"active_servers":
|
|
91
|
-
"total_servers":
|
|
92
|
-
"total_tools":
|
|
104
|
+
"active_servers": 5,
|
|
105
|
+
"total_servers": 5,
|
|
106
|
+
"total_tools": 157
|
|
93
107
|
}
|
|
94
108
|
}
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
"""carriers.py - 四载体一致性 (Facade 外观模式)
|
|
4
4
|
|
|
5
5
|
v3.0 合并自: check_carriers + check_qoderwork_consistency + sync_carriers。
|
|
6
|
-
|
|
6
|
+
四载体 = 命令/技能的 4 个部署面: Qoder Desktop(含 Quest 模式) / CLI / QoderWork / npm 镜像。
|
|
7
|
+
注意: 这是"部署面"轴,与 capability/registry.py:HOST_TABLE 的"宿主产品"轴正交
|
|
8
|
+
(HOST_TABLE 现列 desktop/work;cli/cloud 后续按需)。
|
|
7
9
|
对外应是 1 个 carriers 命令的子操作 (Facade: 多个细粒度检查统一入口)。
|
|
8
10
|
|
|
9
11
|
用法:
|
|
@@ -485,7 +485,11 @@ def check_index(fix):
|
|
|
485
485
|
print('\n--- 5. 知识图谱 (data/index/) ---')
|
|
486
486
|
age = index_age_days()
|
|
487
487
|
if age is None:
|
|
488
|
-
#
|
|
488
|
+
# 全迁 PG 后 kg.duckdb 废弃:环境配了 PG → 知识层在平台,不报缺失
|
|
489
|
+
if os.environ.get('KNOWLEDGE_BACKEND', '').lower() == 'pg' or 'postgresql' in os.environ.get('DATABASE_URL', ''):
|
|
490
|
+
say(OK, '知识层在平台 PostgreSQL(KNOWLEDGE_BACKEND=pg / DATABASE_URL=pg,不依赖本地 kg.duckdb)')
|
|
491
|
+
return
|
|
492
|
+
# 完全缺失(非 PG 环境)→ 先尝试 team_sync pull 拉管理员建好的 kg.duckdb
|
|
489
493
|
if fix:
|
|
490
494
|
print(' 索引缺失, 先从团队仓库拉取 (team_sync pull)...')
|
|
491
495
|
if run_script('team_sync.py', 'pull', timeout=120):
|
|
@@ -549,7 +553,8 @@ def check_style(fix):
|
|
|
549
553
|
else:
|
|
550
554
|
problem(fname + ' 缺失', '该文件提交在 git 中, 先解决团队同步 (team_sync pull)')
|
|
551
555
|
|
|
552
|
-
# kg.duckdb 知识图谱 (统一存储)
|
|
556
|
+
# kg.duckdb 知识图谱 (统一存储) — 全迁 PG 后知识层在平台,本地 duckdb 废弃
|
|
557
|
+
_pg_mode = os.environ.get('KNOWLEDGE_BACKEND', '').lower() == 'pg' or 'postgresql' in os.environ.get('DATABASE_URL', '')
|
|
553
558
|
kg_path = os.path.join(INDEX_DIR, 'kg.duckdb')
|
|
554
559
|
role = ''
|
|
555
560
|
try:
|
|
@@ -561,7 +566,9 @@ def check_style(fix):
|
|
|
561
566
|
except Exception:
|
|
562
567
|
pass
|
|
563
568
|
|
|
564
|
-
if
|
|
569
|
+
if _pg_mode:
|
|
570
|
+
say(OK, '知识层在平台 PostgreSQL(不依赖本地 kg.duckdb)')
|
|
571
|
+
elif os.path.isfile(kg_path):
|
|
565
572
|
say(OK, 'kg.duckdb 知识图谱 (%d KB)' % (os.path.getsize(kg_path) // 1024))
|
|
566
573
|
# 过期检测
|
|
567
574
|
import time as _t
|
|
File without changes
|
|
Binary file
|