claude-smart 0.2.42 → 0.2.44

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 (402) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/README.md +1 -1
  3. package/bin/claude-smart.js +2 -2
  4. package/package.json +9 -3
  5. package/plugin/.claude-plugin/plugin.json +9 -3
  6. package/plugin/.codex-plugin/plugin.json +1 -1
  7. package/plugin/README.md +23 -3
  8. package/plugin/pyproject.toml +3 -3
  9. package/plugin/scripts/_lib.sh +91 -0
  10. package/plugin/scripts/backend-service.sh +51 -4
  11. package/plugin/scripts/cli.sh +3 -1
  12. package/plugin/scripts/codex-hook.js +72 -4
  13. package/plugin/scripts/dashboard-build.sh +1 -0
  14. package/plugin/scripts/dashboard-service.sh +1 -0
  15. package/plugin/scripts/ensure-plugin-root.sh +1 -0
  16. package/plugin/scripts/hook_entry.sh +6 -3
  17. package/plugin/scripts/smart-install.sh +3 -2
  18. package/plugin/src/README.md +57 -0
  19. package/plugin/src/claude_smart/context_format.py +11 -12
  20. package/plugin/src/claude_smart/cs_cite.py +26 -12
  21. package/plugin/src/claude_smart/ids.py +13 -5
  22. package/plugin/uv.lock +126 -5
  23. package/plugin/vendor/reflexio/.env.example +62 -0
  24. package/plugin/vendor/reflexio/LICENSE +201 -0
  25. package/plugin/vendor/reflexio/README.md +338 -0
  26. package/plugin/vendor/reflexio/pyproject.toml +274 -0
  27. package/plugin/vendor/reflexio/reflexio/README.md +184 -0
  28. package/plugin/vendor/reflexio/reflexio/__init__.py +166 -0
  29. package/plugin/vendor/reflexio/reflexio/benchmarks/__init__.py +1 -0
  30. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/README.md +109 -0
  31. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/__init__.py +1 -0
  32. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/backends.py +175 -0
  33. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/bench.py +642 -0
  34. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/embed_cache.py +330 -0
  35. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/report.py +317 -0
  36. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/report.md +43 -0
  37. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/results.json +4478 -0
  38. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/scenarios.py +134 -0
  39. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/seed.py +255 -0
  40. package/plugin/vendor/reflexio/reflexio/cli/README.md +287 -0
  41. package/plugin/vendor/reflexio/reflexio/cli/__init__.py +0 -0
  42. package/plugin/vendor/reflexio/reflexio/cli/__main__.py +56 -0
  43. package/plugin/vendor/reflexio/reflexio/cli/_client.py +86 -0
  44. package/plugin/vendor/reflexio/reflexio/cli/app.py +127 -0
  45. package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +265 -0
  46. package/plugin/vendor/reflexio/reflexio/cli/codex_auth.py +503 -0
  47. package/plugin/vendor/reflexio/reflexio/cli/commands/__init__.py +0 -0
  48. package/plugin/vendor/reflexio/reflexio/cli/commands/admin_cmd.py +65 -0
  49. package/plugin/vendor/reflexio/reflexio/cli/commands/agent_playbooks.py +503 -0
  50. package/plugin/vendor/reflexio/reflexio/cli/commands/api.py +114 -0
  51. package/plugin/vendor/reflexio/reflexio/cli/commands/auth.py +109 -0
  52. package/plugin/vendor/reflexio/reflexio/cli/commands/config_cmd.py +511 -0
  53. package/plugin/vendor/reflexio/reflexio/cli/commands/doctor.py +127 -0
  54. package/plugin/vendor/reflexio/reflexio/cli/commands/embeddings.py +53 -0
  55. package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +478 -0
  56. package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +303 -0
  57. package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +289 -0
  58. package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +964 -0
  59. package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +285 -0
  60. package/plugin/vendor/reflexio/reflexio/cli/commands/status_cmd.py +143 -0
  61. package/plugin/vendor/reflexio/reflexio/cli/commands/user_playbooks.py +373 -0
  62. package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +284 -0
  63. package/plugin/vendor/reflexio/reflexio/cli/errors.py +217 -0
  64. package/plugin/vendor/reflexio/reflexio/cli/log_format.py +247 -0
  65. package/plugin/vendor/reflexio/reflexio/cli/output.py +867 -0
  66. package/plugin/vendor/reflexio/reflexio/cli/paths.py +41 -0
  67. package/plugin/vendor/reflexio/reflexio/cli/run_services.py +391 -0
  68. package/plugin/vendor/reflexio/reflexio/cli/state.py +204 -0
  69. package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +96 -0
  70. package/plugin/vendor/reflexio/reflexio/cli/utils.py +329 -0
  71. package/plugin/vendor/reflexio/reflexio/client/__init__.py +3 -0
  72. package/plugin/vendor/reflexio/reflexio/client/cache.py +150 -0
  73. package/plugin/vendor/reflexio/reflexio/client/client.py +2613 -0
  74. package/plugin/vendor/reflexio/reflexio/defaults.py +23 -0
  75. package/plugin/vendor/reflexio/reflexio/integrations/__init__.py +0 -0
  76. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/.clawhubignore +7 -0
  77. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +274 -0
  78. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +517 -0
  79. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +473 -0
  80. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +2156 -0
  81. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +18 -0
  82. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +241 -0
  83. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +140 -0
  84. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +130 -0
  85. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +113 -0
  86. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +52 -0
  87. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +103 -0
  88. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +156 -0
  89. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +134 -0
  90. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +41 -0
  91. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +17 -0
  92. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +24 -0
  93. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +48 -0
  94. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +278 -0
  95. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +164 -0
  96. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +36 -0
  97. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +35 -0
  98. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +27 -0
  99. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +31 -0
  100. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +42 -0
  101. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +49 -0
  102. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +91 -0
  103. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +50 -0
  104. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tsconfig.json +16 -0
  105. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/types/openclaw.d.ts +230 -0
  106. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +13 -0
  107. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/README.md +120 -0
  108. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/TESTING.md +168 -0
  109. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package-lock.json +1657 -0
  110. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package.json +16 -0
  111. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/HEARTBEAT.md +6 -0
  112. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/README.md +84 -0
  113. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/SKILL.md +194 -0
  114. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/_meta.json +6 -0
  115. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/agents/reflexio-extractor.md +45 -0
  116. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/handler.ts +214 -0
  117. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/setup.ts +55 -0
  118. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/index.ts +327 -0
  119. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/consolidate.ts +233 -0
  120. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/dedup.ts +80 -0
  121. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/io.ts +155 -0
  122. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/openclaw-cli.ts +67 -0
  123. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/search.ts +33 -0
  124. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-playbook.ts +76 -0
  125. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-profile.ts +79 -0
  126. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/openclaw.plugin.json +46 -0
  127. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/package.json +18 -0
  128. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/README.md +36 -0
  129. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/full_consolidation.md +56 -0
  130. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/playbook_extraction.md +217 -0
  131. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/profile_extraction.md +132 -0
  132. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-consolidate/SKILL.md +33 -0
  133. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-embedded/SKILL.md +194 -0
  134. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/HOOK.md +18 -0
  135. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/architecture.md +49 -0
  136. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/comparison.md +31 -0
  137. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/future-work.md +47 -0
  138. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/porting-notes.md +52 -0
  139. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/install.sh +52 -0
  140. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/uninstall.sh +36 -0
  141. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/consolidate.test.ts +135 -0
  142. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/dedup.test.ts +104 -0
  143. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/io.test.ts +175 -0
  144. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/search.test.ts +66 -0
  145. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/smoke-test.ts +140 -0
  146. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-playbook.test.ts +93 -0
  147. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-profile.test.ts +174 -0
  148. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tsconfig.json +16 -0
  149. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/types/openclaw.d.ts +230 -0
  150. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/vitest.config.ts +7 -0
  151. package/plugin/vendor/reflexio/reflexio/lib/__init__.py +23 -0
  152. package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +310 -0
  153. package/plugin/vendor/reflexio/reflexio/lib/_base.py +225 -0
  154. package/plugin/vendor/reflexio/reflexio/lib/_config.py +83 -0
  155. package/plugin/vendor/reflexio/reflexio/lib/_dashboard.py +266 -0
  156. package/plugin/vendor/reflexio/reflexio/lib/_generation.py +176 -0
  157. package/plugin/vendor/reflexio/reflexio/lib/_interactions.py +334 -0
  158. package/plugin/vendor/reflexio/reflexio/lib/_operations.py +153 -0
  159. package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +545 -0
  160. package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +52 -0
  161. package/plugin/vendor/reflexio/reflexio/lib/_search.py +167 -0
  162. package/plugin/vendor/reflexio/reflexio/lib/_storage_labels.py +103 -0
  163. package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +288 -0
  164. package/plugin/vendor/reflexio/reflexio/lib/reflexio_lib.py +27 -0
  165. package/plugin/vendor/reflexio/reflexio/models/__init__.py +0 -0
  166. package/plugin/vendor/reflexio/reflexio/models/api_schema/__init__.py +0 -0
  167. package/plugin/vendor/reflexio/reflexio/models/api_schema/braintrust_schema.py +141 -0
  168. package/plugin/vendor/reflexio/reflexio/models/api_schema/common.py +41 -0
  169. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/__init__.py +3 -0
  170. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +1112 -0
  171. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +63 -0
  172. package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +487 -0
  173. package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +28 -0
  174. package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +83 -0
  175. package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +768 -0
  176. package/plugin/vendor/reflexio/reflexio/models/api_schema/service_schemas.py +9 -0
  177. package/plugin/vendor/reflexio/reflexio/models/api_schema/stall_state_schema.py +32 -0
  178. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/__init__.py +3 -0
  179. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +177 -0
  180. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +129 -0
  181. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/enums.py +25 -0
  182. package/plugin/vendor/reflexio/reflexio/models/api_schema/validators.py +333 -0
  183. package/plugin/vendor/reflexio/reflexio/models/config_schema.py +908 -0
  184. package/plugin/vendor/reflexio/reflexio/models/py.typed +0 -0
  185. package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +90 -0
  186. package/plugin/vendor/reflexio/reflexio/server/README.md +622 -0
  187. package/plugin/vendor/reflexio/reflexio/server/__init__.py +210 -0
  188. package/plugin/vendor/reflexio/reflexio/server/__main__.py +132 -0
  189. package/plugin/vendor/reflexio/reflexio/server/_auth.py +25 -0
  190. package/plugin/vendor/reflexio/reflexio/server/api.py +2868 -0
  191. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/README.md +34 -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 +562 -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 +359 -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 +1871 -0
  206. package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +140 -0
  207. package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +479 -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 +338 -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 +288 -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 +187 -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 +716 -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_consolidation/v2.3.1.prompt.md +69 -0
  245. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.2.prompt.md +71 -0
  246. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.0.2.prompt.md +254 -0
  247. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.1.0.prompt.md +274 -0
  248. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.0.prompt.md +283 -0
  249. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.2.prompt.md +234 -0
  250. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.3.prompt.md +244 -0
  251. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v1.0.0.prompt.md +73 -0
  252. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v2.0.0.prompt.md +86 -0
  253. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.0.0.prompt.md +97 -0
  254. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.1.0.prompt.md +119 -0
  255. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.2.0.prompt.md +123 -0
  256. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +137 -0
  257. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.0.0.prompt.md +14 -0
  258. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.1.0.prompt.md +24 -0
  259. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +29 -0
  260. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.0.0.prompt.md +11 -0
  261. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.1.0.prompt.md +21 -0
  262. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.2.0.prompt.md +25 -0
  263. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.0.0.prompt.md +37 -0
  264. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.1.0.prompt.md +40 -0
  265. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.2.0.prompt.md +36 -0
  266. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v1.0.0.prompt.md +45 -0
  267. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v2.0.0.prompt.md +81 -0
  268. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v3.0.0.prompt.md +80 -0
  269. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate_expert/v1.0.0.prompt.md +34 -0
  270. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_deduplication/v1.0.0.prompt.md +116 -0
  271. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate/v1.0.0.prompt.md +33 -0
  272. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate_override/v1.0.0.prompt.md +16 -0
  273. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +140 -0
  274. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +160 -0
  275. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_main/v1.0.0.prompt.md +14 -0
  276. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/query_reformulation/v1.0.0.prompt.md +19 -0
  277. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/rerank_relevance/v1.1.0.prompt.md +44 -0
  278. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_comparison/v1.0.0.prompt.md +43 -0
  279. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_content_evaluation/v1.0.0.prompt.md +33 -0
  280. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/feedback_extraction_main_v1.jsonl +10 -0
  281. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/profile_update_main_v1.jsonl +10 -0
  282. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +280 -0
  283. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_schema.py +11 -0
  284. package/plugin/vendor/reflexio/reflexio/server/services/README.md +58 -0
  285. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/_eval_health.py +131 -0
  286. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +60 -0
  287. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_service.py +228 -0
  288. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +87 -0
  289. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluator.py +372 -0
  290. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/delayed_group_evaluator.py +156 -0
  291. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/group_evaluation_runner.py +336 -0
  292. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +471 -0
  293. package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +1668 -0
  294. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/__init__.py +0 -0
  295. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_cron.py +196 -0
  296. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_encryption.py +101 -0
  297. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/client.py +167 -0
  298. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/service.py +281 -0
  299. package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +179 -0
  300. package/plugin/vendor/reflexio/reflexio/server/services/configurator/config_storage.py +62 -0
  301. package/plugin/vendor/reflexio/reflexio/server/services/configurator/configurator.py +87 -0
  302. package/plugin/vendor/reflexio/reflexio/server/services/configurator/local_file_config_storage.py +187 -0
  303. package/plugin/vendor/reflexio/reflexio/server/services/configurator/test_config_storage.py +162 -0
  304. package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +112 -0
  305. package/plugin/vendor/reflexio/reflexio/server/services/embedding_text.py +62 -0
  306. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/__init__.py +0 -0
  307. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/distribution.py +33 -0
  308. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +126 -0
  309. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +192 -0
  310. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/hero_state.py +75 -0
  311. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/rule_attribution.py +97 -0
  312. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +515 -0
  313. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/shadow_aggregation.py +90 -0
  314. package/plugin/vendor/reflexio/reflexio/server/services/extraction/__init__.py +0 -0
  315. package/plugin/vendor/reflexio/reflexio/server/services/extraction/agent_run_records.py +91 -0
  316. package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +303 -0
  317. package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +25 -0
  318. package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +358 -0
  319. package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +138 -0
  320. package/plugin/vendor/reflexio/reflexio/server/services/extraction/prior_answer_search.py +217 -0
  321. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +535 -0
  322. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_scheduler.py +171 -0
  323. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +779 -0
  324. package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +1125 -0
  325. package/plugin/vendor/reflexio/reflexio/server/services/extractor_config_utils.py +94 -0
  326. package/plugin/vendor/reflexio/reflexio/server/services/extractor_interaction_utils.py +251 -0
  327. package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +702 -0
  328. package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +835 -0
  329. package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +89 -0
  330. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_aggregator.py +1388 -0
  331. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_consolidator.py +1045 -0
  332. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_extractor.py +436 -0
  333. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_generation_service.py +808 -0
  334. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_constants.py +28 -0
  335. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +362 -0
  336. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/__init__.py +24 -0
  337. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/assistant_webhook.py +246 -0
  338. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/gepa_adapter.py +291 -0
  339. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/judge.py +97 -0
  340. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +96 -0
  341. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +645 -0
  342. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/rollout.py +35 -0
  343. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scenario_resolver.py +93 -0
  344. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scheduler.py +174 -0
  345. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/__init__.py +26 -0
  346. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_document_expander.py +179 -0
  347. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_query_reformulator.py +297 -0
  348. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_deduplicator.py +772 -0
  349. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_extractor.py +462 -0
  350. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service.py +737 -0
  351. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +290 -0
  352. package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +17 -0
  353. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_extractor.py +247 -0
  354. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service.py +803 -0
  355. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +146 -0
  356. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/__init__.py +0 -0
  357. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +80 -0
  358. package/plugin/vendor/reflexio/reflexio/server/services/search/__init__.py +0 -0
  359. package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +756 -0
  360. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/__init__.py +1 -0
  361. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/judge.py +184 -0
  362. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +81 -0
  363. package/plugin/vendor/reflexio/reflexio/server/services/storage/constants.py +2 -0
  364. package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +11 -0
  365. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +154 -0
  366. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention_mixin.py +155 -0
  367. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +59 -0
  368. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +1298 -0
  369. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +1945 -0
  370. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +600 -0
  371. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +346 -0
  372. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +1378 -0
  373. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +747 -0
  374. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +263 -0
  375. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +193 -0
  376. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_share_links.py +166 -0
  377. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +217 -0
  378. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +153 -0
  379. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +384 -0
  380. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +71 -0
  381. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +235 -0
  382. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +170 -0
  383. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +677 -0
  384. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +250 -0
  385. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +154 -0
  386. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +130 -0
  387. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_share_links.py +93 -0
  388. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_stall_state.py +76 -0
  389. package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +572 -0
  390. package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +77 -0
  391. package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +116 -0
  392. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_manager.py +263 -0
  393. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +13 -0
  394. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/llm_model_setting.json +7 -0
  395. package/plugin/vendor/reflexio/reflexio/server/tracing.py +158 -0
  396. package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +113 -0
  397. package/plugin/vendor/reflexio/reflexio/server/uvicorn_logging.py +76 -0
  398. package/plugin/vendor/reflexio/reflexio/test_support/__init__.py +1 -0
  399. package/plugin/vendor/reflexio/reflexio/test_support/llm_fixtures.py +62 -0
  400. package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +242 -0
  401. package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +129 -0
  402. package/plugin/vendor/reflexio/reflexio/test_support/skip_decorators.py +43 -0
@@ -0,0 +1,600 @@
1
+ """Analytics and change log methods for SQLite storage."""
2
+
3
+ import sqlite3
4
+ from collections import defaultdict
5
+ from typing import Any, Literal, cast
6
+
7
+ from reflexio.models.api_schema.braintrust_schema import (
8
+ BraintrustConnection,
9
+ ImportedScore,
10
+ )
11
+ from reflexio.models.api_schema.retriever_schema import PlaybookApplicationStat
12
+ from reflexio.models.api_schema.service_schemas import (
13
+ Interaction,
14
+ PlaybookAggregationChangeLog,
15
+ ProfileChangeLog,
16
+ )
17
+
18
+ from ._base import (
19
+ SQLiteStorageBase,
20
+ _epoch_now,
21
+ _epoch_to_iso,
22
+ _iso_to_epoch,
23
+ _json_dumps,
24
+ _json_loads,
25
+ _row_to_interaction,
26
+ _row_to_playbook_aggregation_change_log,
27
+ _row_to_profile_change_log,
28
+ )
29
+
30
+ type _CitationKind = Literal["playbook", "profile"]
31
+
32
+
33
+ class ExtrasMixin:
34
+ """Mixin providing analytics, change log, and misc operations."""
35
+
36
+ # Type hints for instance attributes/methods provided by SQLiteStorageBase via MRO
37
+ _lock: Any
38
+ conn: sqlite3.Connection
39
+ _execute: Any
40
+ _fetchall: Any
41
+
42
+ # ------------------------------------------------------------------
43
+ # Interaction helpers
44
+ # ------------------------------------------------------------------
45
+
46
+ @SQLiteStorageBase.handle_exceptions
47
+ def get_interactions_by_request_ids(
48
+ self, request_ids: list[str]
49
+ ) -> list[Interaction]:
50
+ if not request_ids:
51
+ return []
52
+ ph = ",".join("?" for _ in request_ids)
53
+ rows = self._fetchall(
54
+ f"SELECT * FROM interactions WHERE request_id IN ({ph}) ORDER BY created_at ASC", # noqa: S608
55
+ request_ids,
56
+ )
57
+ return [_row_to_interaction(r) for r in rows]
58
+
59
+ @SQLiteStorageBase.handle_exceptions
60
+ def get_interactions_by_ids(self, interaction_ids: list[int]) -> list[Interaction]:
61
+ if not interaction_ids:
62
+ return []
63
+ ph = ",".join("?" for _ in interaction_ids)
64
+ rows = self._fetchall(
65
+ f"SELECT * FROM interactions WHERE interaction_id IN ({ph}) ORDER BY created_at ASC", # noqa: S608
66
+ interaction_ids,
67
+ )
68
+ return [_row_to_interaction(r) for r in rows]
69
+
70
+ _fetchone: Any
71
+ _fetchall: Any
72
+
73
+ # ------------------------------------------------------------------
74
+ # Dashboard / Analytics methods
75
+ # ------------------------------------------------------------------
76
+
77
+ @SQLiteStorageBase.handle_exceptions
78
+ def get_dashboard_stats(self, days_back: int = 30) -> dict:
79
+ current_time = _epoch_now()
80
+ seconds_in_period = days_back * 24 * 60 * 60
81
+ current_start = current_time - seconds_in_period
82
+ previous_start = current_start - seconds_in_period
83
+
84
+ current_start_iso = _epoch_to_iso(current_start)
85
+ current_time_iso = _epoch_to_iso(current_time)
86
+ previous_start_iso = _epoch_to_iso(previous_start)
87
+
88
+ def count_in(table: str, time_col: str, start: Any, end: Any) -> int:
89
+ row = self._fetchone(
90
+ f"SELECT COUNT(*) as cnt FROM {table} WHERE {time_col} >= ? AND {time_col} <= ?",
91
+ (start, end),
92
+ )
93
+ return row["cnt"] if row else 0
94
+
95
+ def count_in_lt(table: str, time_col: str, start: Any, end: Any) -> int:
96
+ row = self._fetchone(
97
+ f"SELECT COUNT(*) as cnt FROM {table} WHERE {time_col} >= ? AND {time_col} < ?",
98
+ (start, end),
99
+ )
100
+ return row["cnt"] if row else 0
101
+
102
+ current_stats: dict[str, int | float] = {
103
+ "total_interactions": count_in(
104
+ "interactions", "created_at", current_start_iso, current_time_iso
105
+ ),
106
+ "total_profiles": count_in(
107
+ "profiles", "last_modified_timestamp", current_start, current_time
108
+ ),
109
+ "total_playbooks": (
110
+ count_in(
111
+ "user_playbooks", "created_at", current_start_iso, current_time_iso
112
+ )
113
+ + count_in(
114
+ "agent_playbooks", "created_at", current_start_iso, current_time_iso
115
+ )
116
+ ),
117
+ }
118
+
119
+ previous_stats: dict[str, int | float] = {
120
+ "total_interactions": count_in_lt(
121
+ "interactions", "created_at", previous_start_iso, current_start_iso
122
+ ),
123
+ "total_profiles": count_in_lt(
124
+ "profiles", "last_modified_timestamp", previous_start, current_start
125
+ ),
126
+ "total_playbooks": (
127
+ count_in_lt(
128
+ "user_playbooks",
129
+ "created_at",
130
+ previous_start_iso,
131
+ current_start_iso,
132
+ )
133
+ + count_in_lt(
134
+ "agent_playbooks",
135
+ "created_at",
136
+ previous_start_iso,
137
+ current_start_iso,
138
+ )
139
+ ),
140
+ }
141
+
142
+ # Success rates
143
+ def calc_success_rate(rows: list[sqlite3.Row]) -> float:
144
+ if not rows:
145
+ return 0.0
146
+ total = len(rows)
147
+ success = sum(1 for r in rows if r["is_success"])
148
+ return success / total * 100
149
+
150
+ eval_current = self._fetchall(
151
+ "SELECT is_success FROM agent_success_evaluation_result WHERE created_at >= ? AND created_at <= ?",
152
+ (current_start_iso, current_time_iso),
153
+ )
154
+ eval_previous = self._fetchall(
155
+ "SELECT is_success FROM agent_success_evaluation_result WHERE created_at >= ? AND created_at < ?",
156
+ (previous_start_iso, current_start_iso),
157
+ )
158
+ current_stats["success_rate"] = calc_success_rate(eval_current)
159
+ previous_stats["success_rate"] = calc_success_rate(eval_previous)
160
+
161
+ # Time series
162
+ interactions_ts = self._fetchall(
163
+ "SELECT created_at FROM interactions WHERE created_at >= ? AND created_at <= ? ORDER BY created_at",
164
+ (current_start_iso, current_time_iso),
165
+ )
166
+ profiles_ts = self._fetchall(
167
+ "SELECT last_modified_timestamp FROM profiles WHERE last_modified_timestamp >= ? AND last_modified_timestamp <= ? ORDER BY last_modified_timestamp",
168
+ (current_start, current_time),
169
+ )
170
+ playbooks_ts = self._fetchall(
171
+ "SELECT created_at FROM user_playbooks WHERE created_at >= ? AND created_at <= ? ORDER BY created_at",
172
+ (current_start_iso, current_time_iso),
173
+ )
174
+ evals_ts = self._fetchall(
175
+ "SELECT created_at, is_success FROM agent_success_evaluation_result WHERE created_at >= ? AND created_at <= ? ORDER BY created_at",
176
+ (current_start_iso, current_time_iso),
177
+ )
178
+
179
+ return {
180
+ "current_period": current_stats,
181
+ "previous_period": previous_stats,
182
+ "interactions_time_series": [
183
+ {"timestamp": _iso_to_epoch(r["created_at"]), "value": 1}
184
+ for r in interactions_ts
185
+ ],
186
+ "profiles_time_series": [
187
+ {"timestamp": r["last_modified_timestamp"], "value": 1}
188
+ for r in profiles_ts
189
+ ],
190
+ "playbooks_time_series": [
191
+ {"timestamp": _iso_to_epoch(r["created_at"]), "value": 1}
192
+ for r in playbooks_ts
193
+ ],
194
+ "evaluations_time_series": [
195
+ {
196
+ "timestamp": _iso_to_epoch(r["created_at"]),
197
+ "value": 100 if r["is_success"] else 0,
198
+ }
199
+ for r in evals_ts
200
+ ],
201
+ }
202
+
203
+ @SQLiteStorageBase.handle_exceptions
204
+ def get_playbook_application_stats(
205
+ self, days_back: int = 30
206
+ ) -> list[PlaybookApplicationStat]:
207
+ """Return per-rule citation counts from the ``interactions`` table.
208
+
209
+ Aggregates the JSON ``citations`` column over the look-back window and
210
+ groups by ``(kind, real_id)``. Iteration is done in Python (rather
211
+ than pushing into SQL via ``json_each``) because volumes are bounded
212
+ per org and the resulting code is easier to maintain. Titles come
213
+ from the citation rows themselves — they are captured at injection
214
+ time when the rule is rendered into context.
215
+
216
+ Args:
217
+ days_back (int): Look-back window in days. Must be positive.
218
+
219
+ Returns:
220
+ list[PlaybookApplicationStat]: One row per cited ``(kind,
221
+ real_id)``, sorted by ``applied_count`` descending and then
222
+ by ``last_applied_at`` descending. Empty when no interactions
223
+ in the window carry citations.
224
+ """
225
+ if days_back <= 0:
226
+ return []
227
+
228
+ current_time = _epoch_now()
229
+ start_iso = _epoch_to_iso(current_time - days_back * 24 * 60 * 60)
230
+ rows = self._fetchall(
231
+ "SELECT interaction_id, created_at, citations FROM interactions "
232
+ "WHERE created_at >= ? "
233
+ "AND citations IS NOT NULL AND citations != '' AND citations != '[]' "
234
+ "ORDER BY created_at DESC, interaction_id DESC",
235
+ (start_iso,),
236
+ )
237
+ if not rows:
238
+ return []
239
+
240
+ aggregates: dict[tuple[_CitationKind, str], dict[str, Any]] = defaultdict(
241
+ lambda: {
242
+ "applied_count": 0,
243
+ "title": "",
244
+ "last_applied_at": None,
245
+ "last_interaction_id": None,
246
+ }
247
+ )
248
+ for row in rows:
249
+ citations = _json_loads(row["citations"])
250
+ if not isinstance(citations, list):
251
+ continue
252
+ seen_keys_in_interaction: set[tuple[_CitationKind, str]] = set()
253
+ for c in citations:
254
+ if not isinstance(c, dict):
255
+ continue
256
+ kind = c.get("kind")
257
+ real_id = c.get("real_id")
258
+ if kind not in ("playbook", "profile") or not real_id:
259
+ continue
260
+ key: tuple[_CitationKind, str] = (
261
+ cast(_CitationKind, kind),
262
+ str(real_id),
263
+ )
264
+ if key in seen_keys_in_interaction:
265
+ continue
266
+ seen_keys_in_interaction.add(key)
267
+ agg = aggregates[key]
268
+ agg["applied_count"] += 1
269
+ if agg["last_applied_at"] is None:
270
+ # rows ordered DESC, so the first time we see this key
271
+ # is the most recent occurrence
272
+ agg["last_applied_at"] = _iso_to_epoch(row["created_at"])
273
+ agg["last_interaction_id"] = row["interaction_id"]
274
+ if not agg["title"]:
275
+ title = c.get("title") or ""
276
+ if isinstance(title, str) and title.strip():
277
+ agg["title"] = title.strip()
278
+
279
+ stats = [
280
+ PlaybookApplicationStat(
281
+ real_id=real_id,
282
+ kind=kind,
283
+ title=agg["title"],
284
+ applied_count=agg["applied_count"],
285
+ last_applied_at=agg["last_applied_at"],
286
+ last_interaction_id=agg["last_interaction_id"],
287
+ )
288
+ for (kind, real_id), agg in aggregates.items()
289
+ ]
290
+ stats.sort(
291
+ key=lambda s: (
292
+ -s.applied_count,
293
+ -(s.last_applied_at if s.last_applied_at is not None else 0),
294
+ )
295
+ )
296
+ return stats
297
+
298
+ # ------------------------------------------------------------------
299
+ # Statistics methods
300
+ # ------------------------------------------------------------------
301
+
302
+ @SQLiteStorageBase.handle_exceptions
303
+ def get_profile_statistics(self) -> dict:
304
+ current_ts = _epoch_now()
305
+ expiring_soon_ts = current_ts + (7 * 24 * 60 * 60)
306
+
307
+ rows = self._fetchall(
308
+ "SELECT status, expiration_timestamp FROM profiles WHERE expiration_timestamp >= ?",
309
+ (current_ts,),
310
+ )
311
+ stats = {
312
+ "current_count": 0,
313
+ "pending_count": 0,
314
+ "archived_count": 0,
315
+ "expiring_soon_count": 0,
316
+ }
317
+ for r in rows:
318
+ s = r["status"]
319
+ exp = r["expiration_timestamp"]
320
+ if s is None:
321
+ stats["current_count"] += 1
322
+ if exp is not None and exp <= expiring_soon_ts:
323
+ stats["expiring_soon_count"] += 1
324
+ elif s == "pending":
325
+ stats["pending_count"] += 1
326
+ elif s == "archived":
327
+ stats["archived_count"] += 1
328
+ return stats
329
+
330
+ # ------------------------------------------------------------------
331
+ # Profile Change Log methods
332
+ # ------------------------------------------------------------------
333
+
334
+ @SQLiteStorageBase.handle_exceptions
335
+ def add_profile_change_log(self, profile_change_log: ProfileChangeLog) -> None:
336
+ self._execute(
337
+ """INSERT INTO profile_change_logs
338
+ (user_id, request_id, created_at, added_profiles, removed_profiles, mentioned_profiles)
339
+ VALUES (?,?,?,?,?,?)""",
340
+ (
341
+ profile_change_log.user_id,
342
+ profile_change_log.request_id,
343
+ profile_change_log.created_at,
344
+ _json_dumps(
345
+ [p.model_dump() for p in profile_change_log.added_profiles]
346
+ ),
347
+ _json_dumps(
348
+ [p.model_dump() for p in profile_change_log.removed_profiles]
349
+ ),
350
+ _json_dumps(
351
+ [p.model_dump() for p in profile_change_log.mentioned_profiles]
352
+ ),
353
+ ),
354
+ )
355
+
356
+ @SQLiteStorageBase.handle_exceptions
357
+ def get_profile_change_logs(self, limit: int = 100) -> list[ProfileChangeLog]:
358
+ rows = self._fetchall(
359
+ "SELECT * FROM profile_change_logs ORDER BY created_at DESC LIMIT ?",
360
+ (limit,),
361
+ )
362
+ return [_row_to_profile_change_log(r) for r in rows]
363
+
364
+ @SQLiteStorageBase.handle_exceptions
365
+ def delete_profile_change_log_for_user(self, user_id: str) -> None:
366
+ self._execute("DELETE FROM profile_change_logs WHERE user_id = ?", (user_id,))
367
+
368
+ @SQLiteStorageBase.handle_exceptions
369
+ def delete_all_profile_change_logs(self) -> None:
370
+ self._execute("DELETE FROM profile_change_logs")
371
+
372
+ # ------------------------------------------------------------------
373
+ # Playbook Aggregation Change Log methods
374
+ # ------------------------------------------------------------------
375
+
376
+ @SQLiteStorageBase.handle_exceptions
377
+ def add_playbook_aggregation_change_log(
378
+ self, change_log: PlaybookAggregationChangeLog
379
+ ) -> None:
380
+ self._execute(
381
+ """INSERT INTO playbook_aggregation_change_logs
382
+ (created_at, playbook_name, agent_version, run_mode,
383
+ added_playbooks, removed_playbooks, updated_playbooks)
384
+ VALUES (?,?,?,?,?,?,?)""",
385
+ (
386
+ change_log.created_at,
387
+ change_log.playbook_name,
388
+ change_log.agent_version,
389
+ change_log.run_mode,
390
+ _json_dumps(
391
+ [fb.model_dump() for fb in change_log.added_agent_playbooks]
392
+ ),
393
+ _json_dumps(
394
+ [fb.model_dump() for fb in change_log.removed_agent_playbooks]
395
+ ),
396
+ _json_dumps(
397
+ [
398
+ {"before": e.before.model_dump(), "after": e.after.model_dump()}
399
+ for e in change_log.updated_agent_playbooks
400
+ ]
401
+ ),
402
+ ),
403
+ )
404
+
405
+ @SQLiteStorageBase.handle_exceptions
406
+ def get_playbook_aggregation_change_logs(
407
+ self,
408
+ playbook_name: str,
409
+ agent_version: str,
410
+ limit: int = 100,
411
+ ) -> list[PlaybookAggregationChangeLog]:
412
+ rows = self._fetchall(
413
+ """SELECT * FROM playbook_aggregation_change_logs
414
+ WHERE playbook_name = ? AND agent_version = ?
415
+ ORDER BY created_at DESC LIMIT ?""",
416
+ (playbook_name, agent_version, limit),
417
+ )
418
+ return [_row_to_playbook_aggregation_change_log(r) for r in rows]
419
+
420
+ @SQLiteStorageBase.handle_exceptions
421
+ def delete_all_playbook_aggregation_change_logs(self) -> None:
422
+ self._execute("DELETE FROM playbook_aggregation_change_logs")
423
+
424
+ # ------------------------------------------------------------------
425
+ # Evaluation-overview support (Plan B-backend)
426
+ # ------------------------------------------------------------------
427
+
428
+ @SQLiteStorageBase.handle_exceptions
429
+ def count_sessions_with_shadow_content(self, from_ts: int, to_ts: int) -> int:
430
+ """Count distinct sessions with at least one non-empty shadow interaction.
431
+
432
+ Joins `interactions` with `requests` since `session_id` is on the
433
+ request, not the interaction.
434
+
435
+ Args:
436
+ from_ts (int): Window start, unix epoch seconds.
437
+ to_ts (int): Window end, unix epoch seconds.
438
+
439
+ Returns:
440
+ int: Distinct count of sessions in the window with shadow content.
441
+ """
442
+ rows = self._fetchall(
443
+ """SELECT COUNT(DISTINCT r.session_id) AS n
444
+ FROM interactions i
445
+ JOIN requests r ON i.request_id = r.request_id
446
+ WHERE COALESCE(i.shadow_content, '') != ''
447
+ AND r.session_id != ''
448
+ AND i.created_at >= ?
449
+ AND i.created_at <= ?""",
450
+ (_epoch_to_iso(from_ts), _epoch_to_iso(to_ts)),
451
+ )
452
+ if not rows:
453
+ return 0
454
+ return int(rows[0][0] or 0)
455
+
456
+ @SQLiteStorageBase.handle_exceptions
457
+ def get_interactions_by_session(self, session_id: str) -> list[Interaction]:
458
+ """Return interactions for a session, ordered by created_at.
459
+
460
+ Joins `interactions` with `requests` so we can filter by
461
+ Request.session_id.
462
+
463
+ Args:
464
+ session_id (str): The session whose interactions to fetch.
465
+
466
+ Returns:
467
+ list[Interaction]: Interactions in the session, possibly empty.
468
+ """
469
+ if not session_id:
470
+ return []
471
+ rows = self._fetchall(
472
+ """SELECT i.*
473
+ FROM interactions i
474
+ JOIN requests r ON i.request_id = r.request_id
475
+ WHERE r.session_id = ?
476
+ ORDER BY i.created_at ASC""",
477
+ (session_id,),
478
+ )
479
+ return [_row_to_interaction(r) for r in rows]
480
+
481
+ # ------------------------------------------------------------------
482
+ # Braintrust connector storage (Plan C-backend + Plan C-overview)
483
+ # ------------------------------------------------------------------
484
+
485
+ @SQLiteStorageBase.handle_exceptions
486
+ def save_braintrust_connection(self, connection: BraintrustConnection) -> None:
487
+ """Upsert the org's Braintrust connection.
488
+
489
+ Args:
490
+ connection (BraintrustConnection): Encrypted connection record.
491
+ """
492
+ self._execute(
493
+ """INSERT INTO braintrust_connection
494
+ (org_id, api_key_enc, workspace_id, workspace_name,
495
+ project_ids, last_sync_ts, last_error)
496
+ VALUES (?, ?, ?, ?, ?, ?, ?)
497
+ ON CONFLICT(org_id) DO UPDATE SET
498
+ api_key_enc = excluded.api_key_enc,
499
+ workspace_id = excluded.workspace_id,
500
+ workspace_name = excluded.workspace_name,
501
+ project_ids = excluded.project_ids,
502
+ last_sync_ts = excluded.last_sync_ts,
503
+ last_error = excluded.last_error""",
504
+ (
505
+ connection.org_id,
506
+ connection.api_key_enc,
507
+ connection.workspace_id,
508
+ connection.workspace_name,
509
+ _json_dumps(connection.project_ids),
510
+ connection.last_sync_ts,
511
+ connection.last_error,
512
+ ),
513
+ )
514
+
515
+ @SQLiteStorageBase.handle_exceptions
516
+ def get_braintrust_connection(self, org_id: str) -> BraintrustConnection | None:
517
+ """Fetch the org's Braintrust connection or None if not connected."""
518
+ rows = self._fetchall(
519
+ """SELECT api_key_enc, workspace_id, workspace_name, project_ids,
520
+ last_sync_ts, last_error
521
+ FROM braintrust_connection
522
+ WHERE org_id = ?""",
523
+ (org_id,),
524
+ )
525
+ if not rows:
526
+ return None
527
+ row = rows[0]
528
+ return BraintrustConnection(
529
+ org_id=org_id,
530
+ api_key_enc=row[0],
531
+ workspace_id=row[1],
532
+ workspace_name=row[2] or "",
533
+ project_ids=list(_json_loads(row[3]) or []),
534
+ last_sync_ts=row[4],
535
+ last_error=row[5],
536
+ )
537
+
538
+ @SQLiteStorageBase.handle_exceptions
539
+ def delete_braintrust_connection(self, org_id: str) -> None:
540
+ """Delete the org's connection (idempotent)."""
541
+ self._execute("DELETE FROM braintrust_connection WHERE org_id = ?", (org_id,))
542
+
543
+ @SQLiteStorageBase.handle_exceptions
544
+ def save_imported_scores(self, scores: list[ImportedScore]) -> None:
545
+ """Upsert imported scores by (org_id, source, source_run_id, scorer_name)."""
546
+ if not scores:
547
+ return
548
+ rows = [
549
+ (
550
+ s.org_id,
551
+ s.source,
552
+ s.source_run_id,
553
+ s.session_id,
554
+ s.scorer_name,
555
+ s.value,
556
+ s.ts,
557
+ )
558
+ for s in scores
559
+ ]
560
+ with self._lock:
561
+ self.conn.executemany(
562
+ """INSERT INTO imported_score
563
+ (org_id, source, source_run_id, session_id,
564
+ scorer_name, value, ts)
565
+ VALUES (?, ?, ?, ?, ?, ?, ?)
566
+ ON CONFLICT(org_id, source, source_run_id, scorer_name)
567
+ DO UPDATE SET
568
+ session_id = excluded.session_id,
569
+ value = excluded.value,
570
+ ts = excluded.ts""",
571
+ rows,
572
+ )
573
+ self.conn.commit()
574
+
575
+ @SQLiteStorageBase.handle_exceptions
576
+ def get_imported_scores(
577
+ self, org_id: str, from_ts: int, to_ts: int
578
+ ) -> list[ImportedScore]:
579
+ """Return imported scores for the org in `[from_ts, to_ts]`."""
580
+ rows = self._fetchall(
581
+ """SELECT source, source_run_id, session_id, scorer_name, value, ts
582
+ FROM imported_score
583
+ WHERE org_id = ?
584
+ AND ts >= ?
585
+ AND ts <= ?
586
+ ORDER BY ts ASC""",
587
+ (org_id, from_ts, to_ts),
588
+ )
589
+ return [
590
+ ImportedScore(
591
+ org_id=org_id,
592
+ source=cast(Literal["braintrust"], row[0]),
593
+ source_run_id=row[1],
594
+ session_id=row[2],
595
+ scorer_name=row[3],
596
+ value=float(row[4]),
597
+ ts=int(row[5]),
598
+ )
599
+ for row in rows
600
+ ]