@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,25 @@
|
|
|
1
|
+
"""trigger.py — compatibility facade.
|
|
2
|
+
|
|
3
|
+
Keeps the `maybe_handoff` / `is_handoff_intent` public symbols for manifest.extensions
|
|
4
|
+
(agent.before_push_text) to continue calling as `_hh_trigger.maybe_handoff(session_id, text)`,
|
|
5
|
+
internally delegated to the refactored core.service.HandoffService.
|
|
6
|
+
|
|
7
|
+
New code should use core.service / core.intent_detector directly; do not depend on this facade.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from typing import Optional
|
|
12
|
+
|
|
13
|
+
from .core.intent_detector import is_handoff_intent # noqa: F401 (public API)
|
|
14
|
+
from .core.service import get_default_service
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def maybe_handoff(session_id: str, text: str) -> Optional[str]:
|
|
18
|
+
"""For conversation-core.before_push_text injection point use.
|
|
19
|
+
|
|
20
|
+
Signature fully consistent with original: returns None when not triggered; returns a string when text has been replaced with handoff script.
|
|
21
|
+
"""
|
|
22
|
+
return get_default_service().maybe_handoff(session_id, text)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = ["is_handoff_intent", "maybe_handoff"]
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# knowledge-base Interface Adaptation SOP
|
|
2
|
+
|
|
3
|
+
> When the user's existing knowledge base / FAQ / retrieval system API diverges from this capability's default contract, follow this document for scenario-specific operations.
|
|
4
|
+
> Recommended: use `python scripts/contract-adapt.py knowledge-base` for automated generation; this document is the manual fallback.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Default Contract Overview
|
|
9
|
+
|
|
10
|
+
This capability **calls** the user's knowledge base interfaces (outbound):
|
|
11
|
+
|
|
12
|
+
| Contract | Method | Path | Purpose |
|
|
13
|
+
|---|---|---|---|
|
|
14
|
+
| `faq.search` | POST | `/faq/search` | Keyword search |
|
|
15
|
+
| `faq.list` | GET | `/faq` | List all entries |
|
|
16
|
+
| `faq.upsert` | POST | `/faq` | Create / update |
|
|
17
|
+
| `faq.delete` | DELETE | `/faq/{entry_id}` | Delete entry |
|
|
18
|
+
|
|
19
|
+
Full field definitions in `manifest.yaml` `business_contract.external_apis`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 2. Three-Layer Defense Mechanism
|
|
24
|
+
|
|
25
|
+
| Layer | Artifact Location | Applicable Scenario |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| **L1 Field Mapping** | Only field name / simple type differences | 90% of common cases |
|
|
28
|
+
| **L2 Adapter Subclass** | Auth / path / error code differences | User's own KB system |
|
|
29
|
+
| **L3 Full Custom Implementation** | Protocol-level differences (vector DB / GraphQL / gRPC) | Non-REST protocols |
|
|
30
|
+
|
|
31
|
+
All layers land in `capabilities/knowledge-base/src/adapters/user_custom.py` and are enabled via `KB_ADAPTER=user_custom`.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 3. L1 Field Mapping (most common)
|
|
36
|
+
|
|
37
|
+
### 3.1 Applicability Check
|
|
38
|
+
|
|
39
|
+
- User API is still REST + JSON
|
|
40
|
+
- Only field name differences (within `adapter_slots` scope)
|
|
41
|
+
|
|
42
|
+
### 3.2 Steps
|
|
43
|
+
|
|
44
|
+
**Step 1**: Paste user's curl or OpenAPI
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
curl -X POST https://kb.example.com/api/v3/search \
|
|
48
|
+
-H 'X-Api-Key: xxx' \
|
|
49
|
+
-d '{
|
|
50
|
+
"keyword": "refund",
|
|
51
|
+
"limit": 3
|
|
52
|
+
}'
|
|
53
|
+
# Response:
|
|
54
|
+
# {
|
|
55
|
+
# "results": [
|
|
56
|
+
# { "doc_id": "k001", "title": "How to refund", "content": "...", "tags": ["refund"], "relevance": 0.92 }
|
|
57
|
+
# ]
|
|
58
|
+
# }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Step 2**: Write mapping table `capabilities/knowledge-base/src/adapters/user_custom_mapping.yaml`
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
faq.search:
|
|
65
|
+
request:
|
|
66
|
+
query: keyword # Field name mapping
|
|
67
|
+
top_k: limit
|
|
68
|
+
response:
|
|
69
|
+
# response is array form; transformer needs to map results[] to hits[]
|
|
70
|
+
hits: results
|
|
71
|
+
"hits[].entry.id": "results[].doc_id"
|
|
72
|
+
"hits[].entry.question": "results[].title"
|
|
73
|
+
"hits[].entry.answer": "results[].content"
|
|
74
|
+
"hits[].entry.keywords": "results[].tags"
|
|
75
|
+
"hits[].score": "results[].relevance"
|
|
76
|
+
|
|
77
|
+
faq.list:
|
|
78
|
+
response:
|
|
79
|
+
items: data # User uses data not items
|
|
80
|
+
"items[].id": "data[].doc_id"
|
|
81
|
+
"items[].question": "data[].title"
|
|
82
|
+
"items[].answer": "data[].content"
|
|
83
|
+
"items[].keywords": "data[].tags"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Step 3**: Generate adapter
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python scripts/contract-adapt.py knowledge-base \
|
|
90
|
+
--base-url https://kb.example.com \
|
|
91
|
+
--auth-header "X-Api-Key" \
|
|
92
|
+
--mapping capabilities/knowledge-base/src/adapters/user_custom_mapping.yaml
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Step 4**: Enable
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
export KB_ADAPTER=user_custom
|
|
99
|
+
export KB_REST_BASE_URL=https://kb.example.com
|
|
100
|
+
export KB_REST_TOKEN=<your-api-key>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 4. L2 Adapter Subclass (auth / path style differences)
|
|
106
|
+
|
|
107
|
+
### 4.1 Applicability Check
|
|
108
|
+
|
|
109
|
+
- Auth method is not Bearer (e.g. `X-Api-Key`, signature-based auth)
|
|
110
|
+
- Different path templates
|
|
111
|
+
- Different response wrapping (e.g. `{ code, msg, data: { ... } }`)
|
|
112
|
+
|
|
113
|
+
### 4.2 Template Code
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
# capabilities/knowledge-base/src/adapters/user_custom.py
|
|
117
|
+
from typing import List, Optional
|
|
118
|
+
|
|
119
|
+
from ..core.models import FaqEntry, SearchHit
|
|
120
|
+
from .default_rest import DefaultRestKbClient
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class UserCustomKbClient(DefaultRestKbClient):
|
|
124
|
+
"""User's own KB system adapter (L2)."""
|
|
125
|
+
|
|
126
|
+
def _headers(self) -> dict:
|
|
127
|
+
h = {"Content-Type": "application/json"}
|
|
128
|
+
if self._token:
|
|
129
|
+
h["X-Api-Key"] = self._token # Not Bearer
|
|
130
|
+
return h
|
|
131
|
+
|
|
132
|
+
def search(
|
|
133
|
+
self,
|
|
134
|
+
query: str,
|
|
135
|
+
*,
|
|
136
|
+
top_k: Optional[int] = None,
|
|
137
|
+
min_score: Optional[float] = None,
|
|
138
|
+
) -> List[SearchHit]:
|
|
139
|
+
if not query.strip():
|
|
140
|
+
return []
|
|
141
|
+
payload = {
|
|
142
|
+
"keyword": query, # Field remapping
|
|
143
|
+
"limit": int(top_k or 3),
|
|
144
|
+
}
|
|
145
|
+
# User API path is different
|
|
146
|
+
data = self._post("/api/v3/search", payload)
|
|
147
|
+
results = data.get("results", []) if isinstance(data, dict) else (data or [])
|
|
148
|
+
hits: List[SearchHit] = []
|
|
149
|
+
for r in results:
|
|
150
|
+
hits.append(
|
|
151
|
+
SearchHit(
|
|
152
|
+
entry=FaqEntry(
|
|
153
|
+
id=str(r.get("doc_id", "")),
|
|
154
|
+
question=str(r.get("title", "")),
|
|
155
|
+
answer=str(r.get("content", "")),
|
|
156
|
+
keywords=list(r.get("tags") or []),
|
|
157
|
+
source="remote_api",
|
|
158
|
+
),
|
|
159
|
+
score=float(r.get("relevance", 0.0)),
|
|
160
|
+
)
|
|
161
|
+
)
|
|
162
|
+
return hits
|
|
163
|
+
|
|
164
|
+
def list_all(self) -> List[FaqEntry]:
|
|
165
|
+
data = self._get("/api/v3/docs")
|
|
166
|
+
items = data.get("data", []) if isinstance(data, dict) else (data or [])
|
|
167
|
+
return [
|
|
168
|
+
FaqEntry(
|
|
169
|
+
id=str(it.get("doc_id", "")),
|
|
170
|
+
question=str(it.get("title", "")),
|
|
171
|
+
answer=str(it.get("content", "")),
|
|
172
|
+
keywords=list(it.get("tags") or []),
|
|
173
|
+
source="remote_api",
|
|
174
|
+
)
|
|
175
|
+
for it in items
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def from_env() -> Optional["UserCustomKbClient"]:
|
|
180
|
+
import os
|
|
181
|
+
base = os.getenv("KB_REST_BASE_URL")
|
|
182
|
+
if not base:
|
|
183
|
+
return None
|
|
184
|
+
return UserCustomKbClient(
|
|
185
|
+
base_url=base,
|
|
186
|
+
token=os.getenv("KB_REST_TOKEN"),
|
|
187
|
+
timeout_ms=int(os.getenv("KB_REST_TIMEOUT_MS", "5000")),
|
|
188
|
+
)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 5. L3 Full Custom (vector DB / GraphQL / gRPC)
|
|
194
|
+
|
|
195
|
+
### 5.1 Applicability Check
|
|
196
|
+
|
|
197
|
+
- User uses vector database (Milvus / Pinecone / Qdrant) for semantic search
|
|
198
|
+
- User uses GraphQL instead of REST
|
|
199
|
+
- User uses gRPC
|
|
200
|
+
|
|
201
|
+
### 5.2 Template Code (vector DB example)
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
# capabilities/knowledge-base/src/adapters/user_custom.py
|
|
205
|
+
from typing import List, Optional
|
|
206
|
+
|
|
207
|
+
from ..core.models import FaqEntry, KbStats, SearchHit
|
|
208
|
+
from ..ports.kb_client import KnowledgeBaseClient
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class UserCustomKbClient(KnowledgeBaseClient):
|
|
212
|
+
"""Vector DB adapter example (L3: directly implements KnowledgeBaseClient)."""
|
|
213
|
+
|
|
214
|
+
def __init__(self, **kwargs):
|
|
215
|
+
# TODO Initialize vector DB client:
|
|
216
|
+
# self._milvus = MilvusClient(uri=...)
|
|
217
|
+
# self._embedder = SentenceTransformer(...)
|
|
218
|
+
...
|
|
219
|
+
|
|
220
|
+
def search(self, query, *, top_k=None, min_score=None) -> List[SearchHit]:
|
|
221
|
+
# TODO Call embedder + vector retrieval
|
|
222
|
+
# vec = self._embedder.encode(query)
|
|
223
|
+
# results = self._milvus.search(vec, top_k=top_k or 3)
|
|
224
|
+
results = []
|
|
225
|
+
return [
|
|
226
|
+
SearchHit(
|
|
227
|
+
entry=FaqEntry(id=r["id"], question=r["q"], answer=r["a"]),
|
|
228
|
+
score=float(r["distance"]),
|
|
229
|
+
)
|
|
230
|
+
for r in results
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
def list_all(self) -> List[FaqEntry]:
|
|
234
|
+
# TODO Vector DBs may not support enumeration; return empty or raise NotSupported
|
|
235
|
+
return []
|
|
236
|
+
|
|
237
|
+
def upsert(self, entry: FaqEntry) -> FaqEntry:
|
|
238
|
+
# TODO Write vectors
|
|
239
|
+
return entry
|
|
240
|
+
|
|
241
|
+
def delete(self, entry_id: str) -> bool:
|
|
242
|
+
# TODO
|
|
243
|
+
return False
|
|
244
|
+
|
|
245
|
+
def stats(self) -> KbStats:
|
|
246
|
+
return KbStats(backend="vector_db", entry_count=-1)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def from_env():
|
|
250
|
+
import os
|
|
251
|
+
return UserCustomKbClient(
|
|
252
|
+
endpoint=os.getenv("KB_VECTOR_ENDPOINT", ""),
|
|
253
|
+
api_key=os.getenv("KB_VECTOR_TOKEN", ""),
|
|
254
|
+
)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 6. Switch / Verify
|
|
260
|
+
|
|
261
|
+
### 6.1 Enable user_custom
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
export KB_ADAPTER=user_custom
|
|
265
|
+
# Takes effect after service restart
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### 6.2 Unit Self-Check
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
python -c "
|
|
272
|
+
from capabilities.knowledge_base.src.adapters.factory import build_default
|
|
273
|
+
c = build_default()
|
|
274
|
+
print('adapter:', type(c).__name__)
|
|
275
|
+
hits = c.search('refund')
|
|
276
|
+
for h in hits:
|
|
277
|
+
print(' ', h.score, h.entry.question)
|
|
278
|
+
"
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 6.3 End-to-End
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
curl -X POST http://localhost:3000/api/v1/kb/search \
|
|
285
|
+
-H 'Content-Type: application/json' \
|
|
286
|
+
-d '{"query":"refund","top_k":3}'
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 7. Security Checklist
|
|
292
|
+
|
|
293
|
+
- [ ] `KB_REST_BASE_URL` must use https:// (localhost excepted)
|
|
294
|
+
- [ ] Default reject private network addresses
|
|
295
|
+
- [ ] Auth token only from environment variables
|
|
296
|
+
- [ ] User-uploaded FAQ content sanitized via `_strip_html` (built into router)
|
|
297
|
+
- [ ] Remote exceptions do not print response bodies
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# knowledge-base · FAQ Retrieval Capability
|
|
2
|
+
|
|
3
|
+
> Adds minimal FAQ retrieval to the conversation-core skeleton with zero external dependencies.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# From repo root
|
|
9
|
+
python scripts/add-capability.py knowledge-base
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Configuration
|
|
13
|
+
|
|
14
|
+
| Env Variable | Default | Description |
|
|
15
|
+
|:---|:---|:---|
|
|
16
|
+
| `KB_DATA_FILE` | `capabilities/knowledge-base/data/faq.json` | FAQ data file |
|
|
17
|
+
| `KB_TOP_K` | `3` | Max entries to backfill per query |
|
|
18
|
+
| `KB_MIN_SCORE`| `0.1` | Hit threshold (entries below this are not injected) |
|
|
19
|
+
|
|
20
|
+
## REST API
|
|
21
|
+
|
|
22
|
+
| Method | Path | Purpose |
|
|
23
|
+
|:---|:---|:---|
|
|
24
|
+
| GET | `/api/v1/kb/list` | List all entries |
|
|
25
|
+
| POST | `/api/v1/kb/search` | Keyword search |
|
|
26
|
+
| POST | `/api/v1/kb/upsert` | Create / update |
|
|
27
|
+
| DELETE | `/api/v1/kb/{id}` | Delete |
|
|
28
|
+
| POST | `/api/v1/kb/reload` | Hot-reload from file |
|
|
29
|
+
|
|
30
|
+
## Injection Strategy
|
|
31
|
+
|
|
32
|
+
- `agent.before_start`: Append matched FAQ entries to the end of LLM `instructions`.
|
|
33
|
+
- `server.router_extension`: Mount `/api/v1/kb/*` sub-router.
|
|
34
|
+
|
|
35
|
+
## Data Format
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
[
|
|
39
|
+
{
|
|
40
|
+
"id": "faq_xxx",
|
|
41
|
+
"question": "What ...?",
|
|
42
|
+
"answer": "...",
|
|
43
|
+
"keywords": ["alias1", "alias2"]
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Security
|
|
49
|
+
|
|
50
|
+
- HTML tags are automatically stripped when writing entries (XSS defense).
|
|
51
|
+
- Length limits: `question ≤ 1024`, `answer ≤ 4096`, `query ≤ 256`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "faq_shipping_time",
|
|
4
|
+
"question": "What is the typical shipping time?",
|
|
5
|
+
"answer": "Standard shipping takes 3-5 business days; express shipping arrives within 1-2 business days.",
|
|
6
|
+
"keywords": ["shipping", "delivery", "tracking", "logistics"]
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "faq_return_policy",
|
|
10
|
+
"question": "How do I return a product?",
|
|
11
|
+
"answer": "Return requests can be filed within 30 days of delivery. Visit Account > Orders to initiate a return.",
|
|
12
|
+
"keywords": ["return", "refund", "exchange", "money back"]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "faq_change_address",
|
|
16
|
+
"question": "Can I change the shipping address after ordering?",
|
|
17
|
+
"answer": "You can update the shipping address before the order enters the picking stage. Use Order Detail > Modify Address.",
|
|
18
|
+
"keywords": ["address", "modify", "change shipping", "update address"]
|
|
19
|
+
}
|
|
20
|
+
]
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# knowledge-base capability self-describing manifest
|
|
2
|
+
# Type: capability (optional install)
|
|
3
|
+
|
|
4
|
+
name: "knowledge-base"
|
|
5
|
+
version: "1.1.0"
|
|
6
|
+
type: "capability"
|
|
7
|
+
description: "FAQ retrieval + keyword matching (Phase 3 refactored to ports/adapters/core three-layer architecture)"
|
|
8
|
+
|
|
9
|
+
# ---------------------------------------------------------------------------
|
|
10
|
+
# Dependencies: only depends on the generic skeleton; no external databases
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
dependencies:
|
|
13
|
+
- name: "conversation-core"
|
|
14
|
+
version: ">=1.0.0,<2.0.0"
|
|
15
|
+
|
|
16
|
+
# ---------------------------------------------------------------------------
|
|
17
|
+
# Injection extensions into skeleton (maintains full Phase 2 compatibility; retriever.py is now a facade)
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
extensions:
|
|
20
|
+
# Prepend matched FAQ results to instructions before start_agent
|
|
21
|
+
- inject_at: "agent.before_start"
|
|
22
|
+
inline_code: |
|
|
23
|
+
# [knowledge-base] inject FAQ context if any user keywords present
|
|
24
|
+
if config is not None and getattr(config, "instructions", None):
|
|
25
|
+
from ._capability_loader import try_load_capability
|
|
26
|
+
_kb = try_load_capability("knowledge-base", "src/retriever.py")
|
|
27
|
+
if _kb is not None:
|
|
28
|
+
try:
|
|
29
|
+
config.instructions = _kb.attach_faq_to_instructions(config.instructions)
|
|
30
|
+
except Exception as _kb_exc: # noqa: BLE001
|
|
31
|
+
logger.warning("knowledge-base FAQ injection failed: %s", _kb_exc)
|
|
32
|
+
# Mount sub-router after server.include_router
|
|
33
|
+
- inject_at: "server.router_extension"
|
|
34
|
+
inline_code: |
|
|
35
|
+
# [knowledge-base] mount sub-router
|
|
36
|
+
from ._capability_loader import try_load_capability as _try_load_capability
|
|
37
|
+
_kb_router_mod = _try_load_capability("knowledge-base", "src/router.py")
|
|
38
|
+
if _kb_router_mod is not None and hasattr(_kb_router_mod, "router"):
|
|
39
|
+
app.include_router(
|
|
40
|
+
_kb_router_mod.router, prefix="/api/v1/kb", tags=["knowledge-base"]
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# ---------------------------------------------------------------------------
|
|
44
|
+
# Configuration interface
|
|
45
|
+
# ---------------------------------------------------------------------------
|
|
46
|
+
config:
|
|
47
|
+
data_file:
|
|
48
|
+
description: "FAQ data file path (JSON), used only by local_json adapter"
|
|
49
|
+
default: "capabilities/knowledge-base/data/faq.json"
|
|
50
|
+
env: "KB_DATA_FILE"
|
|
51
|
+
matcher:
|
|
52
|
+
description: "Matching strategy: keyword | tfidf | hybrid (local_json adapter defaults to tfidf)"
|
|
53
|
+
default: "tfidf"
|
|
54
|
+
top_k:
|
|
55
|
+
description: "Maximum number of FAQ entries to backfill"
|
|
56
|
+
default: 3
|
|
57
|
+
env: "KB_TOP_K"
|
|
58
|
+
min_score:
|
|
59
|
+
description: "Score threshold; entries below this threshold are not injected"
|
|
60
|
+
default: 0.1
|
|
61
|
+
env: "KB_MIN_SCORE"
|
|
62
|
+
adapter:
|
|
63
|
+
description: "Which KnowledgeBaseClient implementation to use: local_json | mock | default_rest | user_custom"
|
|
64
|
+
default: "local_json"
|
|
65
|
+
env: "KB_ADAPTER"
|
|
66
|
+
|
|
67
|
+
# ---------------------------------------------------------------------------
|
|
68
|
+
# API endpoints
|
|
69
|
+
# ---------------------------------------------------------------------------
|
|
70
|
+
endpoints:
|
|
71
|
+
- method: GET
|
|
72
|
+
path: /api/v1/kb/list
|
|
73
|
+
description: List all knowledge entries
|
|
74
|
+
- method: POST
|
|
75
|
+
path: /api/v1/kb/search
|
|
76
|
+
description: "Keyword search FAQ (body shape: {query, top_k?})"
|
|
77
|
+
- method: POST
|
|
78
|
+
path: /api/v1/kb/upsert
|
|
79
|
+
description: "Create or update entry (body shape: {id, question, answer, keywords[]})"
|
|
80
|
+
- method: DELETE
|
|
81
|
+
path: /api/v1/kb/{entry_id}
|
|
82
|
+
description: "Delete entry"
|
|
83
|
+
- method: POST
|
|
84
|
+
path: /api/v1/kb/reload
|
|
85
|
+
description: "Reload data from external source"
|
|
86
|
+
- method: GET
|
|
87
|
+
path: /api/v1/kb/stats
|
|
88
|
+
description: "Returns backend / entry count / load time (Phase 3 new)"
|
|
89
|
+
|
|
90
|
+
# ---------------------------------------------------------------------------
|
|
91
|
+
# Business contract (Phase 3 new; follows references/business-contract-spec.md v1.0)
|
|
92
|
+
# ---------------------------------------------------------------------------
|
|
93
|
+
business_contract:
|
|
94
|
+
port_class: "src.ports.kb_client.KnowledgeBaseClient"
|
|
95
|
+
default_adapter: "src.adapters.local_json.LocalJsonKbClient"
|
|
96
|
+
mock_adapter: "src.adapters.mock.MockKbClient"
|
|
97
|
+
customization_sop: "INTERFACE_ADAPT.md"
|
|
98
|
+
external_apis:
|
|
99
|
+
- name: faq.search
|
|
100
|
+
direction: outbound
|
|
101
|
+
method: POST
|
|
102
|
+
path: /faq/search
|
|
103
|
+
description: "Perform keyword search against external FAQ service"
|
|
104
|
+
request_schema:
|
|
105
|
+
query: string
|
|
106
|
+
top_k: int
|
|
107
|
+
min_score: float
|
|
108
|
+
response_schema:
|
|
109
|
+
hits:
|
|
110
|
+
- entry:
|
|
111
|
+
id: string
|
|
112
|
+
question: string
|
|
113
|
+
answer: string
|
|
114
|
+
keywords: string[]
|
|
115
|
+
score: float
|
|
116
|
+
adapter_slots:
|
|
117
|
+
- request.query
|
|
118
|
+
- request.top_k
|
|
119
|
+
- response.hits
|
|
120
|
+
auth:
|
|
121
|
+
type: bearer
|
|
122
|
+
location: header
|
|
123
|
+
name: Authorization
|
|
124
|
+
timeout_ms: 5000
|
|
125
|
+
|
|
126
|
+
- name: faq.list
|
|
127
|
+
direction: outbound
|
|
128
|
+
method: GET
|
|
129
|
+
path: /faq
|
|
130
|
+
description: "List all FAQ entries"
|
|
131
|
+
request_schema: {}
|
|
132
|
+
response_schema:
|
|
133
|
+
items:
|
|
134
|
+
- id: string
|
|
135
|
+
question: string
|
|
136
|
+
answer: string
|
|
137
|
+
keywords: string[]
|
|
138
|
+
adapter_slots:
|
|
139
|
+
- response.items
|
|
140
|
+
timeout_ms: 5000
|
|
141
|
+
|
|
142
|
+
- name: faq.upsert
|
|
143
|
+
direction: outbound
|
|
144
|
+
method: POST
|
|
145
|
+
path: /faq
|
|
146
|
+
description: "Create or update FAQ entry"
|
|
147
|
+
request_schema:
|
|
148
|
+
id: string
|
|
149
|
+
question: string
|
|
150
|
+
answer: string
|
|
151
|
+
keywords: string[]
|
|
152
|
+
response_schema:
|
|
153
|
+
id: string
|
|
154
|
+
question: string
|
|
155
|
+
answer: string
|
|
156
|
+
keywords: string[]
|
|
157
|
+
adapter_slots:
|
|
158
|
+
- request.id
|
|
159
|
+
- request.question
|
|
160
|
+
- request.answer
|
|
161
|
+
- request.keywords
|
|
162
|
+
timeout_ms: 5000
|
|
163
|
+
|
|
164
|
+
- name: faq.delete
|
|
165
|
+
direction: outbound
|
|
166
|
+
method: DELETE
|
|
167
|
+
path: /faq/{entry_id}
|
|
168
|
+
description: "Delete FAQ entry"
|
|
169
|
+
request_schema:
|
|
170
|
+
entry_id: string
|
|
171
|
+
response_schema:
|
|
172
|
+
deleted: string
|
|
173
|
+
adapter_slots:
|
|
174
|
+
- request.entry_id
|
|
175
|
+
timeout_ms: 3000
|
|
176
|
+
|
|
177
|
+
# ---------------------------------------------------------------------------
|
|
178
|
+
# Integration rules
|
|
179
|
+
# ---------------------------------------------------------------------------
|
|
180
|
+
integration:
|
|
181
|
+
mode: "auto"
|
|
182
|
+
auto_adapters:
|
|
183
|
+
- tech_stack: ["react", "vue", "angular"]
|
|
184
|
+
adapter: "frontend-spa"
|
|
185
|
+
description: "Inject an FAQ editor panel component into SPA"
|
|
186
|
+
fallback:
|
|
187
|
+
guided_templates:
|
|
188
|
+
- "../../auto_adapters/integration_templates/generic-frontend.md"
|
|
189
|
+
manual_api:
|
|
190
|
+
rest_endpoint: "/api/v1/kb"
|
|
191
|
+
sdk_packages: []
|
|
192
|
+
|
|
193
|
+
# ---------------------------------------------------------------------------
|
|
194
|
+
# Security
|
|
195
|
+
# ---------------------------------------------------------------------------
|
|
196
|
+
security:
|
|
197
|
+
log_redaction:
|
|
198
|
+
enabled: true
|
|
199
|
+
patterns: ["api_key", "token", "credential", "authorization"]
|
|
200
|
+
input_validation:
|
|
201
|
+
max_query_length: 256
|
|
202
|
+
forbid_html_tags: true # Strip HTML when writing entries to prevent injection
|
|
203
|
+
network:
|
|
204
|
+
enforce_https: true # default_rest adapter enforces HTTPS for non-localhost
|
|
205
|
+
|
|
206
|
+
acceptance:
|
|
207
|
+
- "Provide keyword/tfidf retrieval interface with minimal implementation"
|
|
208
|
+
- "API endpoints available immediately after skeleton startup"
|
|
209
|
+
- "Instructions injection does not modify skeleton files; solely via manifest.extensions"
|
|
210
|
+
- "Switching KB_ADAPTER requires no business code changes (local_json / mock / default_rest / user_custom)"
|
|
211
|
+
- "default_rest adapter rejects private network addresses (except localhost)"
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""knowledge-base capability: FAQ retrieval + keyword matching.
|
|
2
|
+
|
|
3
|
+
Minimal implementation:
|
|
4
|
+
- Data source: local JSON file (hot-reloadable)
|
|
5
|
+
- Matching: keyword weighted scoring + optional TF-IDF (stop-word filtering)
|
|
6
|
+
- Zero external dependencies, pure Python implementation
|
|
7
|
+
"""
|
|
8
|
+
__version__ = "1.0.0"
|