claude-smart 0.2.42 → 0.2.44
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 +3 -3
- package/README.md +1 -1
- package/bin/claude-smart.js +2 -2
- package/package.json +9 -3
- package/plugin/.claude-plugin/plugin.json +9 -3
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/README.md +23 -3
- package/plugin/pyproject.toml +3 -3
- package/plugin/scripts/_lib.sh +91 -0
- package/plugin/scripts/backend-service.sh +51 -4
- package/plugin/scripts/cli.sh +3 -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 +1 -0
- package/plugin/scripts/hook_entry.sh +6 -3
- package/plugin/scripts/smart-install.sh +3 -2
- package/plugin/src/README.md +57 -0
- 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 +126 -5
- package/plugin/vendor/reflexio/.env.example +62 -0
- package/plugin/vendor/reflexio/LICENSE +201 -0
- package/plugin/vendor/reflexio/README.md +338 -0
- package/plugin/vendor/reflexio/pyproject.toml +274 -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 +265 -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 +964 -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 +1112 -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 +768 -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 +333 -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 +622 -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 +2868 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/README.md +34 -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 +562 -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 +359 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/image_utils.py +55 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +1871 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +140 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +479 -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 +338 -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 +288 -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 +187 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/rerank/llm_reranker.py +148 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +716 -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_consolidation/v2.3.1.prompt.md +69 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.2.prompt.md +71 -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 +283 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.2.prompt.md +234 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.3.prompt.md +244 -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 +137 -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/README.md +58 -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 +336 -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 +1668 -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/embedding_text.py +62 -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 +358 -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 +535 -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 +779 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +1125 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extractor_config_utils.py +94 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extractor_interaction_utils.py +251 -0
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +702 -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 +1045 -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 +772 -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 +737 -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 +803 -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 +80 -0
- package/plugin/vendor/reflexio/reflexio/server/services/search/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +756 -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 +1298 -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 +384 -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 +572 -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,41 @@
|
|
|
1
|
+
"""Canonical filesystem paths for reflexio runtime data.
|
|
2
|
+
|
|
3
|
+
Centralizes the resolution of the ``.reflexio`` base directory so every
|
|
4
|
+
caller honors the ``REFLEXIO_LOG_DIR`` env var consistently. When the env
|
|
5
|
+
var is set, the ``.reflexio`` tree is rooted at that path instead of
|
|
6
|
+
``Path.home()``; the ``.reflexio/<subdir>`` suffix is always preserved
|
|
7
|
+
so the on-disk layout stays identical regardless of where the base
|
|
8
|
+
points.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def reflexio_home() -> Path:
|
|
18
|
+
"""Return the canonical ``.reflexio`` directory.
|
|
19
|
+
|
|
20
|
+
Resolution:
|
|
21
|
+
- If ``REFLEXIO_LOG_DIR`` is set, the base is that path (with
|
|
22
|
+
``~`` expanded; resolved to an absolute path, anchored to
|
|
23
|
+
``Path.home()`` if relative).
|
|
24
|
+
- Otherwise the base is ``Path.home()``.
|
|
25
|
+
|
|
26
|
+
The ``.reflexio`` suffix is appended to the base in both cases. The
|
|
27
|
+
directory is **not** created here — callers must
|
|
28
|
+
``mkdir(parents=True, exist_ok=True)`` at point of use.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Path: Absolute path to the resolved ``.reflexio`` directory.
|
|
32
|
+
"""
|
|
33
|
+
base = os.environ.get("REFLEXIO_LOG_DIR")
|
|
34
|
+
if base:
|
|
35
|
+
base_path = Path(base).expanduser()
|
|
36
|
+
if not base_path.is_absolute():
|
|
37
|
+
base_path = Path.home() / base_path
|
|
38
|
+
base_path = base_path.resolve()
|
|
39
|
+
else:
|
|
40
|
+
base_path = Path.home()
|
|
41
|
+
return base_path / ".reflexio"
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
"""Run reflexio services (backend + docs)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import logging
|
|
7
|
+
import os
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
import time
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import reflexio
|
|
14
|
+
from reflexio.cli.env_loader import load_reflexio_env
|
|
15
|
+
from reflexio.cli.utils import ServiceConfig, get_env_port, run_services
|
|
16
|
+
from reflexio.server.llm.providers.embedding_service_provider import (
|
|
17
|
+
embedding_service_url,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
_PACKAGE_DIR = Path(reflexio.__file__).resolve().parent
|
|
23
|
+
# Editable installs lay out as `…/open_source/reflexio/reflexio/__init__.py`,
|
|
24
|
+
# so the repo root is one level above the package dir. PyPI/wheel installs
|
|
25
|
+
# resolve to `…/site-packages/`, where DOCS_DIR will not exist and the
|
|
26
|
+
# docs service is silently skipped (see execute()).
|
|
27
|
+
_EDITABLE_REPO_ROOT = _PACKAGE_DIR.parent
|
|
28
|
+
DOCS_DIR = _EDITABLE_REPO_ROOT / "docs"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def add_arguments(parser: argparse.ArgumentParser) -> None:
|
|
32
|
+
"""Add run-services arguments to the parser.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
parser (argparse.ArgumentParser): The parser to populate with
|
|
36
|
+
run-services flags. Mutated in-place.
|
|
37
|
+
"""
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"--backend-port",
|
|
40
|
+
type=int,
|
|
41
|
+
default=None,
|
|
42
|
+
help="Backend port (default: 8081, env: BACKEND_PORT)",
|
|
43
|
+
)
|
|
44
|
+
parser.add_argument(
|
|
45
|
+
"--docs-port",
|
|
46
|
+
type=int,
|
|
47
|
+
default=None,
|
|
48
|
+
help="Docs port (default: 8082, env: DOCS_PORT)",
|
|
49
|
+
)
|
|
50
|
+
parser.add_argument(
|
|
51
|
+
"--embedding-port",
|
|
52
|
+
type=int,
|
|
53
|
+
default=None,
|
|
54
|
+
help="Embedding service port (default: 8072, env: EMBEDDING_PORT)",
|
|
55
|
+
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"--only",
|
|
58
|
+
type=str,
|
|
59
|
+
default=None,
|
|
60
|
+
help="Comma-separated list of services to start: backend,docs,embedding",
|
|
61
|
+
)
|
|
62
|
+
parser.add_argument(
|
|
63
|
+
"--no-reload",
|
|
64
|
+
action="store_true",
|
|
65
|
+
help="Disable uvicorn auto-reload",
|
|
66
|
+
)
|
|
67
|
+
parser.add_argument(
|
|
68
|
+
"--workers",
|
|
69
|
+
type=int,
|
|
70
|
+
default=2,
|
|
71
|
+
help=(
|
|
72
|
+
"Number of backend worker processes (daemon mode only). "
|
|
73
|
+
"Default 2 enables zero-downtime worker recycling. "
|
|
74
|
+
"Forced to 1 when --reload is on."
|
|
75
|
+
),
|
|
76
|
+
)
|
|
77
|
+
parser.add_argument(
|
|
78
|
+
"--max-requests",
|
|
79
|
+
type=int,
|
|
80
|
+
default=10000,
|
|
81
|
+
help="Worker recycles after this many requests. 0 disables. Default 10000.",
|
|
82
|
+
)
|
|
83
|
+
parser.add_argument(
|
|
84
|
+
"--max-requests-jitter",
|
|
85
|
+
type=int,
|
|
86
|
+
default=1000,
|
|
87
|
+
help="Random 0..jitter per worker. Default 1000.",
|
|
88
|
+
)
|
|
89
|
+
parser.add_argument(
|
|
90
|
+
"--graceful-shutdown-sec",
|
|
91
|
+
type=int,
|
|
92
|
+
default=30,
|
|
93
|
+
help="Drain window on shutdown. Default 30.",
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _build_run_services_parser() -> argparse.ArgumentParser:
|
|
98
|
+
"""Build the standalone run_services CLI parser.
|
|
99
|
+
|
|
100
|
+
The parent ``reflexio`` CLI normally builds the parser and calls
|
|
101
|
+
:func:`add_arguments` to populate it. This helper exists so tests (and
|
|
102
|
+
any ad-hoc ``python -m reflexio.cli.run_services``-style invocation)
|
|
103
|
+
can construct a self-contained parser with all run-services flags.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
argparse.ArgumentParser: Parser populated with all run_services
|
|
107
|
+
flags via :func:`add_arguments`.
|
|
108
|
+
"""
|
|
109
|
+
parser = argparse.ArgumentParser(prog="reflexio.cli.run_services")
|
|
110
|
+
add_arguments(parser)
|
|
111
|
+
return parser
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _warn_if_sqlite_multi_worker(*, storage_backend: str, workers: int) -> None:
|
|
115
|
+
"""Emit a warning when SQLite is paired with multi-worker mode.
|
|
116
|
+
|
|
117
|
+
SQLite supports concurrent reads but serializes writes (even in WAL
|
|
118
|
+
mode). Multi-worker deployments will see increased write latency and
|
|
119
|
+
occasional "database is locked" errors under contention. Operators are
|
|
120
|
+
not blocked — just notified — so they can switch to Postgres/Supabase
|
|
121
|
+
if they hit issues.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
storage_backend (str): One of "sqlite", "postgres", "supabase".
|
|
125
|
+
workers (int): Configured worker count.
|
|
126
|
+
"""
|
|
127
|
+
if storage_backend == "sqlite" and workers > 1:
|
|
128
|
+
logger.warning(
|
|
129
|
+
"SQLite has limited concurrent write throughput; consider "
|
|
130
|
+
"--workers 1 or switching to Postgres/Supabase. (workers=%d)",
|
|
131
|
+
workers,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def resolve_ports(
|
|
136
|
+
args: argparse.Namespace,
|
|
137
|
+
defaults: dict[str, int],
|
|
138
|
+
) -> dict[str, int]:
|
|
139
|
+
"""Resolve service ports from CLI args, env vars, or defaults.
|
|
140
|
+
|
|
141
|
+
Priority: CLI arg > env var > default value.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
args: Parsed CLI arguments (looks for `{name}_port` attributes)
|
|
145
|
+
defaults: Map of service name to default port number
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
dict[str, int]: Resolved ports keyed by service name
|
|
149
|
+
"""
|
|
150
|
+
ports = {}
|
|
151
|
+
for name, default in defaults.items():
|
|
152
|
+
arg_val = getattr(args, f"{name}_port", None)
|
|
153
|
+
ports[name] = (
|
|
154
|
+
arg_val
|
|
155
|
+
if arg_val is not None
|
|
156
|
+
else get_env_port(f"{name.upper()}_PORT", default)
|
|
157
|
+
)
|
|
158
|
+
return ports
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def build_backend_service(
|
|
162
|
+
ports: dict[str, int],
|
|
163
|
+
*,
|
|
164
|
+
app_module: str = "reflexio.server.api:app",
|
|
165
|
+
reload: bool = True,
|
|
166
|
+
reload_includes: list[str] | None = None,
|
|
167
|
+
workers: int = 2,
|
|
168
|
+
max_requests: int = 10000,
|
|
169
|
+
max_requests_jitter: int = 1000,
|
|
170
|
+
graceful_shutdown_sec: int = 30,
|
|
171
|
+
) -> ServiceConfig:
|
|
172
|
+
"""Build a ServiceConfig describing how to spawn the backend.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
ports (dict[str, int]): Resolved port map (must contain "backend").
|
|
176
|
+
app_module (str): ASGI app path; defaults to the production app
|
|
177
|
+
factory.
|
|
178
|
+
reload (bool): When True, enables uvicorn autoreload (single
|
|
179
|
+
worker forced). When False, daemon mode with multi-worker
|
|
180
|
+
request-count recycling is used.
|
|
181
|
+
reload_includes (list[str] | None): Additional glob patterns for
|
|
182
|
+
reload watching. Only used when ``reload`` is True.
|
|
183
|
+
workers (int): Number of uvicorn worker processes. Must be 1
|
|
184
|
+
when ``reload`` is True (validated). Default 2.
|
|
185
|
+
max_requests (int): Daemon-mode worker recycles after this many
|
|
186
|
+
requests. Set to 0 to disable. Default 10000.
|
|
187
|
+
max_requests_jitter (int): Random 0..jitter added to
|
|
188
|
+
``max_requests`` per worker. Default 1000.
|
|
189
|
+
graceful_shutdown_sec (int): Drain window on shutdown. Default 30.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
ServiceConfig: Backend service configuration ready to spawn.
|
|
193
|
+
|
|
194
|
+
Raises:
|
|
195
|
+
ValueError: When ``reload=True`` and ``workers > 1``.
|
|
196
|
+
"""
|
|
197
|
+
if reload and workers > 1:
|
|
198
|
+
raise ValueError(
|
|
199
|
+
"--workers N (N>1) is incompatible with --reload; "
|
|
200
|
+
"pass --no-reload or set --workers 1"
|
|
201
|
+
)
|
|
202
|
+
# Launch via our own ``python -m reflexio.server`` entrypoint rather
|
|
203
|
+
# than the ``uvicorn`` CLI so the log config in
|
|
204
|
+
# :mod:`reflexio.server.uvicorn_logging` is applied upfront via
|
|
205
|
+
# uvicorn's native ``log_config`` parameter.
|
|
206
|
+
cmd = [
|
|
207
|
+
sys.executable,
|
|
208
|
+
"-m",
|
|
209
|
+
"reflexio.server",
|
|
210
|
+
"--app",
|
|
211
|
+
app_module,
|
|
212
|
+
"--host",
|
|
213
|
+
"0.0.0.0", # noqa: S104
|
|
214
|
+
"--port",
|
|
215
|
+
str(ports["backend"]),
|
|
216
|
+
]
|
|
217
|
+
if reload:
|
|
218
|
+
for pattern in reload_includes or []:
|
|
219
|
+
cmd.extend(["--reload-include", pattern])
|
|
220
|
+
cmd.append("--reload")
|
|
221
|
+
# Dev mode is always single-worker; reload + multi-worker is
|
|
222
|
+
# rejected above.
|
|
223
|
+
cmd.extend(["--workers", "1"])
|
|
224
|
+
else:
|
|
225
|
+
cmd.extend(["--workers", str(workers)])
|
|
226
|
+
cmd.extend(["--max-requests", str(max_requests)])
|
|
227
|
+
cmd.extend(["--max-requests-jitter", str(max_requests_jitter)])
|
|
228
|
+
cmd.extend(["--graceful-shutdown-sec", str(graceful_shutdown_sec)])
|
|
229
|
+
return ServiceConfig(name="backend", command=cmd)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def build_nextjs_service(
|
|
233
|
+
name: str,
|
|
234
|
+
ports: dict[str, int],
|
|
235
|
+
*,
|
|
236
|
+
cwd: str,
|
|
237
|
+
) -> ServiceConfig:
|
|
238
|
+
"""Build a Next.js dev server ServiceConfig.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
name: Service name (e.g., "docs", "frontend")
|
|
242
|
+
ports: Resolved port map (must contain key matching name)
|
|
243
|
+
cwd: Working directory for the Next.js project
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
ServiceConfig: Next.js service configuration
|
|
247
|
+
"""
|
|
248
|
+
return ServiceConfig(
|
|
249
|
+
name=name,
|
|
250
|
+
command=["npx", "next", "dev", "-p", str(ports[name])],
|
|
251
|
+
cwd=cwd,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def build_embedding_service(ports: dict[str, int]) -> ServiceConfig:
|
|
256
|
+
"""Build the local embedding daemon service configuration."""
|
|
257
|
+
return ServiceConfig(
|
|
258
|
+
name="embedding",
|
|
259
|
+
command=[
|
|
260
|
+
sys.executable,
|
|
261
|
+
"-m",
|
|
262
|
+
"uvicorn",
|
|
263
|
+
"reflexio.server.llm.embedding_service:app",
|
|
264
|
+
"--host",
|
|
265
|
+
"127.0.0.1",
|
|
266
|
+
"--port",
|
|
267
|
+
str(ports["embedding"]),
|
|
268
|
+
],
|
|
269
|
+
env={"REFLEXIO_EMBEDDING_DAEMON": "1"},
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def parse_only_flag(only: str | None, default_services: set[str]) -> set[str]:
|
|
274
|
+
"""Parse the --only flag into a set of service names.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
only: Comma-separated service names, or None for all defaults
|
|
278
|
+
default_services: Set of services to start when --only is not specified
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
set[str]: Services to start
|
|
282
|
+
"""
|
|
283
|
+
if only:
|
|
284
|
+
return {s.strip() for s in only.split(",")}
|
|
285
|
+
return default_services
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def should_start_local_embedding_service() -> bool:
|
|
289
|
+
"""Return True when backend startup depends on the local embedding daemon."""
|
|
290
|
+
provider = os.environ.get("REFLEXIO_EMBEDDING_PROVIDER", "").strip().lower()
|
|
291
|
+
if provider == "local_service":
|
|
292
|
+
return True
|
|
293
|
+
if provider in {"cloud", "internal_service", "inprocess", "off"}:
|
|
294
|
+
return False
|
|
295
|
+
return os.environ.get("CLAUDE_SMART_USE_LOCAL_EMBEDDING") == "1"
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def _ensure_nextjs_dependencies(project_dir: Path) -> bool:
|
|
299
|
+
"""Install Next.js project dependencies when node_modules is missing."""
|
|
300
|
+
if (project_dir / "node_modules").exists():
|
|
301
|
+
return True
|
|
302
|
+
|
|
303
|
+
print(f"Installing {project_dir.name} dependencies...")
|
|
304
|
+
result = subprocess.run(["npm", "install"], cwd=str(project_dir), check=False)
|
|
305
|
+
if result.returncode != 0:
|
|
306
|
+
print(f"Error: npm install failed in {project_dir}.")
|
|
307
|
+
return False
|
|
308
|
+
return True
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def execute(args: argparse.Namespace) -> None:
|
|
312
|
+
"""Execute the run-services command."""
|
|
313
|
+
load_reflexio_env()
|
|
314
|
+
|
|
315
|
+
# Banner so any captured stdout (e.g. ~/.reflexio/logs/server.log via the
|
|
316
|
+
# Claude Code session-start hook) clearly marks the start of a new server
|
|
317
|
+
# lifetime instead of blurring into output from a previous run.
|
|
318
|
+
bar = "=" * 64
|
|
319
|
+
ts = time.strftime("%Y-%m-%d %H:%M:%S %Z")
|
|
320
|
+
print(f"\n{bar}\n=== NEW REFLEXIO SERVER START — {ts} ===\n{bar}\n")
|
|
321
|
+
|
|
322
|
+
ports = resolve_ports(
|
|
323
|
+
args, defaults={"backend": 8081, "docs": 8082, "embedding": 8072}
|
|
324
|
+
)
|
|
325
|
+
os.environ["API_BACKEND_URL"] = os.environ.get(
|
|
326
|
+
"API_BACKEND_URL", f"http://localhost:{ports['backend']}"
|
|
327
|
+
)
|
|
328
|
+
os.environ["EMBEDDING_PORT"] = str(ports["embedding"])
|
|
329
|
+
|
|
330
|
+
only = parse_only_flag(args.only, {"backend", "docs"})
|
|
331
|
+
if "backend" in only and should_start_local_embedding_service():
|
|
332
|
+
only.add("embedding")
|
|
333
|
+
os.environ["REFLEXIO_EMBEDDING_PROVIDER"] = os.environ.get(
|
|
334
|
+
"REFLEXIO_EMBEDDING_PROVIDER", "local_service"
|
|
335
|
+
)
|
|
336
|
+
os.environ["REFLEXIO_EMBEDDING_SERVICE_URL"] = os.environ.get(
|
|
337
|
+
"REFLEXIO_EMBEDDING_SERVICE_URL",
|
|
338
|
+
embedding_service_url("local_service"),
|
|
339
|
+
)
|
|
340
|
+
docs_explicit = args.only is not None and "docs" in only
|
|
341
|
+
services: list[ServiceConfig] = []
|
|
342
|
+
|
|
343
|
+
if "embedding" in only:
|
|
344
|
+
services.append(build_embedding_service(ports))
|
|
345
|
+
|
|
346
|
+
if "backend" in only:
|
|
347
|
+
reload = not args.no_reload
|
|
348
|
+
# Dev mode (--reload) is always single-worker; coerce silently so
|
|
349
|
+
# users running with default flags (reload on, workers default 2)
|
|
350
|
+
# don't hit the reload+multi-worker rejection in build_backend_service.
|
|
351
|
+
workers = 1 if reload else getattr(args, "workers", 2)
|
|
352
|
+
max_requests = getattr(args, "max_requests", 10000)
|
|
353
|
+
max_requests_jitter = getattr(args, "max_requests_jitter", 1000)
|
|
354
|
+
graceful_shutdown_sec = getattr(args, "graceful_shutdown_sec", 30)
|
|
355
|
+
storage_backend = os.environ.get("REFLEXIO_STORAGE", "sqlite").lower()
|
|
356
|
+
_warn_if_sqlite_multi_worker(storage_backend=storage_backend, workers=workers)
|
|
357
|
+
services.append(
|
|
358
|
+
build_backend_service(
|
|
359
|
+
ports,
|
|
360
|
+
reload=reload,
|
|
361
|
+
reload_includes=["reflexio/server/site_var/site_var_sources/*.json"],
|
|
362
|
+
workers=workers,
|
|
363
|
+
max_requests=max_requests,
|
|
364
|
+
max_requests_jitter=max_requests_jitter,
|
|
365
|
+
graceful_shutdown_sec=graceful_shutdown_sec,
|
|
366
|
+
)
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
if "docs" in only:
|
|
370
|
+
if DOCS_DIR.is_dir():
|
|
371
|
+
if not _ensure_nextjs_dependencies(DOCS_DIR):
|
|
372
|
+
sys.exit(1)
|
|
373
|
+
services.append(build_nextjs_service("docs", ports, cwd=str(DOCS_DIR)))
|
|
374
|
+
elif docs_explicit:
|
|
375
|
+
print(
|
|
376
|
+
f"Cannot start docs: {DOCS_DIR} not found. "
|
|
377
|
+
"The docs site is only available in source/editable installs."
|
|
378
|
+
)
|
|
379
|
+
else:
|
|
380
|
+
print(
|
|
381
|
+
f"Skipping docs: {DOCS_DIR} not found "
|
|
382
|
+
"(docs site is not shipped with the PyPI package)."
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
if not services:
|
|
386
|
+
print("No services selected. Available: backend, docs, embedding")
|
|
387
|
+
return
|
|
388
|
+
|
|
389
|
+
started_ports = {s.name: ports[s.name] for s in services}
|
|
390
|
+
print(f"Starting services: {', '.join(s.name for s in services)}")
|
|
391
|
+
run_services(services, started_ports)
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""Shared CLI state management for Reflexio CLI.
|
|
2
|
+
|
|
3
|
+
Provides a CliState dataclass that travels through the Typer context,
|
|
4
|
+
and a helper to lazily create a ReflexioClient from the state + env
|
|
5
|
+
resolution chain.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from typing import TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
import typer
|
|
15
|
+
|
|
16
|
+
from reflexio.defaults import DEFAULT_AGENT_VERSION, DEFAULT_SERVER_URL, DEFAULT_USER_ID
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from reflexio import ReflexioClient
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class CliState:
|
|
24
|
+
"""Global CLI state passed via typer.Context.obj.
|
|
25
|
+
|
|
26
|
+
Attributes:
|
|
27
|
+
json_mode: Whether to output JSON envelopes
|
|
28
|
+
server_url: Backend API server URL override (from --server-url flag)
|
|
29
|
+
api_key: API key override (from --api-key flag)
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
json_mode: bool = False
|
|
33
|
+
server_url: str | None = None
|
|
34
|
+
api_key: str | None = None
|
|
35
|
+
_client: ReflexioClient | None = field(default=None, repr=False)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def resolve_url(server_url: str | None = None) -> str:
|
|
39
|
+
"""Resolve server URL: explicit value > REFLEXIO_URL env var > default.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
server_url: Explicit URL from CLI flag or caller.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
str: Resolved server URL.
|
|
46
|
+
"""
|
|
47
|
+
return server_url or os.environ.get("REFLEXIO_URL") or DEFAULT_SERVER_URL
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def resolve_api_key(api_key: str | None = None) -> str:
|
|
51
|
+
"""Resolve API key: explicit value > REFLEXIO_API_KEY env var > empty.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
api_key: Explicit API key from CLI flag or caller.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
str: Resolved API key (may be empty).
|
|
58
|
+
"""
|
|
59
|
+
return api_key or os.environ.get("REFLEXIO_API_KEY") or ""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_client(ctx: typer.Context) -> ReflexioClient:
|
|
63
|
+
"""Get or create a ReflexioClient from the CLI context.
|
|
64
|
+
|
|
65
|
+
Resolution order (highest to lowest priority):
|
|
66
|
+
1. CLI flags (--server-url, --api-key via CliState)
|
|
67
|
+
2. Environment variables (REFLEXIO_URL, REFLEXIO_API_KEY)
|
|
68
|
+
3. Defaults (https://www.reflexio.ai/, no api_key)
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
ctx: Typer context with CliState in ctx.obj
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
ReflexioClient: Configured client instance
|
|
75
|
+
"""
|
|
76
|
+
state: CliState = ctx.obj
|
|
77
|
+
if state._client is not None:
|
|
78
|
+
return state._client
|
|
79
|
+
|
|
80
|
+
from reflexio import ReflexioClient
|
|
81
|
+
|
|
82
|
+
state._client = ReflexioClient(
|
|
83
|
+
url_endpoint=resolve_url(state.server_url),
|
|
84
|
+
api_key=resolve_api_key(state.api_key),
|
|
85
|
+
)
|
|
86
|
+
return state._client
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def resolve_user_id(user_id: str | None = None) -> str:
|
|
90
|
+
"""Resolve user_id from flag, env var, or default.
|
|
91
|
+
|
|
92
|
+
Use this for commands that need to **assign** a user_id to stored
|
|
93
|
+
data (e.g., ``publish``), where silently falling back to
|
|
94
|
+
``DEFAULT_USER_ID`` is sensible behavior. For commands that
|
|
95
|
+
**filter** by user_id (e.g., ``search``, where a silent default
|
|
96
|
+
would hide the user's real intent), use :func:`require_user_id`.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
user_id: Explicit user_id from CLI flag
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
str: Resolved user ID
|
|
103
|
+
"""
|
|
104
|
+
if user_id:
|
|
105
|
+
return user_id
|
|
106
|
+
if env_val := os.environ.get("REFLEXIO_USER_ID"):
|
|
107
|
+
return env_val
|
|
108
|
+
return DEFAULT_USER_ID
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def require_user_id(user_id: str | None = None, *, command_hint: str = "") -> str:
|
|
112
|
+
"""Resolve user_id from flag or env var — no silent default.
|
|
113
|
+
|
|
114
|
+
Like :func:`resolve_user_id` but raises ``CliError`` instead of
|
|
115
|
+
falling back to ``DEFAULT_USER_ID`` when nothing is specified.
|
|
116
|
+
Use this in commands that **filter** by user_id, where a silent
|
|
117
|
+
default would hide data under the "user-default" identifier
|
|
118
|
+
instead of doing what the user meant.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
user_id: Explicit user_id from CLI flag
|
|
122
|
+
command_hint: Optional short phrase describing the command
|
|
123
|
+
(e.g., "profile search") to include in the error message.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
str: Resolved user ID.
|
|
127
|
+
|
|
128
|
+
Raises:
|
|
129
|
+
CliError: If no user_id can be resolved from flag or env var.
|
|
130
|
+
"""
|
|
131
|
+
from reflexio.cli.errors import EXIT_VALIDATION, CliError
|
|
132
|
+
|
|
133
|
+
if user_id:
|
|
134
|
+
return user_id
|
|
135
|
+
if env_val := os.environ.get("REFLEXIO_USER_ID"):
|
|
136
|
+
return env_val
|
|
137
|
+
hint = f" for {command_hint}" if command_hint else ""
|
|
138
|
+
raise CliError(
|
|
139
|
+
error_type="validation",
|
|
140
|
+
message=(
|
|
141
|
+
f"--user-id is required{hint}. Set it via --user-id flag "
|
|
142
|
+
"or REFLEXIO_USER_ID env var."
|
|
143
|
+
),
|
|
144
|
+
exit_code=EXIT_VALIDATION,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def resolve_agent_version(agent_version: str | None = None) -> str:
|
|
149
|
+
"""Resolve agent_version from flag, env var, or default.
|
|
150
|
+
|
|
151
|
+
Use this for commands that need to **assign** an agent_version to
|
|
152
|
+
stored data (e.g., ``publish``). For commands that **filter** by
|
|
153
|
+
agent_version (e.g., ``regenerate``), use :func:`require_agent_version`.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
agent_version: Explicit agent_version from CLI flag
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
str: Resolved agent version
|
|
160
|
+
"""
|
|
161
|
+
if agent_version:
|
|
162
|
+
return agent_version
|
|
163
|
+
if env_val := os.environ.get("REFLEXIO_AGENT_VERSION"):
|
|
164
|
+
return env_val
|
|
165
|
+
return DEFAULT_AGENT_VERSION
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def require_agent_version(
|
|
169
|
+
agent_version: str | None = None, *, command_hint: str = ""
|
|
170
|
+
) -> str:
|
|
171
|
+
"""Resolve agent_version from flag or env var — no silent default.
|
|
172
|
+
|
|
173
|
+
Like :func:`resolve_agent_version` but raises ``CliError`` instead
|
|
174
|
+
of falling back to ``DEFAULT_AGENT_VERSION``. Use this in commands
|
|
175
|
+
that **filter or re-run against** a specific agent_version, where
|
|
176
|
+
silently defaulting to ``agent-v0`` would produce misleading
|
|
177
|
+
behavior.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
agent_version: Explicit agent_version from CLI flag
|
|
181
|
+
command_hint: Optional short phrase describing the command to
|
|
182
|
+
include in the error message.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
str: Resolved agent version.
|
|
186
|
+
|
|
187
|
+
Raises:
|
|
188
|
+
CliError: If no agent_version can be resolved from flag or env var.
|
|
189
|
+
"""
|
|
190
|
+
from reflexio.cli.errors import EXIT_VALIDATION, CliError
|
|
191
|
+
|
|
192
|
+
if agent_version:
|
|
193
|
+
return agent_version
|
|
194
|
+
if env_val := os.environ.get("REFLEXIO_AGENT_VERSION"):
|
|
195
|
+
return env_val
|
|
196
|
+
hint = f" for {command_hint}" if command_hint else ""
|
|
197
|
+
raise CliError(
|
|
198
|
+
error_type="validation",
|
|
199
|
+
message=(
|
|
200
|
+
f"--agent-version is required{hint}. Set it via --agent-version "
|
|
201
|
+
"flag or REFLEXIO_AGENT_VERSION env var."
|
|
202
|
+
),
|
|
203
|
+
exit_code=EXIT_VALIDATION,
|
|
204
|
+
)
|