claude-smart 0.2.41 → 0.2.43
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/.claude-plugin/marketplace.json +17 -0
- package/README.md +1 -1
- package/bin/claude-smart.js +86 -48
- package/package.json +10 -3
- package/plugin/.claude-plugin/plugin.json +9 -3
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/README.md +2 -2
- package/plugin/dashboard/next.config.ts +9 -1
- package/plugin/pyproject.toml +2 -2
- package/plugin/scripts/_lib.sh +91 -0
- package/plugin/scripts/backend-service.sh +46 -15
- package/plugin/scripts/cli.sh +29 -1
- package/plugin/scripts/codex-hook.js +72 -4
- package/plugin/scripts/dashboard-build.sh +1 -0
- package/plugin/scripts/dashboard-service.sh +1 -0
- package/plugin/scripts/ensure-plugin-root.sh +7 -14
- package/plugin/scripts/hook_entry.sh +1 -0
- package/plugin/scripts/smart-install.sh +18 -2
- package/plugin/src/claude_smart/cli.py +72 -38
- package/plugin/src/claude_smart/context_format.py +11 -12
- package/plugin/src/claude_smart/cs_cite.py +26 -12
- package/plugin/src/claude_smart/ids.py +13 -5
- package/plugin/uv.lock +1 -1
- package/plugin/vendor/reflexio/.env.example +53 -0
- package/plugin/vendor/reflexio/LICENSE +201 -0
- package/plugin/vendor/reflexio/README.md +338 -0
- package/plugin/vendor/reflexio/pyproject.toml +271 -0
- package/plugin/vendor/reflexio/reflexio/README.md +184 -0
- package/plugin/vendor/reflexio/reflexio/__init__.py +166 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/README.md +109 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/backends.py +175 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/bench.py +642 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/embed_cache.py +330 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/report.py +317 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/report.md +43 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/results.json +4478 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/scenarios.py +134 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/seed.py +255 -0
- package/plugin/vendor/reflexio/reflexio/cli/README.md +287 -0
- package/plugin/vendor/reflexio/reflexio/cli/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/cli/__main__.py +56 -0
- package/plugin/vendor/reflexio/reflexio/cli/_client.py +86 -0
- package/plugin/vendor/reflexio/reflexio/cli/app.py +127 -0
- package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +266 -0
- package/plugin/vendor/reflexio/reflexio/cli/codex_auth.py +503 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/admin_cmd.py +65 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/agent_playbooks.py +503 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/api.py +114 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/auth.py +109 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/config_cmd.py +511 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/doctor.py +127 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/embeddings.py +53 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +478 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +303 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +289 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +961 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +285 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/status_cmd.py +143 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/user_playbooks.py +373 -0
- package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +284 -0
- package/plugin/vendor/reflexio/reflexio/cli/errors.py +217 -0
- package/plugin/vendor/reflexio/reflexio/cli/log_format.py +247 -0
- package/plugin/vendor/reflexio/reflexio/cli/output.py +867 -0
- package/plugin/vendor/reflexio/reflexio/cli/paths.py +41 -0
- package/plugin/vendor/reflexio/reflexio/cli/run_services.py +391 -0
- package/plugin/vendor/reflexio/reflexio/cli/state.py +204 -0
- package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +96 -0
- package/plugin/vendor/reflexio/reflexio/cli/utils.py +329 -0
- package/plugin/vendor/reflexio/reflexio/client/__init__.py +3 -0
- package/plugin/vendor/reflexio/reflexio/client/cache.py +150 -0
- package/plugin/vendor/reflexio/reflexio/client/client.py +2613 -0
- package/plugin/vendor/reflexio/reflexio/defaults.py +23 -0
- package/plugin/vendor/reflexio/reflexio/integrations/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/.clawhubignore +7 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +274 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +517 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +473 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +2156 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +18 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +241 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +140 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +130 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +113 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +52 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +103 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +156 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +134 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +41 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +17 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +24 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +48 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +278 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +164 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +36 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +35 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +27 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +31 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +42 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +49 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +91 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +50 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tsconfig.json +16 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/types/openclaw.d.ts +230 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +13 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/README.md +120 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/TESTING.md +168 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package-lock.json +1657 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package.json +16 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/HEARTBEAT.md +6 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/README.md +84 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/SKILL.md +194 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/_meta.json +6 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/agents/reflexio-extractor.md +45 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/handler.ts +214 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/setup.ts +55 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/index.ts +327 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/consolidate.ts +233 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/dedup.ts +80 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/io.ts +155 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/openclaw-cli.ts +67 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/search.ts +33 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-playbook.ts +76 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-profile.ts +79 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/openclaw.plugin.json +46 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/package.json +18 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/README.md +36 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/full_consolidation.md +56 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/playbook_extraction.md +217 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/profile_extraction.md +132 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-consolidate/SKILL.md +33 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-embedded/SKILL.md +194 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/HOOK.md +18 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/architecture.md +49 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/comparison.md +31 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/future-work.md +47 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/porting-notes.md +52 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/install.sh +52 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/uninstall.sh +36 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/consolidate.test.ts +135 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/dedup.test.ts +104 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/io.test.ts +175 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/search.test.ts +66 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/smoke-test.ts +140 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-playbook.test.ts +93 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-profile.test.ts +174 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tsconfig.json +16 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/types/openclaw.d.ts +230 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/vitest.config.ts +7 -0
- package/plugin/vendor/reflexio/reflexio/lib/__init__.py +23 -0
- package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +310 -0
- package/plugin/vendor/reflexio/reflexio/lib/_base.py +225 -0
- package/plugin/vendor/reflexio/reflexio/lib/_config.py +83 -0
- package/plugin/vendor/reflexio/reflexio/lib/_dashboard.py +266 -0
- package/plugin/vendor/reflexio/reflexio/lib/_generation.py +176 -0
- package/plugin/vendor/reflexio/reflexio/lib/_interactions.py +334 -0
- package/plugin/vendor/reflexio/reflexio/lib/_operations.py +153 -0
- package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +545 -0
- package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +52 -0
- package/plugin/vendor/reflexio/reflexio/lib/_search.py +167 -0
- package/plugin/vendor/reflexio/reflexio/lib/_storage_labels.py +103 -0
- package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +288 -0
- package/plugin/vendor/reflexio/reflexio/lib/reflexio_lib.py +27 -0
- package/plugin/vendor/reflexio/reflexio/models/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/braintrust_schema.py +141 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/common.py +41 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/__init__.py +3 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +1103 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +63 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +487 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +28 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +83 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +766 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/service_schemas.py +9 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/stall_state_schema.py +32 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/__init__.py +3 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +177 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +129 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/enums.py +25 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/validators.py +280 -0
- package/plugin/vendor/reflexio/reflexio/models/config_schema.py +908 -0
- package/plugin/vendor/reflexio/reflexio/models/py.typed +0 -0
- package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +90 -0
- package/plugin/vendor/reflexio/reflexio/server/README.md +616 -0
- package/plugin/vendor/reflexio/reflexio/server/__init__.py +210 -0
- package/plugin/vendor/reflexio/reflexio/server/__main__.py +132 -0
- package/plugin/vendor/reflexio/reflexio/server/_auth.py +25 -0
- package/plugin/vendor/reflexio/reflexio/server/api.py +2714 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/account_api.py +143 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/health_api.py +91 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/pending_tool_call_api.py +572 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +66 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/publisher_api.py +540 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +50 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/stall_state_api.py +100 -0
- package/plugin/vendor/reflexio/reflexio/server/cache/__init__.py +15 -0
- package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +208 -0
- package/plugin/vendor/reflexio/reflexio/server/correlation.py +46 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/__init__.py +30 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +110 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/image_utils.py +55 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +1595 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +112 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +469 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +1122 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_stream_parser.py +197 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +210 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/local_embedding_provider.py +213 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/nomic_embedding_provider.py +255 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/rerank/__init__.py +6 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/rerank/cross_encoder_reranker.py +177 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/rerank/llm_reranker.py +148 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +699 -0
- package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +179 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/_dispatchers.py +54 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/README.md +121 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation/v1.0.0.prompt.md +58 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation_with_comparison/v1.0.0.prompt.md +76 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/answer_synthesis/v1.5.2.prompt.md +88 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/compress_session_for_query/v1.3.0.prompt.md +31 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/document_expansion/v1.0.0.prompt.md +20 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.0.0.prompt.md +53 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.1.0.prompt.md +57 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.2.0.prompt.md +68 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.3.0.prompt.md +70 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.4.0.prompt.md +77 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.5.0.prompt.md +82 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.6.0.prompt.md +83 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.1.0.prompt.md +193 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.2.0.prompt.md +206 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0-deprecated.prompt.md +66 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0.prompt.md +43 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.1.0.prompt.md +46 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0-deprecated.prompt.md +64 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0.prompt.md +39 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.1.0.prompt.md +39 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.2.0.prompt.md +47 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.0.prompt.md +58 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.0.2.prompt.md +254 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.1.0.prompt.md +274 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.0.prompt.md +279 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v1.0.0.prompt.md +73 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v2.0.0.prompt.md +86 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.0.0.prompt.md +97 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.1.0.prompt.md +119 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.2.0.prompt.md +123 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +127 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.0.0.prompt.md +14 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.1.0.prompt.md +24 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +29 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.0.0.prompt.md +11 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.1.0.prompt.md +21 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.2.0.prompt.md +25 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.0.0.prompt.md +37 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.1.0.prompt.md +40 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.2.0.prompt.md +36 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v1.0.0.prompt.md +45 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v2.0.0.prompt.md +81 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v3.0.0.prompt.md +80 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate_expert/v1.0.0.prompt.md +34 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_deduplication/v1.0.0.prompt.md +116 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate/v1.0.0.prompt.md +33 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate_override/v1.0.0.prompt.md +16 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +140 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +160 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_main/v1.0.0.prompt.md +14 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/query_reformulation/v1.0.0.prompt.md +19 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/rerank_relevance/v1.1.0.prompt.md +44 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_comparison/v1.0.0.prompt.md +43 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_content_evaluation/v1.0.0.prompt.md +33 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/feedback_extraction_main_v1.jsonl +10 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/profile_update_main_v1.jsonl +10 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +280 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_schema.py +11 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/_eval_health.py +131 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +60 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_service.py +228 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +87 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluator.py +372 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/delayed_group_evaluator.py +156 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/group_evaluation_runner.py +340 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +471 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +1626 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_cron.py +196 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_encryption.py +101 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/client.py +167 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/service.py +281 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +179 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/config_storage.py +62 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/configurator.py +87 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/local_file_config_storage.py +187 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/test_config_storage.py +162 -0
- package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +112 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/distribution.py +33 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +126 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +192 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/hero_state.py +75 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/rule_attribution.py +97 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +515 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/shadow_aggregation.py +90 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/agent_run_records.py +91 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +303 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +25 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +351 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +138 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/prior_answer_search.py +217 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +468 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_scheduler.py +171 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +777 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +1125 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extractor_config_utils.py +91 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extractor_interaction_utils.py +251 -0
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +689 -0
- package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +835 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +89 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_aggregator.py +1388 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_consolidator.py +960 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_extractor.py +436 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_generation_service.py +808 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_constants.py +28 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +362 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/__init__.py +24 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/assistant_webhook.py +246 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/gepa_adapter.py +291 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/judge.py +97 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +96 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +645 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/rollout.py +35 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scenario_resolver.py +93 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scheduler.py +174 -0
- package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/__init__.py +26 -0
- package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_document_expander.py +179 -0
- package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_query_reformulator.py +297 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_deduplicator.py +741 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_extractor.py +462 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service.py +734 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +290 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +17 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_extractor.py +247 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service.py +800 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +146 -0
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +70 -0
- package/plugin/vendor/reflexio/reflexio/server/services/search/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +671 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/judge.py +184 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +81 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/constants.py +2 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +11 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +154 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/retention_mixin.py +155 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +59 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +1253 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +1945 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +600 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +346 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +1378 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +747 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +263 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +193 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_share_links.py +166 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +217 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +153 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +372 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +71 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +235 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +170 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +677 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +250 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +154 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +130 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_share_links.py +93 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_stall_state.py +76 -0
- package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +568 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +77 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +116 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_manager.py +263 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +13 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/llm_model_setting.json +7 -0
- package/plugin/vendor/reflexio/reflexio/server/tracing.py +158 -0
- package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +113 -0
- package/plugin/vendor/reflexio/reflexio/server/uvicorn_logging.py +76 -0
- package/plugin/vendor/reflexio/reflexio/test_support/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_fixtures.py +62 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +242 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +129 -0
- package/plugin/vendor/reflexio/reflexio/test_support/skip_decorators.py +43 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""Diagnostic health check command."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from reflexio.cli.env_loader import get_env_path
|
|
12
|
+
from reflexio.cli.errors import handle_errors
|
|
13
|
+
from reflexio.cli.output import print_doctor_checks, render
|
|
14
|
+
from reflexio.cli.state import resolve_api_key, resolve_url
|
|
15
|
+
|
|
16
|
+
app = typer.Typer(help="Diagnose Reflexio setup.")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@app.command("check")
|
|
20
|
+
@handle_errors
|
|
21
|
+
def doctor(ctx: typer.Context) -> None:
|
|
22
|
+
"""Run diagnostic checks on Reflexio configuration and connectivity."""
|
|
23
|
+
json_mode = ctx.obj.json_mode
|
|
24
|
+
state = ctx.obj
|
|
25
|
+
checks: list[dict[str, Any]] = []
|
|
26
|
+
|
|
27
|
+
# 1. Env file
|
|
28
|
+
env_path = get_env_path()
|
|
29
|
+
env_exists = env_path.exists()
|
|
30
|
+
checks.append(
|
|
31
|
+
{
|
|
32
|
+
"name": "env_file",
|
|
33
|
+
"status": "pass" if env_exists else "warn",
|
|
34
|
+
"message": f"Env file at {env_path}"
|
|
35
|
+
if env_exists
|
|
36
|
+
else f"No env file at {env_path}",
|
|
37
|
+
"hint": None
|
|
38
|
+
if env_exists
|
|
39
|
+
else "Run: reflexio auth login --api-key KEY --server-url URL",
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# 2. Resolve connection info
|
|
44
|
+
url = resolve_url(state.server_url)
|
|
45
|
+
api_key = resolve_api_key(state.api_key)
|
|
46
|
+
|
|
47
|
+
has_key = bool(api_key)
|
|
48
|
+
checks.append(
|
|
49
|
+
{
|
|
50
|
+
"name": "api_key",
|
|
51
|
+
"status": "pass" if has_key else "warn",
|
|
52
|
+
"message": f"API key configured (****{api_key[-4:]})"
|
|
53
|
+
if has_key
|
|
54
|
+
else "No API key configured",
|
|
55
|
+
"hint": None
|
|
56
|
+
if has_key
|
|
57
|
+
else "Set REFLEXIO_API_KEY env var or run: reflexio auth login --api-key KEY",
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# 3. Server connectivity
|
|
62
|
+
headers: dict[str, str] = {}
|
|
63
|
+
if api_key:
|
|
64
|
+
headers["Authorization"] = f"Bearer {api_key}"
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
resp = requests.get(f"{url.rstrip('/')}/health", headers=headers, timeout=10)
|
|
68
|
+
resp.raise_for_status()
|
|
69
|
+
data = resp.json()
|
|
70
|
+
status = data.get("status", "unknown")
|
|
71
|
+
checks.append(
|
|
72
|
+
{
|
|
73
|
+
"name": "server_health",
|
|
74
|
+
"status": "pass" if status == "healthy" else "warn",
|
|
75
|
+
"message": f"Server at {url} is {status}",
|
|
76
|
+
"hint": None,
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
except requests.ConnectionError:
|
|
80
|
+
is_remote = url and "localhost" not in url and "127.0.0.1" not in url
|
|
81
|
+
hint = (
|
|
82
|
+
"Check your API key and network connection, or verify the server URL"
|
|
83
|
+
if is_remote
|
|
84
|
+
else "Start the server: reflexio services start"
|
|
85
|
+
)
|
|
86
|
+
checks.append(
|
|
87
|
+
{
|
|
88
|
+
"name": "server_health",
|
|
89
|
+
"status": "fail",
|
|
90
|
+
"message": f"Cannot connect to {url}",
|
|
91
|
+
"hint": hint,
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
except requests.HTTPError as exc:
|
|
95
|
+
code = exc.response.status_code if exc.response is not None else 0
|
|
96
|
+
checks.append(
|
|
97
|
+
{
|
|
98
|
+
"name": "server_health",
|
|
99
|
+
"status": "fail",
|
|
100
|
+
"message": f"Server returned HTTP {code}",
|
|
101
|
+
"hint": "Check server logs for details",
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# 4. Python version
|
|
106
|
+
py_version = (
|
|
107
|
+
f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
|
108
|
+
)
|
|
109
|
+
checks.append(
|
|
110
|
+
{
|
|
111
|
+
"name": "python_version",
|
|
112
|
+
"status": "pass" if sys.version_info >= (3, 12) else "warn",
|
|
113
|
+
"message": f"Python {py_version}",
|
|
114
|
+
"hint": None if sys.version_info >= (3, 12) else "Python 3.12+ recommended",
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Render output
|
|
119
|
+
if json_mode:
|
|
120
|
+
all_pass = all(c["status"] == "pass" for c in checks)
|
|
121
|
+
render(checks, json_mode=True, meta={"all_pass": all_pass})
|
|
122
|
+
else:
|
|
123
|
+
print_doctor_checks(checks)
|
|
124
|
+
|
|
125
|
+
fails = sum(1 for c in checks if c["status"] == "fail")
|
|
126
|
+
if fails:
|
|
127
|
+
raise SystemExit(1)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Embedding service commands."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
|
|
8
|
+
import typer
|
|
9
|
+
import uvicorn
|
|
10
|
+
|
|
11
|
+
app = typer.Typer(help="Run Reflexio embedding services.")
|
|
12
|
+
|
|
13
|
+
_DEFAULT_EMBEDDING_PORT = 8072
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _resolve_port(port: int | None) -> int:
|
|
17
|
+
if port is not None:
|
|
18
|
+
return port
|
|
19
|
+
|
|
20
|
+
raw_port = os.environ.get("EMBEDDING_PORT")
|
|
21
|
+
if raw_port is None:
|
|
22
|
+
return _DEFAULT_EMBEDDING_PORT
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
return int(raw_port)
|
|
26
|
+
except ValueError:
|
|
27
|
+
typer.echo(
|
|
28
|
+
f"Warning: invalid EMBEDDING_PORT={raw_port!r}; "
|
|
29
|
+
f"using default {_DEFAULT_EMBEDDING_PORT}",
|
|
30
|
+
err=True,
|
|
31
|
+
)
|
|
32
|
+
return _DEFAULT_EMBEDDING_PORT
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@app.command()
|
|
36
|
+
def serve(
|
|
37
|
+
host: Annotated[
|
|
38
|
+
str,
|
|
39
|
+
typer.Option(help="Host interface for the embedding daemon."),
|
|
40
|
+
] = "127.0.0.1",
|
|
41
|
+
port: Annotated[
|
|
42
|
+
int | None,
|
|
43
|
+
typer.Option(help="Embedding service port (default: EMBEDDING_PORT or 8072)."),
|
|
44
|
+
] = None,
|
|
45
|
+
) -> None:
|
|
46
|
+
"""Serve an OpenAI-compatible local embedding endpoint."""
|
|
47
|
+
resolved_port = _resolve_port(port)
|
|
48
|
+
uvicorn.run(
|
|
49
|
+
"reflexio.server.llm.embedding_service:app",
|
|
50
|
+
host=host,
|
|
51
|
+
port=resolved_port,
|
|
52
|
+
log_level="info",
|
|
53
|
+
)
|
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
"""Manage interactions (conversations) via the Reflexio CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Annotated
|
|
10
|
+
|
|
11
|
+
import typer
|
|
12
|
+
|
|
13
|
+
from reflexio.cli.errors import EXIT_VALIDATION, CliError, handle_errors
|
|
14
|
+
from reflexio.cli.output import (
|
|
15
|
+
pagination_meta,
|
|
16
|
+
print_error,
|
|
17
|
+
print_info,
|
|
18
|
+
print_interactions,
|
|
19
|
+
render,
|
|
20
|
+
)
|
|
21
|
+
from reflexio.cli.state import get_client, require_user_id, resolve_agent_version
|
|
22
|
+
from reflexio.models.api_schema.service_schemas import (
|
|
23
|
+
InteractionData,
|
|
24
|
+
PublishUserInteractionResponse,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
app = typer.Typer(help="Manage interactions (conversations).")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
# Helpers (ported from capture.py)
|
|
32
|
+
# ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _parse_json_payload(raw: str) -> list[dict]:
|
|
36
|
+
"""Parse JSON or JSONL text into a list of conversation payloads.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
raw (str): Raw JSON or JSONL string.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
list[dict]: List of parsed payload dicts, each containing an
|
|
43
|
+
``interactions`` key at minimum.
|
|
44
|
+
|
|
45
|
+
Raises:
|
|
46
|
+
CliError: If the input is empty or contains invalid JSON.
|
|
47
|
+
"""
|
|
48
|
+
stripped = raw.strip()
|
|
49
|
+
if not stripped:
|
|
50
|
+
raise CliError(
|
|
51
|
+
error_type="validation",
|
|
52
|
+
message="Empty input",
|
|
53
|
+
exit_code=EXIT_VALIDATION,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Try single JSON object/array first
|
|
57
|
+
try:
|
|
58
|
+
data = json.loads(stripped)
|
|
59
|
+
if isinstance(data, dict):
|
|
60
|
+
return [data]
|
|
61
|
+
if isinstance(data, list):
|
|
62
|
+
if not all(isinstance(item, dict) for item in data):
|
|
63
|
+
raise CliError(
|
|
64
|
+
error_type="validation",
|
|
65
|
+
message="JSON array elements must be objects, not primitives",
|
|
66
|
+
exit_code=EXIT_VALIDATION,
|
|
67
|
+
)
|
|
68
|
+
return data
|
|
69
|
+
except json.JSONDecodeError:
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
# Fall back to JSONL (one JSON object per line)
|
|
73
|
+
payloads: list[dict] = []
|
|
74
|
+
for lineno, line in enumerate(stripped.splitlines(), start=1):
|
|
75
|
+
line = line.strip()
|
|
76
|
+
if not line:
|
|
77
|
+
continue
|
|
78
|
+
try:
|
|
79
|
+
payloads.append(json.loads(line))
|
|
80
|
+
except json.JSONDecodeError as exc:
|
|
81
|
+
raise CliError(
|
|
82
|
+
error_type="validation",
|
|
83
|
+
message=f"Invalid JSON on line {lineno}: {exc}",
|
|
84
|
+
exit_code=EXIT_VALIDATION,
|
|
85
|
+
) from exc
|
|
86
|
+
return payloads
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _interactions_from_payload(payload: dict) -> list[InteractionData]:
|
|
90
|
+
"""Convert a payload dict into a list of InteractionData objects.
|
|
91
|
+
|
|
92
|
+
Forwards ``tools_used`` (and any other InteractionData field) from each
|
|
93
|
+
item so structured tool-call metadata reaches the server renderer that
|
|
94
|
+
emits ``[used tool: ...]`` markers for playbook extraction.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
payload (dict): Payload with an ``interactions`` list of dicts.
|
|
98
|
+
Each item may include ``role``, ``content``, ``tools_used``,
|
|
99
|
+
and other ``InteractionData`` fields.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
list[InteractionData]: Parsed interaction data objects.
|
|
103
|
+
|
|
104
|
+
Raises:
|
|
105
|
+
CliError: If the payload is missing the ``interactions`` list or
|
|
106
|
+
any item fails ``InteractionData`` validation.
|
|
107
|
+
"""
|
|
108
|
+
raw_interactions = payload.get("interactions", [])
|
|
109
|
+
if not raw_interactions:
|
|
110
|
+
raise CliError(
|
|
111
|
+
error_type="validation",
|
|
112
|
+
message="Payload missing 'interactions' list",
|
|
113
|
+
exit_code=EXIT_VALIDATION,
|
|
114
|
+
)
|
|
115
|
+
try:
|
|
116
|
+
return [InteractionData(**item) for item in raw_interactions]
|
|
117
|
+
except (TypeError, ValueError) as exc:
|
|
118
|
+
raise CliError(
|
|
119
|
+
error_type="validation",
|
|
120
|
+
message=f"Invalid interaction data: {exc}",
|
|
121
|
+
exit_code=EXIT_VALIDATION,
|
|
122
|
+
) from exc
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _read_data_arg(data: str) -> str:
|
|
126
|
+
"""Read inline JSON or from a file path prefixed with ``@``.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
data (str): JSON string, or ``@filepath`` to read from disk.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
str: Raw JSON content.
|
|
133
|
+
|
|
134
|
+
Raises:
|
|
135
|
+
CliError: If the referenced file does not exist.
|
|
136
|
+
"""
|
|
137
|
+
if data.startswith("@"):
|
|
138
|
+
path = Path(data[1:])
|
|
139
|
+
if not path.exists():
|
|
140
|
+
raise CliError(
|
|
141
|
+
error_type="validation",
|
|
142
|
+
message=f"File not found: {path}",
|
|
143
|
+
exit_code=EXIT_VALIDATION,
|
|
144
|
+
)
|
|
145
|
+
return path.read_text()
|
|
146
|
+
return data
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
_MAX_WARNING_LEN = 240
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _oneline(text: str, max_len: int = _MAX_WARNING_LEN) -> str:
|
|
153
|
+
"""Collapse newlines and truncate so a pathological server message
|
|
154
|
+
can't dump a multi-line stack trace into the CLI output.
|
|
155
|
+
|
|
156
|
+
The server's generation service appends free-form exception
|
|
157
|
+
strings into ``warnings``, and historically some backends
|
|
158
|
+
embedded tracebacks in ``StorageError.message``. Even after we
|
|
159
|
+
fix those on the server side, this helper is a belt-and-
|
|
160
|
+
suspenders guard so a future regression can't turn ``reflexio
|
|
161
|
+
publish`` into a terminal dump.
|
|
162
|
+
"""
|
|
163
|
+
collapsed = " ".join(text.split())
|
|
164
|
+
if len(collapsed) <= max_len:
|
|
165
|
+
return collapsed
|
|
166
|
+
return collapsed[: max_len - 1] + "…"
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _print_publish_result(result: PublishUserInteractionResponse, user_id: str) -> None:
|
|
170
|
+
"""Print human-readable publish result with diagnostics.
|
|
171
|
+
|
|
172
|
+
Surfaces storage routing + extraction counts so users can tell *where*
|
|
173
|
+
their publish landed and *what* the extraction produced, not just that
|
|
174
|
+
the call returned 200. Degrades gracefully when the server hasn't
|
|
175
|
+
populated the diagnostic fields (server-async mode, which only returns a
|
|
176
|
+
bare acknowledgement instead of counts + request_id + storage routing).
|
|
177
|
+
"""
|
|
178
|
+
message = _oneline(result.message or "")
|
|
179
|
+
warnings = result.warnings or []
|
|
180
|
+
|
|
181
|
+
if not result.success:
|
|
182
|
+
print_error(f"Publish failed for {user_id}: {message}")
|
|
183
|
+
for warning in warnings:
|
|
184
|
+
print_error(f" Warning: {_oneline(warning)}")
|
|
185
|
+
return
|
|
186
|
+
|
|
187
|
+
header = f"Published ({user_id})"
|
|
188
|
+
if message and message != "Interaction published successfully":
|
|
189
|
+
header = f"{header}: {message}"
|
|
190
|
+
print_info(header)
|
|
191
|
+
|
|
192
|
+
storage_type = getattr(result, "storage_type", None)
|
|
193
|
+
storage_label = getattr(result, "storage_label", None)
|
|
194
|
+
if storage_type or storage_label:
|
|
195
|
+
label = storage_label or "<unknown>"
|
|
196
|
+
kind = storage_type or "?"
|
|
197
|
+
print_info(f" Storage: {kind} → {label}")
|
|
198
|
+
|
|
199
|
+
profiles_added = getattr(result, "profiles_added", None)
|
|
200
|
+
playbooks_added = getattr(result, "playbooks_added", None)
|
|
201
|
+
if profiles_added is not None or playbooks_added is not None:
|
|
202
|
+
parts: list[str] = []
|
|
203
|
+
if profiles_added is not None:
|
|
204
|
+
parts.append(f"{profiles_added} profile(s) added")
|
|
205
|
+
if playbooks_added is not None:
|
|
206
|
+
parts.append(f"{playbooks_added} playbook(s) added")
|
|
207
|
+
print_info(f" Extraction: {', '.join(parts)}")
|
|
208
|
+
|
|
209
|
+
request_id = getattr(result, "request_id", None)
|
|
210
|
+
if request_id:
|
|
211
|
+
print_info(f" Request ID: {request_id}")
|
|
212
|
+
|
|
213
|
+
for warning in warnings:
|
|
214
|
+
print_error(f" Warning: {_oneline(warning)}")
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
# ---------------------------------------------------------------------------
|
|
218
|
+
# Commands
|
|
219
|
+
# ---------------------------------------------------------------------------
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
@app.command()
|
|
223
|
+
@handle_errors
|
|
224
|
+
def publish(
|
|
225
|
+
ctx: typer.Context,
|
|
226
|
+
user_id: Annotated[
|
|
227
|
+
str | None,
|
|
228
|
+
typer.Option(
|
|
229
|
+
help=(
|
|
230
|
+
"User identifier. Falls back to REFLEXIO_USER_ID env var "
|
|
231
|
+
"or 'user_id' inside --file/--data payload."
|
|
232
|
+
)
|
|
233
|
+
),
|
|
234
|
+
] = None,
|
|
235
|
+
session_id: Annotated[
|
|
236
|
+
str | None, typer.Option(help="Session ID for grouping")
|
|
237
|
+
] = None,
|
|
238
|
+
source: Annotated[str, typer.Option(help="Source tag")] = "cli",
|
|
239
|
+
agent_version: Annotated[
|
|
240
|
+
str | None, typer.Option(help="Agent version string")
|
|
241
|
+
] = None,
|
|
242
|
+
wait: Annotated[
|
|
243
|
+
bool, typer.Option(help="Block until processing completes")
|
|
244
|
+
] = False,
|
|
245
|
+
data: Annotated[str | None, typer.Option(help="JSON string or @filepath")] = None,
|
|
246
|
+
file: Annotated[Path | None, typer.Option(help="Path to JSON/JSONL file")] = None,
|
|
247
|
+
stdin: Annotated[bool, typer.Option(help="Read JSON data from stdin")] = False,
|
|
248
|
+
user_message: Annotated[
|
|
249
|
+
str | None, typer.Option(help="Single-turn user message")
|
|
250
|
+
] = None,
|
|
251
|
+
agent_response: Annotated[
|
|
252
|
+
str | None, typer.Option(help="Single-turn agent response")
|
|
253
|
+
] = None,
|
|
254
|
+
skip_aggregation: Annotated[
|
|
255
|
+
bool,
|
|
256
|
+
typer.Option(
|
|
257
|
+
"--skip-aggregation",
|
|
258
|
+
help="Extract profiles/playbooks but skip aggregation to agent playbooks",
|
|
259
|
+
),
|
|
260
|
+
] = False,
|
|
261
|
+
force_extraction: Annotated[
|
|
262
|
+
bool,
|
|
263
|
+
typer.Option(
|
|
264
|
+
"--force-extraction",
|
|
265
|
+
help="Bypass all extraction gates (stride_size, cheap pre-filter, LLM should_run) and always run extractors",
|
|
266
|
+
),
|
|
267
|
+
] = False,
|
|
268
|
+
override_learning_stall: Annotated[
|
|
269
|
+
bool,
|
|
270
|
+
typer.Option(
|
|
271
|
+
"--override-learning-stall",
|
|
272
|
+
help="Run extraction even when a provider auth/billing stall is recorded. Use only for explicit retries after reauth or limit reset.",
|
|
273
|
+
),
|
|
274
|
+
] = False,
|
|
275
|
+
) -> None:
|
|
276
|
+
"""Publish interaction data for a user.
|
|
277
|
+
|
|
278
|
+
Supports three input modes:
|
|
279
|
+
1. ``--user-message`` + ``--agent-response`` for single-turn conversations.
|
|
280
|
+
2. ``--file`` or ``--stdin`` for JSON/JSONL payloads.
|
|
281
|
+
3. ``--data`` for inline JSON (prefix with ``@`` for a file path).
|
|
282
|
+
"""
|
|
283
|
+
client = get_client(ctx)
|
|
284
|
+
json_mode: bool = ctx.obj.json_mode
|
|
285
|
+
|
|
286
|
+
# Announce the endpoint + wait mode up-front (stderr, non-JSON only) so
|
|
287
|
+
# users can tell which server they're hitting before anything happens.
|
|
288
|
+
if not json_mode:
|
|
289
|
+
# The label refers to the *server* extraction mode: "sync" waits
|
|
290
|
+
# for extraction to finish before returning real counts; "async"
|
|
291
|
+
# queues extraction as a server BackgroundTask and returns
|
|
292
|
+
# immediately. The client always blocks on the HTTP round-trip
|
|
293
|
+
# in both cases.
|
|
294
|
+
mode_label = "server-sync" if wait else "server-async"
|
|
295
|
+
print_info(f"Publishing to {client.base_url} ({mode_label})")
|
|
296
|
+
|
|
297
|
+
# Mode 1: single-turn
|
|
298
|
+
if user_message is not None:
|
|
299
|
+
if agent_response is None:
|
|
300
|
+
raise CliError(
|
|
301
|
+
error_type="validation",
|
|
302
|
+
message="--agent-response is required with --user-message",
|
|
303
|
+
exit_code=EXIT_VALIDATION,
|
|
304
|
+
)
|
|
305
|
+
if user_id is None:
|
|
306
|
+
user_id = os.environ.get("REFLEXIO_USER_ID")
|
|
307
|
+
if user_id is None:
|
|
308
|
+
raise CliError(
|
|
309
|
+
error_type="validation",
|
|
310
|
+
message="--user-id is required with --user-message (or set REFLEXIO_USER_ID)",
|
|
311
|
+
exit_code=EXIT_VALIDATION,
|
|
312
|
+
)
|
|
313
|
+
interactions: list[InteractionData | dict] = [
|
|
314
|
+
InteractionData(role="user", content=user_message),
|
|
315
|
+
InteractionData(role="assistant", content=agent_response),
|
|
316
|
+
]
|
|
317
|
+
result = client.publish_interaction(
|
|
318
|
+
user_id=user_id,
|
|
319
|
+
interactions=interactions,
|
|
320
|
+
source=source,
|
|
321
|
+
agent_version=resolve_agent_version(agent_version),
|
|
322
|
+
session_id=session_id,
|
|
323
|
+
wait_for_response=wait,
|
|
324
|
+
skip_aggregation=skip_aggregation,
|
|
325
|
+
force_extraction=force_extraction,
|
|
326
|
+
override_learning_stall=override_learning_stall,
|
|
327
|
+
)
|
|
328
|
+
if json_mode:
|
|
329
|
+
render(result, json_mode=True)
|
|
330
|
+
else:
|
|
331
|
+
_print_publish_result(result, user_id)
|
|
332
|
+
return
|
|
333
|
+
|
|
334
|
+
# Determine raw JSON from --data, --file, or --stdin
|
|
335
|
+
raw: str | None = None
|
|
336
|
+
if data is not None:
|
|
337
|
+
raw = _read_data_arg(data)
|
|
338
|
+
elif file is not None:
|
|
339
|
+
if not file.exists():
|
|
340
|
+
raise CliError(
|
|
341
|
+
error_type="validation",
|
|
342
|
+
message=f"File not found: {file}",
|
|
343
|
+
exit_code=EXIT_VALIDATION,
|
|
344
|
+
)
|
|
345
|
+
raw = file.read_text()
|
|
346
|
+
elif stdin:
|
|
347
|
+
raw = sys.stdin.read()
|
|
348
|
+
|
|
349
|
+
if raw is None:
|
|
350
|
+
raise CliError(
|
|
351
|
+
error_type="validation",
|
|
352
|
+
message="Specify --user-message/--agent-response, --file, --stdin, or --data",
|
|
353
|
+
exit_code=EXIT_VALIDATION,
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
payloads = _parse_json_payload(raw)
|
|
357
|
+
print_info(f"Processing {len(payloads)} payload(s)...")
|
|
358
|
+
|
|
359
|
+
resolved_version = resolve_agent_version(agent_version)
|
|
360
|
+
for payload in payloads:
|
|
361
|
+
interaction_items = _interactions_from_payload(payload)
|
|
362
|
+
resolved_user_id = (
|
|
363
|
+
payload.get("user_id") or user_id or os.environ.get("REFLEXIO_USER_ID")
|
|
364
|
+
)
|
|
365
|
+
if not resolved_user_id:
|
|
366
|
+
raise CliError(
|
|
367
|
+
error_type="validation",
|
|
368
|
+
message=(
|
|
369
|
+
"--user-id is required (or include 'user_id' in the JSON "
|
|
370
|
+
"payload, or set REFLEXIO_USER_ID)"
|
|
371
|
+
),
|
|
372
|
+
exit_code=EXIT_VALIDATION,
|
|
373
|
+
)
|
|
374
|
+
result = client.publish_interaction(
|
|
375
|
+
user_id=resolved_user_id,
|
|
376
|
+
interactions=interaction_items, # type: ignore[arg-type]
|
|
377
|
+
source=payload.get("source", source),
|
|
378
|
+
agent_version=payload.get("agent_version", resolved_version),
|
|
379
|
+
session_id=payload.get("session_id", session_id),
|
|
380
|
+
wait_for_response=wait,
|
|
381
|
+
skip_aggregation=payload.get("skip_aggregation", skip_aggregation),
|
|
382
|
+
force_extraction=payload.get("force_extraction", force_extraction),
|
|
383
|
+
override_learning_stall=payload.get(
|
|
384
|
+
"override_learning_stall", override_learning_stall
|
|
385
|
+
),
|
|
386
|
+
)
|
|
387
|
+
if json_mode:
|
|
388
|
+
render(result, json_mode=True)
|
|
389
|
+
else:
|
|
390
|
+
uid = payload.get("user_id", user_id)
|
|
391
|
+
_print_publish_result(result, uid)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
@app.command(name="list")
|
|
395
|
+
@handle_errors
|
|
396
|
+
def list_interactions(
|
|
397
|
+
ctx: typer.Context,
|
|
398
|
+
user_id: Annotated[str | None, typer.Option(help="Filter by user ID")] = None,
|
|
399
|
+
limit: Annotated[
|
|
400
|
+
int, typer.Option(help="Maximum number of interactions to return")
|
|
401
|
+
] = 20,
|
|
402
|
+
) -> None:
|
|
403
|
+
"""List interactions, optionally filtered by user."""
|
|
404
|
+
client = get_client(ctx)
|
|
405
|
+
resolved_user_id = require_user_id(user_id, command_hint="interactions list")
|
|
406
|
+
result = client.get_interactions(user_id=resolved_user_id, top_k=limit)
|
|
407
|
+
interactions = result.interactions or []
|
|
408
|
+
|
|
409
|
+
json_mode: bool = ctx.obj.json_mode
|
|
410
|
+
if json_mode:
|
|
411
|
+
render(interactions, json_mode=True, meta=pagination_meta(interactions, limit))
|
|
412
|
+
else:
|
|
413
|
+
print_info(f"Found {len(interactions)} interaction(s)")
|
|
414
|
+
if interactions:
|
|
415
|
+
print_interactions(interactions)
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
@app.command()
|
|
419
|
+
@handle_errors
|
|
420
|
+
def search(
|
|
421
|
+
ctx: typer.Context,
|
|
422
|
+
query: Annotated[str, typer.Option(help="Search query string")],
|
|
423
|
+
user_id: Annotated[str | None, typer.Option(help="Filter by user ID")] = None,
|
|
424
|
+
limit: Annotated[int, typer.Option(help="Maximum number of results")] = 10,
|
|
425
|
+
) -> None:
|
|
426
|
+
"""Search interactions by semantic query."""
|
|
427
|
+
client = get_client(ctx)
|
|
428
|
+
result = client.search_interactions(query=query, user_id=user_id, top_k=limit)
|
|
429
|
+
interactions = result.interactions or []
|
|
430
|
+
|
|
431
|
+
json_mode: bool = ctx.obj.json_mode
|
|
432
|
+
if json_mode:
|
|
433
|
+
render(interactions, json_mode=True, meta=pagination_meta(interactions, limit))
|
|
434
|
+
else:
|
|
435
|
+
print_info(f"Found {len(interactions)} interaction(s)")
|
|
436
|
+
if interactions:
|
|
437
|
+
print_interactions(interactions)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
@app.command()
|
|
441
|
+
@handle_errors
|
|
442
|
+
def delete(
|
|
443
|
+
ctx: typer.Context,
|
|
444
|
+
interaction_id: Annotated[str, typer.Option(help="Interaction ID to delete")],
|
|
445
|
+
user_id: Annotated[str, typer.Option(help="User ID that owns the interaction")],
|
|
446
|
+
) -> None:
|
|
447
|
+
"""Delete a single interaction by ID."""
|
|
448
|
+
client = get_client(ctx)
|
|
449
|
+
result = client.delete_interaction(
|
|
450
|
+
user_id=user_id,
|
|
451
|
+
interaction_id=interaction_id,
|
|
452
|
+
wait_for_response=True,
|
|
453
|
+
)
|
|
454
|
+
json_mode: bool = ctx.obj.json_mode
|
|
455
|
+
if json_mode:
|
|
456
|
+
render(result, json_mode=True)
|
|
457
|
+
else:
|
|
458
|
+
print_info(f"Deleted interaction {interaction_id}")
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
@app.command(name="delete-all")
|
|
462
|
+
@handle_errors
|
|
463
|
+
def delete_all(
|
|
464
|
+
ctx: typer.Context,
|
|
465
|
+
yes: Annotated[
|
|
466
|
+
bool, typer.Option("--yes", "-y", help="Skip confirmation prompt")
|
|
467
|
+
] = False,
|
|
468
|
+
) -> None:
|
|
469
|
+
"""Delete ALL interactions. This cannot be undone."""
|
|
470
|
+
if not yes:
|
|
471
|
+
typer.confirm("Delete all interactions? This cannot be undone", abort=True)
|
|
472
|
+
client = get_client(ctx)
|
|
473
|
+
result = client.delete_all_interactions()
|
|
474
|
+
json_mode: bool = ctx.obj.json_mode
|
|
475
|
+
if json_mode:
|
|
476
|
+
render(result, json_mode=True)
|
|
477
|
+
else:
|
|
478
|
+
print_info("All interactions deleted")
|