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,9 @@
1
+ # Backward compatibility — all models are now organized in domain/ and ui/ subpackages.
2
+ # Import from those packages directly for new code:
3
+ # from reflexio.models.api_schema.domain import Interaction, UserProfile, ...
4
+ # from reflexio.models.api_schema.ui import InteractionView, ProfileView, ...
5
+
6
+ # ruff: noqa: I001 — import order is deliberate: domain enums must shadow ui enums
7
+ from .common import * # noqa: F401, F403
8
+ from .ui import * # noqa: F401, F403
9
+ from .domain import * # noqa: F401, F403
@@ -0,0 +1,32 @@
1
+ """Pydantic models for the stall_state HTTP endpoint."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from datetime import datetime
6
+ from typing import Literal
7
+
8
+ from pydantic import BaseModel, Field
9
+
10
+ StallReason = Literal["billing_error", "auth_error"]
11
+ """Canonical stall-reason discriminator.
12
+
13
+ Imported by the storage layer (``sqlite_storage._stall_state``) and the
14
+ LiteLLM provider's stream parser so all three layers share one source of
15
+ truth for the allowed values."""
16
+
17
+
18
+ class StallStateResponse(BaseModel):
19
+ """Returned by GET /stall_state."""
20
+
21
+ stalled: bool = Field(..., description="True when learning is currently paused.")
22
+ reason: StallReason | None = None
23
+ stalled_at: datetime | None = None
24
+ reset_estimate: datetime | None = None
25
+ notified_in_cc: bool = False
26
+ error_message: str | None = None
27
+
28
+
29
+ class MarkNotifiedResponse(BaseModel):
30
+ """Returned by POST /stall_state/notified."""
31
+
32
+ notified_in_cc: bool
@@ -0,0 +1,3 @@
1
+ from .converters import * # noqa: F401, F403
2
+ from .entities import * # noqa: F401, F403
3
+ from .enums import * # noqa: F401, F403
@@ -0,0 +1,177 @@
1
+ """Converters from domain models to UI View models.
2
+
3
+ This module bridges the domain layer and UI layer. It imports from both
4
+ domain/entities (input types) and ui/entities (output types).
5
+ """
6
+
7
+ from ..domain.entities import (
8
+ AgentPlaybook,
9
+ AgentSuccessEvaluationResult,
10
+ Interaction,
11
+ ProfileChangeLog,
12
+ UserPlaybook,
13
+ UserProfile,
14
+ )
15
+ from .entities import (
16
+ AgentPlaybookView,
17
+ EvaluationResultView,
18
+ InteractionView,
19
+ ProfileChangeLogView,
20
+ ProfileView,
21
+ UserPlaybookView,
22
+ )
23
+
24
+ __all__ = [
25
+ "to_interaction_view",
26
+ "to_profile_view",
27
+ "to_user_playbook_view",
28
+ "to_agent_playbook_view",
29
+ "to_evaluation_result_view",
30
+ "to_profile_change_log_view",
31
+ ]
32
+
33
+
34
+ def to_interaction_view(interaction: Interaction) -> InteractionView:
35
+ """Convert internal Interaction to user-facing InteractionView.
36
+
37
+ Args:
38
+ interaction (Interaction): Full internal interaction
39
+
40
+ Returns:
41
+ InteractionView: View without embedding and image_encoding
42
+ """
43
+ return InteractionView(
44
+ interaction_id=interaction.interaction_id,
45
+ user_id=interaction.user_id,
46
+ request_id=interaction.request_id,
47
+ created_at=interaction.created_at,
48
+ role=interaction.role,
49
+ content=interaction.content,
50
+ user_action=interaction.user_action,
51
+ user_action_description=interaction.user_action_description,
52
+ interacted_image_url=interaction.interacted_image_url,
53
+ shadow_content=interaction.shadow_content,
54
+ expert_content=interaction.expert_content,
55
+ tools_used=interaction.tools_used,
56
+ )
57
+
58
+
59
+ def to_profile_view(profile: UserProfile) -> ProfileView:
60
+ """Convert internal UserProfile to user-facing ProfileView.
61
+
62
+ Args:
63
+ profile (UserProfile): Full internal user profile
64
+
65
+ Returns:
66
+ ProfileView: View without embedding
67
+ """
68
+ return ProfileView(
69
+ profile_id=profile.profile_id,
70
+ user_id=profile.user_id,
71
+ content=profile.content,
72
+ last_modified_timestamp=profile.last_modified_timestamp,
73
+ generated_from_request_id=profile.generated_from_request_id,
74
+ profile_time_to_live=profile.profile_time_to_live,
75
+ expiration_timestamp=profile.expiration_timestamp,
76
+ custom_features=profile.custom_features,
77
+ source=profile.source,
78
+ status=profile.status,
79
+ extractor_names=profile.extractor_names,
80
+ source_span=profile.source_span,
81
+ )
82
+
83
+
84
+ def to_user_playbook_view(rf: UserPlaybook) -> UserPlaybookView:
85
+ """Convert internal UserPlaybook to user-facing UserPlaybookView.
86
+
87
+ Args:
88
+ rf (UserPlaybook): Full internal user playbook
89
+
90
+ Returns:
91
+ UserPlaybookView: View without embedding
92
+ """
93
+ return UserPlaybookView(
94
+ user_playbook_id=rf.user_playbook_id,
95
+ user_id=rf.user_id,
96
+ agent_version=rf.agent_version,
97
+ request_id=rf.request_id,
98
+ playbook_name=rf.playbook_name,
99
+ created_at=rf.created_at,
100
+ content=rf.content,
101
+ trigger=rf.trigger,
102
+ rationale=rf.rationale,
103
+ status=rf.status,
104
+ source=rf.source,
105
+ source_interaction_ids=rf.source_interaction_ids,
106
+ source_span=rf.source_span,
107
+ )
108
+
109
+
110
+ def to_agent_playbook_view(fb: AgentPlaybook) -> AgentPlaybookView:
111
+ """Convert internal AgentPlaybook to user-facing AgentPlaybookView.
112
+
113
+ Args:
114
+ fb (AgentPlaybook): Full internal agent playbook
115
+
116
+ Returns:
117
+ AgentPlaybookView: View without embedding
118
+ """
119
+ return AgentPlaybookView(
120
+ agent_playbook_id=fb.agent_playbook_id,
121
+ playbook_name=fb.playbook_name,
122
+ agent_version=fb.agent_version,
123
+ created_at=fb.created_at,
124
+ content=fb.content,
125
+ trigger=fb.trigger,
126
+ rationale=fb.rationale,
127
+ playbook_status=fb.playbook_status,
128
+ playbook_metadata=fb.playbook_metadata,
129
+ status=fb.status,
130
+ )
131
+
132
+
133
+ def to_evaluation_result_view(
134
+ result: AgentSuccessEvaluationResult,
135
+ ) -> EvaluationResultView:
136
+ """Convert internal AgentSuccessEvaluationResult to user-facing EvaluationResultView.
137
+
138
+ Args:
139
+ result (AgentSuccessEvaluationResult): Full internal evaluation result
140
+
141
+ Returns:
142
+ EvaluationResultView: View without embedding
143
+ """
144
+ return EvaluationResultView(
145
+ result_id=result.result_id,
146
+ agent_version=result.agent_version,
147
+ session_id=result.session_id,
148
+ is_success=result.is_success,
149
+ failure_type=result.failure_type,
150
+ failure_reason=result.failure_reason,
151
+ evaluation_name=result.evaluation_name,
152
+ created_at=result.created_at,
153
+ regular_vs_shadow=result.regular_vs_shadow,
154
+ number_of_correction_per_session=result.number_of_correction_per_session,
155
+ user_turns_to_resolution=result.user_turns_to_resolution,
156
+ is_escalated=result.is_escalated,
157
+ )
158
+
159
+
160
+ def to_profile_change_log_view(log: ProfileChangeLog) -> ProfileChangeLogView:
161
+ """Convert internal ProfileChangeLog to user-facing ProfileChangeLogView.
162
+
163
+ Args:
164
+ log (ProfileChangeLog): Full internal profile change log
165
+
166
+ Returns:
167
+ ProfileChangeLogView: View with ProfileView lists instead of UserProfile lists
168
+ """
169
+ return ProfileChangeLogView(
170
+ id=log.id,
171
+ user_id=log.user_id,
172
+ request_id=log.request_id,
173
+ created_at=log.created_at,
174
+ added_profiles=[to_profile_view(p) for p in log.added_profiles],
175
+ removed_profiles=[to_profile_view(p) for p in log.removed_profiles],
176
+ mentioned_profiles=[to_profile_view(p) for p in log.mentioned_profiles],
177
+ )
@@ -0,0 +1,129 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import UTC, datetime
4
+
5
+ from pydantic import BaseModel, Field, field_validator
6
+
7
+ from ..common import NEVER_EXPIRES_TIMESTAMP, ToolUsed
8
+ from ..validators import _validate_image_url
9
+ from .enums import (
10
+ PlaybookStatus,
11
+ ProfileTimeToLive,
12
+ RegularVsShadow,
13
+ Status,
14
+ UserActionType,
15
+ )
16
+
17
+ __all__ = [
18
+ "InteractionView",
19
+ "ProfileView",
20
+ "UserPlaybookView",
21
+ "AgentPlaybookView",
22
+ "EvaluationResultView",
23
+ "ProfileChangeLogView",
24
+ ]
25
+
26
+ # ===============================
27
+ # View Models (user-facing, without embeddings)
28
+ # ===============================
29
+
30
+
31
+ class InteractionView(BaseModel):
32
+ """User-facing Interaction — excludes embedding and image_encoding."""
33
+
34
+ interaction_id: int = 0
35
+ user_id: str
36
+ request_id: str
37
+ created_at: int = Field(default_factory=lambda: int(datetime.now(UTC).timestamp()))
38
+ role: str = "User"
39
+ content: str = ""
40
+ user_action: UserActionType = UserActionType.NONE
41
+ user_action_description: str = ""
42
+ interacted_image_url: str = ""
43
+ shadow_content: str = ""
44
+ expert_content: str = ""
45
+ tools_used: list[ToolUsed] = Field(default_factory=list)
46
+
47
+ @field_validator("interacted_image_url", mode="after")
48
+ @classmethod
49
+ def validate_image_url(cls, v: str) -> str:
50
+ return _validate_image_url(v)
51
+
52
+
53
+ class ProfileView(BaseModel):
54
+ """User-facing UserProfile — excludes embedding."""
55
+
56
+ profile_id: str
57
+ user_id: str
58
+ content: str
59
+ last_modified_timestamp: int
60
+ generated_from_request_id: str
61
+ profile_time_to_live: ProfileTimeToLive = ProfileTimeToLive.INFINITY
62
+ expiration_timestamp: int = NEVER_EXPIRES_TIMESTAMP
63
+ custom_features: dict | None = None
64
+ source: str | None = None
65
+ status: Status | None = None
66
+ extractor_names: list[str] | None = None
67
+ source_span: str | None = None
68
+
69
+
70
+ class UserPlaybookView(BaseModel):
71
+ """User-facing UserPlaybook — excludes embedding."""
72
+
73
+ user_playbook_id: int = 0
74
+ user_id: str | None = None
75
+ agent_version: str
76
+ request_id: str
77
+ playbook_name: str = ""
78
+ created_at: int = Field(default_factory=lambda: int(datetime.now(UTC).timestamp()))
79
+ content: str = ""
80
+ trigger: str | None = None
81
+ rationale: str | None = None
82
+ status: Status | None = None
83
+ source: str | None = None
84
+ source_interaction_ids: list[int] = Field(default_factory=list)
85
+ source_span: str | None = None
86
+
87
+
88
+ class AgentPlaybookView(BaseModel):
89
+ """User-facing AgentPlaybook — excludes embedding."""
90
+
91
+ agent_playbook_id: int = 0
92
+ playbook_name: str = ""
93
+ agent_version: str
94
+ created_at: int = Field(default_factory=lambda: int(datetime.now(UTC).timestamp()))
95
+ content: str
96
+ trigger: str | None = None
97
+ rationale: str | None = None
98
+ playbook_status: PlaybookStatus = PlaybookStatus.PENDING
99
+ playbook_metadata: str = ""
100
+ status: Status | None = None
101
+
102
+
103
+ class EvaluationResultView(BaseModel):
104
+ """User-facing AgentSuccessEvaluationResult — excludes embedding."""
105
+
106
+ result_id: int = 0
107
+ agent_version: str
108
+ session_id: str
109
+ is_success: bool
110
+ failure_type: str | None = None
111
+ failure_reason: str | None = None
112
+ evaluation_name: str | None = None
113
+ created_at: int = Field(default_factory=lambda: int(datetime.now(UTC).timestamp()))
114
+ regular_vs_shadow: RegularVsShadow | None = None
115
+ number_of_correction_per_session: int = 0
116
+ user_turns_to_resolution: int | None = None
117
+ is_escalated: bool = False
118
+
119
+
120
+ class ProfileChangeLogView(BaseModel):
121
+ """User-facing ProfileChangeLog — uses ProfileView lists."""
122
+
123
+ id: int
124
+ user_id: str
125
+ request_id: str
126
+ created_at: int = Field(default_factory=lambda: int(datetime.now(UTC).timestamp()))
127
+ added_profiles: list[ProfileView]
128
+ removed_profiles: list[ProfileView]
129
+ mentioned_profiles: list[ProfileView]
@@ -0,0 +1,25 @@
1
+ """UI-layer enums — re-export domain enums to keep type identity shared.
2
+
3
+ Previously this module declared duplicate StrEnum classes with the same
4
+ variants as the domain enums. That broke type identity for pyright — the
5
+ UI enum and the domain enum were seen as distinct types even though their
6
+ values matched. Re-exporting means ``reflexio.models.api_schema.ui.enums.UserActionType``
7
+ and ``reflexio.models.api_schema.domain.enums.UserActionType`` are the same
8
+ class, and converter functions don't need casts.
9
+ """
10
+
11
+ from reflexio.models.api_schema.domain.enums import (
12
+ PlaybookStatus,
13
+ ProfileTimeToLive,
14
+ RegularVsShadow,
15
+ Status,
16
+ UserActionType,
17
+ )
18
+
19
+ __all__ = [
20
+ "PlaybookStatus",
21
+ "ProfileTimeToLive",
22
+ "RegularVsShadow",
23
+ "Status",
24
+ "UserActionType",
25
+ ]
@@ -0,0 +1,280 @@
1
+ """
2
+ Reusable Pydantic v2 validator types for reflexio.models.
3
+
4
+ This module provides:
5
+ 1. **Data Integrity Validators** - NonEmptyStr, EmbeddingVector, numeric constraints
6
+ 2. **Security Validators** - SafeHttpUrl (SSRF prevention), SanitizedStr (prompt injection mitigation)
7
+ 3. **Mixins** - TimeRangeValidatorMixin for models with start_time/end_time
8
+
9
+ Usage:
10
+ from reflexio.models.api_schema.validators import (
11
+ NonEmptyStr, SafeHttpUrl, SanitizedNonEmptyStr, EmbeddingVector, ...
12
+ )
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import ipaddress
18
+ import os
19
+ import re
20
+ from typing import Annotated, Any
21
+ from urllib.parse import urlparse
22
+
23
+ from pydantic import AfterValidator, HttpUrl
24
+
25
+ # Embedding vector dimensions — must match config_schema.EMBEDDING_DIMENSIONS.
26
+ # Duplicated here to avoid circular imports (config_schema imports from this module).
27
+ EMBEDDING_DIMENSIONS = 512
28
+
29
+
30
+ # =============================================================================
31
+ # Data Integrity Validators
32
+ # =============================================================================
33
+
34
+
35
+ def _check_non_empty_str(v: str) -> str:
36
+ """Validate that a string is not empty or whitespace-only after stripping.
37
+
38
+ Args:
39
+ v (str): The string to validate
40
+
41
+ Returns:
42
+ str: The stripped string
43
+
44
+ Raises:
45
+ ValueError: If the string is empty or whitespace-only
46
+ """
47
+ stripped = v.strip()
48
+ if not stripped:
49
+ raise ValueError("String must not be empty or whitespace-only")
50
+ return stripped
51
+
52
+
53
+ def _check_optional_non_empty_str(v: str | None) -> str | None:
54
+ """Validate that an optional string, if provided, is not empty or whitespace-only.
55
+
56
+ Args:
57
+ v (Optional[str]): The string to validate, or None
58
+
59
+ Returns:
60
+ Optional[str]: The stripped string, or None
61
+
62
+ Raises:
63
+ ValueError: If the string is provided but empty or whitespace-only
64
+ """
65
+ if v is None:
66
+ return v
67
+ stripped = v.strip()
68
+ if not stripped:
69
+ raise ValueError("String must not be empty or whitespace-only")
70
+ return stripped
71
+
72
+
73
+ def _check_embedding_dimensions(v: list[float]) -> list[float]:
74
+ """Validate that an embedding vector is either empty or has the correct dimensions.
75
+
76
+ Args:
77
+ v (list[float]): The embedding vector
78
+
79
+ Returns:
80
+ list[float]: The validated embedding vector
81
+
82
+ Raises:
83
+ ValueError: If the embedding has wrong dimensions (not empty and not EMBEDDING_DIMENSIONS)
84
+ """
85
+ if len(v) > 0 and len(v) != EMBEDDING_DIMENSIONS:
86
+ raise ValueError(
87
+ f"Embedding must be empty or have exactly {EMBEDDING_DIMENSIONS} dimensions, "
88
+ f"got {len(v)}"
89
+ )
90
+ return v
91
+
92
+
93
+ # Reusable Annotated types for data integrity
94
+ NonEmptyStr = Annotated[str, AfterValidator(_check_non_empty_str)]
95
+ """String that rejects empty/whitespace-only values. Strips leading/trailing whitespace."""
96
+
97
+ OptionalNonEmptyStr = Annotated[
98
+ str | None, AfterValidator(_check_optional_non_empty_str)
99
+ ]
100
+ """Optional string that, if provided, rejects empty/whitespace-only values."""
101
+
102
+ EmbeddingVector = Annotated[list[float], AfterValidator(_check_embedding_dimensions)]
103
+ """Embedding vector that must be either empty or exactly EMBEDDING_DIMENSIONS (512) floats."""
104
+
105
+
106
+ # =============================================================================
107
+ # Security Validators — SSRF Prevention
108
+ # =============================================================================
109
+
110
+ # Cloud metadata endpoints — ALWAYS blocked (no legitimate use case)
111
+ METADATA_HOSTS = {"metadata.google.internal"}
112
+ METADATA_IPS = {"169.254.169.254", "fd00:ec2::254"} # AWS/GCP/Azure
113
+
114
+
115
+ def _is_strict_mode() -> bool:
116
+ """Check if strict URL validation is enabled (for production).
117
+
118
+ Returns:
119
+ bool: True if REFLEXIO_BLOCK_PRIVATE_URLS env var is set to true/1/yes
120
+ """
121
+ return os.environ.get("REFLEXIO_BLOCK_PRIVATE_URLS", "").lower() in (
122
+ "true",
123
+ "1",
124
+ "yes",
125
+ )
126
+
127
+
128
+ def _check_safe_url(v: Any) -> Any:
129
+ """Validate URL is not targeting dangerous resources.
130
+
131
+ Always blocks: cloud metadata endpoints, non-http schemes.
132
+ In strict mode (REFLEXIO_BLOCK_PRIVATE_URLS=true): also blocks private IPs and localhost.
133
+
134
+ Args:
135
+ v: The URL value (HttpUrl or string)
136
+
137
+ Returns:
138
+ The validated URL value
139
+
140
+ Raises:
141
+ ValueError: If the URL targets a dangerous resource
142
+ """
143
+ url_str = str(v)
144
+ parsed = urlparse(url_str)
145
+ host = (parsed.hostname or "").lower()
146
+
147
+ # ALWAYS block cloud metadata (never legitimate)
148
+ if host in METADATA_HOSTS:
149
+ raise ValueError(f"URL must not target cloud metadata: {host}")
150
+
151
+ try:
152
+ ip = ipaddress.ip_address(host)
153
+ if str(ip) in METADATA_IPS:
154
+ raise ValueError(f"URL must not target cloud metadata endpoint: {host}")
155
+
156
+ # In strict mode, also block private/localhost
157
+ if _is_strict_mode() and (
158
+ ip.is_private or ip.is_reserved or ip.is_loopback or ip.is_link_local
159
+ ):
160
+ raise ValueError(
161
+ f"URL targets private/reserved IP '{host}'. "
162
+ f"If running locally, unset REFLEXIO_BLOCK_PRIVATE_URLS."
163
+ )
164
+ except ValueError as e:
165
+ if "must not target" in str(e) or "targets private" in str(e):
166
+ raise
167
+ # Not an IP (hostname) — check localhost in strict mode
168
+ if _is_strict_mode() and host in ("localhost", "0.0.0.0"): # noqa: S104
169
+ raise ValueError(
170
+ f"URL targets '{host}'. "
171
+ f"If running locally, unset REFLEXIO_BLOCK_PRIVATE_URLS."
172
+ ) from None
173
+
174
+ return v
175
+
176
+
177
+ SafeHttpUrl = Annotated[HttpUrl, AfterValidator(_check_safe_url)]
178
+ """HTTP URL that blocks cloud metadata endpoints (always) and private IPs (in strict mode).
179
+
180
+ Use for: api_base, endpoint — anywhere the server fetches a user-provided URL.
181
+
182
+ Local dev: works out of the box (localhost allowed)
183
+ Production: set REFLEXIO_BLOCK_PRIVATE_URLS=true in env/Dockerfile for full protection
184
+ """
185
+
186
+
187
+ # =============================================================================
188
+ # Security Validators — Prompt Injection Mitigation
189
+ # =============================================================================
190
+
191
+ # Control characters that can manipulate prompt rendering or terminal output.
192
+ # Excludes tab (\x09), newline (\x0a), carriage return (\x0d) which are legitimate.
193
+ _CONTROL_CHAR_PATTERN = re.compile(
194
+ r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]" # C0 control chars except \t \n \r
195
+ )
196
+
197
+
198
+ def _strip_control_chars(v: str) -> str:
199
+ """Remove invisible control characters that could manipulate prompt rendering.
200
+
201
+ Strips C0 control characters (NULL, bell, backspace, escape sequences, etc.)
202
+ while preserving tabs, newlines, and carriage returns.
203
+
204
+ Args:
205
+ v (str): The string to sanitize
206
+
207
+ Returns:
208
+ str: The sanitized string with control characters removed
209
+ """
210
+ return _CONTROL_CHAR_PATTERN.sub("", v)
211
+
212
+
213
+ SanitizedStr = Annotated[str, AfterValidator(_strip_control_chars)]
214
+ """String with control characters stripped. Use for user content flowing into LLM prompts."""
215
+
216
+ SanitizedNonEmptyStr = Annotated[
217
+ str,
218
+ AfterValidator(_strip_control_chars),
219
+ AfterValidator(_check_non_empty_str),
220
+ ]
221
+ """String that is sanitized (control chars stripped) AND non-empty. Use for config prompts."""
222
+
223
+
224
+ # =============================================================================
225
+ # Time Range Validator Mixin
226
+ # =============================================================================
227
+
228
+
229
+ def _validate_image_url(v: str) -> str:
230
+ """SSRF prevention: if URL is provided, must be safe http(s) or data URI.
231
+
232
+ Args:
233
+ v (str): The image URL to validate
234
+
235
+ Returns:
236
+ str: The validated URL
237
+
238
+ Raises:
239
+ ValueError: If the URL scheme is not http, https, or data, or if it targets unsafe resources
240
+ """
241
+ if not v:
242
+ return v
243
+ parsed = urlparse(v)
244
+ if parsed.scheme not in ("http", "https", "data"):
245
+ raise ValueError(
246
+ f"Image URL scheme must be http, https, or data — got '{parsed.scheme}'"
247
+ )
248
+ if parsed.scheme in ("http", "https"):
249
+ _check_safe_url(v)
250
+ return v
251
+
252
+
253
+ class TimeRangeValidatorMixin:
254
+ """Mixin for models with optional start_time/end_time fields.
255
+
256
+ Validates that end_time is after start_time when both are provided.
257
+ Add to models by including in the class bases alongside BaseModel.
258
+
259
+ Usage:
260
+ class MyRequest(TimeRangeValidatorMixin, BaseModel):
261
+ start_time: Optional[datetime] = None
262
+ end_time: Optional[datetime] = None
263
+ """
264
+
265
+ # Note: This is implemented as a classmethod to be called from
266
+ # @model_validator(mode='after') in each model, rather than using
267
+ # __init_subclass__ magic that could conflict with Pydantic's metaclass.
268
+ @staticmethod
269
+ def validate_time_range(start_time: Any, end_time: Any) -> None:
270
+ """Validate that end_time is after start_time.
271
+
272
+ Args:
273
+ start_time: The start time value
274
+ end_time: The end time value
275
+
276
+ Raises:
277
+ ValueError: If end_time is not after start_time
278
+ """
279
+ if start_time is not None and end_time is not None and end_time <= start_time:
280
+ raise ValueError("end_time must be after start_time")