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,127 @@
1
+ """Diagnostic health check command."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from typing import Any
7
+
8
+ import requests
9
+ import typer
10
+
11
+ from reflexio.cli.env_loader import get_env_path
12
+ from reflexio.cli.errors import handle_errors
13
+ from reflexio.cli.output import print_doctor_checks, render
14
+ from reflexio.cli.state import resolve_api_key, resolve_url
15
+
16
+ app = typer.Typer(help="Diagnose Reflexio setup.")
17
+
18
+
19
+ @app.command("check")
20
+ @handle_errors
21
+ def doctor(ctx: typer.Context) -> None:
22
+ """Run diagnostic checks on Reflexio configuration and connectivity."""
23
+ json_mode = ctx.obj.json_mode
24
+ state = ctx.obj
25
+ checks: list[dict[str, Any]] = []
26
+
27
+ # 1. Env file
28
+ env_path = get_env_path()
29
+ env_exists = env_path.exists()
30
+ checks.append(
31
+ {
32
+ "name": "env_file",
33
+ "status": "pass" if env_exists else "warn",
34
+ "message": f"Env file at {env_path}"
35
+ if env_exists
36
+ else f"No env file at {env_path}",
37
+ "hint": None
38
+ if env_exists
39
+ else "Run: reflexio auth login --api-key KEY --server-url URL",
40
+ }
41
+ )
42
+
43
+ # 2. Resolve connection info
44
+ url = resolve_url(state.server_url)
45
+ api_key = resolve_api_key(state.api_key)
46
+
47
+ has_key = bool(api_key)
48
+ checks.append(
49
+ {
50
+ "name": "api_key",
51
+ "status": "pass" if has_key else "warn",
52
+ "message": f"API key configured (****{api_key[-4:]})"
53
+ if has_key
54
+ else "No API key configured",
55
+ "hint": None
56
+ if has_key
57
+ else "Set REFLEXIO_API_KEY env var or run: reflexio auth login --api-key KEY",
58
+ }
59
+ )
60
+
61
+ # 3. Server connectivity
62
+ headers: dict[str, str] = {}
63
+ if api_key:
64
+ headers["Authorization"] = f"Bearer {api_key}"
65
+
66
+ try:
67
+ resp = requests.get(f"{url.rstrip('/')}/health", headers=headers, timeout=10)
68
+ resp.raise_for_status()
69
+ data = resp.json()
70
+ status = data.get("status", "unknown")
71
+ checks.append(
72
+ {
73
+ "name": "server_health",
74
+ "status": "pass" if status == "healthy" else "warn",
75
+ "message": f"Server at {url} is {status}",
76
+ "hint": None,
77
+ }
78
+ )
79
+ except requests.ConnectionError:
80
+ is_remote = url and "localhost" not in url and "127.0.0.1" not in url
81
+ hint = (
82
+ "Check your API key and network connection, or verify the server URL"
83
+ if is_remote
84
+ else "Start the server: reflexio services start"
85
+ )
86
+ checks.append(
87
+ {
88
+ "name": "server_health",
89
+ "status": "fail",
90
+ "message": f"Cannot connect to {url}",
91
+ "hint": hint,
92
+ }
93
+ )
94
+ except requests.HTTPError as exc:
95
+ code = exc.response.status_code if exc.response is not None else 0
96
+ checks.append(
97
+ {
98
+ "name": "server_health",
99
+ "status": "fail",
100
+ "message": f"Server returned HTTP {code}",
101
+ "hint": "Check server logs for details",
102
+ }
103
+ )
104
+
105
+ # 4. Python version
106
+ py_version = (
107
+ f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
108
+ )
109
+ checks.append(
110
+ {
111
+ "name": "python_version",
112
+ "status": "pass" if sys.version_info >= (3, 12) else "warn",
113
+ "message": f"Python {py_version}",
114
+ "hint": None if sys.version_info >= (3, 12) else "Python 3.12+ recommended",
115
+ }
116
+ )
117
+
118
+ # Render output
119
+ if json_mode:
120
+ all_pass = all(c["status"] == "pass" for c in checks)
121
+ render(checks, json_mode=True, meta={"all_pass": all_pass})
122
+ else:
123
+ print_doctor_checks(checks)
124
+
125
+ fails = sum(1 for c in checks if c["status"] == "fail")
126
+ if fails:
127
+ raise SystemExit(1)
@@ -0,0 +1,53 @@
1
+ """Embedding service commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Annotated
7
+
8
+ import typer
9
+ import uvicorn
10
+
11
+ app = typer.Typer(help="Run Reflexio embedding services.")
12
+
13
+ _DEFAULT_EMBEDDING_PORT = 8072
14
+
15
+
16
+ def _resolve_port(port: int | None) -> int:
17
+ if port is not None:
18
+ return port
19
+
20
+ raw_port = os.environ.get("EMBEDDING_PORT")
21
+ if raw_port is None:
22
+ return _DEFAULT_EMBEDDING_PORT
23
+
24
+ try:
25
+ return int(raw_port)
26
+ except ValueError:
27
+ typer.echo(
28
+ f"Warning: invalid EMBEDDING_PORT={raw_port!r}; "
29
+ f"using default {_DEFAULT_EMBEDDING_PORT}",
30
+ err=True,
31
+ )
32
+ return _DEFAULT_EMBEDDING_PORT
33
+
34
+
35
+ @app.command()
36
+ def serve(
37
+ host: Annotated[
38
+ str,
39
+ typer.Option(help="Host interface for the embedding daemon."),
40
+ ] = "127.0.0.1",
41
+ port: Annotated[
42
+ int | None,
43
+ typer.Option(help="Embedding service port (default: EMBEDDING_PORT or 8072)."),
44
+ ] = None,
45
+ ) -> None:
46
+ """Serve an OpenAI-compatible local embedding endpoint."""
47
+ resolved_port = _resolve_port(port)
48
+ uvicorn.run(
49
+ "reflexio.server.llm.embedding_service:app",
50
+ host=host,
51
+ port=resolved_port,
52
+ log_level="info",
53
+ )
@@ -0,0 +1,478 @@
1
+ """Manage interactions (conversations) via the Reflexio CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import sys
8
+ from pathlib import Path
9
+ from typing import Annotated
10
+
11
+ import typer
12
+
13
+ from reflexio.cli.errors import EXIT_VALIDATION, CliError, handle_errors
14
+ from reflexio.cli.output import (
15
+ pagination_meta,
16
+ print_error,
17
+ print_info,
18
+ print_interactions,
19
+ render,
20
+ )
21
+ from reflexio.cli.state import get_client, require_user_id, resolve_agent_version
22
+ from reflexio.models.api_schema.service_schemas import (
23
+ InteractionData,
24
+ PublishUserInteractionResponse,
25
+ )
26
+
27
+ app = typer.Typer(help="Manage interactions (conversations).")
28
+
29
+
30
+ # ---------------------------------------------------------------------------
31
+ # Helpers (ported from capture.py)
32
+ # ---------------------------------------------------------------------------
33
+
34
+
35
+ def _parse_json_payload(raw: str) -> list[dict]:
36
+ """Parse JSON or JSONL text into a list of conversation payloads.
37
+
38
+ Args:
39
+ raw (str): Raw JSON or JSONL string.
40
+
41
+ Returns:
42
+ list[dict]: List of parsed payload dicts, each containing an
43
+ ``interactions`` key at minimum.
44
+
45
+ Raises:
46
+ CliError: If the input is empty or contains invalid JSON.
47
+ """
48
+ stripped = raw.strip()
49
+ if not stripped:
50
+ raise CliError(
51
+ error_type="validation",
52
+ message="Empty input",
53
+ exit_code=EXIT_VALIDATION,
54
+ )
55
+
56
+ # Try single JSON object/array first
57
+ try:
58
+ data = json.loads(stripped)
59
+ if isinstance(data, dict):
60
+ return [data]
61
+ if isinstance(data, list):
62
+ if not all(isinstance(item, dict) for item in data):
63
+ raise CliError(
64
+ error_type="validation",
65
+ message="JSON array elements must be objects, not primitives",
66
+ exit_code=EXIT_VALIDATION,
67
+ )
68
+ return data
69
+ except json.JSONDecodeError:
70
+ pass
71
+
72
+ # Fall back to JSONL (one JSON object per line)
73
+ payloads: list[dict] = []
74
+ for lineno, line in enumerate(stripped.splitlines(), start=1):
75
+ line = line.strip()
76
+ if not line:
77
+ continue
78
+ try:
79
+ payloads.append(json.loads(line))
80
+ except json.JSONDecodeError as exc:
81
+ raise CliError(
82
+ error_type="validation",
83
+ message=f"Invalid JSON on line {lineno}: {exc}",
84
+ exit_code=EXIT_VALIDATION,
85
+ ) from exc
86
+ return payloads
87
+
88
+
89
+ def _interactions_from_payload(payload: dict) -> list[InteractionData]:
90
+ """Convert a payload dict into a list of InteractionData objects.
91
+
92
+ Forwards ``tools_used`` (and any other InteractionData field) from each
93
+ item so structured tool-call metadata reaches the server renderer that
94
+ emits ``[used tool: ...]`` markers for playbook extraction.
95
+
96
+ Args:
97
+ payload (dict): Payload with an ``interactions`` list of dicts.
98
+ Each item may include ``role``, ``content``, ``tools_used``,
99
+ and other ``InteractionData`` fields.
100
+
101
+ Returns:
102
+ list[InteractionData]: Parsed interaction data objects.
103
+
104
+ Raises:
105
+ CliError: If the payload is missing the ``interactions`` list or
106
+ any item fails ``InteractionData`` validation.
107
+ """
108
+ raw_interactions = payload.get("interactions", [])
109
+ if not raw_interactions:
110
+ raise CliError(
111
+ error_type="validation",
112
+ message="Payload missing 'interactions' list",
113
+ exit_code=EXIT_VALIDATION,
114
+ )
115
+ try:
116
+ return [InteractionData(**item) for item in raw_interactions]
117
+ except (TypeError, ValueError) as exc:
118
+ raise CliError(
119
+ error_type="validation",
120
+ message=f"Invalid interaction data: {exc}",
121
+ exit_code=EXIT_VALIDATION,
122
+ ) from exc
123
+
124
+
125
+ def _read_data_arg(data: str) -> str:
126
+ """Read inline JSON or from a file path prefixed with ``@``.
127
+
128
+ Args:
129
+ data (str): JSON string, or ``@filepath`` to read from disk.
130
+
131
+ Returns:
132
+ str: Raw JSON content.
133
+
134
+ Raises:
135
+ CliError: If the referenced file does not exist.
136
+ """
137
+ if data.startswith("@"):
138
+ path = Path(data[1:])
139
+ if not path.exists():
140
+ raise CliError(
141
+ error_type="validation",
142
+ message=f"File not found: {path}",
143
+ exit_code=EXIT_VALIDATION,
144
+ )
145
+ return path.read_text()
146
+ return data
147
+
148
+
149
+ _MAX_WARNING_LEN = 240
150
+
151
+
152
+ def _oneline(text: str, max_len: int = _MAX_WARNING_LEN) -> str:
153
+ """Collapse newlines and truncate so a pathological server message
154
+ can't dump a multi-line stack trace into the CLI output.
155
+
156
+ The server's generation service appends free-form exception
157
+ strings into ``warnings``, and historically some backends
158
+ embedded tracebacks in ``StorageError.message``. Even after we
159
+ fix those on the server side, this helper is a belt-and-
160
+ suspenders guard so a future regression can't turn ``reflexio
161
+ publish`` into a terminal dump.
162
+ """
163
+ collapsed = " ".join(text.split())
164
+ if len(collapsed) <= max_len:
165
+ return collapsed
166
+ return collapsed[: max_len - 1] + "…"
167
+
168
+
169
+ def _print_publish_result(result: PublishUserInteractionResponse, user_id: str) -> None:
170
+ """Print human-readable publish result with diagnostics.
171
+
172
+ Surfaces storage routing + extraction counts so users can tell *where*
173
+ their publish landed and *what* the extraction produced, not just that
174
+ the call returned 200. Degrades gracefully when the server hasn't
175
+ populated the diagnostic fields (server-async mode, which only returns a
176
+ bare acknowledgement instead of counts + request_id + storage routing).
177
+ """
178
+ message = _oneline(result.message or "")
179
+ warnings = result.warnings or []
180
+
181
+ if not result.success:
182
+ print_error(f"Publish failed for {user_id}: {message}")
183
+ for warning in warnings:
184
+ print_error(f" Warning: {_oneline(warning)}")
185
+ return
186
+
187
+ header = f"Published ({user_id})"
188
+ if message and message != "Interaction published successfully":
189
+ header = f"{header}: {message}"
190
+ print_info(header)
191
+
192
+ storage_type = getattr(result, "storage_type", None)
193
+ storage_label = getattr(result, "storage_label", None)
194
+ if storage_type or storage_label:
195
+ label = storage_label or "<unknown>"
196
+ kind = storage_type or "?"
197
+ print_info(f" Storage: {kind} → {label}")
198
+
199
+ profiles_added = getattr(result, "profiles_added", None)
200
+ playbooks_added = getattr(result, "playbooks_added", None)
201
+ if profiles_added is not None or playbooks_added is not None:
202
+ parts: list[str] = []
203
+ if profiles_added is not None:
204
+ parts.append(f"{profiles_added} profile(s) added")
205
+ if playbooks_added is not None:
206
+ parts.append(f"{playbooks_added} playbook(s) added")
207
+ print_info(f" Extraction: {', '.join(parts)}")
208
+
209
+ request_id = getattr(result, "request_id", None)
210
+ if request_id:
211
+ print_info(f" Request ID: {request_id}")
212
+
213
+ for warning in warnings:
214
+ print_error(f" Warning: {_oneline(warning)}")
215
+
216
+
217
+ # ---------------------------------------------------------------------------
218
+ # Commands
219
+ # ---------------------------------------------------------------------------
220
+
221
+
222
+ @app.command()
223
+ @handle_errors
224
+ def publish(
225
+ ctx: typer.Context,
226
+ user_id: Annotated[
227
+ str | None,
228
+ typer.Option(
229
+ help=(
230
+ "User identifier. Falls back to REFLEXIO_USER_ID env var "
231
+ "or 'user_id' inside --file/--data payload."
232
+ )
233
+ ),
234
+ ] = None,
235
+ session_id: Annotated[
236
+ str | None, typer.Option(help="Session ID for grouping")
237
+ ] = None,
238
+ source: Annotated[str, typer.Option(help="Source tag")] = "cli",
239
+ agent_version: Annotated[
240
+ str | None, typer.Option(help="Agent version string")
241
+ ] = None,
242
+ wait: Annotated[
243
+ bool, typer.Option(help="Block until processing completes")
244
+ ] = False,
245
+ data: Annotated[str | None, typer.Option(help="JSON string or @filepath")] = None,
246
+ file: Annotated[Path | None, typer.Option(help="Path to JSON/JSONL file")] = None,
247
+ stdin: Annotated[bool, typer.Option(help="Read JSON data from stdin")] = False,
248
+ user_message: Annotated[
249
+ str | None, typer.Option(help="Single-turn user message")
250
+ ] = None,
251
+ agent_response: Annotated[
252
+ str | None, typer.Option(help="Single-turn agent response")
253
+ ] = None,
254
+ skip_aggregation: Annotated[
255
+ bool,
256
+ typer.Option(
257
+ "--skip-aggregation",
258
+ help="Extract profiles/playbooks but skip aggregation to agent playbooks",
259
+ ),
260
+ ] = False,
261
+ force_extraction: Annotated[
262
+ bool,
263
+ typer.Option(
264
+ "--force-extraction",
265
+ help="Bypass all extraction gates (stride_size, cheap pre-filter, LLM should_run) and always run extractors",
266
+ ),
267
+ ] = False,
268
+ override_learning_stall: Annotated[
269
+ bool,
270
+ typer.Option(
271
+ "--override-learning-stall",
272
+ help="Run extraction even when a provider auth/billing stall is recorded. Use only for explicit retries after reauth or limit reset.",
273
+ ),
274
+ ] = False,
275
+ ) -> None:
276
+ """Publish interaction data for a user.
277
+
278
+ Supports three input modes:
279
+ 1. ``--user-message`` + ``--agent-response`` for single-turn conversations.
280
+ 2. ``--file`` or ``--stdin`` for JSON/JSONL payloads.
281
+ 3. ``--data`` for inline JSON (prefix with ``@`` for a file path).
282
+ """
283
+ client = get_client(ctx)
284
+ json_mode: bool = ctx.obj.json_mode
285
+
286
+ # Announce the endpoint + wait mode up-front (stderr, non-JSON only) so
287
+ # users can tell which server they're hitting before anything happens.
288
+ if not json_mode:
289
+ # The label refers to the *server* extraction mode: "sync" waits
290
+ # for extraction to finish before returning real counts; "async"
291
+ # queues extraction as a server BackgroundTask and returns
292
+ # immediately. The client always blocks on the HTTP round-trip
293
+ # in both cases.
294
+ mode_label = "server-sync" if wait else "server-async"
295
+ print_info(f"Publishing to {client.base_url} ({mode_label})")
296
+
297
+ # Mode 1: single-turn
298
+ if user_message is not None:
299
+ if agent_response is None:
300
+ raise CliError(
301
+ error_type="validation",
302
+ message="--agent-response is required with --user-message",
303
+ exit_code=EXIT_VALIDATION,
304
+ )
305
+ if user_id is None:
306
+ user_id = os.environ.get("REFLEXIO_USER_ID")
307
+ if user_id is None:
308
+ raise CliError(
309
+ error_type="validation",
310
+ message="--user-id is required with --user-message (or set REFLEXIO_USER_ID)",
311
+ exit_code=EXIT_VALIDATION,
312
+ )
313
+ interactions: list[InteractionData | dict] = [
314
+ InteractionData(role="user", content=user_message),
315
+ InteractionData(role="assistant", content=agent_response),
316
+ ]
317
+ result = client.publish_interaction(
318
+ user_id=user_id,
319
+ interactions=interactions,
320
+ source=source,
321
+ agent_version=resolve_agent_version(agent_version),
322
+ session_id=session_id,
323
+ wait_for_response=wait,
324
+ skip_aggregation=skip_aggregation,
325
+ force_extraction=force_extraction,
326
+ override_learning_stall=override_learning_stall,
327
+ )
328
+ if json_mode:
329
+ render(result, json_mode=True)
330
+ else:
331
+ _print_publish_result(result, user_id)
332
+ return
333
+
334
+ # Determine raw JSON from --data, --file, or --stdin
335
+ raw: str | None = None
336
+ if data is not None:
337
+ raw = _read_data_arg(data)
338
+ elif file is not None:
339
+ if not file.exists():
340
+ raise CliError(
341
+ error_type="validation",
342
+ message=f"File not found: {file}",
343
+ exit_code=EXIT_VALIDATION,
344
+ )
345
+ raw = file.read_text()
346
+ elif stdin:
347
+ raw = sys.stdin.read()
348
+
349
+ if raw is None:
350
+ raise CliError(
351
+ error_type="validation",
352
+ message="Specify --user-message/--agent-response, --file, --stdin, or --data",
353
+ exit_code=EXIT_VALIDATION,
354
+ )
355
+
356
+ payloads = _parse_json_payload(raw)
357
+ print_info(f"Processing {len(payloads)} payload(s)...")
358
+
359
+ resolved_version = resolve_agent_version(agent_version)
360
+ for payload in payloads:
361
+ interaction_items = _interactions_from_payload(payload)
362
+ resolved_user_id = (
363
+ payload.get("user_id") or user_id or os.environ.get("REFLEXIO_USER_ID")
364
+ )
365
+ if not resolved_user_id:
366
+ raise CliError(
367
+ error_type="validation",
368
+ message=(
369
+ "--user-id is required (or include 'user_id' in the JSON "
370
+ "payload, or set REFLEXIO_USER_ID)"
371
+ ),
372
+ exit_code=EXIT_VALIDATION,
373
+ )
374
+ result = client.publish_interaction(
375
+ user_id=resolved_user_id,
376
+ interactions=interaction_items, # type: ignore[arg-type]
377
+ source=payload.get("source", source),
378
+ agent_version=payload.get("agent_version", resolved_version),
379
+ session_id=payload.get("session_id", session_id),
380
+ wait_for_response=wait,
381
+ skip_aggregation=payload.get("skip_aggregation", skip_aggregation),
382
+ force_extraction=payload.get("force_extraction", force_extraction),
383
+ override_learning_stall=payload.get(
384
+ "override_learning_stall", override_learning_stall
385
+ ),
386
+ )
387
+ if json_mode:
388
+ render(result, json_mode=True)
389
+ else:
390
+ uid = payload.get("user_id", user_id)
391
+ _print_publish_result(result, uid)
392
+
393
+
394
+ @app.command(name="list")
395
+ @handle_errors
396
+ def list_interactions(
397
+ ctx: typer.Context,
398
+ user_id: Annotated[str | None, typer.Option(help="Filter by user ID")] = None,
399
+ limit: Annotated[
400
+ int, typer.Option(help="Maximum number of interactions to return")
401
+ ] = 20,
402
+ ) -> None:
403
+ """List interactions, optionally filtered by user."""
404
+ client = get_client(ctx)
405
+ resolved_user_id = require_user_id(user_id, command_hint="interactions list")
406
+ result = client.get_interactions(user_id=resolved_user_id, top_k=limit)
407
+ interactions = result.interactions or []
408
+
409
+ json_mode: bool = ctx.obj.json_mode
410
+ if json_mode:
411
+ render(interactions, json_mode=True, meta=pagination_meta(interactions, limit))
412
+ else:
413
+ print_info(f"Found {len(interactions)} interaction(s)")
414
+ if interactions:
415
+ print_interactions(interactions)
416
+
417
+
418
+ @app.command()
419
+ @handle_errors
420
+ def search(
421
+ ctx: typer.Context,
422
+ query: Annotated[str, typer.Option(help="Search query string")],
423
+ user_id: Annotated[str | None, typer.Option(help="Filter by user ID")] = None,
424
+ limit: Annotated[int, typer.Option(help="Maximum number of results")] = 10,
425
+ ) -> None:
426
+ """Search interactions by semantic query."""
427
+ client = get_client(ctx)
428
+ result = client.search_interactions(query=query, user_id=user_id, top_k=limit)
429
+ interactions = result.interactions or []
430
+
431
+ json_mode: bool = ctx.obj.json_mode
432
+ if json_mode:
433
+ render(interactions, json_mode=True, meta=pagination_meta(interactions, limit))
434
+ else:
435
+ print_info(f"Found {len(interactions)} interaction(s)")
436
+ if interactions:
437
+ print_interactions(interactions)
438
+
439
+
440
+ @app.command()
441
+ @handle_errors
442
+ def delete(
443
+ ctx: typer.Context,
444
+ interaction_id: Annotated[str, typer.Option(help="Interaction ID to delete")],
445
+ user_id: Annotated[str, typer.Option(help="User ID that owns the interaction")],
446
+ ) -> None:
447
+ """Delete a single interaction by ID."""
448
+ client = get_client(ctx)
449
+ result = client.delete_interaction(
450
+ user_id=user_id,
451
+ interaction_id=interaction_id,
452
+ wait_for_response=True,
453
+ )
454
+ json_mode: bool = ctx.obj.json_mode
455
+ if json_mode:
456
+ render(result, json_mode=True)
457
+ else:
458
+ print_info(f"Deleted interaction {interaction_id}")
459
+
460
+
461
+ @app.command(name="delete-all")
462
+ @handle_errors
463
+ def delete_all(
464
+ ctx: typer.Context,
465
+ yes: Annotated[
466
+ bool, typer.Option("--yes", "-y", help="Skip confirmation prompt")
467
+ ] = False,
468
+ ) -> None:
469
+ """Delete ALL interactions. This cannot be undone."""
470
+ if not yes:
471
+ typer.confirm("Delete all interactions? This cannot be undone", abort=True)
472
+ client = get_client(ctx)
473
+ result = client.delete_all_interactions()
474
+ json_mode: bool = ctx.obj.json_mode
475
+ if json_mode:
476
+ render(result, json_mode=True)
477
+ else:
478
+ print_info("All interactions deleted")