@tencent-rtc/trtc-agent-skills 0.1.3 → 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 (360) hide show
  1. package/.cursor/rules/main.mdc +12 -0
  2. package/AGENTS.md +14 -104
  3. package/CLAUDE.md +15 -127
  4. package/CODEBUDDY.md +32 -118
  5. package/README.md +7 -5
  6. package/README.zh.md +7 -5
  7. package/bin/cli.js +133 -41
  8. package/hooks/__pycache__/cursor-adapter.cpython-313.pyc +0 -0
  9. package/hooks/cursor-adapter.py +45 -18
  10. package/hooks/hooks-cursor.json +5 -18
  11. package/hooks/hooks.json +6 -31
  12. package/knowledge-base/conference/web/index.yaml +143 -0
  13. package/knowledge-base/platform-slice-template.md +1041 -133
  14. package/knowledge-base/products.yaml +76 -0
  15. package/knowledge-base/scenario-spec.md +1316 -115
  16. package/knowledge-base/scenarios/conference/base/general-conference.md +22 -2
  17. package/knowledge-base/scenarios/conference/base/webinar-conference.md +14 -0
  18. package/knowledge-base/scenarios/conference/medical/1v1-video-consultation.md +19 -0
  19. package/knowledge-base/scenarios/conference/medical/medical-multidoctor-consultation.md +13 -0
  20. package/knowledge-base/scenarios/live/entertainment-live-room.md +12 -0
  21. package/knowledge-base/slice-spec.md +2377 -299
  22. package/knowledge-base/slices/conference/web/integration-audit.md +1 -1
  23. package/knowledge-base/slices/conference/web/login-auth.md +14 -1
  24. package/knowledge-base/tooling/aliases.yaml +92 -0
  25. package/knowledge-base/tooling/intent-signals.yaml +181 -0
  26. package/knowledge-base/tooling/symptom-keywords.yaml +21 -0
  27. package/package.json +1 -1
  28. package/skills/trtc/SKILL.md +202 -245
  29. package/skills/trtc/hooks/__pycache__/report_prompt.cpython-313.pyc +0 -0
  30. package/skills/{trtc-topic/guardrails → trtc/hooks}/gate_slice_read.py +12 -8
  31. package/skills/{trtc-topic/guardrails → trtc/hooks}/gate_slice_write.py +16 -12
  32. package/skills/{trtc-topic/guardrails → trtc/hooks}/stop_require_apply_evidence.py +22 -14
  33. package/skills/trtc/hooks/topic_phase_gate.py +161 -0
  34. package/skills/{trtc-topic → trtc}/runtime/README.md +2 -2
  35. package/skills/{trtc-onboarding/reference/reporting-protocol.md → trtc/runtime/REPORTING.md} +5 -5
  36. package/skills/{trtc-topic → trtc}/runtime/RUNTIME.md +5 -5
  37. package/skills/trtc/runtime/lib/__init__.py +0 -0
  38. package/skills/{trtc-topic → trtc}/runtime/package-lock.json +2 -2
  39. package/skills/{trtc-topic → trtc}/runtime/package.json +2 -2
  40. package/skills/{trtc-topic → trtc}/runtime/telemetry-bridge.mjs +1 -1
  41. package/skills/{trtc-topic/scripts → trtc/tools}/STATE-MACHINE-GUIDE.md +23 -23
  42. package/skills/trtc/tools/__init__.py +2 -0
  43. package/skills/trtc/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  44. package/skills/trtc/tools/__pycache__/query_classifier.cpython-313.pyc +0 -0
  45. package/skills/trtc/tools/__pycache__/reporting.cpython-313.pyc +0 -0
  46. package/skills/trtc/tools/__pycache__/search.cpython-313.pyc +0 -0
  47. package/skills/trtc/tools/__pycache__/session.cpython-313.pyc +0 -0
  48. package/skills/trtc/tools/apply.py +540 -0
  49. package/skills/trtc/tools/docs.py +712 -0
  50. package/skills/trtc/tools/docsbot.py +182 -0
  51. package/skills/trtc/tools/entry/render_ai_instructions.py +92 -0
  52. package/skills/trtc/tools/flow.py +1089 -0
  53. package/skills/{trtc-topic/scripts → trtc/tools}/init_slice_queue.py +5 -4
  54. package/skills/{trtc-topic/scripts → trtc/tools}/next_slice.py +5 -4
  55. package/skills/trtc/tools/query_classifier.py +301 -0
  56. package/skills/trtc/tools/reporting.py +447 -0
  57. package/skills/trtc/tools/search.py +817 -0
  58. package/skills/trtc/tools/session.py +1261 -0
  59. package/skills/trtc/tools/state_machine.py +690 -0
  60. package/skills/trtc-ai-service/README.md +195 -0
  61. package/skills/trtc-ai-service/README.zh-CN.md +193 -0
  62. package/skills/trtc-ai-service/SKILL.md +945 -0
  63. package/skills/trtc-ai-service/auto_adapters/README.md +40 -0
  64. package/skills/trtc-ai-service/auto_adapters/frontend-spa/README.md +27 -0
  65. package/skills/trtc-ai-service/auto_adapters/frontend-spa/angular/voice-agent.component.ts.tpl +131 -0
  66. package/skills/trtc-ai-service/auto_adapters/frontend-spa/manifest.yaml +57 -0
  67. package/skills/trtc-ai-service/auto_adapters/frontend-spa/react/VoiceAgent.tsx.tpl +142 -0
  68. package/skills/trtc-ai-service/auto_adapters/frontend-spa/vue/VoiceAgent.vue.tpl +121 -0
  69. package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-backend.md +45 -0
  70. package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-frontend.md +51 -0
  71. package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-rest-api.md +93 -0
  72. package/skills/trtc-ai-service/auto_adapters/java-backend/README.md +25 -0
  73. package/skills/trtc-ai-service/auto_adapters/java-backend/manifest.yaml +30 -0
  74. package/skills/trtc-ai-service/auto_adapters/java-backend/quarkus/VoiceAgentFilter.java.tpl +64 -0
  75. package/skills/trtc-ai-service/auto_adapters/java-backend/springboot/VoiceAgentFilter.java.tpl +91 -0
  76. package/skills/trtc-ai-service/auto_adapters/manifest.yaml +43 -0
  77. package/skills/trtc-ai-service/auto_adapters/node-backend/README.md +25 -0
  78. package/skills/trtc-ai-service/auto_adapters/node-backend/express.js.tpl +40 -0
  79. package/skills/trtc-ai-service/auto_adapters/node-backend/fastify.js.tpl +27 -0
  80. package/skills/trtc-ai-service/auto_adapters/node-backend/koa.js.tpl +31 -0
  81. package/skills/trtc-ai-service/auto_adapters/node-backend/manifest.yaml +47 -0
  82. package/skills/trtc-ai-service/auto_adapters/python-backend/README.md +22 -0
  83. package/skills/trtc-ai-service/auto_adapters/python-backend/django.py.tpl +32 -0
  84. package/skills/trtc-ai-service/auto_adapters/python-backend/fastapi.py.tpl +35 -0
  85. package/skills/trtc-ai-service/auto_adapters/python-backend/flask.py.tpl +31 -0
  86. package/skills/trtc-ai-service/auto_adapters/python-backend/manifest.yaml +45 -0
  87. package/skills/trtc-ai-service/capabilities/__init__.py +43 -0
  88. package/skills/trtc-ai-service/capabilities/conversation-core/.env.example +29 -0
  89. package/skills/trtc-ai-service/capabilities/conversation-core/INTEGRATION.md +134 -0
  90. package/skills/trtc-ai-service/capabilities/conversation-core/INTERFACE_ADAPT.md +111 -0
  91. package/skills/trtc-ai-service/capabilities/conversation-core/QUICK_START.md +62 -0
  92. package/skills/trtc-ai-service/capabilities/conversation-core/manifest.yaml +250 -0
  93. package/skills/trtc-ai-service/capabilities/conversation-core/requirements.txt +6 -0
  94. package/skills/trtc-ai-service/capabilities/conversation-core/src/__init__.py +10 -0
  95. package/skills/trtc-ai-service/capabilities/conversation-core/src/_capability_loader.py +218 -0
  96. package/skills/trtc-ai-service/capabilities/conversation-core/src/agent.py +231 -0
  97. package/skills/trtc-ai-service/capabilities/conversation-core/src/credentials.py +132 -0
  98. package/skills/trtc-ai-service/capabilities/conversation-core/src/health.py +355 -0
  99. package/skills/trtc-ai-service/capabilities/conversation-core/src/log_filter.py +76 -0
  100. package/skills/trtc-ai-service/capabilities/conversation-core/src/modality.py +109 -0
  101. package/skills/trtc-ai-service/capabilities/conversation-core/src/server.py +312 -0
  102. package/skills/trtc-ai-service/capabilities/conversation-core/src/trtc_client.py +315 -0
  103. package/skills/trtc-ai-service/capabilities/conversation-core/src/usersig.py +90 -0
  104. package/skills/trtc-ai-service/capabilities/conversation-core/tests/test_skeleton.py +216 -0
  105. package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/README.md +48 -0
  106. package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/app.js +415 -0
  107. package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/index.html +68 -0
  108. package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/styles.css +136 -0
  109. package/skills/trtc-ai-service/capabilities/digital-human/README.md +31 -0
  110. package/skills/trtc-ai-service/capabilities/digital-human/manifest.yaml +64 -0
  111. package/skills/trtc-ai-service/capabilities/digital-human/src/__init__.py +2 -0
  112. package/skills/trtc-ai-service/capabilities/digital-human/src/router.py +43 -0
  113. package/skills/trtc-ai-service/capabilities/human-handoff/INTERFACE_ADAPT.md +353 -0
  114. package/skills/trtc-ai-service/capabilities/human-handoff/README.md +44 -0
  115. package/skills/trtc-ai-service/capabilities/human-handoff/manifest.yaml +227 -0
  116. package/skills/trtc-ai-service/capabilities/human-handoff/src/__init__.py +2 -0
  117. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/__init__.py +9 -0
  118. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/default_rest.py +242 -0
  119. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/factory.py +89 -0
  120. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/local_queue.py +258 -0
  121. package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/mock.py +132 -0
  122. package/skills/trtc-ai-service/capabilities/human-handoff/src/core/__init__.py +25 -0
  123. package/skills/trtc-ai-service/capabilities/human-handoff/src/core/intent_detector.py +75 -0
  124. package/skills/trtc-ai-service/capabilities/human-handoff/src/core/models.py +163 -0
  125. package/skills/trtc-ai-service/capabilities/human-handoff/src/core/service.py +192 -0
  126. package/skills/trtc-ai-service/capabilities/human-handoff/src/feedback_store.py +54 -0
  127. package/skills/trtc-ai-service/capabilities/human-handoff/src/ports/__init__.py +4 -0
  128. package/skills/trtc-ai-service/capabilities/human-handoff/src/ports/handoff_client.py +86 -0
  129. package/skills/trtc-ai-service/capabilities/human-handoff/src/queue.py +62 -0
  130. package/skills/trtc-ai-service/capabilities/human-handoff/src/router.py +201 -0
  131. package/skills/trtc-ai-service/capabilities/human-handoff/src/summary_link.py +77 -0
  132. package/skills/trtc-ai-service/capabilities/human-handoff/src/trigger.py +25 -0
  133. package/skills/trtc-ai-service/capabilities/knowledge-base/INTERFACE_ADAPT.md +297 -0
  134. package/skills/trtc-ai-service/capabilities/knowledge-base/README.md +51 -0
  135. package/skills/trtc-ai-service/capabilities/knowledge-base/data/faq.json +20 -0
  136. package/skills/trtc-ai-service/capabilities/knowledge-base/manifest.yaml +211 -0
  137. package/skills/trtc-ai-service/capabilities/knowledge-base/src/__init__.py +8 -0
  138. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/__init__.py +9 -0
  139. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/default_rest.py +209 -0
  140. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/factory.py +86 -0
  141. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/local_json.py +172 -0
  142. package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/mock.py +91 -0
  143. package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/__init__.py +12 -0
  144. package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/models.py +77 -0
  145. package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/scoring.py +73 -0
  146. package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/service.py +78 -0
  147. package/skills/trtc-ai-service/capabilities/knowledge-base/src/ports/__init__.py +4 -0
  148. package/skills/trtc-ai-service/capabilities/knowledge-base/src/ports/kb_client.py +61 -0
  149. package/skills/trtc-ai-service/capabilities/knowledge-base/src/retriever.py +56 -0
  150. package/skills/trtc-ai-service/capabilities/knowledge-base/src/router.py +85 -0
  151. package/skills/trtc-ai-service/capabilities/session-summary/INTERFACE_ADAPT.md +99 -0
  152. package/skills/trtc-ai-service/capabilities/session-summary/README.md +47 -0
  153. package/skills/trtc-ai-service/capabilities/session-summary/data/test_session.json +18 -0
  154. package/skills/trtc-ai-service/capabilities/session-summary/manifest.yaml +165 -0
  155. package/skills/trtc-ai-service/capabilities/session-summary/src/__init__.py +2 -0
  156. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/__init__.py +5 -0
  157. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/base.py +31 -0
  158. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/default_rest.py +67 -0
  159. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/factory.py +51 -0
  160. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/local_json.py +42 -0
  161. package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/mock.py +22 -0
  162. package/skills/trtc-ai-service/capabilities/session-summary/src/recorder.py +210 -0
  163. package/skills/trtc-ai-service/capabilities/session-summary/src/router.py +93 -0
  164. package/skills/trtc-ai-service/capabilities/session-summary/src/summarizer.py +163 -0
  165. package/skills/trtc-ai-service/capabilities/tool-calling/INTERFACE_ADAPT.md +158 -0
  166. package/skills/trtc-ai-service/capabilities/tool-calling/README.md +50 -0
  167. package/skills/trtc-ai-service/capabilities/tool-calling/data/tools.yaml +58 -0
  168. package/skills/trtc-ai-service/capabilities/tool-calling/examples/__init__.py +1 -0
  169. package/skills/trtc-ai-service/capabilities/tool-calling/examples/local_tools.py +101 -0
  170. package/skills/trtc-ai-service/capabilities/tool-calling/manifest.yaml +146 -0
  171. package/skills/trtc-ai-service/capabilities/tool-calling/src/__init__.py +8 -0
  172. package/skills/trtc-ai-service/capabilities/tool-calling/src/dispatcher.py +54 -0
  173. package/skills/trtc-ai-service/capabilities/tool-calling/src/registry.py +219 -0
  174. package/skills/trtc-ai-service/capabilities/tool-calling/src/router.py +50 -0
  175. package/skills/trtc-ai-service/references/business-contract-spec.md +263 -0
  176. package/skills/trtc-ai-service/scenarios/custom-builder/README.md +86 -0
  177. package/skills/trtc-ai-service/scenarios/custom-builder/output-templates/recipe.yaml.j2 +194 -0
  178. package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q1-business-scenario.md +43 -0
  179. package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q2-io-modality.md +57 -0
  180. package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q3-ui-form.md +55 -0
  181. package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q4-capabilities.md +78 -0
  182. package/skills/trtc-ai-service/scenarios/customer-service/README.md +114 -0
  183. package/skills/trtc-ai-service/scenarios/customer-service/recipe.yaml +154 -0
  184. package/skills/trtc-ai-service/scenarios/customer-service/sample-data/README.md +32 -0
  185. package/skills/trtc-ai-service/scenarios/customer-service/sample-data/faq-sample.json +37 -0
  186. package/skills/trtc-ai-service/scenarios/customer-service/system-prompt.template.md +94 -0
  187. package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/app.js +347 -0
  188. package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/index.html +125 -0
  189. package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/styles.css +487 -0
  190. package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/tokens.css +71 -0
  191. package/skills/trtc-ai-service/scenarios/customer-service/ui/design-system/DESIGN_GUIDELINES.md +370 -0
  192. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/README.md +68 -0
  193. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/app.js +1307 -0
  194. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/data.js +40 -0
  195. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/index.html +233 -0
  196. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/mock-shop.json +21 -0
  197. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/styles.css +603 -0
  198. package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/tokens.css +71 -0
  199. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/agent-link.js +323 -0
  200. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/app.js +458 -0
  201. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/index.html +109 -0
  202. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/styles.css +489 -0
  203. package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/tokens.css +59 -0
  204. package/skills/trtc-ai-service/scripts/add-capability.py +364 -0
  205. package/skills/trtc-ai-service/scripts/contract-adapt.py +334 -0
  206. package/skills/trtc-ai-service/scripts/detect-stack.py +40 -0
  207. package/skills/trtc-ai-service/scripts/lib/__init__.py +20 -0
  208. package/skills/trtc-ai-service/scripts/lib/adapter_codegen.py +509 -0
  209. package/skills/trtc-ai-service/scripts/lib/arbitrator.py +152 -0
  210. package/skills/trtc-ai-service/scripts/lib/contract_resolver.py +519 -0
  211. package/skills/trtc-ai-service/scripts/lib/credential_validators.py +253 -0
  212. package/skills/trtc-ai-service/scripts/lib/curl_parser.py +303 -0
  213. package/skills/trtc-ai-service/scripts/lib/degrader.py +140 -0
  214. package/skills/trtc-ai-service/scripts/lib/injector.py +347 -0
  215. package/skills/trtc-ai-service/scripts/lib/manifest_resolver.py +288 -0
  216. package/skills/trtc-ai-service/scripts/lib/openapi_parser.py +289 -0
  217. package/skills/trtc-ai-service/scripts/lib/stack_detector.py +159 -0
  218. package/skills/trtc-ai-service/scripts/lib/tokens_compile.py +204 -0
  219. package/skills/trtc-ai-service/scripts/post-install-patch.py +225 -0
  220. package/skills/trtc-ai-service/scripts/setup-credentials.py +393 -0
  221. package/skills/trtc-ai-service/scripts/verify-credentials.py +108 -0
  222. package/skills/trtc-ai-service/start.sh +111 -0
  223. package/skills/trtc-ai-service/tests/__init__.py +1 -0
  224. package/skills/trtc-ai-service/tests/test_arbitrator.py +64 -0
  225. package/skills/trtc-ai-service/tests/test_capability_overlay.py +85 -0
  226. package/skills/trtc-ai-service/tests/test_contract_resolver.py +190 -0
  227. package/skills/trtc-ai-service/tests/test_handoff_ports.py +195 -0
  228. package/skills/trtc-ai-service/tests/test_kb_ports.py +195 -0
  229. package/skills/trtc-ai-service/tests/test_manifest_resolver.py +95 -0
  230. package/skills/trtc-ai-service/tests/test_recipe_assembly.py +175 -0
  231. package/skills/trtc-ai-service/tests/test_stack_and_degrader.py +101 -0
  232. package/skills/trtc-ai-service/tests/test_verify_credentials.py +285 -0
  233. package/skills/trtc-ai-service/triggers.yaml +29 -0
  234. package/skills/trtc-conference/SKILL.md +324 -0
  235. package/skills/trtc-conference/flows/onboarding.md +205 -0
  236. package/skills/trtc-conference/flows/topic.md +474 -0
  237. package/skills/trtc-conference/flows/troubleshoot.md +85 -0
  238. package/skills/trtc-conference/hooks/pretooluse_require_business_decisions.py +213 -0
  239. package/skills/trtc-conference/playbooks/medical-quickstart.md +84 -0
  240. package/skills/trtc-conference/playbooks/official-roomkit.md +97 -0
  241. package/skills/trtc-conference/references/local-usersig/basic-info-config.ts +39 -0
  242. package/skills/trtc-conference/references/usersig-handling.md +134 -0
  243. package/skills/trtc-conference/templates/medical-consultation/src/config/lib-generate-test-usersig-es.min.d.ts +4 -0
  244. package/skills/trtc-conference/templates/medical-consultation/src/config/lib-generate-test-usersig-es.min.js +2 -0
  245. package/skills/trtc-conference/tests/__pycache__/test_conference_onboarding_contract.cpython-313-pytest-9.0.2.pyc +0 -0
  246. package/skills/trtc-conference/tests/__pycache__/test_conference_topic_flow_contract.cpython-313-pytest-9.0.2.pyc +0 -0
  247. package/skills/trtc-conference/tests/test_conference_index_contract.py +43 -0
  248. package/skills/trtc-conference/tests/test_conference_onboarding_contract.py +103 -0
  249. package/skills/trtc-conference/tests/test_conference_template_contract.py +25 -0
  250. package/skills/trtc-conference/tests/test_conference_topic_flow_contract.py +132 -0
  251. package/skills/trtc-conference/tools/apply_checks.py +328 -0
  252. package/skills/trtc-conference/verify_lib/__init__.py +0 -0
  253. package/skills/{trtc-apply/guardrails/apply_lib → trtc-conference/verify_lib}/rule_parser.py +1 -1
  254. package/skills/trtc-docs/SKILL.md +91 -119
  255. package/.cursor/rules/ui-mode.mdc +0 -99
  256. package/ai-instructions/base.md +0 -13
  257. package/ai-instructions/ui-mode.md +0 -93
  258. package/knowledge-base/index.yaml +0 -462
  259. package/skills/trtc/room-builder/SKILL.md +0 -133
  260. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/README.md +0 -108
  261. package/skills/trtc/room-builder/tools/render_ai_instructions.py +0 -226
  262. package/skills/trtc-apply/SKILL.md +0 -97
  263. package/skills/trtc-onboarding/SKILL.md +0 -841
  264. package/skills/trtc-onboarding/reference/path-a1-demo.md +0 -103
  265. package/skills/trtc-onboarding/reference/path-a2-integrate.md +0 -737
  266. package/skills/trtc-onboarding/reference/path-b-troubleshoot.md +0 -186
  267. package/skills/trtc-onboarding/reference/path-c-expand.md +0 -43
  268. package/skills/trtc-onboarding/reference/supported-matrix.md +0 -100
  269. package/skills/trtc-search/SKILL.md +0 -228
  270. package/skills/trtc-topic/SKILL.md +0 -622
  271. package/skills/trtc-topic/scripts/apply.py +0 -581
  272. package/skills/trtc-topic/scripts/lib/state_machine.py +0 -328
  273. package/skills/trtc-topic/tests/README.md +0 -70
  274. package/skills/trtc-topic/tests/conftest.py +0 -72
  275. package/skills/trtc-topic/tests/test_apply_cli.py +0 -480
  276. package/skills/trtc-topic/tests/test_end_to_end.py +0 -305
  277. package/skills/trtc-topic/tests/test_finalize_session.py +0 -51
  278. package/skills/trtc-topic/tests/test_gates.py +0 -316
  279. package/skills/trtc-topic/tests/test_session_resolver.py +0 -260
  280. package/skills/trtc-topic/tests/test_state_machine.py +0 -414
  281. package/skills/trtc-topic/tests/test_stop_require_apply.py +0 -99
  282. package/skills/trtc-topic/tests/test_topic_skill_invariants.py +0 -130
  283. /package/skills/{trtc-topic → trtc}/runtime/lib/platforms.py +0 -0
  284. /package/skills/{trtc-topic → trtc}/runtime/telemetry_collector.py +0 -0
  285. /package/skills/{trtc-onboarding/reference → trtc/runtime}/usersig-handling.md +0 -0
  286. /package/skills/{trtc-topic/scripts → trtc/tools}/finalize_session.py +0 -0
  287. /package/skills/{trtc-apply/guardrails/apply_lib → trtc-ai-service/capabilities/conversation-core/tests}/__init__.py +0 -0
  288. /package/skills/{trtc-topic → trtc-conference}/references/execution-units.yaml +0 -0
  289. /package/skills/{trtc/room-builder/templates/scenarios/medical-consultation/src/config → trtc-conference/references/local-usersig}/lib-generate-test-usersig-es.min.d.ts +0 -0
  290. /package/skills/{trtc/room-builder/templates/scenarios/medical-consultation/src/config → trtc-conference/references/local-usersig}/lib-generate-test-usersig-es.min.js +0 -0
  291. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/backend-contract.zh-CN.md +0 -0
  292. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/integration.zh-CN.md +0 -0
  293. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/theme.zh-CN.md +0 -0
  294. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/index.html +0 -0
  295. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/package.json +0 -0
  296. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/postcss.config.js +0 -0
  297. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/App.vue +0 -0
  298. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/ConsultationManagePanel.vue +0 -0
  299. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/LanguageSwitch.vue +0 -0
  300. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/LoadingSpinner.vue +0 -0
  301. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalAlert.vue +0 -0
  302. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalBusinessPanel.vue +0 -0
  303. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalButton.vue +0 -0
  304. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalConfirmDialog.vue +0 -0
  305. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalDataPanel.vue +0 -0
  306. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalRecordPanel.vue +0 -0
  307. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/PrescriptionPanel.vue +0 -0
  308. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/config/basic-info-config.ts +0 -0
  309. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/config/runtime-config.ts +0 -0
  310. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/env.d.ts +0 -0
  311. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationChatPanel.vue +0 -0
  312. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationMembersPanel.vue +0 -0
  313. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationTranscriptionPanel.vue +0 -0
  314. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationVideoStage.vue +0 -0
  315. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/InviteDoctorDialog.vue +0 -0
  316. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/KickMemberConfirmDialog.vue +0 -0
  317. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/types.ts +0 -0
  318. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationChat.ts +0 -0
  319. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationDevices.ts +0 -0
  320. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationParticipants.ts +0 -0
  321. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationPermissions.ts +0 -0
  322. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/utils.ts +0 -0
  323. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/en-US/index.ts +0 -0
  324. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/index.ts +0 -0
  325. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/medicalTranslate.ts +0 -0
  326. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/state.ts +0 -0
  327. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/zh-CN/index.ts +0 -0
  328. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/main.ts +0 -0
  329. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/mock/appointments.ts +0 -0
  330. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/mock/users.ts +0 -0
  331. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/router/index.ts +0 -0
  332. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/index.ts +0 -0
  333. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/appointmentService.ts +0 -0
  334. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/authService.ts +0 -0
  335. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/launchContext.ts +0 -0
  336. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/userService.ts +0 -0
  337. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/appointmentService.ts +0 -0
  338. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/authService.ts +0 -0
  339. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/userService.ts +0 -0
  340. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/types.ts +0 -0
  341. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/shared/icons.ts +0 -0
  342. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/index.css +0 -0
  343. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/tailwind.css +0 -0
  344. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/theme.css +0 -0
  345. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/auth.ts +0 -0
  346. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/format.ts +0 -0
  347. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/navigation.ts +0 -0
  348. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/session.ts +0 -0
  349. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/DoctorConsultationView.vue +0 -0
  350. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/DoctorDashboardView.vue +0 -0
  351. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/LoginView.vue +0 -0
  352. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientConsultationFinishedView.vue +0 -0
  353. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientConsultationView.vue +0 -0
  354. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientSelectDoctorView.vue +0 -0
  355. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientWaitingView.vue +0 -0
  356. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/tsconfig.json +0 -0
  357. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/tsconfig.node.json +0 -0
  358. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/vite.config.ts +0 -0
  359. /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation//346/216/245/345/205/245/350/257/264/346/230/216.md" +0 -0
  360. /package/skills/{trtc-topic/runtime/lib → trtc-conference/tools}/__init__.py +0 -0
@@ -0,0 +1,312 @@
1
+ """FastAPI entry point: exposes skeleton REST API + static Web Demo.
2
+
3
+ Routes:
4
+ GET /api/v1/health —— Real-time connectivity check for 3 keys
5
+ POST /api/v1/get_config —— Generate RoomId / UserSig / modality config
6
+ POST /api/v1/agent/start —— Start AI conversation task
7
+ POST /api/v1/agent/stop —— Stop AI conversation task
8
+ POST /api/v1/agent/control —— Text injection / interrupt
9
+ GET / —— Web Demo static page
10
+
11
+ Design principles (aligned with §3.3):
12
+ - Zero industry assumptions: all routes only do protocol orchestration, no built-in business prompts
13
+ - Configuration as verification: health endpoint provides data source for Web Demo's three LEDs
14
+ - Security compliance: log redaction filter installed at startup; credentials from env vars only
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import logging
19
+ import os
20
+ from pathlib import Path
21
+ from typing import Any, Dict, Optional
22
+
23
+ from dotenv import load_dotenv
24
+
25
+ # Load .env before importing business modules to ensure credentials module reads correct env vars
26
+ _BASE_DIR = Path(__file__).resolve().parent.parent
27
+ load_dotenv(_BASE_DIR / ".env.local")
28
+ load_dotenv(_BASE_DIR / ".env")
29
+
30
+ from fastapi import APIRouter, FastAPI, HTTPException
31
+ from fastapi.middleware.cors import CORSMiddleware
32
+ from fastapi.responses import FileResponse
33
+ from fastapi.staticfiles import StaticFiles
34
+ from pydantic import BaseModel, Field
35
+
36
+ from .agent import ConversationAgent
37
+ from .credentials import load_from_env
38
+ from .health import check_all
39
+ from .log_filter import install_redacting_filter
40
+ from .modality import IoModality
41
+ from .trtc_client import AgentLifecycleConfig
42
+
43
+ logger = logging.getLogger("conversation_core")
44
+
45
+ # Install log redaction filter (P0 security requirement)
46
+ logging.basicConfig(
47
+ level=os.getenv("LOG_LEVEL", "INFO"),
48
+ format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
49
+ )
50
+ install_redacting_filter(logging.getLogger())
51
+
52
+
53
+ # ---------------------------------------------------------------------------
54
+ # Global Agent singleton (startup failure does not prevent /api/v1/health from giving clear diagnostics)
55
+ # ---------------------------------------------------------------------------
56
+ _credentials = load_from_env()
57
+ _io_modality = IoModality() # Phase 1 default: all modalities enabled
58
+ _agent: Optional[ConversationAgent] = None
59
+ _init_error: Optional[str] = None
60
+ try:
61
+ _agent = ConversationAgent(_credentials, _io_modality)
62
+ logger.info("ConversationAgent initialized")
63
+ except Exception as exc: # Credential missing etc. must not crash the process
64
+ _init_error = str(exc)
65
+ logger.warning("ConversationAgent not initialized: %s", _init_error)
66
+
67
+
68
+ # ---------------------------------------------------------------------------
69
+ # Pydantic Models
70
+ # ---------------------------------------------------------------------------
71
+ class GetConfigRequest(BaseModel):
72
+ user_id: Optional[str] = None
73
+ room_id: Optional[str] = None
74
+
75
+
76
+ class StartAgentRequest(BaseModel):
77
+ session_id: str = Field(..., description="session_id returned by get_config")
78
+ instructions: Optional[str] = None
79
+ greeting: Optional[str] = None
80
+ language: Optional[str] = "en" # en | zh
81
+ voice_id: Optional[str] = None # Leave empty to use DEFAULT_VOICE_IDS selected by language
82
+ max_idle_time: Optional[int] = 60
83
+
84
+
85
+ class StopAgentRequest(BaseModel):
86
+ session_id: str
87
+
88
+
89
+ class ControlRequest(BaseModel):
90
+ session_id: str
91
+ text: str
92
+ interrupt: bool = True
93
+
94
+
95
+ # ---------------------------------------------------------------------------
96
+ # FastAPI App
97
+ # ---------------------------------------------------------------------------
98
+ app = FastAPI(
99
+ title="conversation-core",
100
+ version="1.0.0",
101
+ description="TRTC Voice Agent generic skeleton (no business assumptions)",
102
+ )
103
+ app.add_middleware(
104
+ CORSMiddleware,
105
+ allow_origins=["*"],
106
+ allow_credentials=True,
107
+ allow_methods=["*"],
108
+ allow_headers=["*"],
109
+ )
110
+
111
+ api = APIRouter(prefix="/api/v1")
112
+
113
+
114
+ def _to_http_error(exc: Exception) -> HTTPException:
115
+ if isinstance(exc, ValueError):
116
+ return HTTPException(status_code=400, detail=str(exc))
117
+ if isinstance(exc, RuntimeError):
118
+ return HTTPException(status_code=500, detail=str(exc))
119
+ return HTTPException(status_code=500, detail=f"internal: {exc}")
120
+
121
+
122
+ def _require_agent() -> ConversationAgent:
123
+ if _agent is None:
124
+ raise HTTPException(
125
+ status_code=503,
126
+ detail={
127
+ "code": "credentials_missing",
128
+ "message": _init_error or "credentials not configured",
129
+ "hint": "run scripts/setup-credentials.py first",
130
+ },
131
+ )
132
+ return _agent
133
+
134
+
135
+ # ---------------------------------------------------------------------------
136
+ # Health
137
+ # ---------------------------------------------------------------------------
138
+ @api.get("/health")
139
+ def health() -> Dict[str, Any]:
140
+ """Real-time probe of 3 keys' connectivity, used by Web Demo top status bar."""
141
+ cred = load_from_env()
142
+ tc, trtc, llm = check_all(cred.tencent_cloud, cred.trtc, cred.llm)
143
+ overall = "ok" if tc.ok and trtc.ok and llm.ok else "partial_failure"
144
+ return {
145
+ "status": overall,
146
+ "checks": {
147
+ "tencent_cloud": tc.to_dict(),
148
+ "trtc": trtc.to_dict(),
149
+ "llm": llm.to_dict(),
150
+ },
151
+ "configured": cred.fully_configured,
152
+ "missing": cred.missing(),
153
+ "io_modality": _io_modality.to_dict(),
154
+ }
155
+
156
+
157
+ # ---------------------------------------------------------------------------
158
+ # Config / Lifecycle
159
+ # ---------------------------------------------------------------------------
160
+ @api.post("/get_config")
161
+ def get_config(req: GetConfigRequest) -> Dict[str, Any]:
162
+ agent = _require_agent()
163
+ try:
164
+ data = agent.issue_config(user_id=req.user_id, room_id=req.room_id)
165
+ return {"code": 0, "msg": "success", "data": data}
166
+ except Exception as exc:
167
+ raise _to_http_error(exc)
168
+
169
+
170
+ @api.post("/agent/start")
171
+ def agent_start(req: StartAgentRequest) -> Dict[str, Any]:
172
+ agent = _require_agent()
173
+ try:
174
+ defaults = AgentLifecycleConfig()
175
+ cfg = AgentLifecycleConfig(
176
+ instructions=req.instructions or defaults.instructions,
177
+ greeting=req.greeting or defaults.greeting,
178
+ language=req.language or "en",
179
+ voice_id=req.voice_id or "",
180
+ max_idle_time=req.max_idle_time or 60,
181
+ )
182
+ return {"code": 0, "msg": "success", "data": agent.start_agent(req.session_id, cfg)}
183
+ except Exception as exc:
184
+ raise _to_http_error(exc)
185
+
186
+
187
+ @api.post("/agent/stop")
188
+ def agent_stop(req: StopAgentRequest) -> Dict[str, Any]:
189
+ agent = _require_agent()
190
+ try:
191
+ return {"code": 0, "msg": "success", "data": agent.stop_agent(req.session_id)}
192
+ except Exception as exc:
193
+ raise _to_http_error(exc)
194
+
195
+
196
+ @api.post("/agent/control")
197
+ def agent_control(req: ControlRequest) -> Dict[str, Any]:
198
+ agent = _require_agent()
199
+ try:
200
+ return {
201
+ "code": 0,
202
+ "msg": "success",
203
+ "data": agent.push_text(req.session_id, req.text, req.interrupt),
204
+ }
205
+ except Exception as exc:
206
+ raise _to_http_error(exc)
207
+
208
+
209
+ @api.get("/sessions")
210
+ def sessions_list() -> Dict[str, Any]:
211
+ agent = _require_agent()
212
+ return {"code": 0, "data": agent.list_sessions()}
213
+
214
+
215
+ # ---------------------------------------------------------------------------
216
+ # Debug endpoint: for troubleshooting InvalidParameter.UserSig etc.
217
+ # Outputs current config + a test UserSig for comparison against the TRTC official tool:
218
+ # https://console.cloud.tencent.com/trtc/usersigtools
219
+ # Security: only returns SDKAppID / region / endpoint / test UserSig; never exposes plaintext SecretKey
220
+ # ---------------------------------------------------------------------------
221
+ @api.get("/debug/usersig")
222
+ def debug_usersig(user_id: str = "test_user_001") -> Dict[str, Any]:
223
+ cred = load_from_env()
224
+ if not cred.trtc.configured:
225
+ raise HTTPException(status_code=503, detail="TRTC credential not configured")
226
+ from .usersig import gen_user_sig
227
+
228
+ sig = gen_user_sig(
229
+ sdk_app_id=cred.trtc.sdk_app_id,
230
+ sdk_secret_key=cred.trtc.sdk_secret_key,
231
+ user_id=user_id,
232
+ expire_seconds=86400,
233
+ )
234
+ return {
235
+ "sdk_app_id": cred.trtc.sdk_app_id,
236
+ "region": cred.trtc.region,
237
+ "trtc_endpoint": cred.trtc.trtc_endpoint,
238
+ "test_user_id": user_id,
239
+ "test_user_sig": sig,
240
+ "user_sig_length": len(sig),
241
+ "verify_url": "https://console.cloud.tencent.com/trtc/usersigtools",
242
+ "hint": (
243
+ "Paste sdk_app_id / test_user_id / test_user_sig into the TRTC console official verification tool. "
244
+ "If the tool shows UserSig verification passed → SDKSecretKey is correct; "
245
+ "If the tool shows verification failed → the TRTC_SDK_SECRET_KEY you entered does not match this SDKAppID. "
246
+ "Please re-check the SDKSecretKey in the TRTC console (note: this is NOT the Tencent Cloud API SecretKey)."
247
+ ),
248
+ }
249
+
250
+
251
+ app.include_router(api)
252
+ # [human-handoff] mount sub-router
253
+ from ._capability_loader import try_load_capability as _try_load_capability
254
+ _hh_router_mod = _try_load_capability("human-handoff", "src/router.py")
255
+ if _hh_router_mod is not None and hasattr(_hh_router_mod, "router"):
256
+ app.include_router(
257
+ _hh_router_mod.router, prefix="/api/v1/handoff", tags=["human-handoff"]
258
+ )
259
+
260
+ # [session-summary] mount sub-router (default installed; supplies ticket context summaries)
261
+ _ss_router_mod = _try_load_capability("session-summary", "src/router.py")
262
+ if _ss_router_mod is not None and hasattr(_ss_router_mod, "router"):
263
+ app.include_router(
264
+ _ss_router_mod.router, prefix="/api/v1/summary", tags=["session-summary"]
265
+ )
266
+
267
+ # ---------------------------------------------------------------------------
268
+ # Capability route mounting (optional; dynamically loaded via _capability_loader, silently
269
+ # skipped if the capability package is not installed).
270
+ # Injected by add-capability; all use try_load_capability to avoid hyphenated import failures.
271
+ # ---------------------------------------------------------------------------
272
+ from ._capability_loader import try_load_capability as _try_load_capability # noqa: E402
273
+
274
+ # [knowledge-base] mount sub-router
275
+ _kb_router_mod = _try_load_capability("knowledge-base", "src/router.py")
276
+ if _kb_router_mod is not None and hasattr(_kb_router_mod, "router"):
277
+ app.include_router(
278
+ _kb_router_mod.router, prefix="/api/v1/kb", tags=["knowledge-base"]
279
+ )
280
+
281
+
282
+ # ---------------------------------------------------------------------------
283
+ # Web Demo static pages (minimal verification page, no business content)
284
+ # Can point to a custom demo directory (e.g. Path A artifact directory) via
285
+ # the WEB_DEMO_DIR environment variable. Defaults to conversation-core's own web-demo self-check page.
286
+ # ---------------------------------------------------------------------------
287
+ _DEMO_DIR = Path(os.getenv("WEB_DEMO_DIR", str(_BASE_DIR / "web-demo")))
288
+ if _DEMO_DIR.exists():
289
+ app.mount(
290
+ "/static",
291
+ StaticFiles(directory=str(_DEMO_DIR), html=True),
292
+ name="static",
293
+ )
294
+
295
+ @app.get("/")
296
+ def index() -> FileResponse:
297
+ return FileResponse(str(_DEMO_DIR / "index.html"))
298
+
299
+
300
+ # ---------------------------------------------------------------------------
301
+ # Entry point
302
+ # ---------------------------------------------------------------------------
303
+ def main() -> None:
304
+ import uvicorn
305
+
306
+ port = int(os.getenv("PORT", "3000"))
307
+ host = os.getenv("HOST", "0.0.0.0")
308
+ uvicorn.run(app, host=host, port=port)
309
+
310
+
311
+ if __name__ == "__main__":
312
+ main()
@@ -0,0 +1,315 @@
1
+ """TRTC Conversational AI control plane client.
2
+
3
+ Encapsulates the minimal call chain for three REST APIs:
4
+ StartAIConversation / StopAIConversation / ControlAIConversation.
5
+ The skeleton layer only does "protocol encapsulation + credential signing",
6
+ with no built-in business prompts, industry knowledge bases, or FAQ templates.
7
+
8
+ API docs:
9
+ - StartAIConversation: https://cloud.tencent.com/document/product/647/108514
10
+ - StopAIConversation: https://cloud.tencent.com/document/product/647/108513
11
+ - ControlAIConversation: https://cloud.tencent.com/document/product/647/109408
12
+ """
13
+ from __future__ import annotations
14
+
15
+ import hashlib
16
+ import hmac
17
+ import json
18
+ import logging
19
+ import time
20
+ from dataclasses import dataclass
21
+ from datetime import datetime, timezone
22
+ from typing import Any, Dict, Optional
23
+
24
+ import requests
25
+
26
+ from .credentials import LlmCredential, TencentCloudCredential, TrtcCredential
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+ _SERVICE = "trtc"
31
+ _VERSION = "2019-07-22"
32
+
33
+
34
+ def _sign_tc3(secret_key: str, date: str, string_to_sign: str) -> str:
35
+ k_date = hmac.new(
36
+ ("TC3" + secret_key).encode("utf-8"),
37
+ date.encode("utf-8"),
38
+ hashlib.sha256,
39
+ ).digest()
40
+ k_service = hmac.new(k_date, _SERVICE.encode("utf-8"), hashlib.sha256).digest()
41
+ k_signing = hmac.new(k_service, b"tc3_request", hashlib.sha256).digest()
42
+ return hmac.new(k_signing, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()
43
+
44
+
45
+ def _signed_request(
46
+ cred: TencentCloudCredential,
47
+ host: str,
48
+ region: str,
49
+ action: str,
50
+ payload: Dict[str, Any],
51
+ timeout: float = 5.0,
52
+ ) -> Dict[str, Any]:
53
+ body = json.dumps(payload, separators=(",", ":"), ensure_ascii=False)
54
+ timestamp = int(time.time())
55
+ date = datetime.fromtimestamp(timestamp, tz=timezone.utc).strftime("%Y-%m-%d")
56
+
57
+ canonical_headers = (
58
+ f"content-type:application/json; charset=utf-8\n"
59
+ f"host:{host}\n"
60
+ f"x-tc-action:{action.lower()}\n"
61
+ )
62
+ signed_headers = "content-type;host;x-tc-action"
63
+ hashed_payload = hashlib.sha256(body.encode("utf-8")).hexdigest()
64
+ canonical_request = f"POST\n/\n\n{canonical_headers}\n{signed_headers}\n{hashed_payload}"
65
+ credential_scope = f"{date}/{_SERVICE}/tc3_request"
66
+ hashed_canonical = hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()
67
+ string_to_sign = f"TC3-HMAC-SHA256\n{timestamp}\n{credential_scope}\n{hashed_canonical}"
68
+ signature = _sign_tc3(cred.secret_key, date, string_to_sign)
69
+ authorization = (
70
+ f"TC3-HMAC-SHA256 Credential={cred.secret_id}/{credential_scope}, "
71
+ f"SignedHeaders={signed_headers}, Signature={signature}"
72
+ )
73
+ headers = {
74
+ "Authorization": authorization,
75
+ "Content-Type": "application/json; charset=utf-8",
76
+ "Host": host,
77
+ "X-TC-Action": action,
78
+ "X-TC-Timestamp": str(timestamp),
79
+ "X-TC-Version": _VERSION,
80
+ "X-TC-Region": region,
81
+ }
82
+ resp = requests.post(
83
+ f"https://{host}",
84
+ headers=headers,
85
+ data=body.encode("utf-8"),
86
+ timeout=timeout,
87
+ )
88
+ if resp.status_code != 200:
89
+ raise RuntimeError(f"TRTC API HTTP {resp.status_code}: {resp.text[:200]}")
90
+ parsed = resp.json()
91
+ response_obj = parsed.get("Response", {})
92
+ err = response_obj.get("Error")
93
+ request_id = response_obj.get("RequestId", "n/a")
94
+ if err:
95
+ raise RuntimeError(
96
+ f"TRTC API error {err.get('Code')}: {err.get('Message')} "
97
+ f"[endpoint={host}, action={action}, RequestId={request_id}]"
98
+ )
99
+ return response_obj
100
+
101
+
102
+ # Generic voice-assistant guardrails (NO industry/business assumptions).
103
+ #固化在骨架默认值里,确保:① 任何环境/任何 LLM 模型 ② 前端不传 instructions 时
104
+ # 都能避免 TTS 朗读 markdown 特殊符号,并让 AI 采信系统注入的权威上下文。
105
+ _DEFAULT_INSTRUCTIONS = (
106
+ "You are a helpful voice assistant for an online store's customer service. "
107
+ "Always answer in plain spoken language suitable for text-to-speech. "
108
+ "Do NOT use any Markdown or formatting symbols such as asterisks (*), underscores (_), "
109
+ "pound signs (#), backticks (`), tildes (~) or bullet / numbered-list markup, and never "
110
+ "read such symbols aloud. "
111
+ "Keep replies concise, ideally one to three sentences. "
112
+ "For general questions such as product recommendations or shopping advice, answer helpfully "
113
+ "and freely from your own knowledge — never claim you lack a product catalog or cannot help "
114
+ "with general guidance; offer concrete, natural suggestions instead. "
115
+ "Any information provided to you inside a message that begins with [system] is authoritative "
116
+ "context: use it directly to answer the user, and never say you cannot find it or ask the user "
117
+ "to repeat an identifier (such as an order number) that was already given to you."
118
+ )
119
+
120
+
121
+ @dataclass
122
+ class AgentLifecycleConfig:
123
+ """Session lifecycle parameters (business-logic independent)."""
124
+
125
+ instructions: str = _DEFAULT_INSTRUCTIONS
126
+ greeting: str = "Hello, how can I help you?"
127
+ max_idle_time: int = 60 # seconds
128
+ welcome_message: str = ""
129
+ language: str = "en" # Default English (widest compatibility; Chinese requires TRTC app to enable corresponding capability)
130
+ voice_id: str = "v-female-A4b9KqP2" # TRTC FlowTTS default female voice (English Articulate Narrator)
131
+ tts_model: str = "flow_01_turbo"
132
+
133
+
134
+ # TRTC FlowTTS verified voice IDs (taken from oral-coach project, confirmed working)
135
+ # Full voice list: https://trtc.io/document/79682?product=conversationalai
136
+ DEFAULT_VOICE_IDS = {
137
+ ("en", "female"): "v-female-p9Xy7Q1L", # Articulate Narrator
138
+ ("en", "male"): "v-male-A4b9KqP2", # Scholarly Lecturer
139
+ ("zh", "female"): "female-kefu-xiaoyue",
140
+ ("zh", "male"): "male-kefu-xiaoxu",
141
+ }
142
+
143
+
144
+ class TrtcConversationClient:
145
+ """Thin wrapper around TRTC ConversationAI control plane.
146
+
147
+ Constructor parameters:
148
+ tencent: Tencent Cloud API keys (used to sign REST requests).
149
+ trtc: TRTC SDKAppID / SDKSecretKey (the SdkAppId in StartAIConversation).
150
+ llm: LLM credentials, used to populate LLMConfig (passthrough only, not called within the skeleton).
151
+ """
152
+
153
+ def __init__(
154
+ self,
155
+ tencent: TencentCloudCredential,
156
+ trtc: TrtcCredential,
157
+ llm: LlmCredential,
158
+ ) -> None:
159
+ if not tencent.configured:
160
+ raise ValueError("tencent cloud credential not configured")
161
+ if not trtc.configured:
162
+ raise ValueError("trtc credential not configured")
163
+ if not llm.configured:
164
+ raise ValueError("llm credential not configured")
165
+ self.tencent = tencent
166
+ self.trtc = trtc
167
+ self.llm = llm
168
+
169
+ # ------------------------------------------------------------------
170
+ # StartAIConversation
171
+ # ------------------------------------------------------------------
172
+ def start(
173
+ self,
174
+ room_id: str,
175
+ agent_user_id: str,
176
+ agent_user_sig: str,
177
+ target_user_id: str,
178
+ config: Optional[AgentLifecycleConfig] = None,
179
+ room_id_type: int = 0,
180
+ ) -> Dict[str, Any]:
181
+ cfg = config or AgentLifecycleConfig()
182
+ # Resolve voice_id: user explicit > default per language
183
+ voice_id = cfg.voice_id or DEFAULT_VOICE_IDS.get(
184
+ (cfg.language, "female"),
185
+ DEFAULT_VOICE_IDS[("en", "female")],
186
+ )
187
+ payload: Dict[str, Any] = {
188
+ "SdkAppId": self.trtc.sdk_app_id,
189
+ "RoomId": str(room_id),
190
+ "RoomIdType": room_id_type,
191
+ "AgentConfig": {
192
+ "UserId": agent_user_id,
193
+ "UserSig": agent_user_sig,
194
+ "MaxIdleTime": cfg.max_idle_time,
195
+ "TargetUserId": target_user_id,
196
+ "WelcomeMessage": cfg.welcome_message or cfg.greeting,
197
+ # Smart interrupt (critical):
198
+ # InterruptMode 2 = auto + manual dual-track
199
+ # • Auto: user speaks beyond InterruptSpeechDuration ms → stop TTS
200
+ # • Manual: frontend sends type:20001 custom message → immediately stop TTS
201
+ # (for text input: send interrupt before text, then type:20000 triggers new turn)
202
+ "InterruptMode": 2,
203
+ "InterruptSpeechDuration": 500,
204
+ # Subtitle mode: 1 = deliver both user and AI subtitles to client
205
+ "SubtitleMode": 1,
206
+ # Single-word filter: prevent ASR from splitting filler sounds like "um/ah" into single words
207
+ "FilterOneWord": True,
208
+ # Turn detection: 3 = semantic + VAD dual-signal to detect when user has finished speaking
209
+ "TurnDetectionMode": 3,
210
+ "TurnDetection": {"SemanticEagerness": "auto"},
211
+ },
212
+ "STTConfig": {
213
+ "Language": cfg.language,
214
+ "VadLevel": 3,
215
+ "VadSilenceTime": 1000,
216
+ },
217
+ "LLMConfig": json.dumps(
218
+ {
219
+ "LLMType": self.llm.llm_type,
220
+ "Model": self.llm.model,
221
+ "APIKey": self.llm.api_key,
222
+ "APIUrl": self.llm.api_url,
223
+ "Streaming": True,
224
+ "SystemPrompt": cfg.instructions,
225
+ "History": 20,
226
+ "Temperature": 0.4,
227
+ },
228
+ separators=(",", ":"),
229
+ ensure_ascii=False,
230
+ ),
231
+ "TTSConfig": json.dumps(
232
+ {
233
+ "TTSType": "flow",
234
+ "Model": cfg.tts_model,
235
+ "VoiceId": voice_id,
236
+ "Speed": 1.0,
237
+ "Volume": 1.0,
238
+ "Pitch": 0,
239
+ "Language": cfg.language,
240
+ },
241
+ separators=(",", ":"),
242
+ ensure_ascii=False,
243
+ ),
244
+ }
245
+ # Log key diagnostics before starting (UserSig redacted)
246
+ logger.info(
247
+ "StartAIConversation: endpoint=%s region=%s SdkAppId=%s RoomId=%s "
248
+ "agent=%s target=%s userSig=%s...%s(len=%d) lang=%s voice=%s",
249
+ self.trtc.trtc_endpoint,
250
+ self.trtc.trtc_region,
251
+ self.trtc.sdk_app_id,
252
+ room_id,
253
+ agent_user_id,
254
+ target_user_id,
255
+ agent_user_sig[:6],
256
+ agent_user_sig[-4:],
257
+ len(agent_user_sig),
258
+ cfg.language,
259
+ voice_id,
260
+ )
261
+ resp = _signed_request(
262
+ self.tencent,
263
+ host=self.trtc.trtc_endpoint,
264
+ region=self.trtc.trtc_region,
265
+ action="StartAIConversation",
266
+ payload=payload,
267
+ timeout=10.0,
268
+ )
269
+ return {
270
+ "task_id": resp.get("TaskId"),
271
+ "request_id": resp.get("RequestId"),
272
+ }
273
+
274
+ # ------------------------------------------------------------------
275
+ # StopAIConversation
276
+ # ------------------------------------------------------------------
277
+ def stop(self, task_id: str) -> None:
278
+ if not task_id:
279
+ raise ValueError("task_id is required")
280
+ _signed_request(
281
+ self.tencent,
282
+ host=self.trtc.trtc_endpoint,
283
+ region=self.trtc.trtc_region,
284
+ action="StopAIConversation",
285
+ payload={"TaskId": task_id},
286
+ timeout=5.0,
287
+ )
288
+
289
+ # ------------------------------------------------------------------
290
+ # ControlAIConversation: used for text injection / interrupt
291
+ # ------------------------------------------------------------------
292
+ def control(
293
+ self,
294
+ task_id: str,
295
+ command: str,
296
+ text: Optional[str] = None,
297
+ interrupt: bool = True,
298
+ ) -> Dict[str, Any]:
299
+ """Inject text or issue a control command to a running conversation task."""
300
+ if not task_id or not command:
301
+ raise ValueError("task_id and command are required")
302
+ payload: Dict[str, Any] = {"TaskId": task_id, "Command": command}
303
+ if text is not None:
304
+ payload["ServerPushText"] = {
305
+ "Text": text,
306
+ "Interrupt": interrupt,
307
+ }
308
+ return _signed_request(
309
+ self.tencent,
310
+ host=self.trtc.trtc_endpoint,
311
+ region=self.trtc.trtc_region,
312
+ action="ControlAIConversation",
313
+ payload=payload,
314
+ timeout=5.0,
315
+ )