@shulex/cxclawctl 0.1.2 → 0.1.4

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.
Files changed (208) hide show
  1. package/README.md +25 -22
  2. package/capabilities.lock.json +535 -131
  3. package/dist/cli.js +2203 -127
  4. package/dist/cli.js.map +1 -1
  5. package/package.json +20 -6
  6. package/requirements-cli.txt +0 -2
  7. package/skills/__lib__/__init__.py +0 -0
  8. package/skills/__lib__/skill-runtime/bootstrap.py +0 -134
  9. package/skills/__lib__/solvea-api/__init__.py +0 -0
  10. package/skills/__lib__/solvea-api/client.py +0 -1944
  11. package/skills/__lib__/solvea-api/dashboard.py +0 -100
  12. package/skills/__lib__/solvea-api/solvea_api.py +0 -1341
  13. package/skills/agent-analytics/SKILL.md +0 -74
  14. package/skills/agent-analytics/references/chat-report-fields.md +0 -36
  15. package/skills/agent-analytics/references/report-fields.md +0 -130
  16. package/skills/agent-analytics/references/transcript.md +0 -110
  17. package/skills/agent-builder/SKILL.md +0 -42
  18. package/skills/agent-builder/interfaces/fallback-chatflow.md +0 -47
  19. package/skills/agent-builder/references/chatflow/graph-spec.md +0 -259
  20. package/skills/agent-builder/references/chatflow/node-selection.md +0 -89
  21. package/skills/agent-builder/references/chatflow/nodes/agent.md +0 -350
  22. package/skills/agent-builder/references/chatflow/nodes/business-track.md +0 -43
  23. package/skills/agent-builder/references/chatflow/nodes/code.md +0 -157
  24. package/skills/agent-builder/references/chatflow/nodes/collect-order.md +0 -47
  25. package/skills/agent-builder/references/chatflow/nodes/finish.md +0 -34
  26. package/skills/agent-builder/references/chatflow/nodes/human-review.md +0 -60
  27. package/skills/agent-builder/references/chatflow/nodes/if-else.md +0 -100
  28. package/skills/agent-builder/references/chatflow/nodes/intent.md +0 -79
  29. package/skills/agent-builder/references/chatflow/nodes/knowledge-reply.md +0 -43
  30. package/skills/agent-builder/references/chatflow/nodes/llm.md +0 -117
  31. package/skills/agent-builder/references/chatflow/nodes/note.md +0 -38
  32. package/skills/agent-builder/references/chatflow/nodes/question.md +0 -97
  33. package/skills/agent-builder/references/chatflow/nodes/rag-reply.md +0 -68
  34. package/skills/agent-builder/references/chatflow/nodes/reply.md +0 -97
  35. package/skills/agent-builder/references/chatflow/nodes/start.md +0 -35
  36. package/skills/agent-builder/references/chatflow/nodes/sub-graph.md +0 -48
  37. package/skills/agent-builder/references/chatflow/nodes/tool.md +0 -138
  38. package/skills/agent-builder/references/chatflow/nodes/transfer-to-human.md +0 -63
  39. package/skills/agent-builder/references/chatflow/nodes/variable-assignment.md +0 -52
  40. package/skills/agent-builder/references/chatflow/nodes/variable-extract.md +0 -50
  41. package/skills/agent-builder/references/chatflow/nodes/variable-process.md +0 -70
  42. package/skills/agent-builder/references/chatflow/overview.md +0 -53
  43. package/skills/agent-builder/references/chatflow/visual-translation.md +0 -64
  44. package/skills/agent-builder/references/chatflow/workflow.md +0 -134
  45. package/skills/agent-builder/references/multi-agent/create-update.md +0 -185
  46. package/skills/agent-builder/references/multi-agent/graph-spec.md +0 -246
  47. package/skills/agent-builder/references/multi-agent/graph-structure.md +0 -12
  48. package/skills/agent-builder/references/multi-agent/migrate-to-chatflow.md +0 -13
  49. package/skills/agent-builder/references/multi-agent/migration/large.md +0 -554
  50. package/skills/agent-builder/references/multi-agent/migration/principles.md +0 -446
  51. package/skills/agent-builder/references/multi-agent/migration/small.md +0 -225
  52. package/skills/agent-builder/references/multi-agent/orchestration.md +0 -11
  53. package/skills/agent-builder/references/multi-agent/overview.md +0 -48
  54. package/skills/agent-builder/references/multi-agent/update.md +0 -128
  55. package/skills/agent-builder/references/multi-agent/workflow.md +0 -87
  56. package/skills/agent-builder/references/single-agent/overview.md +0 -48
  57. package/skills/agent-builder/references/single-agent/prompt.md +0 -16
  58. package/skills/agent-builder/references/single-agent/tools.md +0 -36
  59. package/skills/agent-builder/references/single-agent/voice.md +0 -46
  60. package/skills/agent-builder/references/tools/http-tool.md +0 -315
  61. package/skills/agent-builder/references/tools/mock-tool.md +0 -279
  62. package/skills/agent-builder/references/tools/overview.md +0 -46
  63. package/skills/agent-builder/references/tools/tool-config.md +0 -43
  64. package/skills/agent-builder/references/tools/x-token.md +0 -34
  65. package/skills/agent-builder/scripts/chatflow/chatflow_builder.py +0 -3458
  66. package/skills/agent-builder/scripts/chatflow/validate_graph.py +0 -1697
  67. package/skills/agent-builder/scripts/copy_marketplace_agent.py +0 -61
  68. package/skills/agent-builder/scripts/multi-agent/legacy_graph_analyzer.py +0 -5974
  69. package/skills/agent-builder/scripts/multi-agent/replay_compare.py +0 -679
  70. package/skills/agent-builder/scripts/patch_agent_tools.py +0 -135
  71. package/skills/agent-builder/scripts/tools/validate_tool_config.py +0 -384
  72. package/skills/agent-tester/SKILL.md +0 -35
  73. package/skills/agent-tester/batch-test/overview.md +0 -86
  74. package/skills/agent-tester/scripts/batch_test_sheet.py +0 -213
  75. package/skills/agent-tester/single-test/badcase-retest.md +0 -85
  76. package/skills/agent-tester/single-test/direct-test.md +0 -24
  77. package/skills/agent-tester/single-test/overview.md +0 -142
  78. package/skills/delivery/SKILL.md +0 -112
  79. package/skills/delivery/interfaces/classify.md +0 -38
  80. package/skills/delivery/interfaces/create-agents.md +0 -89
  81. package/skills/delivery/interfaces/delivery-test.md +0 -67
  82. package/skills/delivery/references/flow.md +0 -40
  83. package/skills/delivery/references/validation.md +0 -15
  84. package/skills/delivery/scripts/batch_test.py +0 -704
  85. package/skills/delivery/scripts/classify.py +0 -22
  86. package/skills/delivery/scripts/create_agents.py +0 -695
  87. package/skills/delivery/scripts/gen_delivery_report.py +0 -335
  88. package/skills/delivery/scripts/gen_excel.py +0 -234
  89. package/skills/delivery/scripts/gen_report.py +0 -208
  90. package/skills/delivery/scripts/plan.py +0 -163
  91. package/skills/delivery/scripts/render.py +0 -713
  92. package/skills/delivery/scripts/render_summary.py +0 -38
  93. package/skills/delivery/scripts/sample_history_cases.py +0 -109
  94. package/skills/kb-builder/SKILL.md +0 -80
  95. package/skills/kb-builder/interfaces/qa-upload.md +0 -55
  96. package/skills/kb-builder/interfaces/web-kb.md +0 -84
  97. package/skills/kb-builder/references/directory.md +0 -373
  98. package/skills/kb-builder/references/export.md +0 -282
  99. package/skills/kb-builder/references/isolation-keywords.md +0 -113
  100. package/skills/kb-builder/references/knowledge.md +0 -153
  101. package/skills/kb-builder/references/product.md +0 -52
  102. package/skills/kb-builder/references/qa-from-help-center.md +0 -58
  103. package/skills/kb-builder/references/qa-from-pdf.md +0 -94
  104. package/skills/kb-builder/references/qa-from-tickets.md +0 -168
  105. package/skills/kb-builder/references/qa-from-web.md +0 -98
  106. package/skills/kb-builder/references/qa-quality.md +0 -73
  107. package/skills/kb-builder/references/reply-template.md +0 -237
  108. package/skills/kb-builder/references/tag-isolation-migration.md +0 -61
  109. package/skills/kb-builder/references/tags.md +0 -45
  110. package/skills/kb-builder/references/upload.md +0 -130
  111. package/skills/kb-builder/scripts/batch_extract_ticket_qa.py +0 -333
  112. package/skills/kb-builder/scripts/build_directory_plan.py +0 -144
  113. package/skills/kb-builder/scripts/crawl_site.py +0 -433
  114. package/skills/kb-builder/scripts/create_dirs.py +0 -146
  115. package/skills/kb-builder/scripts/export_knowledge.py +0 -454
  116. package/skills/kb-builder/scripts/extract_ticket_qa.py +0 -441
  117. package/skills/kb-builder/scripts/extract_web_qa.py +0 -118
  118. package/skills/kb-builder/scripts/import_qa.py +0 -219
  119. package/skills/kb-builder/scripts/import_source_documents.py +0 -143
  120. package/skills/kb-builder/scripts/import_templates.py +0 -409
  121. package/skills/poc/SKILL.md +0 -125
  122. package/skills/poc/assets/default_manual.css +0 -279
  123. package/skills/poc/assets/notice_escalate.png +0 -0
  124. package/skills/poc/assets/notice_escalate2.png +0 -0
  125. package/skills/poc/assets/notice_new_chat.png +0 -0
  126. package/skills/poc/assets/poc_test_template.html +0 -645
  127. package/skills/poc/assets/poc_test_template.md +0 -104
  128. package/skills/poc/assets/step3_preview.png +0 -0
  129. package/skills/poc/assets/step4_order_note.png +0 -0
  130. package/skills/poc/interfaces/classify.md +0 -38
  131. package/skills/poc/interfaces/create-agents.md +0 -108
  132. package/skills/poc/interfaces/poc-test.md +0 -94
  133. package/skills/poc/references/flow.md +0 -47
  134. package/skills/poc/references/kb-directory.md +0 -22
  135. package/skills/poc/references/validation.md +0 -17
  136. package/skills/poc/scripts/classify.py +0 -22
  137. package/skills/poc/scripts/create_agents.py +0 -818
  138. package/skills/poc/scripts/gen_excel.py +0 -234
  139. package/skills/poc/scripts/gen_poc_manual.py +0 -249
  140. package/skills/poc/scripts/gen_report.py +0 -208
  141. package/skills/poc/scripts/inspect_chatflow.py +0 -209
  142. package/skills/poc/scripts/plan.py +0 -178
  143. package/skills/poc/scripts/poc_test.py +0 -495
  144. package/skills/poc/scripts/render.py +0 -713
  145. package/skills/poc/scripts/render_summary.py +0 -41
  146. package/skills/runtime-inspector/SKILL.md +0 -51
  147. package/skills/runtime-inspector/references/frontend-rendering.md +0 -126
  148. package/skills/runtime-inspector/references/model.md +0 -59
  149. package/skills/runtime-inspector/references/sandbox.md +0 -131
  150. package/skills/runtime-inspector/scripts/model_inspect.py +0 -68
  151. package/skills/runtime-inspector/scripts/prepare.py +0 -98
  152. package/skills/runtime-inspector/scripts/process.py +0 -84
  153. package/skills/runtime-inspector/scripts/read_state.py +0 -32
  154. package/skills/runtime-inspector/scripts/sandbox_inspect.py +0 -463
  155. package/skills/runtime-inspector/scripts/test_claude_proxy.py +0 -49
  156. package/skills/runtime-inspector/scripts/test_openai_proxy.py +0 -41
  157. package/skills/runtime-inspector/scripts/verify_persistence.py +0 -101
  158. package/skills/runtime-inspector/scripts/write_test.py +0 -41
  159. package/skills/setup/SKILL.md +0 -17
  160. package/skills/shulex-support/SKILL.md +0 -39
  161. package/skills/shulex-support/references/badcase-analysis/overview.md +0 -34
  162. package/skills/shulex-support/references/badcase-analysis/text/conversation-record.md +0 -105
  163. package/skills/shulex-support/references/badcase-analysis/text/core-flow.md +0 -89
  164. package/skills/shulex-support/references/badcase-analysis/text/log-query-rules.md +0 -36
  165. package/skills/shulex-support/references/badcase-analysis/text/m1-entry.md +0 -53
  166. package/skills/shulex-support/references/badcase-analysis/text/m10-chatflow-service.md +0 -259
  167. package/skills/shulex-support/references/badcase-analysis/text/m11-algorithm-service.md +0 -148
  168. package/skills/shulex-support/references/badcase-analysis/text/m12-quality-inspection.md +0 -57
  169. package/skills/shulex-support/references/badcase-analysis/text/m2-intent.md +0 -120
  170. package/skills/shulex-support/references/badcase-analysis/text/m3-strategy.md +0 -126
  171. package/skills/shulex-support/references/badcase-analysis/text/m4-aifield.md +0 -121
  172. package/skills/shulex-support/references/badcase-analysis/text/m5-agent.md +0 -208
  173. package/skills/shulex-support/references/badcase-analysis/text/m6-tool.md +0 -115
  174. package/skills/shulex-support/references/badcase-analysis/text/m7-reply.md +0 -72
  175. package/skills/shulex-support/references/badcase-analysis/text/m8-error.md +0 -92
  176. package/skills/shulex-support/references/badcase-analysis/text/m9-knowledge-search.md +0 -147
  177. package/skills/shulex-support/references/badcase-analysis/text/sls-query.md +0 -283
  178. package/skills/shulex-support/references/badcase-analysis/voice/core-flow.md +0 -77
  179. package/skills/shulex-support/references/badcase-analysis/voice/dependencies.md +0 -19
  180. package/skills/shulex-support/references/badcase-analysis/voice/platform-api.md +0 -23
  181. package/skills/shulex-support/references/badcase-analysis/voice/sls-playbook.md +0 -31
  182. package/skills/shulex-support/references/product-docs.md +0 -70
  183. package/skills/shulex-support/references/tickets.md +0 -184
  184. package/skills/shulex-support/scripts/support.py +0 -427
  185. package/skills/solvea-desk/SKILL.md +0 -39
  186. package/skills/solvea-desk/references/report/fields.md +0 -82
  187. package/skills/solvea-desk/references/report/report-design.md +0 -200
  188. package/skills/solvea-desk/references/report/report-template.html +0 -44
  189. package/skills/solvea-desk/references/report/report.css +0 -517
  190. package/skills/solvea-desk/references/report/workflow.md +0 -464
  191. package/skills/solvea-desk/references/tickets/query.md +0 -103
  192. package/skills/solvea-desk/references/tickets/tags.md +0 -83
  193. package/skills/solvea-desk/scripts/report/fetch_sources.py +0 -580
  194. package/skills/solvea-desk/scripts/report/render_report.py +0 -763
  195. package/skills/solvea-desk/scripts/tickets/desk_api.py +0 -73
  196. package/skills/solvea-desk/scripts/tickets/fetch_tickets.py +0 -403
  197. package/skills/solvea-desk/scripts/tickets/ticket_tags.py +0 -305
  198. package/skills/solvea-kit/SKILL.md +0 -84
  199. package/skills/solvea-kit/references/agent.md +0 -145
  200. package/skills/solvea-kit/references/chat.md +0 -244
  201. package/skills/solvea-kit/references/intent.md +0 -69
  202. package/skills/solvea-kit/references/plugin.md +0 -53
  203. package/skills/solvea-kit/references/quality-inspection.md +0 -75
  204. package/skills/solvea-kit/references/strategy.md +0 -62
  205. package/skills/solvea-kit/references/tagging.md +0 -231
  206. package/skills/solvea-kit/references/variables.md +0 -53
  207. package/skills/solvea-kit/scripts/generate_label_import_file.py +0 -151
  208. package/skills/solvea-kit/scripts/intent_classify.py +0 -843
@@ -1,209 +0,0 @@
1
- #!/usr/bin/env python3
2
- """为 POC 案例设计精简 chatflow 图视图。
3
-
4
- 把 raw graph(完整 nodes/edges + UUID + 渲染坐标)压成 agent 看一眼就能设计 case 的形态:
5
- - 节点按 category 提取**业务关键字段**(NOTE 的 noteText、AGENT/REPLY 的 prompt、
6
- INTENT 的 intents 列表、TOOL 的 inputParams 等),不仅是字段名
7
- - edge label 中的 intent uuid / next_step uuid **自动解码**为人类可读的名字
8
- - 去掉 position 坐标、UUID 中段(保留前 8 位)等纯渲染元素
9
-
10
- 为什么这段不放 solvea-api:solvea-api 是纯封装层(API + CLI 透传),不掺业务视图加工。
11
- 这种 POC 设计 case 的特定 view 属于 poc skill 自己的职责。
12
-
13
- 用法:
14
- python3 inspect_chatflow.py --agent-id 38099 --pretty
15
- python3 inspect_chatflow.py --agent-id 38099 --agent-id 38100 --agent-id 38101 --pretty
16
- """
17
- import argparse
18
- import json
19
- import os
20
- import sys
21
-
22
- sys.path.insert(0, os.path.join(os.environ.get("SOLVEA_LIB_DIR", os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "__lib__"))), "skill-runtime"))
23
- from bootstrap import * # noqa: F401,F403
24
- from client import SolveaClient
25
-
26
-
27
- # 长 prompt 的截断阈值;prompt / desc 超过这个长度时尾部加 …<truncated>
28
- _PROMPT_TRUNCATE = 1500
29
-
30
-
31
- def _truncate(text: str, limit: int = _PROMPT_TRUNCATE) -> str:
32
- if not isinstance(text, str):
33
- return text
34
- if len(text) <= limit:
35
- return text
36
- return text[:limit] + f"\n…<truncated, total {len(text)} chars>"
37
-
38
-
39
- def _short_id(uuid: str) -> str:
40
- return (uuid or "")[:8]
41
-
42
-
43
- def _summarize_node(n: dict) -> dict:
44
- """按 category 提取关键业务字段。未识别的 category 退回到 raw config。"""
45
- data = n.get("data") or {}
46
- config = data.get("config") or {}
47
- category = data.get("category") or ""
48
- title = data.get("title") or "(start)"
49
-
50
- out: dict = {
51
- "id": _short_id(n.get("id")),
52
- "category": category,
53
- "title": title,
54
- }
55
- desc = data.get("desc")
56
- if desc:
57
- out["desc"] = desc
58
-
59
- if category == "START":
60
- return out
61
-
62
- if category == "NOTE":
63
- out["note_text"] = config.get("noteText", "")
64
- return out
65
-
66
- if category in ("AGENT", "KNOWLEDGE_REPLY"):
67
- agent_data = config.get("agentData") or {}
68
- prompt = agent_data.get("prompt") or (config.get("knowledgeReply") or {}).get("prompt")
69
- if prompt:
70
- out["prompt"] = _truncate(prompt)
71
- next_steps = config.get("nextStep") or []
72
- if next_steps:
73
- out["next_step"] = [
74
- {k: v for k, v in {"id": ns.get("id"), "title": ns.get("title"), "prompt": _truncate(ns.get("prompt") or "", 300)}.items() if v}
75
- for ns in next_steps
76
- ]
77
- if config.get("maxRounds"):
78
- out["max_rounds"] = config["maxRounds"]
79
- return out
80
-
81
- if category == "REPLY":
82
- rc = config.get("replyContent") or {}
83
- if rc.get("prompt"):
84
- out["reply_prompt"] = _truncate(rc["prompt"])
85
- if rc.get("type") and rc["type"] != "PROMPT":
86
- out["reply_type"] = rc["type"]
87
- return out
88
-
89
- if category == "INTENT":
90
- out["intents"] = [
91
- {k: v for k, v in {"id": it.get("id"), "name": it.get("name"), "desc": _truncate(it.get("desc") or "", 400)}.items() if v}
92
- for it in (config.get("intents") or [])
93
- ]
94
- return out
95
-
96
- if category == "TOOL":
97
- tool = config.get("tool") or {}
98
- out["tool_id"] = tool.get("id")
99
- out["tool_type"] = tool.get("type")
100
- params = tool.get("inputParams") or []
101
- if params:
102
- out["input_params"] = [
103
- {"name": p.get("name"), "var_type": p.get("varType"), "from": p.get("variableSelector")}
104
- for p in params
105
- ]
106
- return out
107
-
108
- if category == "VARIABLE_EXTRACT":
109
- ve = config.get("variableExtract") or {}
110
- out["extracts"] = [
111
- {k: v for k, v in {"name": e.get("name"), "describe": e.get("describe"), "type": e.get("type")}.items() if v}
112
- for e in (ve.get("extracts") or [])
113
- ]
114
- return out
115
-
116
- if category == "VARIABLE_ASSIGNMENT":
117
- out["assignments"] = [
118
- {"source": a.get("source"), "target": a.get("target"), "operation": a.get("operation")}
119
- for a in (config.get("variableAssignment") or [])
120
- ]
121
- return out
122
-
123
- if category == "TRANSFER_TO_HUMAN":
124
- h = config.get("transferToHuman") or {}
125
- if h.get("prompt"):
126
- out["handoff_prompt"] = _truncate(h["prompt"])
127
- return out
128
-
129
- # 未知 category:保留原始 config(截断长字符串)便于后续扩展
130
- if config:
131
- out["config"] = config
132
- return out
133
-
134
-
135
- def _build_handle_index(raw_nodes: list) -> dict:
136
- """构造 source_handle uuid → 可读 label 的反查表。
137
-
138
- INTENT 节点的 intents[].id 和 AGENT/KNOWLEDGE_REPLY 节点的 nextStep[].id 都是 uuid,
139
- 会出现在 edge.sourceHandle 上。把它们映射成 `[Intent] xxx` / `[NextStep] xxx`,
140
- edge label 立刻可读,不再是裸 uuid。
141
- """
142
- idx: dict[str, str] = {}
143
- for n in raw_nodes:
144
- data = n.get("data") or {}
145
- config = data.get("config") or {}
146
- category = data.get("category") or ""
147
- if category == "INTENT":
148
- for it in (config.get("intents") or []):
149
- if it.get("id") and it.get("name"):
150
- idx[it["id"]] = f"[Intent] {it['name']}"
151
- elif category in ("AGENT", "KNOWLEDGE_REPLY"):
152
- for ns in (config.get("nextStep") or []):
153
- if ns.get("id") and ns.get("title"):
154
- idx[ns["id"]] = f"[NextStep] {ns['title']}"
155
- return idx
156
-
157
-
158
- def build_summary(client: SolveaClient, agent_id: int) -> dict:
159
- g = client.get_chatflow_graph(agent_id)
160
- graph = g.get("graph") or {}
161
- raw_nodes = graph.get("nodes") or []
162
- raw_edges = graph.get("edges") or []
163
- by_id = {n.get("id"): n for n in raw_nodes}
164
- handle_idx = _build_handle_index(raw_nodes)
165
-
166
- def _title(nid):
167
- return ((by_id.get(nid) or {}).get("data") or {}).get("title") or "(start)"
168
-
169
- nodes = [_summarize_node(n) for n in raw_nodes]
170
-
171
- edges = []
172
- for e in raw_edges:
173
- handle = e.get("sourceHandle") or ""
174
- # 优先解码 intent / next_step uuid,否则回退到 handle 原值
175
- label = handle_idx.get(handle) or handle or e.get("label") or ""
176
- edges.append({
177
- "from": f"{_short_id(e.get('source'))} ({_title(e.get('source'))})",
178
- "to": f"{_short_id(e.get('target'))} ({_title(e.get('target'))})",
179
- "label": label,
180
- })
181
-
182
- return {
183
- "agent_id": g.get("agentId"),
184
- "version": g.get("chatFlowVersion") or g.get("version"),
185
- "stats": {"nodes": len(raw_nodes), "edges": len(raw_edges)},
186
- "nodes": nodes,
187
- "edges": edges,
188
- }
189
-
190
-
191
- def main():
192
- p = argparse.ArgumentParser(description="Inspect chatflow graph for POC case design")
193
- p.add_argument("--agent-id", type=int, action="append", required=True,
194
- help="Agent ID (可重复传多个,例如 --agent-id 38099 --agent-id 38100)")
195
- p.add_argument("--pretty", action="store_true", help="Pretty print JSON")
196
- args = p.parse_args()
197
-
198
- client = SolveaClient()
199
- result = [build_summary(client, aid) for aid in args.agent_id]
200
- out = result[0] if len(result) == 1 else result
201
-
202
- if args.pretty:
203
- print(json.dumps(out, indent=2, ensure_ascii=False))
204
- else:
205
- print(json.dumps(out, ensure_ascii=False))
206
-
207
-
208
- if __name__ == "__main__":
209
- main()
@@ -1,178 +0,0 @@
1
- #!/usr/bin/env python3
2
- """POC 顶层状态规划器。
3
-
4
- 只维护 `/workspace/state/poc/progress.json`,不执行 intent / agent / KB / batch
5
- 等底层能力。其他 skill 的状态只通过路径引用记录在本文件中,避免职责泄漏。
6
- """
7
- import os, sys
8
- sys.path.insert(0, os.path.join(os.environ.get("SOLVEA_LIB_DIR", os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "__lib__"))), "skill-runtime"))
9
- from bootstrap import * # noqa: F401,F403
10
-
11
- import argparse
12
- import json
13
- from datetime import datetime, timezone
14
- from typing import Any
15
-
16
-
17
- STATE_FILE = STATE_DIR / "progress.json"
18
-
19
- STATUS_ORDER = [
20
- "empty",
21
- "classified",
22
- "business_agents_created",
23
- "fallback_agent_created",
24
- "fallback_strategy_linked",
25
- "kb_done",
26
- "cases_ready",
27
- "test_done",
28
- "done",
29
- ]
30
-
31
-
32
- def default_state() -> dict[str, Any]:
33
- return {
34
- "status": "empty",
35
- "tenant": SOLVEA_TENANT_ID or "",
36
- "brand_name": "",
37
- "brand_website": "",
38
- "intent": {
39
- "progress_path": "/workspace/state/poc/progress.json",
40
- "created_log_path": "",
41
- "classification_report_path": "",
42
- "classification_excel_path": "",
43
- },
44
- "fallback_agent": {
45
- "agent_id": "",
46
- "agent_name": "",
47
- "created": False,
48
- },
49
- "kb": {
50
- "enabled": False,
51
- "source_url": "",
52
- "directory_plan_path": "",
53
- "qa_plan_path": "",
54
- "upload_result_path": "",
55
- },
56
- "test": {
57
- "agents": [],
58
- "cases_json_path": "",
59
- "results_path": "",
60
- "manual_path": "",
61
- },
62
- "updated_at": "",
63
- }
64
-
65
-
66
- def read_state() -> dict[str, Any]:
67
- if not STATE_FILE.exists():
68
- return default_state()
69
- try:
70
- loaded = json.loads(STATE_FILE.read_text(encoding="utf-8"))
71
- except Exception:
72
- return default_state()
73
- state = default_state()
74
- merge_dict(state, loaded)
75
- return state
76
-
77
-
78
- def merge_dict(base: dict[str, Any], patch: dict[str, Any]) -> None:
79
- for key, value in patch.items():
80
- if isinstance(value, dict) and isinstance(base.get(key), dict):
81
- merge_dict(base[key], value)
82
- else:
83
- base[key] = value
84
-
85
-
86
- def write_state(state: dict[str, Any]) -> None:
87
- state["updated_at"] = datetime.now(timezone.utc).isoformat()
88
- STATE_FILE.parent.mkdir(parents=True, exist_ok=True)
89
- STATE_FILE.write_text(json.dumps(state, ensure_ascii=False, indent=2), encoding="utf-8")
90
-
91
-
92
- def set_path(state: dict[str, Any], dotted_key: str, raw_value: str) -> None:
93
- parts = [p for p in dotted_key.split(".") if p]
94
- if not parts:
95
- raise ValueError("empty key")
96
- cur = state
97
- for part in parts[:-1]:
98
- nxt = cur.get(part)
99
- if not isinstance(nxt, dict):
100
- nxt = {}
101
- cur[part] = nxt
102
- cur = nxt
103
- value: Any = raw_value
104
- if raw_value.lower() == "true":
105
- value = True
106
- elif raw_value.lower() == "false":
107
- value = False
108
- elif raw_value.startswith("[") or raw_value.startswith("{"):
109
- value = json.loads(raw_value)
110
- cur[parts[-1]] = value
111
-
112
-
113
- def recommendation(status: str) -> str:
114
- return {
115
- "empty": "下一步:读取 poc/interfaces/classify.md 和 poc/interfaces/create-agents.md,确认从 xlsx 分类还是固定 7 意图开始。",
116
- "classified": "下一步:展示分类结果并等待用户确认;确认后调用 /skills/poc/scripts/create_agents.py --mode poc。",
117
- "business_agents_created": "下一步:通过 agent-builder/interfaces/fallback-chatflow.md 创建兜底 CHAT_FLOW agent。",
118
- "fallback_agent_created": "下一步:调用 /skills/poc/scripts/create_agents.py --mode poc --poc-fallback-agent-id <agent_id> 绑定兜底策略。",
119
- "fallback_strategy_linked": "下一步:询问是否进入可选 KB 阶段;跳过则进入 POC 批测。",
120
- "kb_done": "下一步:读取 poc/interfaces/poc-test.md,设计并确认测试 cases。",
121
- "cases_ready": "下一步:执行 poc_test.py,然后生成 POC 测试手册。",
122
- "test_done": "下一步:汇总 POC 测试手册和原始结果,确认交付完成。",
123
- "done": "当前 POC 已完成;如需重跑,请明确要重跑的阶段。",
124
- }.get(status, "状态未知:请检查 progress.json。")
125
-
126
-
127
- def main() -> None:
128
- parser = argparse.ArgumentParser(description="POC top-level progress planner")
129
- parser.add_argument("--init", action="store_true", help="Create progress.json if missing")
130
- parser.add_argument("--status", choices=STATUS_ORDER, help="Update top-level status")
131
- parser.add_argument("--tenant", default=None)
132
- parser.add_argument("--brand-name", default=None)
133
- parser.add_argument("--brand-website", default=None)
134
- parser.add_argument("--set", action="append", default=[], metavar="KEY=VALUE",
135
- help="Set a dotted state path, e.g. intent.created_log_path=/workspace/...")
136
- parser.add_argument("--json", action="store_true", help="Print JSON only")
137
- args = parser.parse_args()
138
-
139
- existed = STATE_FILE.exists()
140
- state = read_state()
141
- changed = False
142
-
143
- if args.init and not existed:
144
- changed = True
145
- if args.status:
146
- state["status"] = args.status
147
- changed = True
148
- if args.tenant is not None:
149
- state["tenant"] = args.tenant
150
- changed = True
151
- if args.brand_name is not None:
152
- state["brand_name"] = args.brand_name
153
- changed = True
154
- if args.brand_website is not None:
155
- state["brand_website"] = args.brand_website
156
- changed = True
157
- for item in args.set:
158
- if "=" not in item:
159
- raise SystemExit(f"--set expects KEY=VALUE, got: {item}")
160
- key, value = item.split("=", 1)
161
- set_path(state, key, value)
162
- changed = True
163
-
164
- if changed:
165
- write_state(state)
166
-
167
- if args.json:
168
- print(json.dumps(state, ensure_ascii=False, indent=2))
169
- return
170
-
171
- print(f"POC progress: {STATE_FILE}")
172
- print(f"status={state.get('status')} tenant={state.get('tenant') or '-'} brand={state.get('brand_name') or '-'}")
173
- print(recommendation(str(state.get("status") or "")))
174
- print(json.dumps(state, ensure_ascii=False, indent=2))
175
-
176
-
177
- if __name__ == "__main__":
178
- main()