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,112 @@
1
+ import inspect
2
+ from copy import deepcopy
3
+ from typing import Any
4
+
5
+ from pydantic import BaseModel
6
+
7
+ _STRICT_SCHEMA_UNSUPPORTED_KEYWORDS = frozenset(
8
+ {
9
+ "exclusiveMaximum",
10
+ "exclusiveMinimum",
11
+ "format",
12
+ "maxItems",
13
+ "maxLength",
14
+ "maxProperties",
15
+ "maximum",
16
+ "minItems",
17
+ "minLength",
18
+ "minProperties",
19
+ "minimum",
20
+ "multipleOf",
21
+ "pattern",
22
+ "patternProperties",
23
+ "propertyNames",
24
+ "uniqueItems",
25
+ }
26
+ )
27
+
28
+
29
+ def is_pydantic_model(response_format: Any) -> bool:
30
+ """
31
+ Check if response_format is a Pydantic BaseModel class.
32
+
33
+ Args:
34
+ response_format: Response format to check.
35
+
36
+ Returns:
37
+ True if response_format is a Pydantic BaseModel class, False otherwise.
38
+ """
39
+ return inspect.isclass(response_format) and issubclass(response_format, BaseModel)
40
+
41
+
42
+ def make_strict_json_schema(schema: dict[str, Any]) -> dict[str, Any]:
43
+ """Return a JSON schema shaped for strict structured-output decoding.
44
+
45
+ Strict structured-output providers generally require object schemas to
46
+ forbid extra keys and list all properties as required. Pydantic optional
47
+ fields are still preserved as nullable via their existing ``anyOf`` /
48
+ ``type: ["...", "null"]`` schema, so the model can emit ``null`` instead
49
+ of omitting the field. Provider-unsupported validation keywords are
50
+ removed from the request schema; Pydantic still enforces them after parse.
51
+ """
52
+
53
+ strict_schema = deepcopy(schema)
54
+
55
+ def visit(node: Any) -> None:
56
+ if not isinstance(node, dict):
57
+ return
58
+
59
+ node.pop("default", None)
60
+ for keyword in _STRICT_SCHEMA_UNSUPPORTED_KEYWORDS:
61
+ node.pop(keyword, None)
62
+
63
+ # Strict structured output (OpenAI) permits ``anyOf`` but rejects
64
+ # ``oneOf`` and ``discriminator``. Pydantic emits ``oneOf`` for
65
+ # discriminated unions; fold it into ``anyOf`` so generation is
66
+ # constrained to the same variants. Pydantic still enforces the
67
+ # discriminator after parse, so semantics are preserved.
68
+ one_of = node.pop("oneOf", None)
69
+ node.pop("discriminator", None)
70
+ if isinstance(one_of, list):
71
+ node["anyOf"] = node.get("anyOf", []) + one_of
72
+
73
+ properties = node.get("properties")
74
+ if isinstance(properties, dict):
75
+ node["additionalProperties"] = False
76
+ node["required"] = list(properties.keys())
77
+ for child in properties.values():
78
+ visit(child)
79
+ else:
80
+ additional = node.get("additionalProperties")
81
+ if isinstance(additional, dict):
82
+ visit(additional)
83
+
84
+ defs = node.get("$defs")
85
+ if isinstance(defs, dict):
86
+ for child in defs.values():
87
+ visit(child)
88
+
89
+ for key in ("items", "contains", "not"):
90
+ visit(node.get(key))
91
+
92
+ for key in ("anyOf", "allOf", "prefixItems"):
93
+ children = node.get(key)
94
+ if isinstance(children, list):
95
+ for child in children:
96
+ visit(child)
97
+
98
+ visit(strict_schema)
99
+ return strict_schema
100
+
101
+
102
+ def strict_response_format_for_model(model: type[BaseModel]) -> dict[str, Any]:
103
+ """Build a LiteLLM/OpenAI-compatible strict ``json_schema`` response format."""
104
+
105
+ return {
106
+ "type": "json_schema",
107
+ "json_schema": {
108
+ "name": model.__name__,
109
+ "schema": make_strict_json_schema(model.model_json_schema()),
110
+ "strict": True,
111
+ },
112
+ }
@@ -0,0 +1,469 @@
1
+ """Auto-detect available LLM providers and resolve default models by API key.
2
+
3
+ Resolution order (highest priority first):
4
+ 1. LLMConfig override (org-level configuration)
5
+ 2. llm_model_setting.json site var (non-empty string values)
6
+ 3. Auto-detect from available API keys in environment / APIKeyConfig
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import logging
12
+ import os
13
+ from dataclasses import dataclass
14
+ from enum import StrEnum
15
+ from typing import TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from reflexio.models.config_schema import APIKeyConfig
19
+
20
+ # Env var opting into the Claude Code CLI provider (registered in
21
+ # reflexio.server.llm.providers.claude_code_provider). When set to "1"
22
+ # *and* the active host CLI is available, the provider is auto-detected
23
+ # with highest priority — reflexio will route extraction/evaluation
24
+ # calls through the local CLI instead of requiring an API key.
25
+ _CLAUDE_CODE_ENABLE_ENV = "CLAUDE_SMART_USE_LOCAL_CLI"
26
+ _CLAUDE_CODE_PROVIDER = "claude-code"
27
+
28
+ # Companion provider key for the local ONNX embedder (registered in
29
+ # reflexio.server.llm.providers.local_embedding_provider). Surfaces in
30
+ # ``providers`` only when ``CLAUDE_SMART_USE_LOCAL_EMBEDDING=1`` is set
31
+ # (claude-smart's explicit opt-in); otherwise the embedding role still
32
+ # silently falls back to "local" when chromadb is importable but no
33
+ # cloud embedder is configured — see Path 3 in ``_auto_detect_model``.
34
+ _LOCAL_EMBEDDING_PROVIDER = "local"
35
+
36
+ logger = logging.getLogger(__name__)
37
+
38
+ # ---------------------------------------------------------------------------
39
+ # Provider detection
40
+ # ---------------------------------------------------------------------------
41
+
42
+ _ENV_TO_PROVIDER: dict[str, str] = {
43
+ "OPENAI_API_KEY": "openai",
44
+ "ANTHROPIC_API_KEY": "anthropic",
45
+ "GEMINI_API_KEY": "gemini",
46
+ "DEEPSEEK_API_KEY": "deepseek",
47
+ "OPENROUTER_API_KEY": "openrouter",
48
+ "MINIMAX_API_KEY": "minimax",
49
+ "DASHSCOPE_API_KEY": "dashscope",
50
+ "XAI_API_KEY": "xai",
51
+ "MOONSHOT_API_KEY": "moonshot",
52
+ "ZAI_API_KEY": "zai",
53
+ }
54
+
55
+ # When multiple keys are set, prefer providers in this order. The
56
+ # claude-code CLI provider sits at the top — when it's available, users
57
+ # are explicitly opting into local-auth extraction and should not be
58
+ # surprised by an OpenAI/Anthropic API bill from a leftover env var.
59
+ _PROVIDER_PRIORITY: list[str] = [
60
+ _CLAUDE_CODE_PROVIDER,
61
+ _LOCAL_EMBEDDING_PROVIDER,
62
+ "anthropic",
63
+ "gemini",
64
+ "openrouter",
65
+ "deepseek",
66
+ "minimax",
67
+ "dashscope",
68
+ "xai",
69
+ "moonshot",
70
+ "zai",
71
+ "openai",
72
+ ]
73
+
74
+ # Maps APIKeyConfig field names to provider keys (field name == provider key
75
+ # for all current providers, but kept explicit for clarity).
76
+ _API_KEY_CONFIG_FIELDS: dict[str, str] = {
77
+ "openai": "openai",
78
+ "anthropic": "anthropic",
79
+ "gemini": "gemini",
80
+ "deepseek": "deepseek",
81
+ "openrouter": "openrouter",
82
+ "minimax": "minimax",
83
+ "dashscope": "dashscope",
84
+ "xai": "xai",
85
+ "moonshot": "moonshot",
86
+ "zai": "zai",
87
+ }
88
+
89
+
90
+ def detect_available_providers(
91
+ api_key_config: APIKeyConfig | None = None,
92
+ ) -> list[str]:
93
+ """Detect available LLM providers from APIKeyConfig and/or environment variables.
94
+
95
+ Args:
96
+ api_key_config: Optional org-level API key configuration. Fields set here
97
+ take precedence over environment variables.
98
+
99
+ Returns:
100
+ list[str]: Available provider keys in priority order.
101
+ """
102
+ available: set[str] = set()
103
+
104
+ # Check APIKeyConfig fields
105
+ if api_key_config:
106
+ for field, provider in _API_KEY_CONFIG_FIELDS.items():
107
+ if getattr(api_key_config, field, None) is not None:
108
+ available.add(provider)
109
+
110
+ # Check environment variables
111
+ for env_var, provider in _ENV_TO_PROVIDER.items():
112
+ if os.environ.get(env_var):
113
+ available.add(provider)
114
+
115
+ # Claude Code CLI and the local ONNX embedder are opt-in via their
116
+ # own env vars + runtime requirements (`claude` on PATH for the CLI,
117
+ # `chromadb` installed for the embedder). Their availability helpers
118
+ # own the detection logic so there's one source of truth.
119
+ from reflexio.server.llm.providers.claude_code_provider import (
120
+ is_claude_code_available,
121
+ )
122
+ from reflexio.server.llm.providers.local_embedding_provider import (
123
+ is_local_embedder_available,
124
+ )
125
+
126
+ if is_claude_code_available():
127
+ available.add(_CLAUDE_CODE_PROVIDER)
128
+ if is_local_embedder_available():
129
+ available.add(_LOCAL_EMBEDDING_PROVIDER)
130
+
131
+ return [p for p in _PROVIDER_PRIORITY if p in available]
132
+
133
+
134
+ # ---------------------------------------------------------------------------
135
+ # Per-provider default models
136
+ # ---------------------------------------------------------------------------
137
+
138
+
139
+ @dataclass(frozen=True)
140
+ class ProviderDefaults:
141
+ """Default model names for a given provider.
142
+
143
+ Any field may be ``None`` for a role the provider does not support.
144
+ For example, the ``local`` ONNX embedder has no generation model;
145
+ the ``claude-code`` CLI has no embedding endpoint. ``_auto_detect_model``
146
+ falls through to the next provider in priority order when the
147
+ requested role is missing.
148
+
149
+ Args:
150
+ generation: Model for content generation, or None.
151
+ evaluation: Model for evaluation/scoring, or None.
152
+ should_run: Model for lightweight "should run extraction" checks, or None.
153
+ pre_retrieval: Model for pre-retrieval query reformulation, or None.
154
+ embedding: Model for embedding generation, or None.
155
+ extraction_agent: Sonnet-tier model for the resumable extraction loop, or None.
156
+ """
157
+
158
+ generation: str | None
159
+ evaluation: str | None
160
+ should_run: str | None
161
+ pre_retrieval: str | None
162
+ embedding: str | None
163
+ extraction_agent: str | None = None
164
+
165
+
166
+ _PROVIDER_DEFAULTS: dict[str, ProviderDefaults] = {
167
+ # claude-code routes through the local Claude Code CLI via LiteLLM's
168
+ # custom provider mechanism (see providers/claude_code_provider.py).
169
+ # The model-name suffix after "claude-code/" is opaque — the CLI
170
+ # picks whichever model the user has auth for.
171
+ _CLAUDE_CODE_PROVIDER: ProviderDefaults(
172
+ generation="claude-code/default",
173
+ evaluation="claude-code/default",
174
+ should_run="claude-code/default",
175
+ pre_retrieval="claude-code/default",
176
+ embedding=None,
177
+ extraction_agent="claude-code/default",
178
+ ),
179
+ # local is an embedding-only provider that routes through an
180
+ # in-process ONNX model (chromadb's all-MiniLM-L6-v2). Generation
181
+ # roles stay None — use claude-code for those.
182
+ _LOCAL_EMBEDDING_PROVIDER: ProviderDefaults(
183
+ generation=None,
184
+ evaluation=None,
185
+ should_run=None,
186
+ pre_retrieval=None,
187
+ embedding="local/minilm-l6-v2",
188
+ ),
189
+ "openai": ProviderDefaults(
190
+ generation="gpt-5-mini",
191
+ evaluation="gpt-5-mini",
192
+ should_run="gpt-5-nano",
193
+ pre_retrieval="gpt-5-nano",
194
+ embedding="text-embedding-3-small",
195
+ extraction_agent="gpt-5-mini",
196
+ ),
197
+ "anthropic": ProviderDefaults(
198
+ generation="claude-sonnet-4-6",
199
+ evaluation="claude-sonnet-4-6",
200
+ should_run="claude-haiku-4-5-20251001",
201
+ pre_retrieval="claude-haiku-4-5-20251001",
202
+ embedding=None,
203
+ extraction_agent="claude-sonnet-4-6",
204
+ ),
205
+ "gemini": ProviderDefaults(
206
+ generation="gemini/gemini-3-flash-preview",
207
+ evaluation="gemini/gemini-3-flash-preview",
208
+ should_run="gemini/gemini-3-flash-preview",
209
+ pre_retrieval="gemini/gemini-3-flash-preview",
210
+ embedding="gemini/gemini-embedding-001",
211
+ ),
212
+ "deepseek": ProviderDefaults(
213
+ generation="deepseek/deepseek-chat",
214
+ evaluation="deepseek/deepseek-chat",
215
+ should_run="deepseek/deepseek-chat",
216
+ pre_retrieval="deepseek/deepseek-chat",
217
+ embedding=None,
218
+ ),
219
+ "openrouter": ProviderDefaults(
220
+ generation="openrouter/google/gemini-3-flash-preview",
221
+ evaluation="openrouter/google/gemini-3-flash-preview",
222
+ should_run="openrouter/google/gemini-3-flash-preview",
223
+ pre_retrieval="openrouter/google/gemini-3-flash-preview",
224
+ embedding=None,
225
+ ),
226
+ "minimax": ProviderDefaults(
227
+ generation="minimax/MiniMax-M3",
228
+ evaluation="minimax/MiniMax-M3",
229
+ should_run="minimax/MiniMax-M3",
230
+ pre_retrieval="minimax/MiniMax-M3",
231
+ embedding=None,
232
+ # Same M2.7 model handles resumable extraction. Surfaced by an
233
+ # e2e run on a MiniMax-only VPS where publish printed
234
+ # "No provider in ['minimax'] supports role=extraction_agent"
235
+ # warnings and silently skipped profile creation. Without this,
236
+ # MiniMax-only users can publish but get zero profiles.
237
+ extraction_agent="minimax/MiniMax-M3",
238
+ ),
239
+ "dashscope": ProviderDefaults(
240
+ generation="dashscope/qwen-plus",
241
+ evaluation="dashscope/qwen-plus",
242
+ should_run="dashscope/qwen-turbo",
243
+ pre_retrieval="dashscope/qwen-turbo",
244
+ embedding=None,
245
+ ),
246
+ "xai": ProviderDefaults(
247
+ generation="xai/grok-3-mini",
248
+ evaluation="xai/grok-3-mini",
249
+ should_run="xai/grok-3-mini",
250
+ pre_retrieval="xai/grok-3-mini",
251
+ embedding=None,
252
+ ),
253
+ "moonshot": ProviderDefaults(
254
+ generation="moonshot/moonshot-v1-8k",
255
+ evaluation="moonshot/moonshot-v1-8k",
256
+ should_run="moonshot/moonshot-v1-8k",
257
+ pre_retrieval="moonshot/moonshot-v1-8k",
258
+ embedding=None,
259
+ ),
260
+ "zai": ProviderDefaults(
261
+ generation="zai/glm-5.1",
262
+ evaluation="zai/glm-5.1",
263
+ should_run="zai/glm-5.1",
264
+ pre_retrieval="zai/glm-5.1",
265
+ embedding=None,
266
+ ),
267
+ }
268
+
269
+
270
+ EMBEDDING_CAPABLE_PROVIDERS: frozenset[str] = frozenset(
271
+ p for p, d in _PROVIDER_DEFAULTS.items() if d.embedding is not None
272
+ )
273
+
274
+
275
+ GENERATION_CAPABLE_PROVIDERS: frozenset[str] = frozenset(
276
+ p for p, d in _PROVIDER_DEFAULTS.items() if d.generation is not None
277
+ )
278
+
279
+
280
+ def _local_cli_provider_hint() -> str:
281
+ return (
282
+ f"or set {_CLAUDE_CODE_ENABLE_ENV}=1 with the active host CLI "
283
+ "(claude for Claude Code, codex for Codex) available."
284
+ )
285
+
286
+
287
+ # ---------------------------------------------------------------------------
288
+ # Model role enum and resolution
289
+ # ---------------------------------------------------------------------------
290
+
291
+
292
+ class ModelRole(StrEnum):
293
+ """Roles that require an LLM model name."""
294
+
295
+ GENERATION = "generation"
296
+ EVALUATION = "evaluation"
297
+ SHOULD_RUN = "should_run"
298
+ PRE_RETRIEVAL = "pre_retrieval"
299
+ EMBEDDING = "embedding"
300
+ # Sonnet-tier agent that drives the resumable extraction tool loop.
301
+ EXTRACTION_AGENT = "extraction_agent"
302
+
303
+
304
+ def _auto_detect_model(
305
+ role: ModelRole,
306
+ providers: list[str],
307
+ ) -> str:
308
+ """Pick the default model for *role* from the first available provider.
309
+
310
+ For the EMBEDDING role, if the primary provider has no embedding support,
311
+ search the remaining providers for one that does.
312
+
313
+ Args:
314
+ role: The model role to resolve.
315
+ providers: Available providers in priority order.
316
+
317
+ Returns:
318
+ str: The resolved model name.
319
+
320
+ Raises:
321
+ RuntimeError: If no suitable provider is found.
322
+ """
323
+ if not providers:
324
+ raise RuntimeError(
325
+ "No LLM provider available. Set at least one of: "
326
+ + ", ".join(sorted(_ENV_TO_PROVIDER))
327
+ + f" in your .env file, {_local_cli_provider_hint()}"
328
+ )
329
+
330
+ if role == ModelRole.EMBEDDING:
331
+ # Path 1+2: explicit claude-smart opt-in or a cloud embedder. The
332
+ # priority list places `local` at position 2, so when the env var is
333
+ # set ``providers`` already contains "local" and this loop returns it
334
+ # before any cloud provider. When the env var is unset, only cloud
335
+ # providers can hit here (local is filtered out by
336
+ # ``is_local_embedder_available``).
337
+ for provider in providers:
338
+ defaults = _PROVIDER_DEFAULTS[provider]
339
+ if defaults.embedding:
340
+ return defaults.embedding
341
+ # Path 3: no embedding-capable provider in `providers`, but chromadb
342
+ # is importable — silently fall back to the local ONNX embedder so
343
+ # users with only a non-embedding LLM key (Anthropic, MiniMax, etc.)
344
+ # are not blocked at startup.
345
+ from reflexio.server.llm.providers.local_embedding_provider import (
346
+ is_chromadb_importable,
347
+ )
348
+
349
+ if is_chromadb_importable():
350
+ return _PROVIDER_DEFAULTS[_LOCAL_EMBEDDING_PROVIDER].embedding # type: ignore[return-value]
351
+ raise RuntimeError(
352
+ "No embedding-capable provider configured and chromadb is not "
353
+ "importable. Set OPENAI_API_KEY or GEMINI_API_KEY, or "
354
+ "`pip install chromadb`."
355
+ )
356
+
357
+ # Non-embedding roles: fall through to the first provider whose slot
358
+ # for this role is non-None. Lets embedding-only providers (e.g.
359
+ # "local") sit in the priority list without breaking generation.
360
+ for provider in providers:
361
+ defaults = _PROVIDER_DEFAULTS[provider]
362
+ model_name = getattr(defaults, role.value)
363
+ if model_name:
364
+ return model_name
365
+ raise RuntimeError(f"No provider in {providers} supports role={role.value}.")
366
+
367
+
368
+ def resolve_model_name(
369
+ role: ModelRole,
370
+ *,
371
+ site_var_value: str | None = None,
372
+ config_override: str | None = None,
373
+ api_key_config: APIKeyConfig | None = None,
374
+ ) -> str:
375
+ """Resolve a model name using the 3-tier chain.
376
+
377
+ Resolution order (highest priority first):
378
+ 1. config_override (from LLMConfig, org-level)
379
+ 2. site_var_value (from llm_model_setting.json, non-empty strings only)
380
+ 3. Auto-detect from available API keys
381
+
382
+ Args:
383
+ role: The model role to resolve.
384
+ site_var_value: Value from llm_model_setting.json. Empty strings are treated as unset.
385
+ config_override: Value from org-level LLMConfig.
386
+ api_key_config: Optional org-level API key configuration for provider detection.
387
+
388
+ Returns:
389
+ str: The resolved model name.
390
+
391
+ Raises:
392
+ RuntimeError: If no API keys are available and no override is set.
393
+ """
394
+ if config_override:
395
+ return config_override
396
+ if site_var_value:
397
+ return site_var_value
398
+ providers = detect_available_providers(api_key_config)
399
+ return _auto_detect_model(role, providers)
400
+
401
+
402
+ def validate_llm_availability(
403
+ api_key_config: APIKeyConfig | None = None,
404
+ ) -> None:
405
+ """Validate that at least one LLM provider and one embedding provider are available.
406
+
407
+ Should be called once during startup. Logs the auto-selected provider at INFO level.
408
+
409
+ Args:
410
+ api_key_config: Optional org-level API key configuration.
411
+
412
+ Raises:
413
+ RuntimeError: If no API keys are found, or if no embedding-capable provider is available.
414
+ """
415
+ providers = detect_available_providers(api_key_config)
416
+ if not providers:
417
+ raise RuntimeError(
418
+ "No LLM provider available. Set at least one of: "
419
+ + ", ".join(sorted(_ENV_TO_PROVIDER))
420
+ + f" in your .env file, {_local_cli_provider_hint()}"
421
+ )
422
+
423
+ logger.info("Auto-detected LLM providers (priority order): %s", providers)
424
+ generation_provider = next(
425
+ (p for p in providers if _PROVIDER_DEFAULTS[p].generation), None
426
+ )
427
+ if generation_provider is None:
428
+ # Configurations that surface only embedding-capable providers
429
+ # (e.g. ``providers == ["local"]`` from chromadb being importable
430
+ # but no LLM key set) leave every generation-role lookup
431
+ # unresolvable. Failing here means the next reflexio call would
432
+ # raise "No provider supports role=generation" deep inside the
433
+ # extraction pipeline; we'd rather raise at startup with the
434
+ # same actionable message users hit when no providers are
435
+ # detected at all.
436
+ raise RuntimeError(
437
+ "No generation-capable LLM provider available. Set at least "
438
+ "one of: "
439
+ + ", ".join(sorted(_ENV_TO_PROVIDER))
440
+ + f" in your .env file, {_local_cli_provider_hint()}"
441
+ )
442
+ logger.info("Primary provider for generation: %s", generation_provider)
443
+
444
+ # Validate embedding availability. When no embedding-capable provider
445
+ # is configured, fall back to the in-process local ONNX embedder if
446
+ # chromadb is importable — this keeps users with only a non-embedding
447
+ # LLM key (Anthropic, MiniMax, etc.) from being blocked at startup.
448
+ embedding_provider = next(
449
+ (p for p in providers if _PROVIDER_DEFAULTS[p].embedding), None
450
+ )
451
+ if embedding_provider:
452
+ logger.info("Embedding provider: %s", embedding_provider)
453
+ return
454
+
455
+ from reflexio.server.llm.providers.local_embedding_provider import (
456
+ is_chromadb_importable,
457
+ )
458
+
459
+ if is_chromadb_importable():
460
+ logger.info(
461
+ "Embedding provider: %s (fallback — no cloud embedder configured)",
462
+ _LOCAL_EMBEDDING_PROVIDER,
463
+ )
464
+ return
465
+ raise RuntimeError(
466
+ "No embedding-capable provider configured and chromadb is not "
467
+ "importable. Set OPENAI_API_KEY or GEMINI_API_KEY, or "
468
+ "`pip install chromadb`."
469
+ )
@@ -0,0 +1 @@
1
+ """Custom LiteLLM providers registered by reflexio."""