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,290 @@
1
+ """Utility functions for the profile generation service"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from datetime import datetime, timedelta
7
+ from typing import Any, Literal
8
+
9
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
10
+
11
+ from reflexio.models.api_schema.common import NEVER_EXPIRES_TIMESTAMP
12
+ from reflexio.models.api_schema.internal_schema import RequestInteractionDataModel
13
+ from reflexio.models.api_schema.service_schemas import (
14
+ ProfileTimeToLive,
15
+ UserProfile,
16
+ )
17
+ from reflexio.server.prompt.prompt_manager import PromptManager
18
+ from reflexio.server.services.service_utils import (
19
+ MessageConstructionConfig,
20
+ PromptConfig,
21
+ construct_messages_from_interactions,
22
+ extract_interactions_from_request_interaction_data_models,
23
+ format_sessions_to_history_string,
24
+ )
25
+
26
+
27
+ class ProfileUpdates(BaseModel):
28
+ add_profiles: list[UserProfile] = []
29
+ delete_profiles: list[UserProfile] = []
30
+ mention_profiles: list[UserProfile] = []
31
+
32
+ @field_validator(
33
+ "add_profiles", "delete_profiles", "mention_profiles", mode="before"
34
+ )
35
+ @classmethod
36
+ def coerce_none_to_list(cls, v: Any) -> list[UserProfile]:
37
+ return v if v is not None else []
38
+
39
+
40
+ class ProfileGenerationRequest(BaseModel):
41
+ user_id: str
42
+ request_id: str
43
+ source: str | None = None
44
+ rerun_start_time: int | None = None # Unix timestamp for rerun flows
45
+ rerun_end_time: int | None = None # Unix timestamp for rerun flows
46
+ auto_run: bool = (
47
+ True # True for regular flow (checks stride_size), False for rerun/manual
48
+ )
49
+ force_extraction: bool = False # when True, bypass all extraction gates (stride_size, cheap pre-filter, LLM should_run)
50
+
51
+
52
+ @dataclass(frozen=True)
53
+ class ProfileGenerationServiceConstants:
54
+ PROFILE_EXTRACTORS_CONFIG_NAME = "profile_extractor_config"
55
+ # ===============================
56
+ # prompt ids
57
+ # ===============================
58
+ PROFILE_SHOULD_GENERATE_PROMPT_ID = "profile_should_generate"
59
+ PROFILE_SHOULD_GENERATE_OVERRIDE_PROMPT_ID = "profile_should_generate_override"
60
+ PROFILE_UPDATE_MAIN_PROMPT_ID = "profile_update_main"
61
+ PROFILE_UPDATE_INSTRUCTION_START_PROMPT_ID = "profile_update_instruction_start"
62
+ PROFILE_UPDATE_INSTRUCTION_PROMPT_ID = "profile_update_instruction"
63
+
64
+
65
+ # ===============================
66
+ # Pydantic classes for profile_update_main prompt output schema
67
+ # ===============================
68
+
69
+
70
+ class ProfileAddItem(BaseModel):
71
+ """
72
+ Schema for a single profile item to be added.
73
+
74
+ Attributes:
75
+ content (str): The profile content based on content definition
76
+ time_to_live (str): Time to live for the profile - one of: 'one_day', 'one_week', 'one_month', 'one_quarter', 'one_year', 'infinity'
77
+ metadata (str, optional): Metadata extracted for the profile based on metadata definition
78
+ """
79
+
80
+ content: str = Field(description="Profile content based on content definition")
81
+ time_to_live: Literal[
82
+ "one_day", "one_week", "one_month", "one_quarter", "one_year", "infinity"
83
+ ] = Field(
84
+ description="Time to live for the profile - determines when the profile expires"
85
+ )
86
+ metadata: str | None = Field(
87
+ default=None,
88
+ description="Metadata extracted for the profile based on metadata definition",
89
+ )
90
+ source_span: str | None = Field(
91
+ default=None,
92
+ description="Verbatim excerpt from the source that most directly supports this profile item",
93
+ )
94
+ notes: str | None = Field(
95
+ default=None,
96
+ description="Free-form extraction notes — confidence, caveats, or alternative readings",
97
+ )
98
+ reader_angle: str | None = Field(
99
+ default=None,
100
+ description="The extraction perspective or reader role that surfaced this item",
101
+ )
102
+
103
+ # OpenAI structured output requires explicit schema constraints
104
+ model_config = ConfigDict(
105
+ extra="allow",
106
+ json_schema_extra={"additionalProperties": False},
107
+ )
108
+
109
+
110
+ class ProfileUpdateOutput(BaseModel):
111
+ """
112
+ Legacy output schema for profile_update_main prompt (kept for backward compatibility).
113
+ Represents the complete set of profile updates including additions, deletions, and mentions.
114
+
115
+ Attributes:
116
+ add (list[ProfileAddItem], optional): List of new profiles to be added
117
+ delete (list[str], optional): List of existing profile contents to be deleted
118
+ mention (list[str], optional): List of existing profile contents that were mentioned/referenced
119
+ """
120
+
121
+ add: list[ProfileAddItem] | None = Field(
122
+ default=None,
123
+ description="List of new profiles to be added with their content, time to live, and optional metadata",
124
+ )
125
+ delete: list[str] | None = Field(
126
+ default=None,
127
+ description="List of existing profile contents to be deleted (profiles that are contradicted by new interactions)",
128
+ )
129
+ mention: list[str] | None = Field(
130
+ default=None,
131
+ description="List of existing profile contents that were mentioned or referenced in the new interactions",
132
+ )
133
+
134
+ # OpenAI schema parsing requires explicitly forbidding additional properties
135
+ model_config = ConfigDict(
136
+ extra="allow",
137
+ json_schema_extra={"additionalProperties": False},
138
+ )
139
+
140
+
141
+ class StructuredProfilesOutput(BaseModel):
142
+ """
143
+ Output schema for extraction-only profile extraction.
144
+ Only extracts profiles — no delete/mention operations.
145
+
146
+ Attributes:
147
+ profiles (list[ProfileAddItem], optional): List of extracted profiles with content, time_to_live, and optional metadata
148
+ """
149
+
150
+ profiles: list[ProfileAddItem] | None = Field(
151
+ default=None,
152
+ description="List of extracted profiles with content, time_to_live, and optional metadata",
153
+ )
154
+
155
+ model_config = ConfigDict(
156
+ extra="allow",
157
+ json_schema_extra={"additionalProperties": False},
158
+ )
159
+
160
+
161
+ def calculate_expiration_timestamp(
162
+ last_modified_timestamp: int, profile_time_to_live: ProfileTimeToLive
163
+ ) -> int:
164
+ """
165
+ Calculate the expiration timestamp for a profile based on the last modified timestamp and the profile time to live.
166
+ Args:
167
+ last_modified_timestamp (int): The timestamp of the last modification of the profile.
168
+ profile_time_to_live (ProfileTimeToLive): The time to live of the profile.
169
+ Returns:
170
+ The expiration timestamp for the profile.
171
+ """
172
+ if profile_time_to_live == ProfileTimeToLive.INFINITY:
173
+ return NEVER_EXPIRES_TIMESTAMP
174
+
175
+ last_modified_datetime = datetime.fromtimestamp(last_modified_timestamp)
176
+ if profile_time_to_live == ProfileTimeToLive.ONE_DAY:
177
+ expiration_timestamp = last_modified_datetime + timedelta(days=1)
178
+ elif profile_time_to_live == ProfileTimeToLive.ONE_WEEK:
179
+ expiration_timestamp = last_modified_datetime + timedelta(days=7)
180
+ elif profile_time_to_live == ProfileTimeToLive.ONE_MONTH:
181
+ expiration_timestamp = last_modified_datetime + timedelta(days=30)
182
+ elif profile_time_to_live == ProfileTimeToLive.ONE_QUARTER:
183
+ expiration_timestamp = last_modified_datetime + timedelta(days=90)
184
+ elif profile_time_to_live == ProfileTimeToLive.ONE_YEAR:
185
+ expiration_timestamp = last_modified_datetime + timedelta(days=365)
186
+ else:
187
+ raise ValueError(f"Invalid profile time to live: {profile_time_to_live}")
188
+ return int(expiration_timestamp.timestamp())
189
+
190
+
191
+ def check_string_token_overlap(str1: str, str2: str, threshold: float = 0.7) -> bool:
192
+ """
193
+ Check if two strings have significant token overlap, indicating they might be referring to the same thing.
194
+ This is useful for fuzzy matching when exact string matching is too strict.
195
+
196
+ Args:
197
+ str1 (str): First string to compare
198
+ str2 (str): Second string to compare
199
+ threshold (float): Minimum overlap ratio required to consider strings as matching (0.0 to 1.0)
200
+
201
+ Returns:
202
+ bool: True if strings have significant overlap, False otherwise
203
+ """
204
+ # Normalize strings: lowercase and split into tokens
205
+ tokens1 = set(str1.lower().split())
206
+ tokens2 = set(str2.lower().split())
207
+
208
+ # Calculate overlap
209
+ if not tokens1 or not tokens2:
210
+ return False
211
+
212
+ # Calculate Jaccard similarity
213
+ intersection = len(tokens1.intersection(tokens2))
214
+
215
+ # Calculate overlap ratio
216
+ overlap_ratio = max(intersection / len(tokens1), intersection / len(tokens2))
217
+
218
+ return overlap_ratio >= threshold
219
+
220
+
221
+ def construct_profile_extraction_messages_from_sessions(
222
+ prompt_manager: PromptManager,
223
+ request_interaction_data_models: list[RequestInteractionDataModel],
224
+ existing_profiles: list[UserProfile],
225
+ agent_context_prompt: str,
226
+ context_prompt: str,
227
+ extraction_definition_prompt: str,
228
+ metadata_definition_prompt: str | None = None,
229
+ ) -> list[dict]:
230
+ """
231
+ Construct LLM messages for profile extraction from sessions.
232
+
233
+ This function uses the shared message construction interface to build messages
234
+ with a system prompt and a final user prompt specific to profile extraction.
235
+ Interactions are formatted grouped by session.
236
+
237
+ Args:
238
+ prompt_manager: The prompt manager for rendering prompt templates
239
+ request_interaction_data_models: List of request interaction groups to extract profiles from
240
+ existing_profiles: List of existing user profiles for context
241
+ agent_context_prompt: Context about the agent for system message
242
+ context_prompt: Additional context for system message
243
+ extraction_definition_prompt: Definition of what profiles should contain
244
+ metadata_definition_prompt: Optional definition for profile metadata
245
+
246
+ Returns:
247
+ list[dict]: List of messages ready for profile extraction
248
+ """
249
+ # Format existing profiles for the final prompt
250
+ formatted_existing_profiles = ", ".join(
251
+ [profile.content for profile in existing_profiles]
252
+ )
253
+
254
+ # Configure system message (before interactions)
255
+ # Stable content (instructions, examples, definitions) goes in system message for token caching
256
+ system_config = PromptConfig(
257
+ prompt_id=ProfileGenerationServiceConstants.PROFILE_UPDATE_INSTRUCTION_START_PROMPT_ID,
258
+ variables={
259
+ "agent_context_prompt": agent_context_prompt,
260
+ "context_prompt": context_prompt,
261
+ "extraction_definition_prompt": extraction_definition_prompt,
262
+ "metadata_definition_prompt": metadata_definition_prompt,
263
+ },
264
+ )
265
+
266
+ # Configure final user message (after interactions)
267
+ # Only dynamic per-call data goes in user message
268
+ user_config = PromptConfig(
269
+ prompt_id=ProfileGenerationServiceConstants.PROFILE_UPDATE_MAIN_PROMPT_ID,
270
+ variables={
271
+ "existing_profiles": formatted_existing_profiles,
272
+ "interactions": format_sessions_to_history_string(
273
+ request_interaction_data_models
274
+ ),
275
+ },
276
+ )
277
+
278
+ # Extract flat interactions for message construction (needed for image handling)
279
+ interactions = extract_interactions_from_request_interaction_data_models(
280
+ request_interaction_data_models
281
+ )
282
+
283
+ # Use shared message construction
284
+ config = MessageConstructionConfig(
285
+ prompt_manager=prompt_manager,
286
+ system_prompt_config=system_config,
287
+ user_prompt_config=user_config,
288
+ )
289
+
290
+ return construct_messages_from_interactions(interactions, config)
@@ -0,0 +1,17 @@
1
+ """Reflection service: critique-and-revise of cited memories after publish."""
2
+
3
+ from reflexio.server.services.reflection.reflection_service import ReflectionService
4
+ from reflexio.server.services.reflection.reflection_service_utils import (
5
+ ReflectionDecision,
6
+ ReflectionOutput,
7
+ ReflectionResult,
8
+ ReflectionServiceRequest,
9
+ )
10
+
11
+ __all__ = [
12
+ "ReflectionService",
13
+ "ReflectionServiceRequest",
14
+ "ReflectionDecision",
15
+ "ReflectionOutput",
16
+ "ReflectionResult",
17
+ ]
@@ -0,0 +1,247 @@
1
+ """LLM call that proposes per-citation reflection decisions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import logging
7
+ from typing import TYPE_CHECKING, Any
8
+
9
+ from reflexio.server.llm.litellm_client import LiteLLMClient
10
+ from reflexio.server.llm.model_defaults import ModelRole, resolve_model_name
11
+ from reflexio.server.services.reflection.reflection_service_utils import (
12
+ ReflectionOutput,
13
+ )
14
+ from reflexio.server.services.service_utils import (
15
+ log_llm_messages,
16
+ log_model_response,
17
+ )
18
+ from reflexio.server.site_var.site_var_manager import SiteVarManager
19
+
20
+ if TYPE_CHECKING:
21
+ from reflexio.models.api_schema.domain.entities import (
22
+ Interaction,
23
+ UserPlaybook,
24
+ UserProfile,
25
+ )
26
+ from reflexio.server.api_endpoints.request_context import RequestContext
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+ REFLECTION_TIMEOUT_SECONDS = 300
31
+ REFLECTION_MAX_RETRIES = 1
32
+ REFLECTION_PROMPT_ID = "memory_reflection"
33
+
34
+
35
+ class ReflectionExtractor:
36
+ """Build the reflection prompt and ask the LLM for decisions.
37
+
38
+ Thin wrapper around one ``LiteLLMClient`` call using
39
+ ``ReflectionOutput`` as the structured-output schema. Does not touch
40
+ storage.
41
+ """
42
+
43
+ def __init__(
44
+ self,
45
+ request_context: RequestContext,
46
+ llm_client: LiteLLMClient,
47
+ agent_context: str,
48
+ model_override: str | None,
49
+ ):
50
+ """Build a new extractor.
51
+
52
+ Args:
53
+ request_context (RequestContext): For prompt manager and
54
+ config access.
55
+ llm_client (LiteLLMClient): Shared LLM client.
56
+ agent_context (str): Agent-context prompt fragment from
57
+ config (free-form text describing the agent).
58
+ model_override (str | None): If set, used directly. Otherwise
59
+ falls back to ``LLMConfig.generation_model_name`` and the
60
+ site default for ``ModelRole.GENERATION``.
61
+ """
62
+ self.request_context = request_context
63
+ self.client = llm_client
64
+ self.agent_context = agent_context
65
+ self.model_name = self._resolve_model(model_override)
66
+
67
+ def _resolve_model(self, model_override: str | None) -> str:
68
+ config = self.request_context.configurator.get_config()
69
+ llm_config = config.llm_config if config else None
70
+ api_key_config = config.api_key_config if config else None
71
+ model_setting = SiteVarManager().get_site_var("llm_model_setting")
72
+ site_var = model_setting if isinstance(model_setting, dict) else {}
73
+ return resolve_model_name(
74
+ ModelRole.GENERATION,
75
+ site_var_value=site_var.get("default_generation_model_name"),
76
+ config_override=(
77
+ model_override
78
+ or (llm_config.generation_model_name if llm_config else None)
79
+ ),
80
+ api_key_config=api_key_config,
81
+ )
82
+
83
+ def run(
84
+ self,
85
+ *,
86
+ window_interactions: list[Interaction],
87
+ cited_profiles: list[UserProfile],
88
+ cited_user_playbooks: list[UserPlaybook],
89
+ horizon_by_key: dict[tuple[str, str], bool] | None = None,
90
+ ) -> ReflectionOutput:
91
+ """Render the prompt, call the LLM, return parsed output.
92
+
93
+ Returns an empty ``ReflectionOutput`` when nothing to consider
94
+ or when the LLM response cannot be parsed. LLM exceptions
95
+ propagate — the calling service decides whether to swallow.
96
+ """
97
+ if not cited_profiles and not cited_user_playbooks:
98
+ return ReflectionOutput()
99
+
100
+ per_citation_context = _build_per_citation_context(
101
+ cited_profiles=cited_profiles,
102
+ cited_user_playbooks=cited_user_playbooks,
103
+ horizon_by_key=horizon_by_key or {},
104
+ )
105
+
106
+ rendered = self.request_context.prompt_manager.render_prompt(
107
+ REFLECTION_PROMPT_ID,
108
+ {
109
+ "agent_context": self.agent_context or "",
110
+ "window_interactions_json": _interactions_to_json(window_interactions),
111
+ "cited_profiles_json": _profiles_to_json(cited_profiles),
112
+ "cited_user_playbooks_json": _playbooks_to_json(cited_user_playbooks),
113
+ "per_citation_context_json": per_citation_context,
114
+ },
115
+ )
116
+ messages = [{"role": "user", "content": rendered}]
117
+
118
+ logger.info(
119
+ "event=reflection_llm_start cited_profiles=%d cited_playbooks=%d "
120
+ "window_interactions=%d model=%s",
121
+ len(cited_profiles),
122
+ len(cited_user_playbooks),
123
+ len(window_interactions),
124
+ self.model_name,
125
+ )
126
+ log_llm_messages(logger, "Memory reflection", messages)
127
+
128
+ response = self.client.generate_chat_response(
129
+ messages=messages,
130
+ model=self.model_name,
131
+ response_format=ReflectionOutput,
132
+ timeout=REFLECTION_TIMEOUT_SECONDS,
133
+ max_retries=REFLECTION_MAX_RETRIES,
134
+ )
135
+ log_model_response(logger, "Memory reflection model response", response)
136
+
137
+ if isinstance(response, ReflectionOutput):
138
+ return response
139
+ logger.warning(
140
+ "event=reflection_llm_unparsed response_type=%s",
141
+ type(response).__name__,
142
+ )
143
+ return ReflectionOutput()
144
+
145
+
146
+ def _interactions_to_json(interactions: list[Interaction]) -> str:
147
+ payload: list[dict[str, Any]] = [
148
+ {
149
+ "interaction_id": i.interaction_id,
150
+ "request_id": i.request_id,
151
+ "role": i.role,
152
+ "content": i.content,
153
+ "tools_used": (
154
+ [t.model_dump() for t in i.tools_used] if i.tools_used else []
155
+ ),
156
+ "citations": [c.model_dump() for c in i.citations] if i.citations else [],
157
+ "created_at": i.created_at,
158
+ }
159
+ for i in interactions
160
+ ]
161
+ return json.dumps(payload, ensure_ascii=False, indent=2)
162
+
163
+
164
+ def _profiles_to_json(profiles: list[UserProfile]) -> str:
165
+ payload = [
166
+ {
167
+ "profile_id": p.profile_id,
168
+ "content": p.content,
169
+ "profile_time_to_live": p.profile_time_to_live.value,
170
+ "custom_features": p.custom_features,
171
+ "source": p.source,
172
+ "last_modified_timestamp": p.last_modified_timestamp,
173
+ }
174
+ for p in profiles
175
+ ]
176
+ return json.dumps(payload, ensure_ascii=False, indent=2)
177
+
178
+
179
+ def _playbooks_to_json(playbooks: list[UserPlaybook]) -> str:
180
+ """Serialize cited playbooks for the reflection prompt.
181
+
182
+ The prompt reads each rule's orientation directly from its ``content``
183
+ wording — no derived ``polarity`` hint is injected (that would re-derive
184
+ polarity, which is retired under LLM-judged orientation).
185
+
186
+ Args:
187
+ playbooks (list[UserPlaybook]): The cited playbooks to serialize.
188
+
189
+ Returns:
190
+ str: JSON array string with one object per cited playbook.
191
+ """
192
+ payload = [
193
+ {
194
+ "user_playbook_id": p.user_playbook_id,
195
+ "playbook_name": p.playbook_name,
196
+ "content": p.content,
197
+ "trigger": p.trigger,
198
+ "rationale": p.rationale,
199
+ "source": p.source,
200
+ }
201
+ for p in playbooks
202
+ ]
203
+ return json.dumps(payload, ensure_ascii=False, indent=2)
204
+
205
+
206
+ def _build_per_citation_context(
207
+ *,
208
+ cited_profiles: list[UserProfile],
209
+ cited_user_playbooks: list[UserPlaybook],
210
+ horizon_by_key: dict[tuple[str, str], bool],
211
+ ) -> str:
212
+ """Serialize per-citation horizon flags into a JSON string for the prompt.
213
+
214
+ For each cited profile/playbook, emits an object with target_kind,
215
+ target_id, and has_full_horizon. ``has_full_horizon`` defaults to
216
+ True when the citation key isn't in ``horizon_by_key`` (defensive
217
+ fallback — the caller normally populates the dict from
218
+ _filter_citations_by_horizon).
219
+
220
+ Args:
221
+ cited_profiles (list[UserProfile]): Profile citations to include.
222
+ cited_user_playbooks (list[UserPlaybook]): Playbook citations to include.
223
+ horizon_by_key (dict[tuple[str, str], bool]): Maps (kind, id) to
224
+ has_full_horizon flag.
225
+
226
+ Returns:
227
+ str: JSON array string with per-citation horizon context.
228
+ """
229
+ payload: list[dict[str, Any]] = [
230
+ {
231
+ "target_kind": "profile",
232
+ "target_id": p.profile_id,
233
+ "has_full_horizon": horizon_by_key.get(("profile", p.profile_id), True),
234
+ }
235
+ for p in cited_profiles
236
+ ]
237
+ payload.extend(
238
+ {
239
+ "target_kind": "playbook",
240
+ "target_id": str(pb.user_playbook_id),
241
+ "has_full_horizon": horizon_by_key.get(
242
+ ("playbook", str(pb.user_playbook_id)), True
243
+ ),
244
+ }
245
+ for pb in cited_user_playbooks
246
+ )
247
+ return json.dumps(payload, ensure_ascii=False, indent=2)