@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,305 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Query and safely mutate Tars ticket tags."""
3
-
4
- import os
5
- import sys
6
- sys.path.insert(0, os.path.join(os.environ["SOLVEA_LIB_DIR"], "skill-runtime"))
7
- from bootstrap import SOLVEA_ENV # noqa: E402,F401
8
-
9
- import argparse
10
- import json
11
- from pathlib import Path
12
- from typing import Any
13
-
14
- import httpx
15
-
16
- from desk_api import DeskApiConfig, request_json, resolve_desk_api_config
17
-
18
-
19
- TAG_LIST_PATH = "/api_v2/tars/api/tags/list"
20
- TICKET_TAGS_PATH = "/api_v2/tars/api/tags/ticket_tags"
21
- BATCH_TICKET_TAGS_PATH = "/api_v2/tars/api/tags/new/getTags"
22
- TAG_SEARCH_PATH = "/api_v2/tars/api/tags/new/find"
23
- BIND_TAGS_PATH = "/api_v2/tars/api/tags/manual/binding"
24
- UNBIND_TAGS_PATH = "/api_v2/tars/api/tags/manual/unbinding"
25
-
26
-
27
- class TagVerificationError(RuntimeError):
28
- def __init__(
29
- self,
30
- *,
31
- before: dict[str, Any],
32
- requested: dict[str, Any],
33
- after: dict[str, Any],
34
- operation: str,
35
- ) -> None:
36
- super().__init__(f"{operation} tag verification failed")
37
- self.evidence = {
38
- "operation": operation,
39
- "before": before,
40
- "requested": requested,
41
- "after": after,
42
- }
43
-
44
-
45
- def list_tags(client: httpx.Client, config: DeskApiConfig) -> Any:
46
- return request_json(client, config, "GET", TAG_LIST_PATH).get("data", [])
47
-
48
-
49
- def get_ticket_tags(
50
- client: httpx.Client,
51
- config: DeskApiConfig,
52
- ticket_number: str,
53
- ) -> dict[str, Any]:
54
- normalized = ticket_number.strip()
55
- if not normalized:
56
- raise ValueError("ticket number cannot be empty")
57
- data = request_json(
58
- client,
59
- config,
60
- "GET",
61
- TICKET_TAGS_PATH,
62
- params={"ticketNum": normalized},
63
- ).get("data", {})
64
- if not isinstance(data, dict):
65
- raise ValueError("ticket tag response data must be an object")
66
- return data
67
-
68
-
69
- def batch_get_ticket_tags(
70
- client: httpx.Client,
71
- config: DeskApiConfig,
72
- ticket_ids: list[int],
73
- ) -> list[Any]:
74
- if not ticket_ids or any(
75
- isinstance(value, bool) or not isinstance(value, int) for value in ticket_ids
76
- ):
77
- raise ValueError("ticketIdList must be a non-empty integer list")
78
- data = request_json(
79
- client,
80
- config,
81
- "POST",
82
- BATCH_TICKET_TAGS_PATH,
83
- json_body={"ticketIdList": ticket_ids},
84
- ).get("data", [])
85
- if not isinstance(data, list):
86
- raise ValueError("batch ticket tag response data must be a list")
87
- return data
88
-
89
-
90
- def search_tags(
91
- client: httpx.Client,
92
- config: DeskApiConfig,
93
- name: str,
94
- ) -> list[Any]:
95
- normalized = name.strip()
96
- if not normalized:
97
- raise ValueError("tag name cannot be empty")
98
- data = request_json(
99
- client,
100
- config,
101
- "GET",
102
- TAG_SEARCH_PATH,
103
- params={"tagName": normalized},
104
- ).get("data", [])
105
- if not isinstance(data, list):
106
- raise ValueError("tag search response data must be a list")
107
- return data
108
-
109
-
110
- def load_ticket_ids_file(path: str | Path) -> list[int]:
111
- payload = json.loads(Path(path).read_text(encoding="utf-8"))
112
- ticket_ids = payload.get("ticketIdList") if isinstance(payload, dict) else None
113
- if not isinstance(ticket_ids, list) or not ticket_ids or any(
114
- isinstance(value, bool) or not isinstance(value, int) for value in ticket_ids
115
- ):
116
- raise ValueError("ticketIdList must be a non-empty integer list")
117
- return ticket_ids
118
-
119
-
120
- def load_tags_file(path: str | Path) -> list[dict[str, int | str]]:
121
- payload = json.loads(Path(path).read_text(encoding="utf-8"))
122
- tags = payload.get("tags") if isinstance(payload, dict) else None
123
- return _normalize_tags(tags)
124
-
125
-
126
- def _normalize_tags(tags: Any) -> list[dict[str, int | str]]:
127
- if not isinstance(tags, list) or not tags:
128
- raise ValueError("tags must be a non-empty list")
129
- normalized = []
130
- for tag in tags:
131
- if (
132
- not isinstance(tag, dict)
133
- or isinstance(tag.get("id"), bool)
134
- or not isinstance(tag.get("id"), int)
135
- ):
136
- raise ValueError("each tag id must be an integer")
137
- if not isinstance(tag.get("name"), str) or not tag["name"].strip():
138
- raise ValueError("each tag name must be non-empty")
139
- normalized.append({"id": tag["id"], "name": tag["name"].strip()})
140
- return normalized
141
-
142
-
143
- def _user_tag_ids(tag_state: dict[str, Any]) -> set[int]:
144
- values = tag_state.get("userTags", [])
145
- if not isinstance(values, list):
146
- return set()
147
- result = set()
148
- for tag in values:
149
- if not isinstance(tag, dict) or isinstance(tag.get("id"), bool):
150
- continue
151
- try:
152
- result.add(int(tag["id"]))
153
- except (KeyError, TypeError, ValueError):
154
- continue
155
- return result
156
-
157
-
158
- def change_tags(
159
- client: httpx.Client,
160
- config: DeskApiConfig,
161
- *,
162
- operation: str,
163
- ticket_number: str,
164
- tags: list[dict[str, int | str]],
165
- confirmed: bool,
166
- ) -> dict[str, Any]:
167
- if operation not in {"bind", "unbind"}:
168
- raise ValueError("operation must be bind or unbind")
169
- normalized_ticket_number = ticket_number.strip()
170
- if not normalized_ticket_number:
171
- raise ValueError("ticket number cannot be empty")
172
- normalized_tags = _normalize_tags(tags)
173
- before = get_ticket_tags(client, config, normalized_ticket_number)
174
- requested = {"ticketNum": normalized_ticket_number, "tags": normalized_tags}
175
- if not confirmed:
176
- return {
177
- "ok": False,
178
- "status": "confirmation_required",
179
- "operation": operation,
180
- "before": before,
181
- "requested": requested,
182
- }
183
-
184
- path = BIND_TAGS_PATH if operation == "bind" else UNBIND_TAGS_PATH
185
- server_payload = request_json(client, config, "POST", path, json_body=requested)
186
- after = get_ticket_tags(client, config, normalized_ticket_number)
187
- requested_ids = {int(tag["id"]) for tag in normalized_tags}
188
- after_user_ids = _user_tag_ids(after)
189
- verified = (
190
- requested_ids <= after_user_ids
191
- if operation == "bind"
192
- else requested_ids.isdisjoint(after_user_ids)
193
- )
194
- if not verified:
195
- raise TagVerificationError(
196
- before=before,
197
- requested=requested,
198
- after=after,
199
- operation=operation,
200
- )
201
- return {
202
- "ok": True,
203
- "operation": operation,
204
- "verified": True,
205
- "before": before,
206
- "requested": requested,
207
- "after": after,
208
- "server_result": server_payload.get("data"),
209
- }
210
-
211
-
212
- def build_parser() -> argparse.ArgumentParser:
213
- parser = argparse.ArgumentParser(description="Query and manage Shulex Desk ticket tags")
214
- subparsers = parser.add_subparsers(dest="operation", required=True)
215
- subparsers.add_parser("list-tags", help="Return the complete Tars tag tree")
216
-
217
- get_parser = subparsers.add_parser("get-ticket-tags", help="Get one ticket's tags")
218
- get_parser.add_argument("--ticket-number", required=True)
219
-
220
- batch_parser = subparsers.add_parser(
221
- "batch-get-ticket-tags", help="Get tags for internal ticket IDs"
222
- )
223
- batch_parser.add_argument("--ticket-ids-file", required=True)
224
-
225
- search_parser = subparsers.add_parser("search-tags", help="Search tag paths by node name")
226
- search_parser.add_argument("--name", required=True)
227
-
228
- for operation in ("bind-tags", "unbind-tags"):
229
- write_parser = subparsers.add_parser(
230
- operation,
231
- help="Bind tags to a ticket" if operation == "bind-tags" else "Unbind tags from a ticket",
232
- )
233
- write_parser.add_argument("--ticket-number", required=True)
234
- write_parser.add_argument("--tags-file", required=True)
235
- write_parser.add_argument(
236
- "--confirm",
237
- action="store_true",
238
- help="Send the write request after the user explicitly confirms the preview",
239
- )
240
- return parser
241
-
242
-
243
- def main() -> int:
244
- parser = build_parser()
245
- args = parser.parse_args()
246
- config = resolve_desk_api_config()
247
- if not config.token:
248
- print(json.dumps({
249
- "ok": False,
250
- "operation": args.operation,
251
- "error": "desk_runtime_not_configured",
252
- "message": "Check SOLVEA_ENV and the corresponding Solvea token environment variable.",
253
- }, ensure_ascii=False, indent=2))
254
- return 2
255
-
256
- try:
257
- with httpx.Client(timeout=60.0) as client:
258
- if args.operation == "list-tags":
259
- data = list_tags(client, config)
260
- elif args.operation == "get-ticket-tags":
261
- data = get_ticket_tags(client, config, args.ticket_number)
262
- elif args.operation == "batch-get-ticket-tags":
263
- data = batch_get_ticket_tags(
264
- client, config, load_ticket_ids_file(args.ticket_ids_file)
265
- )
266
- elif args.operation == "search-tags":
267
- data = search_tags(client, config, args.name)
268
- else:
269
- data = change_tags(
270
- client,
271
- config,
272
- operation="bind" if args.operation == "bind-tags" else "unbind",
273
- ticket_number=args.ticket_number,
274
- tags=load_tags_file(args.tags_file),
275
- confirmed=args.confirm,
276
- )
277
- except TagVerificationError as exc:
278
- print(json.dumps({
279
- "ok": False,
280
- "operation": args.operation,
281
- "error": type(exc).__name__,
282
- "message": str(exc),
283
- **exc.evidence,
284
- }, ensure_ascii=False, indent=2))
285
- return 3
286
- except (OSError, ValueError, RuntimeError, json.JSONDecodeError, httpx.HTTPError) as exc:
287
- print(json.dumps({
288
- "ok": False,
289
- "operation": args.operation,
290
- "error": type(exc).__name__,
291
- "message": str(exc),
292
- }, ensure_ascii=False, indent=2))
293
- return 1
294
-
295
- result = data if args.operation in {"bind-tags", "unbind-tags"} else {
296
- "ok": True,
297
- "operation": args.operation,
298
- "data": data,
299
- }
300
- print(json.dumps(result, ensure_ascii=False, indent=2))
301
- return 0
302
-
303
-
304
- if __name__ == "__main__":
305
- raise SystemExit(main())
@@ -1,84 +0,0 @@
1
- ---
2
- name: solvea-kit
3
- description: Shulex 路由与运营配置工具包。用于意图、策略、变量系统、AI 质检和标签树的查询与管理;也负责将 Agent/工具/CHAT_FLOW/知识库/测试/数据分析等需求分流到对应 skill。
4
- ---
5
-
6
- # Solvea Kit
7
-
8
- Solvea Kit 保留路由与运营相关配置:意图、策略、变量系统、AI 质检和标签树。Agent、工具、CHAT_FLOW、测试、知识库和分析类需求按下方分流。
9
-
10
- ## Solvea API CLI
11
-
12
- 所有查询与写入操作,均使用 `/skill-lib/solvea-api/solvea_api.py`:
13
-
14
- ```bash
15
- npx --yes @shulex/cxclawctl@latest api <command> --pretty
16
- # 例如:
17
- npx --yes @shulex/cxclawctl@latest api list-agents --pretty
18
- ```
19
-
20
- ## 能力分流
21
-
22
- | 用户诉求 | 去哪里 |
23
- |---|---|
24
- | 通用意图分类实现(供 POC / Delivery 调用) | 本 skill:`scripts/intent_classify.py` |
25
- | 意图创建、查询、更新、启停 | 本 skill:`references/intent.md` |
26
- | 策略创建、查询、更新、启停、entity condition | 本 skill:`references/strategy.md` |
27
- | 变量系统字段查询、初始化、创建、更新、删除、启停 | 本 skill:`references/variables.md` |
28
- | AI 质检开关、规则、自定义规则、预警 | 本 skill:`references/quality-inspection.md` |
29
- | 标签树 / 标签组 / 标签节点 / 批量导入 | 本 skill:`references/tagging.md` |
30
- | SINGLE_AGENT / 语音 Agent / MULTI_AGENT / CHAT_FLOW / 工具配置 | `agent-builder` |
31
- | CHAT_FLOW 图构建、校验、迁移 | `agent-builder` |
32
- | 售前 POC 流程、POC 测试手册 | `poc` |
33
- | 正式交付流程、交付回归 | `delivery` |
34
- | 知识库内容、目录、QA、隔离关键词、回复模板库 | `kb-builder` |
35
- | badcase、异常回复、失败节点,或按 ChatId / External ID 定位会话 | `shulex-support`(优先级高于所有数据分析入口,进入 Agent 会话诊断场景) |
36
- | Agent 运营数据、指标、趋势、原始会话列表下钻(不要求解释异常根因) | `agent-analytics` |
37
- | Shulex Desk 工单查询、报表和标签操作 | `solvea-desk` |
38
- | 售后咨询、创建/查询/追加售后工单 | `shulex-support` |
39
-
40
- ## 核心约束(必须遵守,不用查文档也要记住)
41
-
42
- 1. **统一走 CLI** — 所有查询与写入都通过文档指定的 CLI;鉴权和调用目标由工程逻辑处理,agent 不读取、不切换、不解释底层配置。
43
- 2. **先查后改** — 更新任何资源前必须先 get 或 list 确认现状
44
- 3. **写入配置落 state** — 大 JSON 或待用户确认的配置写 `/workspace/state/solvea-kit/`,不要写 `/workspace/tmp/`
45
- 4. **写入操作需确认** — 修改线上数据前必须与用户确认
46
-
47
- ## 模块文档(按需读取)
48
-
49
- 遇到具体问题时,用 `read_file` 读取对应模块文档:
50
-
51
- | 文档 | 内容 | 何时读 |
52
- |-------------------------------------------------------|------|--------|
53
- | `/skills/solvea-kit/references/intent.md` | 意图管理 | 创建、更新、启用、禁用意图 |
54
- | `/skills/solvea-kit/references/strategy.md` | 策略管理 | 创建、更新、启用、禁用策略;查看 entity condition |
55
- | `/skills/solvea-kit/references/variables.md` | 变量系统管理 | 查询、初始化、创建、更新、删除、启停及使用边界 |
56
- | `/skills/solvea-kit/references/quality-inspection.md` | AI 质检管理 | 查看质检、管理规则/自定义规则/预警 |
57
- | `/skills/solvea-kit/references/tagging.md` | 标签树管理 | 标签组、标签节点、模板下载、批量导入 |
58
-
59
- ## 目录结构
60
-
61
- ```text
62
- solvea-kit/
63
- ├── SKILL.md
64
- ├── scripts/
65
- │ ├── generate_label_import_file.py # 根据标签 JSON 生成标签树导入 xlsx
66
- │ └── intent_classify.py # 通用意图分类实现,POC/Delivery 通过 wrapper 调用
67
- └── references/
68
- ├── intent.md
69
- ├── strategy.md
70
- ├── variables.md # 变量系统管理
71
- ├── quality-inspection.md # AI 质检管理
72
- ├── tagging.md # 标签树管理
73
- ├── agent.md # 历史兼容,不作新入口
74
- ├── plugin.md # 历史兼容,不作新入口
75
- └── chat.md # 历史兼容,不作新入口
76
- ```
77
-
78
- ## 过时文档
79
-
80
- 以下文档暂时保留用于历史兼容,不作为新任务入口:
81
-
82
- - `/skills/solvea-kit/references/agent.md`:已迁入 `agent-builder`
83
- - `/skills/solvea-kit/references/plugin.md`:工具能力已迁入 `agent-builder`
84
- - `/skills/solvea-kit/references/chat.md`:测试和会话分析已拆到 `poc` / `delivery` / `agent-analytics` / `shulex-support`
@@ -1,145 +0,0 @@
1
- # Agent 管理
2
-
3
- > 已过时:Agent 构建、修改、复制、语音 Agent、CHAT_FLOW 和工具绑定已迁入 `agent-builder`。本文件仅保留历史兼容,不作为新任务入口。
4
-
5
- ## 能力概览
6
-
7
- | 类型 | 适用场景 | 何时选用 |
8
- |------|---------|---------|
9
- | SINGLE_AGENT | 单一目标:FAQ问答、查询、生成 | 任务目标明确、不超过3个流程分支、一个 Prompt 能说清职责边界 |
10
- | CHAT_FLOW | 多分支流程:意图分类、条件路由、多步骤处理 | 需要条件分支、人工审批、超过3个流程节点,Prompt 无法涵盖 |
11
- | Voice Agent | 语音对话 | 同上,但 category=voice |
12
-
13
- CHAT_FLOW 图构建、修改、校验和发布由 `chatflow` skill 维护,本文件不展开节点规则。
14
-
15
- ---
16
-
17
- ## SINGLE_AGENT
18
-
19
- ### 能力
20
-
21
- 用户输入 → [Prompt + Tools] → LLM 自主推理(可多轮工具调用) → 输出
22
-
23
- 适用条件:
24
- - 任务目标单一明确(问答、查询、生成)
25
- - 不需要条件分支或人工审批
26
- - 一个 Prompt 能说清职责边界
27
- - 客服FAQ问答、预约助手、数据查询
28
- - 流程不超过3个分支;超过时改用 CHAT_FLOW,太长的 prompt 难以维护
29
-
30
- ### API
31
-
32
- | 操作 | 方法 | 路径 | 说明 |
33
- |------|------|------|------|
34
- | 列表/详情 | POST | `/api_v2/gpt/ap/queryAgent` | 不返回 chatFlowGraph |
35
- | 创建 | POST | `/api_v2/gpt/ap/createAgent` | |
36
- | 更新 | POST | `/api_v2/gpt/ap/updateAgent` | 必须提交完整对象 |
37
-
38
- ### CLI
39
-
40
- ```bash
41
- npx --yes @shulex/cxclawctl@latest api list-agents --pretty
42
- npx --yes @shulex/cxclawctl@latest api get-agent --id <agent_id> --pretty
43
- npx --yes @shulex/cxclawctl@latest api create-agent \
44
- --data '{"name":"FAQ_Bot","type":"SINGLE_AGENT","prompt":"...","displayPrompt":"..."}' --pretty
45
- ```
46
-
47
- ### 原则
48
-
49
- - 更新前必须先 `get-agent` 获取完整对象,`update-agent` 不支持 partial patch
50
- - `prompt` 和 `displayPrompt` 必须同步更新,两者不一致导致执行与展示不符
51
- - `agentId` 字段必须等于 `id`,否则更新失败
52
-
53
- ## Voice Agent
54
-
55
- 语音 Agent 与文本 Agent **共用** `POST /api_v2/gpt/ap/createAgent` / `updateAgent` 接口。后端按 `meta.category == "voice"` 分流到语音处理逻辑。语音对话记录走独立 internal API。
56
-
57
- ### 创建示例
58
-
59
- ```json
60
- {
61
- "projectId": 103,
62
- "name": "Voice_Support",
63
- "description": "客服语音助手",
64
- "type": "SINGLE_AGENT",
65
- "source": "MANUAL",
66
- "prompt": "你是一个语音客服助手。用简短的口语化句子回答,避免列表和 markdown。涉及专业术语时附上通俗解释。",
67
- "displayPrompt": "你是一个语音客服助手。用简短的口语化句子回答,避免列表和 markdown。涉及专业术语时附上通俗解释。",
68
- "meta": {
69
- "category": "voice",
70
- "version": "v1",
71
- "assistant": {
72
- "callType": "INBOUND_PHONE_CALL",
73
- "firstMessage": "您好,请问有什么可以帮您?",
74
- "language": "zh-CN"
75
- },
76
- "knowledgeAiReplyPlugin": {
77
- "type": "KNOWLEDGE_AI_REPLY",
78
- "meta": {
79
- "knowledgeAiReplyConfig": {
80
- "enable": true,
81
- "directoryIds": [32254, 32255],
82
- "useAgentPrompt": true
83
- }
84
- }
85
- }
86
- }
87
- }
88
- ```
89
-
90
- ### 字段说明
91
-
92
- | 字段 | 必填 | 说明 |
93
- |---|---|---|
94
- | `projectId` | ✅ | 当前租户 project ID |
95
- | `name` | ✅ | 长度 ≤ 40 |
96
- | `type` | ✅ | 固定 `SINGLE_AGENT`(MULTI_AGENT 后端会拒) |
97
- | `source` | 推荐 | `MANUAL` 区分手动创建;`SYSTEM` 系统自动生成 |
98
- | `prompt` | 可选 | agent 角色/语气/策略。**和 `displayPrompt` 文本必须一致**(不一致执行与展示分裂) |
99
- | `displayPrompt` | 可选 | 同 `prompt`;不传则后端按 `meta.version` 自动用默认模板 |
100
- | `description` | 可选 | agent 描述 |
101
- | `meta.category` | ✅ | 固定 `"voice"`。**必须放 `meta` 里**,顶层不走语音分流 |
102
- | `meta.version` | 推荐 | `"v1"` 走新版默认 prompt(KB_Reply + Transfer_To_Agent 工具引用) |
103
- | `meta.assistant` | ✅ | 整个对象不能为 null,否则 400 `"Assistant config cannot be empty"` |
104
- | `meta.assistant.callType` | ✅ | 枚举:`INBOUND_PHONE_CALL`(入呼)/ `OUTBOUND_PHONE_CALL`(出呼)/ `WEB_CALL`(网页语音) |
105
- | `meta.assistant.firstMessage` | 可选 | 接通后第一句话 |
106
- | `meta.assistant.language` | 可选 | 语言代码,如 `zh-CN` / `ja-JP` / `en-US`,决定语音识别和合成 |
107
- | `meta.assistant.specials[]` | 可选 | 绑定真实电话号码:`[{phoneNumberId, language}]`。`phoneNumberId` 必须存在且未被其它 agent 绑定 |
108
- | `meta.assistant.voiceTone` | 看场景 | 音色配置。**create 不传**(后端不强制);**update 必传**(含 `voiceId` / `voiceProvider`) |
109
- | `meta.knowledgeAiReplyPlugin` | 可选 | 覆盖后端默认注入的 KB_Reply 内置工具,绑到指定知识库目录 |
110
- | `...knowledgeAiReplyConfig.directoryIds` | 绑 KB 时必填 | 知识库目录 ID 数组(用 `list-directories` 查) |
111
- | `...knowledgeAiReplyConfig.enable` | 绑 KB 时必填 | `true` 启用 KB 检索 |
112
- | `...knowledgeAiReplyConfig.useAgentPrompt` | 推荐 | `true` 让 KB 检索结果用 agent 的 prompt 改写(语气一致) |
113
-
114
- > ⚠️ **上表是完整 schema,没列的字段一律不要发明**。出现 400 优先回看上表,**不要靠改字段组合反复试**(见 rules.md §4 调试预算)。
115
-
116
- ### API 端点
117
-
118
- | 操作 | 方法 | 路径 | 说明 |
119
- |------|------|------|------|
120
- | 列表 | POST | `/api_v2/gpt/ap/queryAgent` | `category=voice` 作为顶层过滤参数 |
121
- | 创建 / 更新 | POST | `/api_v2/gpt/ap/createAgent` 或 `updateAgent` | |
122
- | 对话记录分页 | POST | `/api_v2/as_bot/voice-report/transcript-page` | internal.shulex.com |
123
- | 对话详情 | GET | `/api_v2/gpt/voice/transcript/projectId/{pid}/history/{hid}` | internal.shulex.com |
124
-
125
- ### CLI
126
-
127
- ```bash
128
- npx --yes @shulex/cxclawctl@latest api list-voice-agents --pretty
129
-
130
- # 创建:payload 存成 json 文件,避免 shell 转义出问题(多语言 prompt 尤其推荐)
131
- npx --yes @shulex/cxclawctl@latest api create-agent \
132
- --data-file /workspace/tmp/voice_agent_payload.json --pretty
133
-
134
- npx --yes @shulex/cxclawctl@latest api list-voice-transcripts --pretty
135
- npx --yes @shulex/cxclawctl@latest api get-voice-transcript \
136
- --history-id 019d4dac-aa36-744d-8c5d-d54bc3f7e528 --pretty
137
- ```
138
-
139
- ### 注意事项
140
-
141
- - **接口说明**:对话记录接口由 CLI 内部处理域名与鉴权
142
- - **额外 header**:`x-language: cn` + `x-token-domain: .shulex.com`
143
- - **时间戳**:`beginTimestamp` / `endTimestamp` 毫秒级
144
- - 音色 ID 从 `/api_v2/gpt/ap/voiceConfig` 查询,可选条件 gender / language / provider
145
- - `list-voice-agents` 等价于 `list-agents --category voice`