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,303 @@
1
+ """Profile management commands (list, search, delete, generate)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+
9
+ from reflexio.cli.errors import (
10
+ EXIT_VALIDATION,
11
+ CliError,
12
+ handle_errors,
13
+ raise_if_failed,
14
+ )
15
+ from reflexio.cli.output import (
16
+ pagination_meta,
17
+ print_info,
18
+ print_user_profiles,
19
+ render,
20
+ )
21
+ from reflexio.cli.state import get_client, require_user_id
22
+
23
+ app = typer.Typer(
24
+ help=(
25
+ "Manage user profiles. Profiles are normally derived "
26
+ "automatically from published interactions (via 'reflexio "
27
+ "publish' + 'reflexio user-profiles regenerate'), but you "
28
+ "can also seed them manually with 'reflexio user-profiles add'."
29
+ ),
30
+ )
31
+
32
+
33
+ @app.command(name="list")
34
+ @handle_errors
35
+ def list_profiles(
36
+ ctx: typer.Context,
37
+ user_id: Annotated[
38
+ str | None,
39
+ typer.Option("--user-id", help="User ID to filter profiles"),
40
+ ] = None,
41
+ limit: Annotated[
42
+ int,
43
+ typer.Option("--limit", help="Maximum number of profiles to return"),
44
+ ] = 20,
45
+ status: Annotated[
46
+ str | None,
47
+ typer.Option("--status", help="Status filter (current/pending/archived)"),
48
+ ] = None,
49
+ ) -> None:
50
+ """List user profiles.
51
+
52
+ Args:
53
+ ctx: Typer context with CliState in ctx.obj
54
+ user_id: Optional user ID filter
55
+ limit: Maximum number of profiles to return
56
+ status: Optional status filter (current, pending, archived)
57
+ """
58
+ if status and status not in ("current", "pending", "archived"):
59
+ raise CliError(
60
+ error_type="validation",
61
+ message=f"Invalid status: {status}. Must be current, pending, or archived.",
62
+ exit_code=EXIT_VALIDATION,
63
+ )
64
+
65
+ client = get_client(ctx)
66
+ if user_id:
67
+ # Filtered: query a single user via /api/get_profiles
68
+ resp = client.get_profiles(
69
+ user_id=user_id,
70
+ top_k=limit,
71
+ status_filter=[status] if status else None,
72
+ )
73
+ else:
74
+ # Unfiltered: query every user via /api/get_all_profiles.
75
+ # We intentionally do NOT fall back to resolve_user_id() here —
76
+ # "no --user-id" means "all users", not "the default user".
77
+ resp = client.get_all_profiles(
78
+ limit=limit,
79
+ status_filter=status,
80
+ )
81
+ profiles = resp.user_profiles or []
82
+
83
+ json_mode: bool = ctx.obj.json_mode
84
+ if json_mode:
85
+ render(profiles, json_mode=True, meta=pagination_meta(profiles, limit))
86
+ else:
87
+ print_info(f"Found {len(profiles)} profile(s)")
88
+ if profiles:
89
+ print_user_profiles(profiles)
90
+
91
+
92
+ @app.command()
93
+ @handle_errors
94
+ def search_user_profiles(
95
+ ctx: typer.Context,
96
+ query: Annotated[
97
+ str,
98
+ typer.Argument(help="Semantic search query for profiles"),
99
+ ],
100
+ user_id: Annotated[
101
+ str | None,
102
+ typer.Option("--user-id", help="User ID to filter profiles"),
103
+ ] = None,
104
+ limit: Annotated[
105
+ int,
106
+ typer.Option("--limit", help="Maximum number of results"),
107
+ ] = 10,
108
+ threshold: Annotated[
109
+ float | None,
110
+ typer.Option("--threshold", help="Similarity threshold"),
111
+ ] = None,
112
+ ) -> None:
113
+ """Search user profiles by semantic query.
114
+
115
+ Args:
116
+ ctx: Typer context with CliState in ctx.obj
117
+ query: Search query string
118
+ user_id: Optional user ID filter
119
+ limit: Maximum number of results
120
+ threshold: Optional similarity threshold
121
+ """
122
+ client = get_client(ctx)
123
+ # Profile search requires a specific user_id — the server's
124
+ # SearchUserProfileRequest.user_id is NonEmptyStr (cross-user
125
+ # profile search is not currently supported). require_user_id
126
+ # errors out cleanly instead of silently falling back to
127
+ # DEFAULT_USER_ID.
128
+ resolved_user_id = require_user_id(user_id, command_hint="profile search")
129
+
130
+ kwargs: dict = {
131
+ "query": query,
132
+ "user_id": resolved_user_id,
133
+ "top_k": limit,
134
+ }
135
+ if threshold is not None:
136
+ kwargs["threshold"] = threshold
137
+
138
+ resp = client.search_user_profiles(**kwargs)
139
+ profiles = resp.user_profiles or []
140
+
141
+ json_mode: bool = ctx.obj.json_mode
142
+ if json_mode:
143
+ render(profiles, json_mode=True, meta=pagination_meta(profiles, limit))
144
+ else:
145
+ print_info(f"Found {len(profiles)} profile(s)")
146
+ if profiles:
147
+ print_user_profiles(profiles)
148
+
149
+
150
+ @app.command()
151
+ @handle_errors
152
+ def delete(
153
+ ctx: typer.Context,
154
+ user_id: Annotated[
155
+ str,
156
+ typer.Option("--user-id", help="User ID (required)"),
157
+ ],
158
+ profile_id: Annotated[
159
+ str,
160
+ typer.Option("--profile-id", help="Specific profile ID to delete"),
161
+ ] = "",
162
+ ) -> None:
163
+ """Delete a user profile.
164
+
165
+ Args:
166
+ ctx: Typer context with CliState in ctx.obj
167
+ user_id: User ID owning the profile
168
+ profile_id: Specific profile ID to delete (empty string for all user profiles)
169
+ """
170
+ client = get_client(ctx)
171
+ resp = client.delete_profile(
172
+ user_id=user_id,
173
+ profile_id=profile_id,
174
+ wait_for_response=True,
175
+ )
176
+
177
+ json_mode: bool = ctx.obj.json_mode
178
+ if json_mode:
179
+ render(resp, json_mode=True)
180
+ else:
181
+ label = (
182
+ f"profile {profile_id}" if profile_id else f"profiles for user {user_id}"
183
+ )
184
+ print_info(f"Deleted {label}")
185
+
186
+
187
+ @app.command(name="delete-all")
188
+ @handle_errors
189
+ def delete_all(
190
+ ctx: typer.Context,
191
+ yes: Annotated[
192
+ bool,
193
+ typer.Option("--yes", "-y", help="Skip confirmation prompt"),
194
+ ] = False,
195
+ ) -> None:
196
+ """Delete all profiles.
197
+
198
+ Args:
199
+ ctx: Typer context with CliState in ctx.obj
200
+ yes: If True, skip confirmation prompt
201
+ """
202
+ if not yes:
203
+ confirmed = typer.confirm("Are you sure you want to delete all profiles?")
204
+ if not confirmed:
205
+ raise typer.Abort()
206
+
207
+ client = get_client(ctx)
208
+ resp = client.delete_all_profiles()
209
+
210
+ json_mode: bool = ctx.obj.json_mode
211
+ if json_mode:
212
+ render(resp, json_mode=True)
213
+ else:
214
+ print_info("All profiles deleted")
215
+
216
+
217
+ @app.command()
218
+ @handle_errors
219
+ def add(
220
+ ctx: typer.Context,
221
+ user_id: Annotated[
222
+ str,
223
+ typer.Option("--user-id", help="User ID owning the profile"),
224
+ ],
225
+ content: Annotated[
226
+ str,
227
+ typer.Option("--content", help="Profile content text"),
228
+ ],
229
+ ) -> None:
230
+ """Manually add a user profile, bypassing interaction-based inference.
231
+
232
+ Useful for seeding a known fact about the user (testing, migration,
233
+ manual fact injection). Most users should rely on automatic profile
234
+ generation via ``reflexio publish`` + ``reflexio user-profiles
235
+ regenerate``.
236
+
237
+ Args:
238
+ ctx: Typer context with CliState in ctx.obj
239
+ user_id: User the profile belongs to
240
+ content: Profile content text (used for embedding)
241
+ """
242
+ client = get_client(ctx)
243
+ resp = client.add_user_profile(
244
+ [{"user_id": user_id, "content": content, "source": "cli-manual"}]
245
+ )
246
+
247
+ json_mode: bool = ctx.obj.json_mode
248
+ if json_mode:
249
+ render(resp, json_mode=True)
250
+ else:
251
+ raise_if_failed(resp, default="Failed to add user profile")
252
+ print_info(f"User profile added: {content[:80]}")
253
+
254
+
255
+ @app.command()
256
+ @handle_errors
257
+ def regenerate(
258
+ ctx: typer.Context,
259
+ user_id: Annotated[
260
+ str,
261
+ typer.Option("--user-id", help="User ID (required)"),
262
+ ],
263
+ wait: Annotated[
264
+ bool,
265
+ typer.Option("--wait", help="Wait for profile generation to complete"),
266
+ ] = False,
267
+ ) -> None:
268
+ """Re-run profile generation for a user.
269
+
270
+ Re-runs the inference pipeline over the user's published
271
+ interactions to refresh their profiles. Renamed from
272
+ ``generate`` for consistency with ``agent-playbooks regenerate``.
273
+
274
+ Args:
275
+ ctx: Typer context with CliState in ctx.obj
276
+ user_id: User ID to generate profiles for
277
+ wait: If True, wait for generation to complete
278
+ """
279
+ client = get_client(ctx)
280
+ resp = client.rerun_profile_generation(
281
+ user_id=user_id,
282
+ wait_for_response=wait,
283
+ )
284
+
285
+ # When waiting, auto-promote PENDING profiles to CURRENT so they're
286
+ # immediately visible in `list` output. Without this, regenerated
287
+ # profiles stay in PENDING status and the default list filter (CURRENT
288
+ # only) returns 0 results.
289
+ promoted = 0
290
+ if wait:
291
+ try:
292
+ upgrade_resp = client.upgrade_profiles(user_id=user_id)
293
+ promoted = upgrade_resp.profiles_promoted
294
+ except Exception:
295
+ print_info("Warning: promotion failed, but regeneration succeeded")
296
+
297
+ json_mode: bool = ctx.obj.json_mode
298
+ if json_mode:
299
+ render(resp, json_mode=True)
300
+ elif wait:
301
+ print_info(f"Profile generation complete ({promoted} profile(s) promoted)")
302
+ else:
303
+ print_info("Profile generation started")
@@ -0,0 +1,289 @@
1
+ """Service management commands (Typer wrapper around existing run/stop logic)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import logging
7
+ import os
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import Annotated
11
+
12
+ import typer
13
+
14
+ from reflexio.cli import run_services as run_mod
15
+ from reflexio.cli import stop_services as stop_mod
16
+ from reflexio.cli.bootstrap_config import _VALID_STORAGE_BACKENDS
17
+
18
+ _logger = logging.getLogger(__name__)
19
+
20
+ app = typer.Typer(help="Start and stop Reflexio services.")
21
+
22
+
23
+ def _ensure_llm_configured(env_path: Path) -> None:
24
+ """Run the first-run LLM + embedding wizard when no key is configured.
25
+
26
+ Called by ``services start`` before uvicorn boots. Replaces the ugly
27
+ ``RuntimeError: No LLM API keys found`` traceback that used to crash the
28
+ FastAPI lifespan handler on a fresh install.
29
+
30
+ Behaviour matrix:
31
+ - At least one LLM key AND an embedding-capable provider in env →
32
+ return silently, startup continues.
33
+ - At least one LLM key but no cloud embedder, and ``chromadb`` is
34
+ importable → log "Using local embedder as fallback" and return;
35
+ runtime auto-detection (Layer A) will pick ``local/minilm-l6-v2``
36
+ for the EMBEDDING role. No prompt, no blocking.
37
+ - No LLM key, interactive TTY → prompt for a provider + key, then
38
+ (conditionally) prompt for an embedding key, re-load the .env so
39
+ the new values land in ``os.environ``, and return.
40
+ - Missing only an embedding key (e.g. user set ANTHROPIC_API_KEY
41
+ manually) AND chromadb is unavailable → prompt only for an
42
+ embedding provider.
43
+ - No LLM key, non-interactive stdin (CI, nohup, container) → print a
44
+ clean pointer to the .env file and raise ``typer.Exit(1)`` so the
45
+ user never sees the uvicorn/starlette traceback.
46
+
47
+ Args:
48
+ env_path (Path): Path to the user's ``.env`` file (``~/.reflexio/.env``
49
+ in the default installation). Keys selected in the wizard are
50
+ written here.
51
+
52
+ Raises:
53
+ typer.Exit: When stdin is not a TTY and no LLM key is configured.
54
+ """
55
+ from dotenv import load_dotenv
56
+
57
+ from reflexio.cli.commands.setup_cmd import (
58
+ _prompt_embedding_provider,
59
+ _prompt_llm_provider,
60
+ )
61
+ from reflexio.server.llm.model_defaults import (
62
+ EMBEDDING_CAPABLE_PROVIDERS,
63
+ GENERATION_CAPABLE_PROVIDERS,
64
+ detect_available_providers,
65
+ )
66
+ from reflexio.server.llm.providers.local_embedding_provider import (
67
+ is_chromadb_importable,
68
+ )
69
+
70
+ providers = detect_available_providers()
71
+ has_embedding = any(p in EMBEDDING_CAPABLE_PROVIDERS for p in providers)
72
+ has_generation = any(p in GENERATION_CAPABLE_PROVIDERS for p in providers)
73
+ embedding_provider = os.environ.get("REFLEXIO_EMBEDDING_PROVIDER", "").lower()
74
+ if embedding_provider in {"local_service", "internal_service"}:
75
+ has_embedding = True
76
+ if providers and has_generation and has_embedding:
77
+ return
78
+
79
+ # Path 3 of the embedding auto-detection: if a generation provider is
80
+ # configured but no cloud embedder, and chromadb is importable, the
81
+ # runtime will silently fall back to the local MiniLM embedder (see
82
+ # ``_auto_detect_model`` in model_defaults.py). No need to prompt or
83
+ # block startup. We require ``has_generation`` here because providers
84
+ # like ``["local"]`` (embedder-only) leave the GENERATION role
85
+ # unresolvable and must still trip the wizard.
86
+ if has_generation and is_chromadb_importable():
87
+ _logger.info("Using local embedder as fallback (no cloud embedder configured)")
88
+ return
89
+
90
+ if not sys.stdin.isatty():
91
+ typer.echo(
92
+ "\nReflexio is not fully configured yet — "
93
+ + (
94
+ "no generation-capable LLM API key"
95
+ if not has_generation
96
+ else "no embedding-capable provider"
97
+ )
98
+ + f" was found in {env_path}.\n"
99
+ "Set one of OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, ... "
100
+ "in that file, or run `reflexio setup init` interactively, "
101
+ "then retry `reflexio services start`."
102
+ )
103
+ raise typer.Exit(1)
104
+
105
+ if not has_generation:
106
+ typer.echo(
107
+ "\nWelcome to Reflexio! Let's pick an LLM provider before "
108
+ "starting the local services."
109
+ )
110
+ typer.echo(
111
+ "(If you wanted Managed or Self-hosted Reflexio instead, press "
112
+ "Ctrl+C and run `reflexio setup init`.)"
113
+ )
114
+ _, _, provider_key = _prompt_llm_provider(env_path)
115
+ _prompt_embedding_provider(env_path, provider_key)
116
+ else:
117
+ typer.echo(
118
+ "\nYour LLM provider doesn't support text embeddings — Reflexio "
119
+ "needs an embedding model for semantic search."
120
+ )
121
+ non_embedding_provider = next(
122
+ p for p in providers if p not in EMBEDDING_CAPABLE_PROVIDERS
123
+ )
124
+ _prompt_embedding_provider(env_path, non_embedding_provider)
125
+
126
+ load_dotenv(dotenv_path=env_path, override=True)
127
+ typer.echo()
128
+
129
+
130
+ def validate_storage_backend(storage: str | None) -> None:
131
+ """Validate and apply a storage backend selection.
132
+
133
+ If *storage* is not None, validates it against known backends and sets
134
+ the ``REFLEXIO_STORAGE`` environment variable.
135
+
136
+ .. deprecated::
137
+ Prefer :func:`reflexio.cli.bootstrap_config.resolve_storage` which
138
+ implements the full priority chain (CLI flag > env var > config > default)
139
+ and config file persistence.
140
+
141
+ Args:
142
+ storage: Storage backend name (e.g. ``"sqlite"``, ``"supabase"``),
143
+ or None to skip validation.
144
+
145
+ Raises:
146
+ typer.BadParameter: If *storage* is not a recognised backend.
147
+ """
148
+ if storage is None:
149
+ return
150
+ storage_lower = storage.lower()
151
+ if storage_lower not in _VALID_STORAGE_BACKENDS:
152
+ raise typer.BadParameter(
153
+ f"Invalid storage backend '{storage}'. "
154
+ f"Must be one of: {', '.join(sorted(_VALID_STORAGE_BACKENDS))}"
155
+ )
156
+ os.environ["REFLEXIO_STORAGE"] = storage_lower
157
+
158
+
159
+ @app.command()
160
+ def start(
161
+ backend_port: Annotated[
162
+ int | None, typer.Option(help="Backend server port (default: 8081)")
163
+ ] = None,
164
+ docs_port: Annotated[
165
+ int | None, typer.Option(help="Docs server port (default: 8082)")
166
+ ] = None,
167
+ embedding_port: Annotated[
168
+ int | None, typer.Option(help="Embedding service port (default: 8072)")
169
+ ] = None,
170
+ only: Annotated[
171
+ str | None,
172
+ typer.Option(help="Comma-separated services: backend,docs,embedding"),
173
+ ] = None,
174
+ no_reload: Annotated[
175
+ bool, typer.Option("--no-reload", help="Disable uvicorn auto-reload")
176
+ ] = False,
177
+ storage: Annotated[
178
+ str | None,
179
+ typer.Option(
180
+ help=(
181
+ "Storage backend to use (sqlite, supabase, or postgres). "
182
+ "See deployment docs for additional enterprise backends."
183
+ )
184
+ ),
185
+ ] = None,
186
+ workers: Annotated[
187
+ int,
188
+ typer.Option(
189
+ "--workers",
190
+ help=(
191
+ "Number of backend worker processes (daemon mode only). "
192
+ "Default 2 enables zero-downtime worker recycling."
193
+ ),
194
+ ),
195
+ ] = 2,
196
+ max_requests: Annotated[
197
+ int,
198
+ typer.Option(
199
+ "--max-requests",
200
+ help="Worker recycles after this many requests (0 disables). Default 10000.",
201
+ ),
202
+ ] = 10000,
203
+ max_requests_jitter: Annotated[
204
+ int,
205
+ typer.Option("--max-requests-jitter", help="Random 0..jitter per worker."),
206
+ ] = 1000,
207
+ graceful_shutdown_sec: Annotated[
208
+ int,
209
+ typer.Option(
210
+ "--graceful-shutdown-sec",
211
+ help="Seconds to drain in-flight requests on shutdown.",
212
+ ),
213
+ ] = 30,
214
+ ) -> None:
215
+ """Start Reflexio services (backend, docs)."""
216
+ from reflexio.cli.bootstrap_config import resolve_storage, save_storage_to_config
217
+ from reflexio.cli.env_loader import get_env_path, load_reflexio_env
218
+
219
+ # Load .env BEFORE resolve_storage so env vars from ~/.reflexio/.env
220
+ # (e.g. REFLEXIO_STORAGE=supabase) are visible to the resolution chain.
221
+ load_reflexio_env()
222
+
223
+ if (
224
+ not os.environ.get("REFLEXIO_EMBEDDING_PROVIDER")
225
+ and os.environ.get("CLAUDE_SMART_USE_LOCAL_EMBEDDING") == "1"
226
+ ):
227
+ os.environ["REFLEXIO_EMBEDDING_PROVIDER"] = "local_service"
228
+
229
+ selected_services = run_mod.parse_only_flag(only, {"backend", "docs"})
230
+
231
+ # First-run guard: if the backend's lifespan validator would reject the
232
+ # current env (no LLM key, or no embedding-capable provider), prompt now
233
+ # so users see a friendly wizard instead of a lifespan traceback.
234
+ if "backend" in selected_services:
235
+ _ensure_llm_configured(get_env_path())
236
+
237
+ resolved = resolve_storage(storage)
238
+ os.environ["REFLEXIO_STORAGE"] = resolved
239
+
240
+ # If user explicitly passed --storage, also persist to config and .env
241
+ if storage is not None:
242
+ save_storage_to_config(resolved)
243
+
244
+ from reflexio.cli.env_loader import set_env_var
245
+
246
+ env_path = get_env_path()
247
+ if env_path.exists():
248
+ set_env_var(env_path, "REFLEXIO_STORAGE", resolved)
249
+
250
+ args = argparse.Namespace(
251
+ backend_port=backend_port,
252
+ docs_port=docs_port,
253
+ embedding_port=embedding_port,
254
+ only=only,
255
+ no_reload=no_reload,
256
+ workers=workers,
257
+ max_requests=max_requests,
258
+ max_requests_jitter=max_requests_jitter,
259
+ graceful_shutdown_sec=graceful_shutdown_sec,
260
+ )
261
+ run_mod.execute(args)
262
+
263
+
264
+ @app.command()
265
+ def stop(
266
+ backend_port: Annotated[
267
+ int | None, typer.Option(help="Backend server port (default: 8081)")
268
+ ] = None,
269
+ docs_port: Annotated[
270
+ int | None, typer.Option(help="Docs server port (default: 8082)")
271
+ ] = None,
272
+ embedding_port: Annotated[
273
+ int | None, typer.Option(help="Embedding service port (default: 8072)")
274
+ ] = None,
275
+ only: Annotated[
276
+ str | None,
277
+ typer.Option(help="Comma-separated services: backend,docs,embedding"),
278
+ ] = None,
279
+ force: Annotated[bool, typer.Option("--force", help="SIGKILL immediately")] = False,
280
+ ) -> None:
281
+ """Stop Reflexio services."""
282
+ args = argparse.Namespace(
283
+ backend_port=backend_port,
284
+ docs_port=docs_port,
285
+ embedding_port=embedding_port,
286
+ only=only,
287
+ force=force,
288
+ )
289
+ stop_mod.execute(args)