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.
Files changed (396) hide show
  1. package/.claude-plugin/marketplace.json +17 -0
  2. package/README.md +1 -1
  3. package/bin/claude-smart.js +86 -48
  4. package/package.json +10 -3
  5. package/plugin/.claude-plugin/plugin.json +9 -3
  6. package/plugin/.codex-plugin/plugin.json +1 -1
  7. package/plugin/README.md +2 -2
  8. package/plugin/dashboard/next.config.ts +9 -1
  9. package/plugin/pyproject.toml +2 -2
  10. package/plugin/scripts/_lib.sh +91 -0
  11. package/plugin/scripts/backend-service.sh +46 -15
  12. package/plugin/scripts/cli.sh +29 -1
  13. package/plugin/scripts/codex-hook.js +72 -4
  14. package/plugin/scripts/dashboard-build.sh +1 -0
  15. package/plugin/scripts/dashboard-service.sh +1 -0
  16. package/plugin/scripts/ensure-plugin-root.sh +7 -14
  17. package/plugin/scripts/hook_entry.sh +1 -0
  18. package/plugin/scripts/smart-install.sh +18 -2
  19. package/plugin/src/claude_smart/cli.py +72 -38
  20. package/plugin/src/claude_smart/context_format.py +11 -12
  21. package/plugin/src/claude_smart/cs_cite.py +26 -12
  22. package/plugin/src/claude_smart/ids.py +13 -5
  23. package/plugin/uv.lock +1 -1
  24. package/plugin/vendor/reflexio/.env.example +53 -0
  25. package/plugin/vendor/reflexio/LICENSE +201 -0
  26. package/plugin/vendor/reflexio/README.md +338 -0
  27. package/plugin/vendor/reflexio/pyproject.toml +271 -0
  28. package/plugin/vendor/reflexio/reflexio/README.md +184 -0
  29. package/plugin/vendor/reflexio/reflexio/__init__.py +166 -0
  30. package/plugin/vendor/reflexio/reflexio/benchmarks/__init__.py +1 -0
  31. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/README.md +109 -0
  32. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/__init__.py +1 -0
  33. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/backends.py +175 -0
  34. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/bench.py +642 -0
  35. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/embed_cache.py +330 -0
  36. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/report.py +317 -0
  37. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/report.md +43 -0
  38. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/results.json +4478 -0
  39. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/scenarios.py +134 -0
  40. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/seed.py +255 -0
  41. package/plugin/vendor/reflexio/reflexio/cli/README.md +287 -0
  42. package/plugin/vendor/reflexio/reflexio/cli/__init__.py +0 -0
  43. package/plugin/vendor/reflexio/reflexio/cli/__main__.py +56 -0
  44. package/plugin/vendor/reflexio/reflexio/cli/_client.py +86 -0
  45. package/plugin/vendor/reflexio/reflexio/cli/app.py +127 -0
  46. package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +266 -0
  47. package/plugin/vendor/reflexio/reflexio/cli/codex_auth.py +503 -0
  48. package/plugin/vendor/reflexio/reflexio/cli/commands/__init__.py +0 -0
  49. package/plugin/vendor/reflexio/reflexio/cli/commands/admin_cmd.py +65 -0
  50. package/plugin/vendor/reflexio/reflexio/cli/commands/agent_playbooks.py +503 -0
  51. package/plugin/vendor/reflexio/reflexio/cli/commands/api.py +114 -0
  52. package/plugin/vendor/reflexio/reflexio/cli/commands/auth.py +109 -0
  53. package/plugin/vendor/reflexio/reflexio/cli/commands/config_cmd.py +511 -0
  54. package/plugin/vendor/reflexio/reflexio/cli/commands/doctor.py +127 -0
  55. package/plugin/vendor/reflexio/reflexio/cli/commands/embeddings.py +53 -0
  56. package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +478 -0
  57. package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +303 -0
  58. package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +289 -0
  59. package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +961 -0
  60. package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +285 -0
  61. package/plugin/vendor/reflexio/reflexio/cli/commands/status_cmd.py +143 -0
  62. package/plugin/vendor/reflexio/reflexio/cli/commands/user_playbooks.py +373 -0
  63. package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +284 -0
  64. package/plugin/vendor/reflexio/reflexio/cli/errors.py +217 -0
  65. package/plugin/vendor/reflexio/reflexio/cli/log_format.py +247 -0
  66. package/plugin/vendor/reflexio/reflexio/cli/output.py +867 -0
  67. package/plugin/vendor/reflexio/reflexio/cli/paths.py +41 -0
  68. package/plugin/vendor/reflexio/reflexio/cli/run_services.py +391 -0
  69. package/plugin/vendor/reflexio/reflexio/cli/state.py +204 -0
  70. package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +96 -0
  71. package/plugin/vendor/reflexio/reflexio/cli/utils.py +329 -0
  72. package/plugin/vendor/reflexio/reflexio/client/__init__.py +3 -0
  73. package/plugin/vendor/reflexio/reflexio/client/cache.py +150 -0
  74. package/plugin/vendor/reflexio/reflexio/client/client.py +2613 -0
  75. package/plugin/vendor/reflexio/reflexio/defaults.py +23 -0
  76. package/plugin/vendor/reflexio/reflexio/integrations/__init__.py +0 -0
  77. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/.clawhubignore +7 -0
  78. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +274 -0
  79. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +517 -0
  80. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +473 -0
  81. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +2156 -0
  82. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +18 -0
  83. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +241 -0
  84. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +140 -0
  85. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +130 -0
  86. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +113 -0
  87. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +52 -0
  88. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +103 -0
  89. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +156 -0
  90. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +134 -0
  91. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +41 -0
  92. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +17 -0
  93. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +24 -0
  94. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +48 -0
  95. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +278 -0
  96. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +164 -0
  97. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +36 -0
  98. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +35 -0
  99. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +27 -0
  100. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +31 -0
  101. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +42 -0
  102. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +49 -0
  103. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +91 -0
  104. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +50 -0
  105. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tsconfig.json +16 -0
  106. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/types/openclaw.d.ts +230 -0
  107. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +13 -0
  108. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/README.md +120 -0
  109. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/TESTING.md +168 -0
  110. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package-lock.json +1657 -0
  111. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package.json +16 -0
  112. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/HEARTBEAT.md +6 -0
  113. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/README.md +84 -0
  114. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/SKILL.md +194 -0
  115. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/_meta.json +6 -0
  116. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/agents/reflexio-extractor.md +45 -0
  117. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/handler.ts +214 -0
  118. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/setup.ts +55 -0
  119. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/index.ts +327 -0
  120. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/consolidate.ts +233 -0
  121. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/dedup.ts +80 -0
  122. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/io.ts +155 -0
  123. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/openclaw-cli.ts +67 -0
  124. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/search.ts +33 -0
  125. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-playbook.ts +76 -0
  126. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-profile.ts +79 -0
  127. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/openclaw.plugin.json +46 -0
  128. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/package.json +18 -0
  129. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/README.md +36 -0
  130. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/full_consolidation.md +56 -0
  131. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/playbook_extraction.md +217 -0
  132. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/profile_extraction.md +132 -0
  133. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-consolidate/SKILL.md +33 -0
  134. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-embedded/SKILL.md +194 -0
  135. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/HOOK.md +18 -0
  136. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/architecture.md +49 -0
  137. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/comparison.md +31 -0
  138. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/future-work.md +47 -0
  139. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/porting-notes.md +52 -0
  140. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/install.sh +52 -0
  141. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/uninstall.sh +36 -0
  142. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/consolidate.test.ts +135 -0
  143. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/dedup.test.ts +104 -0
  144. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/io.test.ts +175 -0
  145. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/search.test.ts +66 -0
  146. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/smoke-test.ts +140 -0
  147. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-playbook.test.ts +93 -0
  148. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-profile.test.ts +174 -0
  149. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tsconfig.json +16 -0
  150. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/types/openclaw.d.ts +230 -0
  151. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/vitest.config.ts +7 -0
  152. package/plugin/vendor/reflexio/reflexio/lib/__init__.py +23 -0
  153. package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +310 -0
  154. package/plugin/vendor/reflexio/reflexio/lib/_base.py +225 -0
  155. package/plugin/vendor/reflexio/reflexio/lib/_config.py +83 -0
  156. package/plugin/vendor/reflexio/reflexio/lib/_dashboard.py +266 -0
  157. package/plugin/vendor/reflexio/reflexio/lib/_generation.py +176 -0
  158. package/plugin/vendor/reflexio/reflexio/lib/_interactions.py +334 -0
  159. package/plugin/vendor/reflexio/reflexio/lib/_operations.py +153 -0
  160. package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +545 -0
  161. package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +52 -0
  162. package/plugin/vendor/reflexio/reflexio/lib/_search.py +167 -0
  163. package/plugin/vendor/reflexio/reflexio/lib/_storage_labels.py +103 -0
  164. package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +288 -0
  165. package/plugin/vendor/reflexio/reflexio/lib/reflexio_lib.py +27 -0
  166. package/plugin/vendor/reflexio/reflexio/models/__init__.py +0 -0
  167. package/plugin/vendor/reflexio/reflexio/models/api_schema/__init__.py +0 -0
  168. package/plugin/vendor/reflexio/reflexio/models/api_schema/braintrust_schema.py +141 -0
  169. package/plugin/vendor/reflexio/reflexio/models/api_schema/common.py +41 -0
  170. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/__init__.py +3 -0
  171. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +1103 -0
  172. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +63 -0
  173. package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +487 -0
  174. package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +28 -0
  175. package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +83 -0
  176. package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +766 -0
  177. package/plugin/vendor/reflexio/reflexio/models/api_schema/service_schemas.py +9 -0
  178. package/plugin/vendor/reflexio/reflexio/models/api_schema/stall_state_schema.py +32 -0
  179. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/__init__.py +3 -0
  180. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +177 -0
  181. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +129 -0
  182. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/enums.py +25 -0
  183. package/plugin/vendor/reflexio/reflexio/models/api_schema/validators.py +280 -0
  184. package/plugin/vendor/reflexio/reflexio/models/config_schema.py +908 -0
  185. package/plugin/vendor/reflexio/reflexio/models/py.typed +0 -0
  186. package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +90 -0
  187. package/plugin/vendor/reflexio/reflexio/server/README.md +616 -0
  188. package/plugin/vendor/reflexio/reflexio/server/__init__.py +210 -0
  189. package/plugin/vendor/reflexio/reflexio/server/__main__.py +132 -0
  190. package/plugin/vendor/reflexio/reflexio/server/_auth.py +25 -0
  191. package/plugin/vendor/reflexio/reflexio/server/api.py +2714 -0
  192. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/account_api.py +143 -0
  193. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/health_api.py +91 -0
  194. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/pending_tool_call_api.py +572 -0
  195. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +66 -0
  196. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/publisher_api.py +540 -0
  197. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +50 -0
  198. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/stall_state_api.py +100 -0
  199. package/plugin/vendor/reflexio/reflexio/server/cache/__init__.py +15 -0
  200. package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +208 -0
  201. package/plugin/vendor/reflexio/reflexio/server/correlation.py +46 -0
  202. package/plugin/vendor/reflexio/reflexio/server/llm/__init__.py +30 -0
  203. package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +110 -0
  204. package/plugin/vendor/reflexio/reflexio/server/llm/image_utils.py +55 -0
  205. package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +1595 -0
  206. package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +112 -0
  207. package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +469 -0
  208. package/plugin/vendor/reflexio/reflexio/server/llm/providers/__init__.py +1 -0
  209. package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +1122 -0
  210. package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_stream_parser.py +197 -0
  211. package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +210 -0
  212. package/plugin/vendor/reflexio/reflexio/server/llm/providers/local_embedding_provider.py +213 -0
  213. package/plugin/vendor/reflexio/reflexio/server/llm/providers/nomic_embedding_provider.py +255 -0
  214. package/plugin/vendor/reflexio/reflexio/server/llm/rerank/__init__.py +6 -0
  215. package/plugin/vendor/reflexio/reflexio/server/llm/rerank/cross_encoder_reranker.py +177 -0
  216. package/plugin/vendor/reflexio/reflexio/server/llm/rerank/llm_reranker.py +148 -0
  217. package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +699 -0
  218. package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +179 -0
  219. package/plugin/vendor/reflexio/reflexio/server/prompt/__init__.py +0 -0
  220. package/plugin/vendor/reflexio/reflexio/server/prompt/_dispatchers.py +54 -0
  221. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/README.md +121 -0
  222. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation/v1.0.0.prompt.md +58 -0
  223. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation_with_comparison/v1.0.0.prompt.md +76 -0
  224. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/answer_synthesis/v1.5.2.prompt.md +88 -0
  225. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/compress_session_for_query/v1.3.0.prompt.md +31 -0
  226. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/document_expansion/v1.0.0.prompt.md +20 -0
  227. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.0.0.prompt.md +53 -0
  228. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.1.0.prompt.md +57 -0
  229. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.2.0.prompt.md +68 -0
  230. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.3.0.prompt.md +70 -0
  231. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.4.0.prompt.md +77 -0
  232. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.5.0.prompt.md +82 -0
  233. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.6.0.prompt.md +83 -0
  234. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.1.0.prompt.md +193 -0
  235. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.2.0.prompt.md +206 -0
  236. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0-deprecated.prompt.md +66 -0
  237. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0.prompt.md +43 -0
  238. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.1.0.prompt.md +46 -0
  239. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0-deprecated.prompt.md +64 -0
  240. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0.prompt.md +39 -0
  241. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.1.0.prompt.md +39 -0
  242. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.2.0.prompt.md +47 -0
  243. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.0.prompt.md +58 -0
  244. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.0.2.prompt.md +254 -0
  245. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.1.0.prompt.md +274 -0
  246. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.0.prompt.md +279 -0
  247. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v1.0.0.prompt.md +73 -0
  248. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v2.0.0.prompt.md +86 -0
  249. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.0.0.prompt.md +97 -0
  250. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.1.0.prompt.md +119 -0
  251. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.2.0.prompt.md +123 -0
  252. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +127 -0
  253. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.0.0.prompt.md +14 -0
  254. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.1.0.prompt.md +24 -0
  255. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +29 -0
  256. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.0.0.prompt.md +11 -0
  257. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.1.0.prompt.md +21 -0
  258. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.2.0.prompt.md +25 -0
  259. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.0.0.prompt.md +37 -0
  260. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.1.0.prompt.md +40 -0
  261. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.2.0.prompt.md +36 -0
  262. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v1.0.0.prompt.md +45 -0
  263. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v2.0.0.prompt.md +81 -0
  264. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v3.0.0.prompt.md +80 -0
  265. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate_expert/v1.0.0.prompt.md +34 -0
  266. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_deduplication/v1.0.0.prompt.md +116 -0
  267. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate/v1.0.0.prompt.md +33 -0
  268. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate_override/v1.0.0.prompt.md +16 -0
  269. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +140 -0
  270. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +160 -0
  271. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_main/v1.0.0.prompt.md +14 -0
  272. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/query_reformulation/v1.0.0.prompt.md +19 -0
  273. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/rerank_relevance/v1.1.0.prompt.md +44 -0
  274. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_comparison/v1.0.0.prompt.md +43 -0
  275. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_content_evaluation/v1.0.0.prompt.md +33 -0
  276. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/feedback_extraction_main_v1.jsonl +10 -0
  277. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/profile_update_main_v1.jsonl +10 -0
  278. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +280 -0
  279. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_schema.py +11 -0
  280. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/_eval_health.py +131 -0
  281. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +60 -0
  282. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_service.py +228 -0
  283. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +87 -0
  284. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluator.py +372 -0
  285. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/delayed_group_evaluator.py +156 -0
  286. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/group_evaluation_runner.py +340 -0
  287. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +471 -0
  288. package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +1626 -0
  289. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/__init__.py +0 -0
  290. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_cron.py +196 -0
  291. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_encryption.py +101 -0
  292. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/client.py +167 -0
  293. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/service.py +281 -0
  294. package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +179 -0
  295. package/plugin/vendor/reflexio/reflexio/server/services/configurator/config_storage.py +62 -0
  296. package/plugin/vendor/reflexio/reflexio/server/services/configurator/configurator.py +87 -0
  297. package/plugin/vendor/reflexio/reflexio/server/services/configurator/local_file_config_storage.py +187 -0
  298. package/plugin/vendor/reflexio/reflexio/server/services/configurator/test_config_storage.py +162 -0
  299. package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +112 -0
  300. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/__init__.py +0 -0
  301. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/distribution.py +33 -0
  302. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +126 -0
  303. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +192 -0
  304. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/hero_state.py +75 -0
  305. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/rule_attribution.py +97 -0
  306. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +515 -0
  307. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/shadow_aggregation.py +90 -0
  308. package/plugin/vendor/reflexio/reflexio/server/services/extraction/__init__.py +0 -0
  309. package/plugin/vendor/reflexio/reflexio/server/services/extraction/agent_run_records.py +91 -0
  310. package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +303 -0
  311. package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +25 -0
  312. package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +351 -0
  313. package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +138 -0
  314. package/plugin/vendor/reflexio/reflexio/server/services/extraction/prior_answer_search.py +217 -0
  315. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +468 -0
  316. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_scheduler.py +171 -0
  317. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +777 -0
  318. package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +1125 -0
  319. package/plugin/vendor/reflexio/reflexio/server/services/extractor_config_utils.py +91 -0
  320. package/plugin/vendor/reflexio/reflexio/server/services/extractor_interaction_utils.py +251 -0
  321. package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +689 -0
  322. package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +835 -0
  323. package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +89 -0
  324. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_aggregator.py +1388 -0
  325. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_consolidator.py +960 -0
  326. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_extractor.py +436 -0
  327. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_generation_service.py +808 -0
  328. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_constants.py +28 -0
  329. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +362 -0
  330. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/__init__.py +24 -0
  331. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/assistant_webhook.py +246 -0
  332. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/gepa_adapter.py +291 -0
  333. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/judge.py +97 -0
  334. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +96 -0
  335. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +645 -0
  336. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/rollout.py +35 -0
  337. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scenario_resolver.py +93 -0
  338. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scheduler.py +174 -0
  339. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/__init__.py +26 -0
  340. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_document_expander.py +179 -0
  341. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_query_reformulator.py +297 -0
  342. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_deduplicator.py +741 -0
  343. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_extractor.py +462 -0
  344. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service.py +734 -0
  345. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +290 -0
  346. package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +17 -0
  347. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_extractor.py +247 -0
  348. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service.py +800 -0
  349. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +146 -0
  350. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/__init__.py +0 -0
  351. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +70 -0
  352. package/plugin/vendor/reflexio/reflexio/server/services/search/__init__.py +0 -0
  353. package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +671 -0
  354. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/__init__.py +1 -0
  355. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/judge.py +184 -0
  356. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +81 -0
  357. package/plugin/vendor/reflexio/reflexio/server/services/storage/constants.py +2 -0
  358. package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +11 -0
  359. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +154 -0
  360. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention_mixin.py +155 -0
  361. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +59 -0
  362. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +1253 -0
  363. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +1945 -0
  364. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +600 -0
  365. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +346 -0
  366. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +1378 -0
  367. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +747 -0
  368. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +263 -0
  369. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +193 -0
  370. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_share_links.py +166 -0
  371. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +217 -0
  372. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +153 -0
  373. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +372 -0
  374. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +71 -0
  375. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +235 -0
  376. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +170 -0
  377. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +677 -0
  378. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +250 -0
  379. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +154 -0
  380. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +130 -0
  381. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_share_links.py +93 -0
  382. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_stall_state.py +76 -0
  383. package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +568 -0
  384. package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +77 -0
  385. package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +116 -0
  386. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_manager.py +263 -0
  387. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +13 -0
  388. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/llm_model_setting.json +7 -0
  389. package/plugin/vendor/reflexio/reflexio/server/tracing.py +158 -0
  390. package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +113 -0
  391. package/plugin/vendor/reflexio/reflexio/server/uvicorn_logging.py +76 -0
  392. package/plugin/vendor/reflexio/reflexio/test_support/__init__.py +1 -0
  393. package/plugin/vendor/reflexio/reflexio/test_support/llm_fixtures.py +62 -0
  394. package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +242 -0
  395. package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +129 -0
  396. 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
+ )