@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.
- package/.cursor/rules/main.mdc +12 -0
- package/AGENTS.md +14 -104
- package/CLAUDE.md +15 -127
- package/CODEBUDDY.md +32 -118
- package/README.md +7 -5
- package/README.zh.md +7 -5
- package/bin/cli.js +133 -41
- package/hooks/__pycache__/cursor-adapter.cpython-313.pyc +0 -0
- package/hooks/cursor-adapter.py +45 -18
- package/hooks/hooks-cursor.json +5 -18
- package/hooks/hooks.json +6 -31
- package/knowledge-base/conference/web/index.yaml +143 -0
- package/knowledge-base/platform-slice-template.md +1041 -133
- package/knowledge-base/products.yaml +76 -0
- package/knowledge-base/scenario-spec.md +1316 -115
- package/knowledge-base/scenarios/conference/base/general-conference.md +22 -2
- package/knowledge-base/scenarios/conference/base/webinar-conference.md +14 -0
- package/knowledge-base/scenarios/conference/medical/1v1-video-consultation.md +19 -0
- package/knowledge-base/scenarios/conference/medical/medical-multidoctor-consultation.md +13 -0
- package/knowledge-base/scenarios/live/entertainment-live-room.md +12 -0
- package/knowledge-base/slice-spec.md +2377 -299
- package/knowledge-base/slices/conference/web/integration-audit.md +1 -1
- package/knowledge-base/slices/conference/web/login-auth.md +14 -1
- package/knowledge-base/tooling/aliases.yaml +92 -0
- package/knowledge-base/tooling/intent-signals.yaml +181 -0
- package/knowledge-base/tooling/symptom-keywords.yaml +21 -0
- package/package.json +1 -1
- package/skills/trtc/SKILL.md +202 -245
- package/skills/trtc/hooks/__pycache__/report_prompt.cpython-313.pyc +0 -0
- package/skills/{trtc-topic/guardrails → trtc/hooks}/gate_slice_read.py +12 -8
- package/skills/{trtc-topic/guardrails → trtc/hooks}/gate_slice_write.py +16 -12
- package/skills/{trtc-topic/guardrails → trtc/hooks}/stop_require_apply_evidence.py +22 -14
- package/skills/trtc/hooks/topic_phase_gate.py +161 -0
- package/skills/{trtc-topic → trtc}/runtime/README.md +2 -2
- package/skills/{trtc-onboarding/reference/reporting-protocol.md → trtc/runtime/REPORTING.md} +5 -5
- package/skills/{trtc-topic → trtc}/runtime/RUNTIME.md +5 -5
- package/skills/trtc/runtime/lib/__init__.py +0 -0
- package/skills/{trtc-topic → trtc}/runtime/package-lock.json +2 -2
- package/skills/{trtc-topic → trtc}/runtime/package.json +2 -2
- package/skills/{trtc-topic → trtc}/runtime/telemetry-bridge.mjs +1 -1
- package/skills/{trtc-topic/scripts → trtc/tools}/STATE-MACHINE-GUIDE.md +23 -23
- package/skills/trtc/tools/__init__.py +2 -0
- package/skills/trtc/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- package/skills/trtc/tools/__pycache__/query_classifier.cpython-313.pyc +0 -0
- package/skills/trtc/tools/__pycache__/reporting.cpython-313.pyc +0 -0
- package/skills/trtc/tools/__pycache__/search.cpython-313.pyc +0 -0
- package/skills/trtc/tools/__pycache__/session.cpython-313.pyc +0 -0
- package/skills/trtc/tools/apply.py +540 -0
- package/skills/trtc/tools/docs.py +712 -0
- package/skills/trtc/tools/docsbot.py +182 -0
- package/skills/trtc/tools/entry/render_ai_instructions.py +92 -0
- package/skills/trtc/tools/flow.py +1089 -0
- package/skills/{trtc-topic/scripts → trtc/tools}/init_slice_queue.py +5 -4
- package/skills/{trtc-topic/scripts → trtc/tools}/next_slice.py +5 -4
- package/skills/trtc/tools/query_classifier.py +301 -0
- package/skills/trtc/tools/reporting.py +447 -0
- package/skills/trtc/tools/search.py +817 -0
- package/skills/trtc/tools/session.py +1261 -0
- package/skills/trtc/tools/state_machine.py +690 -0
- package/skills/trtc-ai-service/README.md +195 -0
- package/skills/trtc-ai-service/README.zh-CN.md +193 -0
- package/skills/trtc-ai-service/SKILL.md +945 -0
- package/skills/trtc-ai-service/auto_adapters/README.md +40 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/README.md +27 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/angular/voice-agent.component.ts.tpl +131 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/manifest.yaml +57 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/react/VoiceAgent.tsx.tpl +142 -0
- package/skills/trtc-ai-service/auto_adapters/frontend-spa/vue/VoiceAgent.vue.tpl +121 -0
- package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-backend.md +45 -0
- package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-frontend.md +51 -0
- package/skills/trtc-ai-service/auto_adapters/integration_templates/generic-rest-api.md +93 -0
- package/skills/trtc-ai-service/auto_adapters/java-backend/README.md +25 -0
- package/skills/trtc-ai-service/auto_adapters/java-backend/manifest.yaml +30 -0
- package/skills/trtc-ai-service/auto_adapters/java-backend/quarkus/VoiceAgentFilter.java.tpl +64 -0
- package/skills/trtc-ai-service/auto_adapters/java-backend/springboot/VoiceAgentFilter.java.tpl +91 -0
- package/skills/trtc-ai-service/auto_adapters/manifest.yaml +43 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/README.md +25 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/express.js.tpl +40 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/fastify.js.tpl +27 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/koa.js.tpl +31 -0
- package/skills/trtc-ai-service/auto_adapters/node-backend/manifest.yaml +47 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/README.md +22 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/django.py.tpl +32 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/fastapi.py.tpl +35 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/flask.py.tpl +31 -0
- package/skills/trtc-ai-service/auto_adapters/python-backend/manifest.yaml +45 -0
- package/skills/trtc-ai-service/capabilities/__init__.py +43 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/.env.example +29 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/INTEGRATION.md +134 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/INTERFACE_ADAPT.md +111 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/QUICK_START.md +62 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/manifest.yaml +250 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/requirements.txt +6 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/__init__.py +10 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/_capability_loader.py +218 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/agent.py +231 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/credentials.py +132 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/health.py +355 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/log_filter.py +76 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/modality.py +109 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/server.py +312 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/trtc_client.py +315 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/src/usersig.py +90 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/tests/test_skeleton.py +216 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/README.md +48 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/app.js +415 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/index.html +68 -0
- package/skills/trtc-ai-service/capabilities/conversation-core/web-demo/styles.css +136 -0
- package/skills/trtc-ai-service/capabilities/digital-human/README.md +31 -0
- package/skills/trtc-ai-service/capabilities/digital-human/manifest.yaml +64 -0
- package/skills/trtc-ai-service/capabilities/digital-human/src/__init__.py +2 -0
- package/skills/trtc-ai-service/capabilities/digital-human/src/router.py +43 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/INTERFACE_ADAPT.md +353 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/README.md +44 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/manifest.yaml +227 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/__init__.py +2 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/__init__.py +9 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/default_rest.py +242 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/factory.py +89 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/local_queue.py +258 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/adapters/mock.py +132 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/core/__init__.py +25 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/core/intent_detector.py +75 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/core/models.py +163 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/core/service.py +192 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/feedback_store.py +54 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/ports/__init__.py +4 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/ports/handoff_client.py +86 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/queue.py +62 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/router.py +201 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/summary_link.py +77 -0
- package/skills/trtc-ai-service/capabilities/human-handoff/src/trigger.py +25 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/INTERFACE_ADAPT.md +297 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/README.md +51 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/data/faq.json +20 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/manifest.yaml +211 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/__init__.py +8 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/__init__.py +9 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/default_rest.py +209 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/factory.py +86 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/local_json.py +172 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/adapters/mock.py +91 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/__init__.py +12 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/models.py +77 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/scoring.py +73 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/core/service.py +78 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/ports/__init__.py +4 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/ports/kb_client.py +61 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/retriever.py +56 -0
- package/skills/trtc-ai-service/capabilities/knowledge-base/src/router.py +85 -0
- package/skills/trtc-ai-service/capabilities/session-summary/INTERFACE_ADAPT.md +99 -0
- package/skills/trtc-ai-service/capabilities/session-summary/README.md +47 -0
- package/skills/trtc-ai-service/capabilities/session-summary/data/test_session.json +18 -0
- package/skills/trtc-ai-service/capabilities/session-summary/manifest.yaml +165 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/__init__.py +2 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/__init__.py +5 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/base.py +31 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/default_rest.py +67 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/factory.py +51 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/local_json.py +42 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/adapters/mock.py +22 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/recorder.py +210 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/router.py +93 -0
- package/skills/trtc-ai-service/capabilities/session-summary/src/summarizer.py +163 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/INTERFACE_ADAPT.md +158 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/README.md +50 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/data/tools.yaml +58 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/examples/__init__.py +1 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/examples/local_tools.py +101 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/manifest.yaml +146 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/src/__init__.py +8 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/src/dispatcher.py +54 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/src/registry.py +219 -0
- package/skills/trtc-ai-service/capabilities/tool-calling/src/router.py +50 -0
- package/skills/trtc-ai-service/references/business-contract-spec.md +263 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/README.md +86 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/output-templates/recipe.yaml.j2 +194 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q1-business-scenario.md +43 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q2-io-modality.md +57 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q3-ui-form.md +55 -0
- package/skills/trtc-ai-service/scenarios/custom-builder/prompts/q4-capabilities.md +78 -0
- package/skills/trtc-ai-service/scenarios/customer-service/README.md +114 -0
- package/skills/trtc-ai-service/scenarios/customer-service/recipe.yaml +154 -0
- package/skills/trtc-ai-service/scenarios/customer-service/sample-data/README.md +32 -0
- package/skills/trtc-ai-service/scenarios/customer-service/sample-data/faq-sample.json +37 -0
- package/skills/trtc-ai-service/scenarios/customer-service/system-prompt.template.md +94 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/app.js +347 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/index.html +125 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/styles.css +487 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/admin-board/tokens.css +71 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/design-system/DESIGN_GUIDELINES.md +370 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/README.md +68 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/app.js +1307 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/data.js +40 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/index.html +233 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/mock-shop.json +21 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/styles.css +603 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/voice-customer-service/tokens.css +71 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/agent-link.js +323 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/app.js +458 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/index.html +109 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/styles.css +489 -0
- package/skills/trtc-ai-service/scenarios/customer-service/ui/widget-floating/tokens.css +59 -0
- package/skills/trtc-ai-service/scripts/add-capability.py +364 -0
- package/skills/trtc-ai-service/scripts/contract-adapt.py +334 -0
- package/skills/trtc-ai-service/scripts/detect-stack.py +40 -0
- package/skills/trtc-ai-service/scripts/lib/__init__.py +20 -0
- package/skills/trtc-ai-service/scripts/lib/adapter_codegen.py +509 -0
- package/skills/trtc-ai-service/scripts/lib/arbitrator.py +152 -0
- package/skills/trtc-ai-service/scripts/lib/contract_resolver.py +519 -0
- package/skills/trtc-ai-service/scripts/lib/credential_validators.py +253 -0
- package/skills/trtc-ai-service/scripts/lib/curl_parser.py +303 -0
- package/skills/trtc-ai-service/scripts/lib/degrader.py +140 -0
- package/skills/trtc-ai-service/scripts/lib/injector.py +347 -0
- package/skills/trtc-ai-service/scripts/lib/manifest_resolver.py +288 -0
- package/skills/trtc-ai-service/scripts/lib/openapi_parser.py +289 -0
- package/skills/trtc-ai-service/scripts/lib/stack_detector.py +159 -0
- package/skills/trtc-ai-service/scripts/lib/tokens_compile.py +204 -0
- package/skills/trtc-ai-service/scripts/post-install-patch.py +225 -0
- package/skills/trtc-ai-service/scripts/setup-credentials.py +393 -0
- package/skills/trtc-ai-service/scripts/verify-credentials.py +108 -0
- package/skills/trtc-ai-service/start.sh +111 -0
- package/skills/trtc-ai-service/tests/__init__.py +1 -0
- package/skills/trtc-ai-service/tests/test_arbitrator.py +64 -0
- package/skills/trtc-ai-service/tests/test_capability_overlay.py +85 -0
- package/skills/trtc-ai-service/tests/test_contract_resolver.py +190 -0
- package/skills/trtc-ai-service/tests/test_handoff_ports.py +195 -0
- package/skills/trtc-ai-service/tests/test_kb_ports.py +195 -0
- package/skills/trtc-ai-service/tests/test_manifest_resolver.py +95 -0
- package/skills/trtc-ai-service/tests/test_recipe_assembly.py +175 -0
- package/skills/trtc-ai-service/tests/test_stack_and_degrader.py +101 -0
- package/skills/trtc-ai-service/tests/test_verify_credentials.py +285 -0
- package/skills/trtc-ai-service/triggers.yaml +29 -0
- package/skills/trtc-conference/SKILL.md +324 -0
- package/skills/trtc-conference/flows/onboarding.md +205 -0
- package/skills/trtc-conference/flows/topic.md +474 -0
- package/skills/trtc-conference/flows/troubleshoot.md +85 -0
- package/skills/trtc-conference/hooks/pretooluse_require_business_decisions.py +213 -0
- package/skills/trtc-conference/playbooks/medical-quickstart.md +84 -0
- package/skills/trtc-conference/playbooks/official-roomkit.md +97 -0
- package/skills/trtc-conference/references/local-usersig/basic-info-config.ts +39 -0
- package/skills/trtc-conference/references/usersig-handling.md +134 -0
- package/skills/trtc-conference/templates/medical-consultation/src/config/lib-generate-test-usersig-es.min.d.ts +4 -0
- package/skills/trtc-conference/templates/medical-consultation/src/config/lib-generate-test-usersig-es.min.js +2 -0
- package/skills/trtc-conference/tests/__pycache__/test_conference_onboarding_contract.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-conference/tests/__pycache__/test_conference_topic_flow_contract.cpython-313-pytest-9.0.2.pyc +0 -0
- package/skills/trtc-conference/tests/test_conference_index_contract.py +43 -0
- package/skills/trtc-conference/tests/test_conference_onboarding_contract.py +103 -0
- package/skills/trtc-conference/tests/test_conference_template_contract.py +25 -0
- package/skills/trtc-conference/tests/test_conference_topic_flow_contract.py +132 -0
- package/skills/trtc-conference/tools/apply_checks.py +328 -0
- package/skills/trtc-conference/verify_lib/__init__.py +0 -0
- package/skills/{trtc-apply/guardrails/apply_lib → trtc-conference/verify_lib}/rule_parser.py +1 -1
- package/skills/trtc-docs/SKILL.md +91 -119
- package/.cursor/rules/ui-mode.mdc +0 -99
- package/ai-instructions/base.md +0 -13
- package/ai-instructions/ui-mode.md +0 -93
- package/knowledge-base/index.yaml +0 -462
- package/skills/trtc/room-builder/SKILL.md +0 -133
- package/skills/trtc/room-builder/templates/scenarios/medical-consultation/README.md +0 -108
- package/skills/trtc/room-builder/tools/render_ai_instructions.py +0 -226
- package/skills/trtc-apply/SKILL.md +0 -97
- package/skills/trtc-onboarding/SKILL.md +0 -841
- package/skills/trtc-onboarding/reference/path-a1-demo.md +0 -103
- package/skills/trtc-onboarding/reference/path-a2-integrate.md +0 -737
- package/skills/trtc-onboarding/reference/path-b-troubleshoot.md +0 -186
- package/skills/trtc-onboarding/reference/path-c-expand.md +0 -43
- package/skills/trtc-onboarding/reference/supported-matrix.md +0 -100
- package/skills/trtc-search/SKILL.md +0 -228
- package/skills/trtc-topic/SKILL.md +0 -622
- package/skills/trtc-topic/scripts/apply.py +0 -581
- package/skills/trtc-topic/scripts/lib/state_machine.py +0 -328
- package/skills/trtc-topic/tests/README.md +0 -70
- package/skills/trtc-topic/tests/conftest.py +0 -72
- package/skills/trtc-topic/tests/test_apply_cli.py +0 -480
- package/skills/trtc-topic/tests/test_end_to_end.py +0 -305
- package/skills/trtc-topic/tests/test_finalize_session.py +0 -51
- package/skills/trtc-topic/tests/test_gates.py +0 -316
- package/skills/trtc-topic/tests/test_session_resolver.py +0 -260
- package/skills/trtc-topic/tests/test_state_machine.py +0 -414
- package/skills/trtc-topic/tests/test_stop_require_apply.py +0 -99
- package/skills/trtc-topic/tests/test_topic_skill_invariants.py +0 -130
- /package/skills/{trtc-topic → trtc}/runtime/lib/platforms.py +0 -0
- /package/skills/{trtc-topic → trtc}/runtime/telemetry_collector.py +0 -0
- /package/skills/{trtc-onboarding/reference → trtc/runtime}/usersig-handling.md +0 -0
- /package/skills/{trtc-topic/scripts → trtc/tools}/finalize_session.py +0 -0
- /package/skills/{trtc-apply/guardrails/apply_lib → trtc-ai-service/capabilities/conversation-core/tests}/__init__.py +0 -0
- /package/skills/{trtc-topic → trtc-conference}/references/execution-units.yaml +0 -0
- /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
- /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
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/backend-contract.zh-CN.md +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/integration.zh-CN.md +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/docs/theme.zh-CN.md +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/index.html +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/package.json +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/postcss.config.js +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/App.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/ConsultationManagePanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/LanguageSwitch.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/LoadingSpinner.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalAlert.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalBusinessPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalButton.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalConfirmDialog.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalDataPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/MedicalRecordPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/components/PrescriptionPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/config/basic-info-config.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/config/runtime-config.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/env.d.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationChatPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationMembersPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationTranscriptionPanel.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/ConsultationVideoStage.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/InviteDoctorDialog.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/components/KickMemberConfirmDialog.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/types.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationChat.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationDevices.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationParticipants.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/useConsultationPermissions.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/features/consultation/utils.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/en-US/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/medicalTranslate.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/state.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/i18n/zh-CN/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/main.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/mock/appointments.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/mock/users.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/router/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/index.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/appointmentService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/authService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/launchContext.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/integration/userService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/appointmentService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/authService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/mock/userService.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/services/adapters/types.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/shared/icons.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/index.css +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/tailwind.css +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/styles/theme.css +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/auth.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/format.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/navigation.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/utils/session.ts +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/DoctorConsultationView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/DoctorDashboardView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/LoginView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientConsultationFinishedView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientConsultationView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientSelectDoctorView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/src/views/PatientWaitingView.vue +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/tsconfig.json +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/tsconfig.node.json +0 -0
- /package/skills/{trtc/room-builder/templates/scenarios → trtc-conference/templates}/medical-consultation/vite.config.ts +0 -0
- /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
- /package/skills/{trtc-topic/runtime/lib → trtc-conference/tools}/__init__.py +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Tokenization + scoring utilities: migrated from original retriever.py.
|
|
2
|
+
|
|
3
|
+
No external dependencies, pure Python:
|
|
4
|
+
- Chinese: character bigram splitting
|
|
5
|
+
- English: word-level splitting
|
|
6
|
+
- TF-IDF scoring (keywords weighted 3x)
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import math
|
|
11
|
+
import re
|
|
12
|
+
from typing import Dict, Iterable, List
|
|
13
|
+
|
|
14
|
+
from .models import FaqEntry
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
_WORD_RE = re.compile(r"[A-Za-z0-9_]+")
|
|
18
|
+
_CN_RE = re.compile(r"[\u4e00-\u9fff]+")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def tokenize(text: str) -> List[str]:
|
|
22
|
+
"""Mixed Chinese/English tokenization."""
|
|
23
|
+
if not text:
|
|
24
|
+
return []
|
|
25
|
+
text = text.lower()
|
|
26
|
+
tokens: List[str] = []
|
|
27
|
+
tokens.extend(_WORD_RE.findall(text))
|
|
28
|
+
for blob in _CN_RE.findall(text):
|
|
29
|
+
if len(blob) == 1:
|
|
30
|
+
tokens.append(blob)
|
|
31
|
+
else:
|
|
32
|
+
tokens.extend(blob[i : i + 2] for i in range(len(blob) - 1))
|
|
33
|
+
return tokens
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def doc_tokens(entry: FaqEntry) -> List[str]:
|
|
37
|
+
"""Generate token list for scoring a single entry (keywords weighted 3x)."""
|
|
38
|
+
toks = tokenize(entry.question) + tokenize(entry.answer)
|
|
39
|
+
for kw in entry.keywords:
|
|
40
|
+
toks.extend(tokenize(kw) * 3)
|
|
41
|
+
return toks
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def build_df(entries: Iterable[FaqEntry]) -> Dict[str, int]:
|
|
45
|
+
"""Build document frequency table."""
|
|
46
|
+
df: Dict[str, int] = {}
|
|
47
|
+
for e in entries:
|
|
48
|
+
for t in set(doc_tokens(e)):
|
|
49
|
+
df[t] = df.get(t, 0) + 1
|
|
50
|
+
return df
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def tfidf_score(
|
|
54
|
+
entry: FaqEntry,
|
|
55
|
+
q_tokens: List[str],
|
|
56
|
+
*,
|
|
57
|
+
df: Dict[str, int],
|
|
58
|
+
n_docs: int,
|
|
59
|
+
) -> float:
|
|
60
|
+
"""TF-IDF score (normalized to [0, 1])."""
|
|
61
|
+
d_tokens = doc_tokens(entry)
|
|
62
|
+
if not d_tokens:
|
|
63
|
+
return 0.0
|
|
64
|
+
tf: Dict[str, int] = {}
|
|
65
|
+
for t in d_tokens:
|
|
66
|
+
tf[t] = tf.get(t, 0) + 1
|
|
67
|
+
score = 0.0
|
|
68
|
+
for t in q_tokens:
|
|
69
|
+
if t not in tf:
|
|
70
|
+
continue
|
|
71
|
+
idf = math.log((n_docs + 1) / (1 + df.get(t, 0))) + 1
|
|
72
|
+
score += (tf[t] / len(d_tokens)) * idf
|
|
73
|
+
return max(0.0, min(score, 1.0))
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""KbService — Application service layer, combining KnowledgeBaseClient with instruction concatenation logic.
|
|
2
|
+
|
|
3
|
+
Only depends on ports (KnowledgeBaseClient interface); does not know the specific backend.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
|
|
9
|
+
from ..ports.kb_client import KnowledgeBaseClient
|
|
10
|
+
from .models import FaqEntry, KbStats, SearchHit
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class KbService:
|
|
14
|
+
|
|
15
|
+
def __init__(self, *, client: KnowledgeBaseClient) -> None:
|
|
16
|
+
self._client = client
|
|
17
|
+
|
|
18
|
+
# ------------------------------------------------------------------
|
|
19
|
+
def search(
|
|
20
|
+
self,
|
|
21
|
+
query: str,
|
|
22
|
+
*,
|
|
23
|
+
top_k: Optional[int] = None,
|
|
24
|
+
min_score: Optional[float] = None,
|
|
25
|
+
) -> List[SearchHit]:
|
|
26
|
+
return self._client.search(query, top_k=top_k, min_score=min_score)
|
|
27
|
+
|
|
28
|
+
def list_all(self) -> List[FaqEntry]:
|
|
29
|
+
return self._client.list_all()
|
|
30
|
+
|
|
31
|
+
def upsert(self, entry: FaqEntry) -> FaqEntry:
|
|
32
|
+
return self._client.upsert(entry)
|
|
33
|
+
|
|
34
|
+
def delete(self, entry_id: str) -> bool:
|
|
35
|
+
return self._client.delete(entry_id)
|
|
36
|
+
|
|
37
|
+
def stats(self) -> KbStats:
|
|
38
|
+
return self._client.stats()
|
|
39
|
+
|
|
40
|
+
def reload(self) -> int:
|
|
41
|
+
return self._client.reload()
|
|
42
|
+
|
|
43
|
+
# ------------------------------------------------------------------
|
|
44
|
+
# For injection into conversation-core.before_start: concatenate search results into instructions
|
|
45
|
+
# ------------------------------------------------------------------
|
|
46
|
+
def attach_faq_to_instructions(
|
|
47
|
+
self,
|
|
48
|
+
instructions: str,
|
|
49
|
+
*,
|
|
50
|
+
max_hits: int = 3,
|
|
51
|
+
) -> str:
|
|
52
|
+
if not instructions:
|
|
53
|
+
return instructions
|
|
54
|
+
hits = self._client.search(instructions, top_k=max_hits)
|
|
55
|
+
if not hits:
|
|
56
|
+
return instructions
|
|
57
|
+
block = ["", "# Retrieved Knowledge (auto-injected by knowledge-base capability)"]
|
|
58
|
+
for h in hits:
|
|
59
|
+
block.append(f"- Q: {h.entry.question}")
|
|
60
|
+
block.append(f" A: {h.entry.answer}")
|
|
61
|
+
return instructions + "\n" + "\n".join(block)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# ---------------------------------------------------------------------------
|
|
65
|
+
_default_service: Optional[KbService] = None
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_default_service() -> KbService:
|
|
69
|
+
global _default_service
|
|
70
|
+
if _default_service is None:
|
|
71
|
+
from ..adapters.factory import get_client
|
|
72
|
+
_default_service = KbService(client=get_client())
|
|
73
|
+
return _default_service
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def reset_default_service() -> None:
|
|
77
|
+
global _default_service
|
|
78
|
+
_default_service = None
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""knowledge-base abstract port (Port).
|
|
2
|
+
|
|
3
|
+
Aligned with manifest.yaml.business_contract.external_apis:
|
|
4
|
+
- search -> faq.search
|
|
5
|
+
- list_all -> faq.list
|
|
6
|
+
- upsert -> faq.upsert
|
|
7
|
+
- delete -> faq.delete
|
|
8
|
+
|
|
9
|
+
All concrete implementations (local_json / default_rest / mock / user_custom) must inherit this ABC.
|
|
10
|
+
The core layer only depends on this interface.
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from abc import ABC, abstractmethod
|
|
15
|
+
from typing import List, Optional
|
|
16
|
+
|
|
17
|
+
from ..core.models import FaqEntry, KbStats, SearchHit
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class KnowledgeBaseClient(ABC):
|
|
21
|
+
"""Unified interface contract for knowledge base backends."""
|
|
22
|
+
|
|
23
|
+
# ------------------------------------------------------------------
|
|
24
|
+
# Aligned with business_contract
|
|
25
|
+
# ------------------------------------------------------------------
|
|
26
|
+
@abstractmethod
|
|
27
|
+
def search(
|
|
28
|
+
self,
|
|
29
|
+
query: str,
|
|
30
|
+
*,
|
|
31
|
+
top_k: Optional[int] = None,
|
|
32
|
+
min_score: Optional[float] = None,
|
|
33
|
+
) -> List[SearchHit]:
|
|
34
|
+
"""Search for matching FAQ entries. Corresponds to business_contract.faq.search."""
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
def list_all(self) -> List[FaqEntry]:
|
|
38
|
+
"""List all entries. Corresponds to business_contract.faq.list."""
|
|
39
|
+
|
|
40
|
+
@abstractmethod
|
|
41
|
+
def upsert(self, entry: FaqEntry) -> FaqEntry:
|
|
42
|
+
"""Create or update a single entry. Corresponds to business_contract.faq.upsert."""
|
|
43
|
+
|
|
44
|
+
@abstractmethod
|
|
45
|
+
def delete(self, entry_id: str) -> bool:
|
|
46
|
+
"""Delete a single entry. Corresponds to business_contract.faq.delete."""
|
|
47
|
+
|
|
48
|
+
# ------------------------------------------------------------------
|
|
49
|
+
# Dashboard helper methods (default implementation; remote backends may not override)
|
|
50
|
+
# ------------------------------------------------------------------
|
|
51
|
+
def stats(self) -> KbStats:
|
|
52
|
+
"""Return statistics (defaults to live calculation based on list_all)."""
|
|
53
|
+
items = self.list_all()
|
|
54
|
+
return KbStats(
|
|
55
|
+
backend=type(self).__name__,
|
|
56
|
+
entry_count=len(items),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def reload(self) -> int:
|
|
60
|
+
"""Reload data from external source. Default no-op; local implementations can override to re-read files."""
|
|
61
|
+
return len(self.list_all())
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""retriever.py — compatibility facade.
|
|
2
|
+
|
|
3
|
+
Keeps the original `attach_faq_to_instructions` / `get_retriever` / `FaqEntry` / `SearchHit`
|
|
4
|
+
public symbols for manifest.extensions (agent.before_start) and external callers to continue using.
|
|
5
|
+
|
|
6
|
+
New code should use directly:
|
|
7
|
+
- adapters.factory.get_client() Get KnowledgeBaseClient instance
|
|
8
|
+
- core.service.get_default_service() Get KbService instance
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import warnings
|
|
13
|
+
|
|
14
|
+
from .core.models import FaqEntry, SearchHit # noqa: F401 (public API)
|
|
15
|
+
from .core.service import get_default_service
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def attach_faq_to_instructions(instructions: str) -> str:
|
|
19
|
+
"""For use by conversation-core.before_start injection point.
|
|
20
|
+
|
|
21
|
+
Keeps old signature: single instructions parameter, returns concatenated instructions.
|
|
22
|
+
"""
|
|
23
|
+
return get_default_service().attach_faq_to_instructions(instructions)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# --------------------------------------------------------------------
|
|
27
|
+
# Deprecated shim: original FaqRetriever global instance / class
|
|
28
|
+
# --------------------------------------------------------------------
|
|
29
|
+
def get_retriever():
|
|
30
|
+
"""[DEPRECATED] Return KnowledgeBaseClient instance.
|
|
31
|
+
|
|
32
|
+
Old FaqRetriever class method names (list_entries/upsert/delete/search/reload)
|
|
33
|
+
have corresponding methods on the new client (list_all/upsert/delete/search/reload),
|
|
34
|
+
though some signatures differ slightly (list_entries -> list_all).
|
|
35
|
+
"""
|
|
36
|
+
warnings.warn(
|
|
37
|
+
"knowledge_base.retriever.get_retriever() is deprecated; "
|
|
38
|
+
"use adapters.factory.get_client() or core.service.get_default_service() instead.",
|
|
39
|
+
DeprecationWarning,
|
|
40
|
+
stacklevel=2,
|
|
41
|
+
)
|
|
42
|
+
from .adapters.factory import get_client
|
|
43
|
+
return get_client()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Legacy alias
|
|
47
|
+
FaqRetriever = "FaqRetriever (deprecated; use adapters.local_json.LocalJsonKbClient)"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
"FaqEntry",
|
|
52
|
+
"FaqRetriever",
|
|
53
|
+
"SearchHit",
|
|
54
|
+
"attach_faq_to_instructions",
|
|
55
|
+
"get_retriever",
|
|
56
|
+
]
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""knowledge-base FastAPI sub-router.
|
|
2
|
+
|
|
3
|
+
Mounted on skeleton: app.include_router(router, prefix="/api/v1/kb")
|
|
4
|
+
|
|
5
|
+
Refactoring notes:
|
|
6
|
+
- All business logic delegated to core.service.KbService
|
|
7
|
+
- Response fields remain fully consistent with Phase 2 (using SearchHit.to_dict / FaqEntry.to_dict)
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import re
|
|
12
|
+
from typing import List, Optional
|
|
13
|
+
|
|
14
|
+
from fastapi import APIRouter, HTTPException
|
|
15
|
+
from pydantic import BaseModel, Field
|
|
16
|
+
|
|
17
|
+
from .core.models import FaqEntry
|
|
18
|
+
from .core.service import get_default_service
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
router = APIRouter()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
_HTML_TAG_RE = re.compile(r"<[^>]+>")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _strip_html(s: str) -> str:
|
|
28
|
+
return _HTML_TAG_RE.sub("", s).strip()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class UpsertRequest(BaseModel):
|
|
32
|
+
id: str = Field(..., max_length=64)
|
|
33
|
+
question: str = Field(..., max_length=1024)
|
|
34
|
+
answer: str = Field(..., max_length=4096)
|
|
35
|
+
keywords: List[str] = Field(default_factory=list)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SearchRequest(BaseModel):
|
|
39
|
+
query: str = Field(..., max_length=256)
|
|
40
|
+
top_k: Optional[int] = Field(default=None, ge=1, le=20)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@router.get("/list")
|
|
44
|
+
def list_entries() -> dict:
|
|
45
|
+
items = get_default_service().list_all()
|
|
46
|
+
return {"code": 0, "data": [e.to_dict() for e in items]}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@router.post("/search")
|
|
50
|
+
def search(req: SearchRequest) -> dict:
|
|
51
|
+
hits = get_default_service().search(req.query, top_k=req.top_k)
|
|
52
|
+
return {"code": 0, "data": [h.to_dict() for h in hits]}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@router.post("/upsert")
|
|
56
|
+
def upsert(req: UpsertRequest) -> dict:
|
|
57
|
+
entry = FaqEntry(
|
|
58
|
+
id=req.id.strip(),
|
|
59
|
+
question=_strip_html(req.question),
|
|
60
|
+
answer=_strip_html(req.answer),
|
|
61
|
+
keywords=[_strip_html(k) for k in (req.keywords or []) if k.strip()],
|
|
62
|
+
)
|
|
63
|
+
if not entry.id or not entry.question:
|
|
64
|
+
raise HTTPException(status_code=400, detail="id and question are required")
|
|
65
|
+
saved = get_default_service().upsert(entry)
|
|
66
|
+
return {"code": 0, "data": saved.to_dict()}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@router.delete("/{entry_id}")
|
|
70
|
+
def delete(entry_id: str) -> dict:
|
|
71
|
+
ok = get_default_service().delete(entry_id)
|
|
72
|
+
if not ok:
|
|
73
|
+
raise HTTPException(status_code=404, detail=f"entry not found: {entry_id}")
|
|
74
|
+
return {"code": 0, "data": {"deleted": entry_id}}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@router.post("/reload")
|
|
78
|
+
def reload_data() -> dict:
|
|
79
|
+
n = get_default_service().reload()
|
|
80
|
+
return {"code": 0, "data": {"count": n}}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@router.get("/stats")
|
|
84
|
+
def stats() -> dict:
|
|
85
|
+
return {"code": 0, "data": get_default_service().stats().to_dict()}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# session-summary Interface Adaptation SOP
|
|
2
|
+
|
|
3
|
+
> Session summary + structured summary write-back to CRM / ticketing / data platform.
|
|
4
|
+
> This capability's source code has not been refactored to ports/adapters/core in this release (Phase 1 compromise).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Default Contract Overview
|
|
9
|
+
|
|
10
|
+
| Contract | Method | Path | Purpose |
|
|
11
|
+
|---|---|---|---|
|
|
12
|
+
| `summary.write_to_crm` | POST | `/sessions/{session_id}/summary` | Write finalized summary to user's CRM / ticketing system |
|
|
13
|
+
| `summary.llm_summarize` | — | Reuses conversation-core `llm.chat_completions` | LLM secondary summarization, no separate adaptation needed |
|
|
14
|
+
|
|
15
|
+
Full field details in `manifest.yaml.business_contract.external_apis`.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. Default Behavior
|
|
20
|
+
|
|
21
|
+
session-summary currently **only writes to local files by default** (path `data/<session_id>.json`),
|
|
22
|
+
and does not actively write to any remote system. This means:
|
|
23
|
+
|
|
24
|
+
- Integrators need to scan the `data/` directory themselves or call `/api/v1/summary/{session_id}` to pull
|
|
25
|
+
- No outbound calls are enabled, keeping security risk low
|
|
26
|
+
- Suitable as a "draft state"; integrators plug into business systems on demand
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 3. Enabling CRM Write-Back
|
|
31
|
+
|
|
32
|
+
### 3.1 Configure Default Contract
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Enable CRM write-back + user's CRM API fully matches default contract
|
|
36
|
+
export SS_CRM_WRITE_ENABLED=1
|
|
37
|
+
export SS_CRM_BASE_URL=https://crm.example.com
|
|
38
|
+
export SS_CRM_TOKEN=sk-xxx
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
> The current capability source code has **not implemented** the `SS_CRM_*` environment variable logic;
|
|
42
|
+
> you need to write an adapter subclass per §4 below before enabling. After Phase 4's full refactor, this will become out-of-the-box.
|
|
43
|
+
|
|
44
|
+
### 3.2 Custom Field Mapping
|
|
45
|
+
|
|
46
|
+
If the user's CRM API has different field names (e.g. `summary` / `priority` / `tags`), write a simple
|
|
47
|
+
webhook middleware layer or append an HTTP call at the end of `recorder.py`'s `finalize_session` function.
|
|
48
|
+
|
|
49
|
+
Reference code snippet (manually append to `src/recorder.py`'s finalize section):
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import os, requests
|
|
53
|
+
def _maybe_write_crm(session_id: str, summary_payload: dict):
|
|
54
|
+
base = os.getenv("SS_CRM_BASE_URL")
|
|
55
|
+
if not base or os.getenv("SS_CRM_WRITE_ENABLED") != "1":
|
|
56
|
+
return
|
|
57
|
+
# Field remapping example
|
|
58
|
+
body = {
|
|
59
|
+
"session_id": session_id,
|
|
60
|
+
"summary": summary_payload.get("topic"), # User's field is called summary
|
|
61
|
+
"priority": summary_payload.get("outcome"), # User's field is called priority
|
|
62
|
+
"tags": summary_payload.get("next_actions"),
|
|
63
|
+
}
|
|
64
|
+
requests.post(
|
|
65
|
+
f"{base}/sessions/{session_id}/summary",
|
|
66
|
+
json=body,
|
|
67
|
+
headers={"Authorization": f"Bearer {os.getenv('SS_CRM_TOKEN', '')}"},
|
|
68
|
+
timeout=5,
|
|
69
|
+
)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 4. Phase 4 Plan: Full ports/adapters Refactor
|
|
75
|
+
|
|
76
|
+
The following will be introduced in the future:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
capabilities/session-summary/src/
|
|
80
|
+
├── ports/
|
|
81
|
+
│ └── crm_client.py # ABC: write_summary / query_summary
|
|
82
|
+
└── adapters/
|
|
83
|
+
├── local_file.py # Default implementation: local disk only (current behavior)
|
|
84
|
+
├── default_rest.py # Calls per default CRM contract
|
|
85
|
+
├── mock.py # Mock for demos
|
|
86
|
+
└── user_custom.py # User integration wizard generator
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
At that time, `SS_ADAPTER=user_custom` will support direct switching without manually modifying recorder.py.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 5. Security Checklist
|
|
94
|
+
|
|
95
|
+
- [ ] CRM write-back auto-redacts sensitive fields (`secret_id` / `api_key` / `token` etc.)
|
|
96
|
+
- [ ] `SS_CRM_BASE_URL` must use https:// (localhost excepted)
|
|
97
|
+
- [ ] Reject private network addresses
|
|
98
|
+
- [ ] Disk file permissions enforced to 0600 (declared in manifest.security.storage)
|
|
99
|
+
- [ ] Summary transcripts filter out sensitive user PII (phone / ID numbers) — current capability **not implemented**; user's business layer must handle this
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# session-summary · Session Summary + Structured Abstract
|
|
2
|
+
|
|
3
|
+
> Auto-archives turn records for each session on top of conversation-core,
|
|
4
|
+
> and produces structured summaries (topics / intents / next_actions) after calling `finalize`.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
python scripts/add-capability.py session-summary
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Configuration
|
|
13
|
+
|
|
14
|
+
| Env Variable | Default | Description |
|
|
15
|
+
|:---|:---|:---|
|
|
16
|
+
| `SS_STORAGE_DIR` | `capabilities/session-summary/data/` | Summary landing directory (permissions 0600) |
|
|
17
|
+
| `SS_RETENTION_DAYS` | `30` | Retention days; auto-cleanup after expiry |
|
|
18
|
+
| `SS_LLM_SUMMARY` | `true` | Whether to call LLM for secondary summarization (depends on `LLM_API_KEY`) |
|
|
19
|
+
|
|
20
|
+
## REST API
|
|
21
|
+
|
|
22
|
+
| Method | Path | Purpose |
|
|
23
|
+
|:---|:---|:---|
|
|
24
|
+
| GET | `/api/v1/summary/_list?_offset=0&_limit=20` | Recent summary list |
|
|
25
|
+
| GET | `/api/v1/summary/{session_id}` | Single session summary details |
|
|
26
|
+
| POST | `/api/v1/summary/{session_id}/finalize` | Close session and trigger summary |
|
|
27
|
+
|
|
28
|
+
## Summary Output
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"topics": ["order", "shipping"],
|
|
33
|
+
"user_intents": ["When will my order ship?"],
|
|
34
|
+
"next_actions": ["Please update my address"],
|
|
35
|
+
"highlights": ["12 turns recorded"],
|
|
36
|
+
"engine": "heuristic",
|
|
37
|
+
"model": null
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
LLM path falls back to local heuristic implementation on failure, ensuring offline availability.
|
|
42
|
+
|
|
43
|
+
## Security
|
|
44
|
+
|
|
45
|
+
- Disk file permissions enforced to `0600`
|
|
46
|
+
- Sensitive fields (`secret_id / api_key / token / credential`) redacted before writing
|
|
47
|
+
- Transcript text max length `4096`
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"session_id": "test_session",
|
|
3
|
+
"opened_at": 1780905036.267712,
|
|
4
|
+
"closed_at": null,
|
|
5
|
+
"turns": [
|
|
6
|
+
{
|
|
7
|
+
"role": "user",
|
|
8
|
+
"text": "Can you check the delivery status of order A1234?",
|
|
9
|
+
"ts": 1780905036.26798
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"role": "assistant",
|
|
13
|
+
"text": "Usually 3-5 business days.",
|
|
14
|
+
"ts": 1780905036.2682061
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"summary": null
|
|
18
|
+
}
|