@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
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
"""Execution-step state machine for the topic skill.
|
|
2
|
-
|
|
3
|
-
The state machine is the enforcement mechanism for topic execution. It stores a
|
|
4
|
-
single ``execution_queue`` in ``.trtc-session.yaml``. Each execution step has a
|
|
5
|
-
uniform shape:
|
|
6
|
-
|
|
7
|
-
{id, type: "slice" | "unit", status, slices: [...]}
|
|
8
|
-
|
|
9
|
-
Slices remain the knowledge and rule source. Execution steps define how many
|
|
10
|
-
slices are delivered in one read/write/apply loop.
|
|
11
|
-
"""
|
|
12
|
-
from __future__ import annotations
|
|
13
|
-
|
|
14
|
-
from pathlib import Path
|
|
15
|
-
from typing import Optional, Tuple
|
|
16
|
-
|
|
17
|
-
import yaml
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
_TRANSITIONS = {
|
|
21
|
-
("not_started", "mark_slice_read"): "slice_read",
|
|
22
|
-
("slice_read", "mark_code_written"): "code_written",
|
|
23
|
-
("code_written", "mark_apply_passed"): "apply_passed",
|
|
24
|
-
("code_written", "mark_apply_failed"): "apply_failed",
|
|
25
|
-
("apply_failed", "mark_code_written"): "code_written",
|
|
26
|
-
("apply_passed", "mark_user_confirmed"): "ADVANCE_INDEX",
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
_KNOWN_TRANSITIONS = {t for (_state, t) in _TRANSITIONS.keys()}
|
|
30
|
-
_TOPIC_ROOT = Path(__file__).resolve().parents[2]
|
|
31
|
-
_EXECUTION_UNITS_PATH = _TOPIC_ROOT / "references" / "execution-units.yaml"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def _load(path: Path) -> dict:
|
|
35
|
-
return yaml.safe_load(path.read_text()) or {}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def _save(path: Path, data: dict) -> None:
|
|
39
|
-
path.write_text(yaml.safe_dump(data, sort_keys=False, allow_unicode=True))
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def _step_id_from_slices(slice_ids: list[str]) -> str:
|
|
43
|
-
if len(slice_ids) == 1:
|
|
44
|
-
return slice_ids[0]
|
|
45
|
-
return "__".join(s.split("/", 1)[1] for s in slice_ids)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def _step_type(slice_ids: list[str]) -> str:
|
|
49
|
-
return "unit" if len(slice_ids) > 1 else "slice"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def _make_step(step_id: str, title: str, slice_ids: list[str], *, status: str = "pending") -> dict:
|
|
53
|
-
return {
|
|
54
|
-
"id": step_id,
|
|
55
|
-
"type": _step_type(slice_ids),
|
|
56
|
-
"title": title,
|
|
57
|
-
"status": status,
|
|
58
|
-
"slices": slice_ids,
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def _build_declared_unit_steps(raw_units, plan: list[str]) -> list[dict]:
|
|
63
|
-
"""Group only slices already present in confirmed_plan."""
|
|
64
|
-
configured = [
|
|
65
|
-
sid
|
|
66
|
-
for raw in raw_units or []
|
|
67
|
-
for sid in (raw.get("slices") or [])
|
|
68
|
-
]
|
|
69
|
-
duplicates = sorted({sid for sid in configured if configured.count(sid) > 1})
|
|
70
|
-
if duplicates:
|
|
71
|
-
raise RuntimeError("delivery unit config contains duplicate slices: " + ", ".join(duplicates))
|
|
72
|
-
|
|
73
|
-
remaining = list(plan)
|
|
74
|
-
steps: list[dict] = []
|
|
75
|
-
|
|
76
|
-
for raw in raw_units or []:
|
|
77
|
-
group = raw.get("slices") or []
|
|
78
|
-
slice_ids = [sid for sid in group if sid in remaining]
|
|
79
|
-
if len(slice_ids) < 2:
|
|
80
|
-
continue
|
|
81
|
-
step_id = raw.get("id") or _step_id_from_slices(slice_ids)
|
|
82
|
-
steps.append(_make_step(step_id, raw.get("title") or step_id, slice_ids))
|
|
83
|
-
for sid in slice_ids:
|
|
84
|
-
remaining.remove(sid)
|
|
85
|
-
|
|
86
|
-
for sid in remaining:
|
|
87
|
-
steps.append(_make_step(sid, sid, [sid]))
|
|
88
|
-
|
|
89
|
-
order = {sid: i for i, sid in enumerate(plan)}
|
|
90
|
-
steps.sort(key=lambda step: min(order[sid] for sid in step["slices"]))
|
|
91
|
-
return steps
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def _scenario_delivery_units(data: dict) -> list[dict]:
|
|
95
|
-
scenario = data.get("scenario")
|
|
96
|
-
if not scenario or not _EXECUTION_UNITS_PATH.exists():
|
|
97
|
-
return []
|
|
98
|
-
config = yaml.safe_load(_EXECUTION_UNITS_PATH.read_text()) or {}
|
|
99
|
-
return (
|
|
100
|
-
(config.get("scenarios") or {})
|
|
101
|
-
.get(scenario, {})
|
|
102
|
-
.get("delivery_units")
|
|
103
|
-
or []
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def _build_slice_steps(plan: list[str]) -> list[dict]:
|
|
108
|
-
return [_make_step(sid, sid, [sid]) for sid in plan]
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def _flatten_slices(queue: list[dict]) -> list[str]:
|
|
112
|
-
return [sid for step in queue for sid in step.get("slices", [])]
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def _execution_queue_from_legacy(data: dict) -> list[dict] | None:
|
|
116
|
-
"""Best-effort read compatibility for old sessions."""
|
|
117
|
-
if data.get("execution_queue"):
|
|
118
|
-
return data["execution_queue"]
|
|
119
|
-
if data.get("delivery_unit_queue"):
|
|
120
|
-
return [
|
|
121
|
-
_make_step(
|
|
122
|
-
entry.get("id") or _step_id_from_slices(entry.get("slices", [])),
|
|
123
|
-
entry.get("title") or entry.get("id") or "",
|
|
124
|
-
entry.get("slices", []),
|
|
125
|
-
status=entry.get("status", "pending"),
|
|
126
|
-
)
|
|
127
|
-
for entry in data["delivery_unit_queue"]
|
|
128
|
-
]
|
|
129
|
-
if data.get("slice_queue"):
|
|
130
|
-
return [
|
|
131
|
-
_make_step(entry.get("id"), entry.get("id"), [entry.get("id")], status=entry.get("status", "pending"))
|
|
132
|
-
for entry in data["slice_queue"]
|
|
133
|
-
if entry.get("id")
|
|
134
|
-
]
|
|
135
|
-
return None
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def _current_index_state(data: dict) -> tuple[int, str]:
|
|
139
|
-
if "current_execution_index" in data or "current_execution_state" in data:
|
|
140
|
-
return data.get("current_execution_index", 0), data.get("current_execution_state") or "not_started"
|
|
141
|
-
if data.get("execution_granularity") in {"unit", "delivery_unit"}:
|
|
142
|
-
return data.get("current_unit_index", 0), data.get("current_unit_state") or "not_started"
|
|
143
|
-
return data.get("current_slice_index", 0), data.get("current_slice_state") or "not_started"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def init_queue(session_path) -> None:
|
|
147
|
-
"""Materialise ``confirmed_plan`` into ``execution_queue``.
|
|
148
|
-
|
|
149
|
-
Idempotent when the queue already covers the same confirmed_plan. Refuses
|
|
150
|
-
re-init if the plan changed after topic took ownership.
|
|
151
|
-
"""
|
|
152
|
-
path = Path(session_path)
|
|
153
|
-
data = _load(path)
|
|
154
|
-
plan = data.get("confirmed_plan")
|
|
155
|
-
if not plan:
|
|
156
|
-
raise RuntimeError(
|
|
157
|
-
"confirmed_plan is missing or empty in session — onboarding A2 "
|
|
158
|
-
"should have populated it before topic ran init_queue."
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
expected_ids = list(plan)
|
|
162
|
-
existing_queue = data.get("execution_queue")
|
|
163
|
-
if existing_queue is not None:
|
|
164
|
-
if _flatten_slices(existing_queue) != expected_ids:
|
|
165
|
-
raise RuntimeError(
|
|
166
|
-
"execution_queue is frozen and differs from confirmed_plan — "
|
|
167
|
-
"remove execution_queue / current_execution_index / "
|
|
168
|
-
"current_execution_state from the session file and run init again."
|
|
169
|
-
)
|
|
170
|
-
return
|
|
171
|
-
|
|
172
|
-
if data.get("execution_granularity") in {"unit", "delivery_unit"}:
|
|
173
|
-
raw_units = data.get("delivery_units") or _scenario_delivery_units(data)
|
|
174
|
-
queue = _build_declared_unit_steps(raw_units, expected_ids)
|
|
175
|
-
else:
|
|
176
|
-
queue = _build_slice_steps(expected_ids)
|
|
177
|
-
|
|
178
|
-
data["execution_queue"] = queue
|
|
179
|
-
data["current_execution_index"] = 0
|
|
180
|
-
data["current_execution_state"] = "not_started"
|
|
181
|
-
_save(path, data)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
def current_scope(session_path) -> dict:
|
|
185
|
-
"""Return the active execution step."""
|
|
186
|
-
path = Path(session_path)
|
|
187
|
-
if not path.exists():
|
|
188
|
-
return {"initialised": False, "reason": "session file missing"}
|
|
189
|
-
|
|
190
|
-
data = _load(path)
|
|
191
|
-
queue = _execution_queue_from_legacy(data)
|
|
192
|
-
if not queue:
|
|
193
|
-
return {"initialised": False, "reason": "execution_queue not set"}
|
|
194
|
-
|
|
195
|
-
idx, state = _current_index_state(data)
|
|
196
|
-
if state == "all_done":
|
|
197
|
-
return {
|
|
198
|
-
"initialised": True,
|
|
199
|
-
"kind": "execution",
|
|
200
|
-
"index": idx,
|
|
201
|
-
"state": "all_done",
|
|
202
|
-
"total": len(queue),
|
|
203
|
-
"id": None,
|
|
204
|
-
"title": None,
|
|
205
|
-
"type": None,
|
|
206
|
-
"slice_ids": [],
|
|
207
|
-
"queue": queue,
|
|
208
|
-
}
|
|
209
|
-
if idx is None or idx < 0 or idx >= len(queue):
|
|
210
|
-
return {"initialised": False, "reason": "execution cursor out of range"}
|
|
211
|
-
|
|
212
|
-
step = queue[idx]
|
|
213
|
-
slice_ids = step.get("slices") or [step.get("id")]
|
|
214
|
-
return {
|
|
215
|
-
"initialised": True,
|
|
216
|
-
"kind": step.get("type", _step_type(slice_ids)),
|
|
217
|
-
"index": idx,
|
|
218
|
-
"state": state,
|
|
219
|
-
"total": len(queue),
|
|
220
|
-
"id": step.get("id"),
|
|
221
|
-
"title": step.get("title") or step.get("id"),
|
|
222
|
-
"type": step.get("type", _step_type(slice_ids)),
|
|
223
|
-
"slice_ids": slice_ids,
|
|
224
|
-
"queue": queue,
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
def current_slice(session_path) -> Tuple[Optional[int], Optional[str], Optional[str]]:
|
|
229
|
-
"""Compatibility helper returning the first slice in the current step."""
|
|
230
|
-
scope = current_scope(session_path)
|
|
231
|
-
if not scope.get("initialised"):
|
|
232
|
-
return (None, None, None)
|
|
233
|
-
if scope.get("state") == "all_done":
|
|
234
|
-
return (scope.get("index"), None, "all_done")
|
|
235
|
-
slice_ids = scope.get("slice_ids") or []
|
|
236
|
-
return (scope.get("index"), slice_ids[0] if slice_ids else None, scope.get("state"))
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
def advance(session_path, transition: str) -> str:
|
|
240
|
-
if transition not in _KNOWN_TRANSITIONS:
|
|
241
|
-
raise RuntimeError(
|
|
242
|
-
f"unknown transition '{transition}'. Known transitions: "
|
|
243
|
-
f"{sorted(_KNOWN_TRANSITIONS)}"
|
|
244
|
-
)
|
|
245
|
-
|
|
246
|
-
path = Path(session_path)
|
|
247
|
-
data = _load(path)
|
|
248
|
-
queue = data.get("execution_queue")
|
|
249
|
-
if not queue:
|
|
250
|
-
legacy = _execution_queue_from_legacy(data)
|
|
251
|
-
if legacy:
|
|
252
|
-
queue = legacy
|
|
253
|
-
data["execution_queue"] = queue
|
|
254
|
-
else:
|
|
255
|
-
raise RuntimeError("execution_queue not initialised — call init_queue() before advance().")
|
|
256
|
-
|
|
257
|
-
state = data.get("current_execution_state")
|
|
258
|
-
idx = data.get("current_execution_index", 0)
|
|
259
|
-
if state is None:
|
|
260
|
-
legacy_idx, legacy_state = _current_index_state(data)
|
|
261
|
-
idx = legacy_idx
|
|
262
|
-
state = legacy_state
|
|
263
|
-
data["current_execution_index"] = idx
|
|
264
|
-
data["current_execution_state"] = state
|
|
265
|
-
|
|
266
|
-
if state == "all_done":
|
|
267
|
-
raise RuntimeError(
|
|
268
|
-
"all_done — the execution queue is finished; no further transitions "
|
|
269
|
-
"are allowed. Start a new scenario or reset the session."
|
|
270
|
-
)
|
|
271
|
-
|
|
272
|
-
next_state = _TRANSITIONS.get((state, transition))
|
|
273
|
-
if next_state is None:
|
|
274
|
-
raise RuntimeError(
|
|
275
|
-
f"illegal transition '{transition}' from state '{state}'. "
|
|
276
|
-
f"Allowed from '{state}': "
|
|
277
|
-
f"{sorted(t for (s, t) in _TRANSITIONS.keys() if s == state)}"
|
|
278
|
-
)
|
|
279
|
-
|
|
280
|
-
if next_state == "ADVANCE_INDEX":
|
|
281
|
-
step = queue[idx]
|
|
282
|
-
step["status"] = "done"
|
|
283
|
-
evidence_ids = [step.get("id"), *step.get("slices", [])]
|
|
284
|
-
for evidence_id in [eid for eid in evidence_ids if eid]:
|
|
285
|
-
ev_path = path.parent / ".trtc-apply-evidence" / (evidence_id.replace("/", "__") + ".json")
|
|
286
|
-
try:
|
|
287
|
-
ev_path.unlink()
|
|
288
|
-
except FileNotFoundError:
|
|
289
|
-
pass
|
|
290
|
-
|
|
291
|
-
new_idx = idx + 1
|
|
292
|
-
data["execution_queue"] = queue
|
|
293
|
-
data["current_execution_index"] = new_idx
|
|
294
|
-
data["current_execution_state"] = "all_done" if new_idx >= len(queue) else "not_started"
|
|
295
|
-
_save(path, data)
|
|
296
|
-
return data["current_execution_state"]
|
|
297
|
-
|
|
298
|
-
data["execution_queue"] = queue
|
|
299
|
-
data["current_execution_state"] = next_state
|
|
300
|
-
_save(path, data)
|
|
301
|
-
return next_state
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
def status(session_path) -> dict:
|
|
305
|
-
path = Path(session_path)
|
|
306
|
-
if not path.exists():
|
|
307
|
-
return {"initialised": False, "reason": "session file missing"}
|
|
308
|
-
data = _load(path)
|
|
309
|
-
queue = _execution_queue_from_legacy(data)
|
|
310
|
-
if not queue:
|
|
311
|
-
return {"initialised": False, "reason": "execution_queue not set"}
|
|
312
|
-
|
|
313
|
-
idx, state = _current_index_state(data)
|
|
314
|
-
current = queue[idx] if idx < len(queue) else None
|
|
315
|
-
slice_ids = (current.get("slices") if current else None) or []
|
|
316
|
-
step_type = current.get("type", _step_type(slice_ids)) if current else None
|
|
317
|
-
return {
|
|
318
|
-
"initialised": True,
|
|
319
|
-
"kind": step_type or "execution",
|
|
320
|
-
"index": idx,
|
|
321
|
-
"state": state,
|
|
322
|
-
"total": len(queue),
|
|
323
|
-
"current_slice_id": slice_ids[0] if slice_ids else None,
|
|
324
|
-
"current_unit_id": current.get("id") if current and step_type == "unit" else None,
|
|
325
|
-
"current_id": current.get("id") if current else None,
|
|
326
|
-
"slice_ids": slice_ids,
|
|
327
|
-
"queue": queue,
|
|
328
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# Topic state-machine tests
|
|
2
|
-
|
|
3
|
-
> ⚪ **内部 — 不对外发布**。这些测试只供 TRTC 知识库维护者使用。
|
|
4
|
-
> 跟项目根 `tests/` 的定位一致,不会随 skill 包分发到用户机器;
|
|
5
|
-
> 发布脚本应当排除整个 `tests/` 目录。end user 不会跑、也不应跑这些测试。
|
|
6
|
-
|
|
7
|
-
这套测试守护 topic skill 的 slice-loop 状态机、PreToolUse / Stop 守门员
|
|
8
|
-
与 `apply.py` 的契约——也就是阻止 AI 批量读 slice、批量生成代码、跳过 `apply`
|
|
9
|
-
这三类坏行为的那一层硬约束。每次改动 `scripts/`、`scripts/lib/`、
|
|
10
|
-
`guardrails/` 下任何一个文件都应跑一遍这套测试。
|
|
11
|
-
|
|
12
|
-
## 运行
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
# 在 repo 根
|
|
16
|
-
python3 -m pytest ${CLAUDE_PLUGIN_ROOT}/skills/trtc-topic/tests/
|
|
17
|
-
|
|
18
|
-
# 看详细
|
|
19
|
-
python3 -m pytest ${CLAUDE_PLUGIN_ROOT}/skills/trtc-topic/tests/ -v
|
|
20
|
-
|
|
21
|
-
# 单文件
|
|
22
|
-
python3 -m pytest ${CLAUDE_PLUGIN_ROOT}/skills/trtc-topic/tests/test_state_machine.py -v
|
|
23
|
-
|
|
24
|
-
# 单 case
|
|
25
|
-
python3 -m pytest \
|
|
26
|
-
${CLAUDE_PLUGIN_ROOT}/skills/trtc-topic/tests/test_apply_cli.py::TestAutoAdvanceOnPass::test_pause_on_failure_pass_advances_to_next_slice -v
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
依赖:pytest 8+ 与 PyYAML(项目已有)。
|
|
30
|
-
|
|
31
|
-
## 覆盖矩阵(85 cases)
|
|
32
|
-
|
|
33
|
-
| 文件 | cases | 守护对象 | 关键场景 |
|
|
34
|
-
|---|---|---|---|
|
|
35
|
-
| `test_state_machine.py` | 25 | `scripts/lib/state_machine.py` | `init_queue` / `current_slice` / `advance` 全部合法 transition;非法 transition 抛错;apply_failed → 重试;user_confirmed 后清理 evidence;queue 末尾 → all_done |
|
|
36
|
-
| `test_gates.py` | 19 | `guardrails/gate_slice_read.py`、`guardrails/gate_slice_write.py` | session 缺失/queue 未初始化静默放行;只放行 cursor 当前 slice 的 .md;`not_started`/`apply_passed` 状态拦 Write;`slice_read`/`code_written`/`apply_failed` 放行 Edit |
|
|
37
|
-
| `test_apply_cli.py` | 16 | `scripts/apply.py` | pass + fail + static-only + 4 类 usage error;`auto_advance_policy` 五种值;apply 失败永远 pause;最后一个 slice → all_done;demo-test-2 三条 regression(注释/字符串塞 pattern / fail 输出不泄漏 patterns)|
|
|
38
|
-
| `test_stop_require_apply.py` | 8 | `guardrails/stop_require_apply_evidence.py` | session/queue 缺失放行;`not_started` / `slice_read` / `apply_passed` / `all_done` 放行;`code_written` / `apply_failed` 拦截 |
|
|
39
|
-
| `test_end_to_end.py` | 3 | 全链路 | 手动 confirm 完整循环;apply 失败路径;`pause_on_failure` 自动推进路径 |
|
|
40
|
-
| `test_topic_skill_invariants.py` | 4 | `topic/SKILL.md` 结构不变量 | Apply Evidence Block 已删;STATE-MACHINE-GUIDE.md 存在且被引用;topic/SKILL.md 不超过 480 行;Calling apply 段保持紧凑 |
|
|
41
|
-
| `test_session_resolver.py` | 10 | 三个 CLI 共享的 session 路径解析 | 4 级解析链(`--session` flag → `$TRTC_SESSION_PATH` → `$CLAUDE_PROJECT_DIR/.trtc-session.yaml` → cwd);找不到时给 actionable 提示;三个 CLI 行为一致 |
|
|
42
|
-
|
|
43
|
-
## Fixtures(`conftest.py`)
|
|
44
|
-
|
|
45
|
-
- `session_factory(**overrides)` — 在 `tmp_path` 写一个 `${CLAUDE_PROJECT_DIR}/.trtc-session.yaml`。
|
|
46
|
-
默认仿真"general-conference / web 集成中"的状态。`overrides` 可换 `confirmed_plan`、
|
|
47
|
-
`auto_advance_policy` 等任意根级字段。
|
|
48
|
-
- `project_factory()` — 在 `tmp_path/user-project/src/` 造空项目骨架,
|
|
49
|
-
测试可以往里写 .vue / .ts。
|
|
50
|
-
|
|
51
|
-
## 依赖的目录布局(已对齐 apply skill)
|
|
52
|
-
|
|
53
|
-
```
|
|
54
|
-
topic/
|
|
55
|
-
├── guardrails/ ← Claude Code 注册的 hook
|
|
56
|
-
│ ├── gate_slice_read.py
|
|
57
|
-
│ ├── gate_slice_write.py
|
|
58
|
-
│ └── stop_require_apply_evidence.py
|
|
59
|
-
├── scripts/ ← AI 通过 Bash 调用的 runtime CLI
|
|
60
|
-
│ ├── apply.py
|
|
61
|
-
│ ├── init_slice_queue.py
|
|
62
|
-
│ ├── next_slice.py
|
|
63
|
-
│ └── lib/
|
|
64
|
-
│ └── state_machine.py ← 被 import 的库(不直接跑)
|
|
65
|
-
└── tests/ ← ⚪ 本目录
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
如果你 git mv 了 `scripts/` 或 `scripts/lib/` 下的任何文件,这套测试里的
|
|
69
|
-
`sys.path.insert` / `parents[N]` / 命令行路径都需要同步更新——跑全套就能
|
|
70
|
-
立刻发现哪些路径断了。
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"""pytest fixtures for the topic state-machine and gate hooks.
|
|
2
|
-
|
|
3
|
-
These fixtures only know about session files and a simulated project root.
|
|
4
|
-
They never touch the real repo session.
|
|
5
|
-
"""
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
|
|
10
|
-
import pytest
|
|
11
|
-
import yaml
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Default confirmed_plan used by most tests — mirrors the general-conference
|
|
15
|
-
# minimal scope (P0).
|
|
16
|
-
DEFAULT_CONFIRMED_PLAN = [
|
|
17
|
-
"conference/login-auth",
|
|
18
|
-
"conference/room-lifecycle",
|
|
19
|
-
"conference/participant-list",
|
|
20
|
-
"conference/video-layout",
|
|
21
|
-
"conference/device-control",
|
|
22
|
-
"conference/network-quality",
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@pytest.fixture
|
|
27
|
-
def session_factory(tmp_path: Path):
|
|
28
|
-
"""Factory that writes a `.trtc-session.yaml` into tmp_path.
|
|
29
|
-
|
|
30
|
-
Returns a callable: ``make_session(**overrides) -> Path``.
|
|
31
|
-
Defaults are picked to match a typical mid-integration general-conference/web
|
|
32
|
-
session so individual tests only override what they care about.
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
def _make(**overrides) -> Path:
|
|
36
|
-
base = {
|
|
37
|
-
"schema_version": 1,
|
|
38
|
-
"status": "active",
|
|
39
|
-
"product": "conference",
|
|
40
|
-
"platform": "web",
|
|
41
|
-
"intent": "integrate-scenario",
|
|
42
|
-
"scenario": "general-conference",
|
|
43
|
-
"ui_mode": None,
|
|
44
|
-
"current_step": "topic-handoff",
|
|
45
|
-
"confirmed_plan": list(DEFAULT_CONFIRMED_PLAN),
|
|
46
|
-
"completed_steps": [],
|
|
47
|
-
"project_state": {
|
|
48
|
-
"project_root": str(tmp_path / "user-project"),
|
|
49
|
-
},
|
|
50
|
-
}
|
|
51
|
-
base.update(overrides)
|
|
52
|
-
path = tmp_path / ".trtc-session.yaml"
|
|
53
|
-
path.write_text(yaml.safe_dump(base, sort_keys=False, allow_unicode=True))
|
|
54
|
-
return path
|
|
55
|
-
|
|
56
|
-
return _make
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
@pytest.fixture
|
|
60
|
-
def project_factory(tmp_path: Path):
|
|
61
|
-
"""Factory that creates an empty user project skeleton at tmp_path/user-project.
|
|
62
|
-
|
|
63
|
-
Returns the project root Path. Tests can write whatever Vue/TS files they
|
|
64
|
-
need into it.
|
|
65
|
-
"""
|
|
66
|
-
|
|
67
|
-
def _make() -> Path:
|
|
68
|
-
root = tmp_path / "user-project"
|
|
69
|
-
(root / "src").mkdir(parents=True, exist_ok=True)
|
|
70
|
-
return root
|
|
71
|
-
|
|
72
|
-
return _make
|