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,572 @@
1
+ """
2
+ Unified search service that searches across all entity types in parallel.
3
+
4
+ Executes in two phases:
5
+ Phase A: Query reformulation + embedding generation (sequential)
6
+ Phase B: Entity searches across profiles, agent playbooks, user playbooks (parallel)
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import contextvars
12
+ import logging
13
+ import os
14
+ import threading
15
+ import time
16
+ from collections import OrderedDict
17
+ from collections.abc import Callable
18
+ from concurrent.futures import Future, ThreadPoolExecutor
19
+ from concurrent.futures import TimeoutError as FuturesTimeoutError
20
+ from typing import TYPE_CHECKING, Any
21
+
22
+ from reflexio.models.api_schema.retriever_schema import (
23
+ ConversationTurn,
24
+ SearchAgentPlaybookRequest,
25
+ SearchUserPlaybookRequest,
26
+ SearchUserProfileRequest,
27
+ UnifiedSearchRequest,
28
+ UnifiedSearchResponse,
29
+ )
30
+ from reflexio.models.api_schema.service_schemas import (
31
+ AgentPlaybook,
32
+ PlaybookStatus,
33
+ UserPlaybook,
34
+ UserProfile,
35
+ )
36
+ from reflexio.models.config_schema import (
37
+ RetrievalFloorConfig,
38
+ SearchMode,
39
+ SearchOptions,
40
+ )
41
+ from reflexio.server.llm.litellm_client import LiteLLMClient
42
+ from reflexio.server.prompt.prompt_manager import PromptManager
43
+ from reflexio.server.services.pre_retrieval import QueryReformulator
44
+ from reflexio.server.services.retrieval.relevance_floor import apply_relevance_floor
45
+ from reflexio.server.services.storage.storage_base import BaseStorage
46
+ from reflexio.server.tracing import profile_step, set_span_data
47
+
48
+ if TYPE_CHECKING:
49
+ from reflexio.server.api_endpoints.request_context import RequestContext
50
+
51
+ logger = logging.getLogger(__name__)
52
+ _DEFAULT_ENTITY_TYPES = frozenset({"profiles", "agent_playbooks", "user_playbooks"})
53
+ # Statuses returned for agent_playbooks when the caller does not pass an
54
+ # explicit ``agent_playbook_status_filter``. Excludes REJECTED so that a
55
+ # rejection in the dashboard immediately suppresses the playbook from search
56
+ # results — every consumer benefits without opting in. Callers that genuinely
57
+ # want REJECTED items (e.g. admin views) must pass the full list explicitly.
58
+ _DEFAULT_AGENT_PLAYBOOK_STATUSES: tuple[PlaybookStatus, ...] = (
59
+ PlaybookStatus.APPROVED,
60
+ PlaybookStatus.PENDING,
61
+ )
62
+ _SEARCH_FANOUT_MAX_WORKERS = max(
63
+ 1, int(os.getenv("REFLEXIO_SEARCH_FANOUT_WORKERS", "16") or "16")
64
+ )
65
+ _SEARCH_FANOUT_EXECUTOR = ThreadPoolExecutor(
66
+ max_workers=_SEARCH_FANOUT_MAX_WORKERS,
67
+ thread_name_prefix="reflexio-search",
68
+ )
69
+ _EMBEDDING_CACHE_TTL_SECONDS = max(
70
+ 0, int(os.getenv("REFLEXIO_QUERY_EMBEDDING_CACHE_TTL_SECONDS", "300") or "300")
71
+ )
72
+ _EMBEDDING_CACHE_MAX_SIZE = max(
73
+ 1, int(os.getenv("REFLEXIO_QUERY_EMBEDDING_CACHE_MAX_SIZE", "1024") or "1024")
74
+ )
75
+ _embedding_cache_lock = threading.Lock()
76
+ _embedding_cache: OrderedDict[tuple[str, int, str, str], tuple[float, list[float]]] = (
77
+ OrderedDict()
78
+ )
79
+
80
+
81
+ def run_unified_search(
82
+ request: UnifiedSearchRequest,
83
+ org_id: str,
84
+ storage: BaseStorage,
85
+ llm_client: LiteLLMClient,
86
+ prompt_manager: PromptManager,
87
+ pre_retrieval_model_name: str | None = None,
88
+ retrieval_floor: RetrievalFloorConfig | None = None,
89
+ ) -> UnifiedSearchResponse:
90
+ """
91
+ Search across all entity types (profiles, agent playbooks, user playbooks) in parallel.
92
+
93
+ Phase A runs query reformulation and embedding generation sequentially.
94
+ Phase B runs all entity searches in parallel using the results from Phase A.
95
+
96
+ Args:
97
+ request (UnifiedSearchRequest): The unified search request
98
+ org_id (str): Organization ID (used for feature flag checks)
99
+ storage: Storage instance (BaseStorage implementation)
100
+ llm_client (LiteLLMClient): Shared LLM client instance
101
+ prompt_manager (PromptManager): Prompt manager for query reformulator
102
+ pre_retrieval_model_name (str, optional): Model name override for query reformulation.
103
+ Caller should resolve this from config and/or site vars.
104
+
105
+ Returns:
106
+ UnifiedSearchResponse: Combined results from all entity types
107
+ """
108
+ if not request.query:
109
+ return UnifiedSearchResponse(success=True, msg="No query provided")
110
+
111
+ top_k = request.top_k if request.top_k is not None else 5
112
+ threshold = request.threshold if request.threshold is not None else 0.3
113
+
114
+ floor_cfg = retrieval_floor or RetrievalFloorConfig()
115
+ floor_on = floor_cfg.enabled
116
+ fetch_k = max(top_k, floor_cfg.pool_size) if floor_on else top_k
117
+
118
+ # --- Phase A: query reformulation + embedding generation ---
119
+ reformulated_query, embedding = _run_phase_a(
120
+ query=request.query,
121
+ storage=storage,
122
+ llm_client=llm_client,
123
+ prompt_manager=prompt_manager,
124
+ supports_embedding=storage.supports_embedding,
125
+ conversation_history=request.conversation_history,
126
+ enable_reformulation=bool(request.enable_reformulation),
127
+ pre_retrieval_model_name=pre_retrieval_model_name,
128
+ search_mode=request.search_mode,
129
+ )
130
+
131
+ # --- Phase B: parallel searches across all entity types ---
132
+ profiles, agent_playbooks, user_playbooks = _run_phase_b(
133
+ request=request,
134
+ org_id=org_id,
135
+ storage=storage,
136
+ embedding=embedding,
137
+ query=reformulated_query,
138
+ top_k=fetch_k,
139
+ threshold=threshold,
140
+ )
141
+
142
+ if profiles is None:
143
+ return UnifiedSearchResponse(success=False, msg="Search failed")
144
+
145
+ if floor_on:
146
+ profiles, agent_playbooks, user_playbooks = _apply_floors(
147
+ query=reformulated_query,
148
+ profiles=profiles,
149
+ agent_playbooks=agent_playbooks, # type: ignore[arg-type]
150
+ user_playbooks=user_playbooks, # type: ignore[arg-type]
151
+ top_k=top_k,
152
+ cfg=floor_cfg,
153
+ )
154
+
155
+ return UnifiedSearchResponse(
156
+ success=True,
157
+ profiles=profiles,
158
+ agent_playbooks=agent_playbooks, # type: ignore[reportArgumentType]
159
+ user_playbooks=user_playbooks, # type: ignore[reportArgumentType]
160
+ reformulated_query=reformulated_query
161
+ if reformulated_query != request.query
162
+ else None,
163
+ )
164
+
165
+
166
+ def _run_phase_a(
167
+ query: str,
168
+ storage: BaseStorage,
169
+ llm_client: LiteLLMClient,
170
+ prompt_manager: PromptManager,
171
+ supports_embedding: bool = True,
172
+ conversation_history: list[ConversationTurn] | None = None,
173
+ enable_reformulation: bool = False,
174
+ pre_retrieval_model_name: str | None = None,
175
+ search_mode: SearchMode = SearchMode.HYBRID,
176
+ ) -> tuple[str, list[float] | None]:
177
+ """Run query reformulation and embedding generation sequentially.
178
+
179
+ Args:
180
+ query (str): The original search query
181
+ storage (BaseStorage): Storage instance
182
+ llm_client (LiteLLMClient): Shared LLM client instance
183
+ prompt_manager (PromptManager): Prompt manager instance
184
+ supports_embedding (bool): Whether the storage backend supports embedding generation.
185
+ When False, skips embedding and returns None (local/self-host storage).
186
+ conversation_history (list, optional): Prior conversation turns for context-aware query reformulation
187
+ enable_reformulation (bool): Whether query reformulation is enabled for this request
188
+ pre_retrieval_model_name (str, optional): Model name override for query reformulation
189
+ search_mode (SearchMode): Search mode; FTS-only mode skips embedding generation entirely
190
+
191
+ Returns:
192
+ tuple[str, Optional[list[float]]]: (standalone_query, embedding_vector) — embedding is None when unsupported or on failure
193
+ """
194
+ reformulator = QueryReformulator(
195
+ llm_client=llm_client,
196
+ prompt_manager=prompt_manager,
197
+ model_name=pre_retrieval_model_name,
198
+ )
199
+
200
+ # Query reformulation (rewrite() handles all exceptions internally)
201
+ with profile_step(
202
+ "search.reformulate",
203
+ enabled=enable_reformulation,
204
+ has_conversation_history=bool(conversation_history),
205
+ ):
206
+ if enable_reformulation:
207
+ result = reformulator.rewrite(query, conversation_history)
208
+ standalone_query = result.standalone_query
209
+ else:
210
+ standalone_query = query
211
+
212
+ # Embedding generation (uses reformulated query for semantic accuracy).
213
+ # FTS-only search has no use for an embedding, so skip the call entirely.
214
+ embedding = None
215
+ if supports_embedding and search_mode != SearchMode.FTS:
216
+ with profile_step(
217
+ "search.embedding",
218
+ backend=_storage_backend_name(storage),
219
+ purpose="query",
220
+ ) as span:
221
+ try:
222
+ embedding = _get_cached_query_embedding(storage, standalone_query)
223
+ span.set_data("embedding_generated", embedding is not None)
224
+ except Exception as e:
225
+ span.set_data("embedding_generated", False)
226
+ logger.error("Embedding generation failed: %s", e)
227
+
228
+ return standalone_query, embedding
229
+
230
+
231
+ def _run_phase_b(
232
+ request: UnifiedSearchRequest,
233
+ org_id: str, # noqa: ARG001
234
+ storage: BaseStorage,
235
+ embedding: list[float] | None,
236
+ query: str,
237
+ top_k: int,
238
+ threshold: float,
239
+ ) -> tuple[
240
+ list[UserProfile] | None,
241
+ list[AgentPlaybook] | None,
242
+ list[UserPlaybook] | None,
243
+ ]:
244
+ """Run parallel searches across all entity types by delegating to storage methods.
245
+
246
+ Args:
247
+ request (UnifiedSearchRequest): The search request (for filters)
248
+ org_id (str): Organization ID
249
+ storage (BaseStorage): Storage instance
250
+ embedding (Optional[list[float]]): Pre-computed query embedding, or None for text-only search
251
+ query (str): Query string (possibly rewritten) for FTS
252
+ top_k (int): Maximum results per entity type
253
+ threshold (float): Minimum match threshold
254
+
255
+ Returns:
256
+ tuple: (profiles, agent_playbooks, user_playbooks) — all None on timeout/failure
257
+ """
258
+ options = SearchOptions(query_embedding=embedding, search_mode=request.search_mode)
259
+
260
+ entity_types = set(request.entity_types or _DEFAULT_ENTITY_TYPES)
261
+ allowed_agent_statuses = request.agent_playbook_status_filter
262
+ try:
263
+ with profile_step(
264
+ "search.phase_b",
265
+ backend=_storage_backend_name(storage),
266
+ entity_types=sorted(entity_types),
267
+ top_k=top_k,
268
+ ) as span:
269
+ profiles_future = (
270
+ _submit_with_current_context(
271
+ _SEARCH_FANOUT_EXECUTOR,
272
+ _search_profiles_via_storage,
273
+ storage,
274
+ query,
275
+ top_k,
276
+ threshold,
277
+ request.user_id,
278
+ embedding,
279
+ request.search_mode,
280
+ )
281
+ if "profiles" in entity_types
282
+ else None
283
+ )
284
+ agent_playbooks_future = (
285
+ _submit_with_current_context(
286
+ _SEARCH_FANOUT_EXECUTOR,
287
+ _search_agent_playbooks_via_storage,
288
+ storage,
289
+ query,
290
+ top_k,
291
+ threshold,
292
+ request.agent_version,
293
+ request.playbook_name,
294
+ allowed_agent_statuses,
295
+ options,
296
+ )
297
+ if "agent_playbooks" in entity_types
298
+ else None
299
+ )
300
+ if "user_playbooks" in entity_types:
301
+ rf_request = SearchUserPlaybookRequest(
302
+ query=query,
303
+ user_id=request.user_id,
304
+ agent_version=request.agent_version,
305
+ playbook_name=request.playbook_name,
306
+ status_filter=None,
307
+ threshold=threshold,
308
+ top_k=top_k,
309
+ search_mode=request.search_mode,
310
+ )
311
+ user_playbooks_future = _submit_with_current_context(
312
+ _SEARCH_FANOUT_EXECUTOR,
313
+ _search_user_playbooks_via_storage,
314
+ storage,
315
+ rf_request,
316
+ options,
317
+ )
318
+ else:
319
+ user_playbooks_future = None
320
+
321
+ profiles = profiles_future.result(timeout=30) if profiles_future else []
322
+ agent_playbooks = (
323
+ agent_playbooks_future.result(timeout=30)
324
+ if agent_playbooks_future
325
+ else []
326
+ )
327
+ user_playbooks = (
328
+ user_playbooks_future.result(timeout=30)
329
+ if user_playbooks_future
330
+ else []
331
+ )
332
+ set_span_data(
333
+ span,
334
+ {
335
+ "profiles_count": len(profiles),
336
+ "agent_playbooks_count": len(agent_playbooks),
337
+ "user_playbooks_count": len(user_playbooks),
338
+ },
339
+ )
340
+ except FuturesTimeoutError:
341
+ logger.error("Unified search timed out")
342
+ return None, None, None
343
+ except Exception as e:
344
+ logger.error("Unified search failed: %s", e)
345
+ return None, None, None
346
+
347
+ return profiles, agent_playbooks, user_playbooks
348
+
349
+
350
+ def _apply_floors(
351
+ query: str,
352
+ profiles: list[UserProfile],
353
+ agent_playbooks: list[AgentPlaybook],
354
+ user_playbooks: list[UserPlaybook],
355
+ top_k: int,
356
+ cfg: RetrievalFloorConfig,
357
+ ) -> tuple[list[UserProfile], list[AgentPlaybook], list[UserPlaybook]]:
358
+ """Apply the per-arm relevance floor to each entity arm in parallel."""
359
+ with ThreadPoolExecutor(max_workers=3) as ex:
360
+ f_profiles = _submit_with_current_context(
361
+ ex,
362
+ apply_relevance_floor,
363
+ query,
364
+ profiles,
365
+ cfg.profile_floor,
366
+ top_k,
367
+ arm="profiles",
368
+ )
369
+ f_agent = _submit_with_current_context(
370
+ ex,
371
+ apply_relevance_floor,
372
+ query,
373
+ agent_playbooks,
374
+ cfg.agent_playbook_floor,
375
+ top_k,
376
+ arm="agent_playbooks",
377
+ )
378
+ f_user = _submit_with_current_context(
379
+ ex,
380
+ apply_relevance_floor,
381
+ query,
382
+ user_playbooks,
383
+ cfg.user_playbook_floor,
384
+ top_k,
385
+ arm="user_playbooks",
386
+ )
387
+ return f_profiles.result(), f_agent.result(), f_user.result()
388
+
389
+
390
+ def _get_cached_query_embedding(
391
+ storage: BaseStorage,
392
+ query: str,
393
+ ) -> list[float]:
394
+ """Return a cached query embedding when available."""
395
+ model_name = str(getattr(storage, "embedding_model_name", "unknown"))
396
+ dimensions = int(getattr(storage, "embedding_dimensions", 0) or 0)
397
+ normalized_query = " ".join(query.casefold().split())
398
+ key = (model_name, dimensions, normalized_query, "query")
399
+ now = time.monotonic()
400
+ if _EMBEDDING_CACHE_TTL_SECONDS > 0:
401
+ with _embedding_cache_lock:
402
+ cached = _embedding_cache.get(key)
403
+ if cached is not None:
404
+ created_at, value = cached
405
+ if now - created_at <= _EMBEDDING_CACHE_TTL_SECONDS:
406
+ _embedding_cache.move_to_end(key)
407
+ return list(value)
408
+ del _embedding_cache[key]
409
+
410
+ embedding = storage._get_embedding(query, purpose="query") # type: ignore[reportAttributeAccessIssue]
411
+ if _EMBEDDING_CACHE_TTL_SECONDS > 0 and embedding:
412
+ with _embedding_cache_lock:
413
+ _embedding_cache[key] = (now, list(embedding))
414
+ _embedding_cache.move_to_end(key)
415
+ while len(_embedding_cache) > _EMBEDDING_CACHE_MAX_SIZE:
416
+ _embedding_cache.popitem(last=False)
417
+ return embedding
418
+
419
+
420
+ def _search_agent_playbooks_via_storage(
421
+ storage: BaseStorage,
422
+ query: str,
423
+ top_k: int,
424
+ threshold: float,
425
+ agent_version: str | None,
426
+ playbook_name: str | None,
427
+ allowed_statuses: list[PlaybookStatus] | None,
428
+ options: SearchOptions,
429
+ ) -> list[AgentPlaybook]:
430
+ """Search agent playbooks, restricted to one or more approval statuses.
431
+
432
+ When ``allowed_statuses`` is None or empty, falls back to
433
+ ``_DEFAULT_AGENT_PLAYBOOK_STATUSES`` (APPROVED + PENDING). Callers that
434
+ genuinely want REJECTED playbooks must opt in by passing the full list.
435
+ """
436
+ with profile_step(
437
+ "search.branch.agent_playbooks",
438
+ backend=_storage_backend_name(storage),
439
+ top_k=top_k,
440
+ ) as span:
441
+ statuses = (
442
+ list(allowed_statuses)
443
+ if allowed_statuses
444
+ else list(_DEFAULT_AGENT_PLAYBOOK_STATUSES)
445
+ )
446
+ request = SearchAgentPlaybookRequest(
447
+ query=query,
448
+ agent_version=agent_version,
449
+ playbook_name=playbook_name,
450
+ status_filter=[None],
451
+ playbook_status_filter=statuses,
452
+ threshold=threshold,
453
+ top_k=top_k,
454
+ search_mode=options.search_mode,
455
+ )
456
+ results: list[AgentPlaybook] = []
457
+ seen_ids: set[str] = set()
458
+ for playbook in storage.search_agent_playbooks(request, options):
459
+ playbook_id = str(getattr(playbook, "agent_playbook_id", ""))
460
+ if playbook_id and playbook_id not in seen_ids:
461
+ seen_ids.add(playbook_id)
462
+ results.append(playbook)
463
+ if len(results) >= top_k:
464
+ break
465
+ span.set_data("result_count", len(results))
466
+ return results
467
+
468
+
469
+ def _search_profiles_via_storage(
470
+ storage: BaseStorage,
471
+ query: str,
472
+ top_k: int,
473
+ threshold: float,
474
+ user_id: str | None,
475
+ embedding: list[float] | None,
476
+ search_mode: SearchMode,
477
+ ) -> list[UserProfile]:
478
+ """Search profiles via storage.search_user_profile, returning [] on error or missing user_id.
479
+
480
+ Args:
481
+ storage (BaseStorage): Storage instance
482
+ query (str): Search query text
483
+ top_k (int): Maximum results
484
+ threshold (float): Minimum match threshold
485
+ user_id (Optional[str]): User ID filter (required for profile search)
486
+ embedding (Optional[list[float]]): Pre-computed query embedding, or None for text-only search
487
+ search_mode (SearchMode): Search mode (hybrid/vector/fts)
488
+
489
+ Returns:
490
+ list[UserProfile]: Matching profiles, or [] on error/missing user_id
491
+ """
492
+ with profile_step(
493
+ "search.branch.profiles",
494
+ backend=_storage_backend_name(storage),
495
+ top_k=top_k,
496
+ ) as span:
497
+ if not user_id:
498
+ span.set_data("result_count", 0)
499
+ return []
500
+ try:
501
+ profiles = storage.search_user_profile(
502
+ SearchUserProfileRequest(
503
+ user_id=user_id,
504
+ query=query,
505
+ top_k=top_k,
506
+ threshold=threshold,
507
+ search_mode=search_mode,
508
+ ),
509
+ status_filter=[None],
510
+ query_embedding=embedding,
511
+ )
512
+ span.set_data("result_count", len(profiles))
513
+ return profiles
514
+ except Exception as e:
515
+ span.set_data("result_count", 0)
516
+ logger.error("Profile search failed: %s", e)
517
+ return []
518
+
519
+
520
+ def _search_user_playbooks_via_storage(
521
+ storage: BaseStorage,
522
+ request: SearchUserPlaybookRequest,
523
+ options: SearchOptions,
524
+ ) -> list[UserPlaybook]:
525
+ with profile_step(
526
+ "search.branch.user_playbooks",
527
+ backend=_storage_backend_name(storage),
528
+ top_k=request.top_k,
529
+ ) as span:
530
+ user_playbooks = storage.search_user_playbooks(request, options)
531
+ span.set_data("result_count", len(user_playbooks))
532
+ return user_playbooks
533
+
534
+
535
+ def _submit_with_current_context(
536
+ executor: ThreadPoolExecutor,
537
+ fn: Callable[..., object],
538
+ *args: object,
539
+ **kwargs: object,
540
+ ) -> Future[Any]:
541
+ context = contextvars.copy_context()
542
+ return executor.submit(context.run, fn, *args, **kwargs)
543
+
544
+
545
+ def _storage_backend_name(storage: BaseStorage) -> str:
546
+ class_name = storage.__class__.__name__.lower()
547
+ if "postgres" in class_name:
548
+ return "postgres"
549
+ if "supabase" in class_name:
550
+ return "supabase"
551
+ return class_name
552
+
553
+
554
+ class UnifiedSearchService:
555
+ """Class handle for the classic unified search pipeline.
556
+
557
+ Wraps :func:`run_unified_search` so the dispatcher factory can return an
558
+ object whose ``__class__.__name__`` can be inspected uniformly alongside
559
+ the agentic search service (Phase 4).
560
+
561
+ Args:
562
+ llm_client (LiteLLMClient): Configured LLM client.
563
+ request_context (RequestContext): Current request context.
564
+ """
565
+
566
+ def __init__(
567
+ self,
568
+ llm_client: LiteLLMClient,
569
+ request_context: RequestContext,
570
+ ) -> None:
571
+ self.llm_client = llm_client
572
+ self.request_context = request_context
@@ -0,0 +1,77 @@
1
+ # Site Variables
2
+ Description: Global configuration manager for site-wide variables and per-org feature flags
3
+
4
+ > Part of the [Reflexio Server](../README.md).
5
+
6
+ ## Main Entry Points
7
+
8
+ - **Manager**: `site_var_manager.py` - `SiteVarManager` (singleton)
9
+ - **Feature Flags**: `feature_flags.py` - Per-org feature gating helpers
10
+ - **Sources**: `site_var_sources/` - JSON/TXT config files
11
+
12
+ ## Purpose
13
+
14
+ 1. **Global settings** - Model names, embedding models
15
+ 2. **Feature flags** - Per-org feature gating (global enable or per-org allowlist)
16
+ 3. **Dual storage** - File-based with optional Redis caching
17
+ 4. **Auto-fallback** - Redis → File system graceful degradation
18
+
19
+ ## Feature Flags
20
+
21
+ **File**: `feature_flags.py`
22
+ **Config**: `site_var_sources/feature_flags.json`
23
+
24
+ Per-org feature gating with fail-open defaults. Each flag supports global enable or per-org allowlist.
25
+
26
+ ```python
27
+ from reflexio.server.site_var.feature_flags import is_feature_enabled, get_all_feature_flags
28
+
29
+ is_feature_enabled(org_id, "deduplicator") # Single flag check
30
+ get_all_feature_flags(org_id) # All flags as dict[str, bool]
31
+ ```
32
+
33
+ **Config format** (`feature_flags.json`):
34
+ ```json
35
+ {
36
+ "deduplicator": {
37
+ "enabled": true,
38
+ "enabled_org_ids": []
39
+ }
40
+ }
41
+ ```
42
+
43
+ **Resolution logic**: Enabled if `enabled=True` (global) OR `org_id` in `enabled_org_ids`. Unknown flags default to enabled (fail-open).
44
+
45
+ **Current flags**: `invitation_only` (global, gates registration), `deduplicator` (gates playbook deduplication).
46
+
47
+ ## Usage
48
+
49
+ ```python
50
+ from reflexio.server.site_var.site_var_manager import SiteVarManager
51
+
52
+ manager = SiteVarManager()
53
+ config = manager.get_site_var("app_config") # Returns dict or string
54
+ ```
55
+
56
+ ## File Structure
57
+
58
+ ```
59
+ site_var/
60
+ ├── site_var_manager.py # SiteVarManager (singleton)
61
+ ├── feature_flags.py # Per-org feature flag helpers
62
+ └── site_var_sources/
63
+ ├── app_config.json # JSON → parsed dict
64
+ ├── model_config.json
65
+ └── feature_flags.json # Feature flag config (per-flag enable + org allowlist)
66
+ ```
67
+
68
+ ## Architecture Pattern
69
+
70
+ - **JSON priority**: `.json` files take precedence over `.txt`
71
+ - **Variable name**: Filename without extension
72
+ - **Redis optional**: Enable via `SiteVarManager(enable_redis=True)`
73
+ - **Feature flags**: Loaded via SiteVarManager, resolved per-org at request time
74
+
75
+ ## See Also
76
+
77
+ - [Server README](../README.md) -- FastAPI backend component overview