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,179 @@
1
+ """Process-local concurrency limiters for latency-sensitive operations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import threading
7
+ import time
8
+ from collections.abc import Callable
9
+ from contextlib import contextmanager
10
+ from dataclasses import dataclass
11
+ from typing import Any, Literal
12
+
13
+ from fastapi import HTTPException, status
14
+
15
+ from reflexio.server.usage_metrics import record_usage_event
16
+
17
+ OperationName = Literal["search", "publish", "aggregation"]
18
+
19
+ _DEFAULT_LIMITS: dict[OperationName, int] = {
20
+ "search": 8,
21
+ "publish": 4,
22
+ "aggregation": 1,
23
+ }
24
+ _DEFAULT_TIMEOUT_SECONDS: dict[OperationName, float] = {
25
+ "search": 2.0,
26
+ "publish": 5.0,
27
+ "aggregation": 1.0,
28
+ }
29
+
30
+
31
+ @dataclass
32
+ class _LimiterState:
33
+ semaphore: threading.BoundedSemaphore
34
+ limit: int
35
+ waiting: int = 0
36
+
37
+
38
+ _limiters: dict[tuple[str, OperationName], _LimiterState] = {}
39
+ _limiters_lock = threading.Lock()
40
+
41
+
42
+ def _env_key(operation: OperationName, suffix: str) -> str:
43
+ return f"REFLEXIO_{operation.upper()}_CONCURRENCY_{suffix}"
44
+
45
+
46
+ def _limit_for(operation: OperationName) -> int:
47
+ raw = os.getenv(_env_key(operation, "LIMIT"), "").strip()
48
+ if raw.isdigit():
49
+ return max(1, int(raw))
50
+ return _DEFAULT_LIMITS[operation]
51
+
52
+
53
+ def _timeout_for(operation: OperationName) -> float:
54
+ raw = os.getenv(_env_key(operation, "TIMEOUT_SECONDS"), "").strip()
55
+ if raw:
56
+ try:
57
+ return max(0.0, float(raw))
58
+ except ValueError:
59
+ pass
60
+ return _DEFAULT_TIMEOUT_SECONDS[operation]
61
+
62
+
63
+ def _state_for(org_id: str, operation: OperationName) -> _LimiterState:
64
+ key = (str(org_id), operation)
65
+ desired_limit = _limit_for(operation)
66
+ with _limiters_lock:
67
+ state = _limiters.get(key)
68
+ if state is None or state.limit != desired_limit:
69
+ state = _LimiterState(
70
+ semaphore=threading.BoundedSemaphore(desired_limit),
71
+ limit=desired_limit,
72
+ )
73
+ _limiters[key] = state
74
+ return state
75
+
76
+
77
+ def _record_limiter_event(
78
+ *,
79
+ org_id: str,
80
+ operation: OperationName,
81
+ event_name: str,
82
+ outcome: str,
83
+ wait_ms: int,
84
+ waiting: int,
85
+ limit: int,
86
+ ) -> None:
87
+ record_usage_event(
88
+ org_id=org_id,
89
+ event_name=event_name,
90
+ event_category="limiter",
91
+ pipeline=operation,
92
+ outcome=outcome,
93
+ duration_ms=wait_ms,
94
+ metadata={
95
+ "operation": operation,
96
+ "waiting": waiting,
97
+ "limit": limit,
98
+ },
99
+ )
100
+
101
+
102
+ @contextmanager
103
+ def operation_limit(
104
+ org_id: str,
105
+ operation: OperationName,
106
+ *,
107
+ timeout_seconds: float | None = None,
108
+ ) -> Any:
109
+ """Acquire the per-org limiter for an operation, recording wait metrics."""
110
+ state = _state_for(org_id, operation)
111
+ timeout = _timeout_for(operation) if timeout_seconds is None else timeout_seconds
112
+ start = time.perf_counter()
113
+ with _limiters_lock:
114
+ state.waiting += 1
115
+ waiting = state.waiting
116
+ acquired = False
117
+ try:
118
+ acquired = state.semaphore.acquire(timeout=timeout)
119
+ wait_ms = int((time.perf_counter() - start) * 1000)
120
+ with _limiters_lock:
121
+ state.waiting -= 1
122
+ waiting_after = state.waiting
123
+ if not acquired:
124
+ _record_limiter_event(
125
+ org_id=org_id,
126
+ operation=operation,
127
+ event_name="limiter_acquire_timeout",
128
+ outcome="timeout",
129
+ wait_ms=wait_ms,
130
+ waiting=waiting_after,
131
+ limit=state.limit,
132
+ )
133
+ raise TimeoutError(
134
+ f"{operation} concurrency limit reached for org {org_id}"
135
+ )
136
+ _record_limiter_event(
137
+ org_id=org_id,
138
+ operation=operation,
139
+ event_name="limiter_acquired",
140
+ outcome="acquired",
141
+ wait_ms=wait_ms,
142
+ waiting=waiting,
143
+ limit=state.limit,
144
+ )
145
+ yield
146
+ finally:
147
+ if acquired:
148
+ state.semaphore.release()
149
+
150
+
151
+ def run_with_operation_limit[T](
152
+ *,
153
+ org_id: str,
154
+ operation: OperationName,
155
+ fn: Callable[[], T],
156
+ timeout_seconds: float | None = None,
157
+ ) -> T:
158
+ with operation_limit(org_id, operation, timeout_seconds=timeout_seconds):
159
+ return fn()
160
+
161
+
162
+ def limiter_http_exception(operation: OperationName) -> HTTPException:
163
+ """Return the API error used when an operation limiter is saturated."""
164
+ retry_after = str(max(1, int(_timeout_for(operation))))
165
+ status_code = (
166
+ status.HTTP_429_TOO_MANY_REQUESTS
167
+ if operation == "search"
168
+ else status.HTTP_503_SERVICE_UNAVAILABLE
169
+ )
170
+ return HTTPException(
171
+ status_code=status_code,
172
+ detail=f"{operation} concurrency limit reached",
173
+ headers={"Retry-After": retry_after},
174
+ )
175
+
176
+
177
+ def reset_operation_limiters_for_tests() -> None:
178
+ with _limiters_lock:
179
+ _limiters.clear()
@@ -0,0 +1,54 @@
1
+ """Heuristic question-shape classifiers for conditional prompt rendering.
2
+
3
+ The search-agent prompt is split: the main prompt covers Patterns A-H dispatch
4
+ plus all pattern recipes EXCEPT Pattern D. Pattern D's recipe lives in a
5
+ separate prompt file and is appended only when the question is classified as
6
+ list-shape. This isolation prevents Pattern D rule changes from bleeding into
7
+ non-list questions (the dominant regression mode in v1.20.0/v1.21.0/v1.22.0/
8
+ v1.23.0 search iterations).
9
+
10
+ False negatives fall through to Pattern A behaviour (safe default — the
11
+ main prompt's dispatch test still routes the agent to the correct pattern).
12
+ False positives are tolerable: Pattern D recipe in context but the agent's
13
+ own dispatch test still picks the right pattern.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import re
19
+
20
+ # Patterns that signal list/enumeration shape.
21
+ # Order matters only for early-exit; any match returns True.
22
+ _LIST_PATTERNS: tuple[re.Pattern[str], ...] = (
23
+ # "Which sports", "what books", "which TV series", "which fantasy novels"
24
+ # — plural noun (≥4 chars to avoid matching short verbs like "is", "was",
25
+ # "does"), optionally preceded by up to 2 intermediate words (adjectives /
26
+ # short qualifiers like "TV", "other").
27
+ re.compile(r"\b(which|what)\s+(?:\w+\s+){0,2}\w{3,}s\b", re.IGNORECASE),
28
+ # Counting / total / list-all operators
29
+ re.compile(
30
+ r"\b(how many|how much|total|list (all|every)|all the|every|count)\b",
31
+ re.IGNORECASE,
32
+ ),
33
+ # Exclusion-shaped lists ("besides X", "other than Y", "not Z-related")
34
+ re.compile(r"\b(besides|other than)\b", re.IGNORECASE),
35
+ # "What other places", "what other movies"
36
+ re.compile(r"\bother\s+\w+s?\b", re.IGNORECASE),
37
+ # Superlatives over a category
38
+ re.compile(r"\b(most|least|highest|lowest|best|worst)\s+\w+", re.IGNORECASE),
39
+ )
40
+
41
+
42
+ def is_pattern_d_question(query: str) -> bool:
43
+ """Return True when the question's shape suggests Pattern D (list/aggregation).
44
+
45
+ Args:
46
+ query (str): The user question text.
47
+
48
+ Returns:
49
+ bool: True if any list/enumeration heuristic matches; False otherwise.
50
+ """
51
+ return any(p.search(query) for p in _LIST_PATTERNS)
52
+
53
+
54
+ __all__ = ["is_pattern_d_question"]
@@ -0,0 +1,121 @@
1
+ # prompt_bank
2
+
3
+ File-based versioned prompt templates for LLM operations.
4
+
5
+ > Part of the [Reflexio Server](../../README.md). See also the [Playbook Service](../../services/playbook/README.md) for prompt usage in playbook extraction.
6
+
7
+ ## Main Entry Points
8
+
9
+ - **Manager**: `../prompt_manager.py` — `PromptManager`
10
+ - **Templates**: Each subdirectory is a `prompt_id`
11
+
12
+ ## Directory Structure
13
+
14
+ ```
15
+ prompt_bank/
16
+ ├── README.md
17
+ ├── playbook_aggregation/
18
+ │ ├── v1.0.0.prompt.md
19
+ │ ├── v1.1.0.prompt.md
20
+ │ └── v2.1.0.prompt.md ← active: true in frontmatter
21
+ ├── query_reformulation/
22
+ │ └── v1.0.0.prompt.md ← active: true (only version)
23
+ └── ...
24
+ ```
25
+
26
+ ## File Format
27
+
28
+ Each `.prompt.md` file is self-contained with YAML frontmatter:
29
+
30
+ ```markdown
31
+ ---
32
+ active: true
33
+ description: "What this prompt does"
34
+ changelog: "Why this version was created"
35
+ variables:
36
+ - var1
37
+ - var2
38
+ ---
39
+
40
+ Your prompt content with {var1} and {var2} placeholders.
41
+ ```
42
+
43
+ ### Frontmatter Fields
44
+
45
+ | Field | Type | Required | Purpose |
46
+ |-------|------|----------|---------|
47
+ | `active` | bool | No | `true` on the active version. Exactly one per prompt_id |
48
+ | `description` | string | No | What this prompt does. Include on all versions for context |
49
+ | `changelog` | string | No | Why this version was created — what changed from the previous version |
50
+ | `variables` | list[str] | Yes | Required template variables for validation |
51
+
52
+ ## Usage
53
+
54
+ ```python
55
+ # Access via request_context
56
+ rendered = request_context.prompt_manager.render_prompt(
57
+ "profile_update_main",
58
+ {"variable1": "value1", "variable2": "value2"}
59
+ )
60
+ ```
61
+
62
+ ## Adding a New Prompt
63
+
64
+ 1. Create directory: `mkdir prompt_bank/my_new_prompt/`
65
+ 2. Create `v1.0.0.prompt.md` with frontmatter and `{variable}` placeholders
66
+ 3. Set `active: true` in frontmatter
67
+
68
+ ## Version Naming Convention
69
+
70
+ File names: `v{MAJOR}.{MINOR}.{PATCH}.prompt.md`
71
+
72
+ - **MAJOR**: Breaking changes that introduce a different set of variables
73
+ - **MINOR**: Significant updates without changing variables
74
+ - **PATCH**: Minor tweaks to prompt content
75
+
76
+ ## Deactivating a Prompt Version
77
+
78
+ When creating a replacement version, deactivate the old version by **removing** the `active: true` line from its frontmatter. Do NOT add `active: false` — simply omit the field. Prompts without the `active` field default to `active: false` (see `prompt_manager.py` line 211: `meta.get("active", False)`). Only the new replacement version should have `active: true`.
79
+
80
+ **Before** (old version `v1.0.0.prompt.md`):
81
+ ```yaml
82
+ ---
83
+ active: true
84
+ description: "Original prompt"
85
+ variables:
86
+ - var1
87
+ ---
88
+ ```
89
+
90
+ **After** (old version `v1.0.0.prompt.md` — `active` line removed):
91
+ ```yaml
92
+ ---
93
+ description: "Original prompt"
94
+ variables:
95
+ - var1
96
+ ---
97
+ ```
98
+
99
+ **New version** (`v2.0.0.prompt.md`):
100
+ ```yaml
101
+ ---
102
+ active: true
103
+ description: "Improved prompt"
104
+ changelog: "Replaced v1.0.0 with better instructions"
105
+ variables:
106
+ - var1
107
+ ---
108
+ ```
109
+
110
+ ## Key Rules
111
+
112
+ - **Prompt ID** = Directory name
113
+ - **Variables** use `{variable_name}` syntax in prompt body
114
+ - **Exactly one** version per prompt must have `active: true`
115
+ - **Deactivate old versions** by removing the `active: true` line — never add `active: false`
116
+ - **NEVER hardcode prompts** — always use `PromptManager`
117
+
118
+ ## See Also
119
+
120
+ - [Server README](../../README.md) -- FastAPI backend component overview
121
+ - [Playbook Service README](../../services/playbook/README.md) -- how prompts are used in playbook extraction and aggregation
@@ -0,0 +1,58 @@
1
+ ---
2
+ active: true
3
+ description: "Evaluates agent success based on user interactions"
4
+ variables:
5
+ - agent_context_prompt
6
+ - success_definition_prompt
7
+ - tool_can_use
8
+ - metadata_definition_prompt
9
+ - interactions
10
+ ---
11
+
12
+ [Instruction]
13
+ Given the interactions above, evaluate if the agent has successfully completed the user's primary requested task by the end of the session, based on the success definition below.
14
+ The agent may make mistakes or take wrong actions during the session. The user may provide corrections or ask the agent to try differently. These mid-session errors do NOT constitute failure — focus on the final outcome. As long as the user's primary task is completed successfully by the end of the session, set is_success to True.
15
+ Step 1: Identify the user's primary task from the interactions. Then determine if the agent has fulfilled this task by the end of the session based on the success definition. If so, return with is_success equals to True, else set is_success to False and continue to next step.
16
+ Step 2: If the agent did not complete the primary task by the end of the session, determine what is the failure type and failure reason.
17
+ There are four types of failures:
18
+ - 'missing_tool': Agent does not have the right tool or action that it can take to get the sufficient information to answer user's request.
19
+ - 'wrong_tool': Tools or actions are available, but agent should use the right tool or performed the right action.
20
+ - 'insufficient_info_from_tool': Agent has performed the right action and tool use, but the tool or action does not have enough/right information to successfully answer user's request
21
+ - 'wrong_answer': Agent has enough information but still didn't successfully answer user's request
22
+ Step 3: Determine if the user was escalated (handed off to a human agent or another agent). Set is_escalated to True if so, False otherwise. Escalation typically means the agent could not resolve the issue itself. Note: escalated sessions are likely unsuccessful, but unsuccessful sessions are not necessarily escalated.
23
+
24
+ [Context]
25
+ {agent_context_prompt}
26
+
27
+ [Success definition]
28
+ {success_definition_prompt}
29
+
30
+ [Interactions]
31
+ User and agent interactions:
32
+ {interactions}
33
+
34
+ [Tools]
35
+ {tool_can_use}
36
+
37
+ [Metadata Definition]
38
+ {metadata_definition_prompt}
39
+
40
+ [Output]
41
+ Generate the output in valid JSON format using the following schema
42
+ # success case example
43
+ ```json
44
+ {{
45
+ "is_success": true,
46
+ "is_escalated": false
47
+ }}
48
+ ```
49
+
50
+ # failure case example
51
+ ```json
52
+ {{
53
+ "is_success": false,
54
+ "failure_type": "missing_tool" or "wrong_tool" or "insufficient_info_from_tool" or "wrong_answer",
55
+ "failure_reason": "explain reason for failure, what agent need to do differently",
56
+ "is_escalated": true
57
+ }}
58
+ ```
@@ -0,0 +1,76 @@
1
+ ---
2
+ active: false
3
+ description: "DEPRECATED — session-level shadow comparison combined prompt (F1 cleanup). The session-level approach suffers from trajectory contamination: user turns 2+ react to the regular response, not the shadow, so the two trajectories are not apples-to-apples. Replaced by the per-turn shadow_comparison prompt. Kept as a historical record so any v1.0.0 verdicts produced under this prompt can still be located in audit logs."
4
+ variables:
5
+ - agent_context_prompt
6
+ - success_definition_prompt
7
+ - request_1_interactions
8
+ - request_2_interactions
9
+ - tool_can_use
10
+ - metadata_definition_prompt
11
+ ---
12
+
13
+ [Instruction]
14
+ You have two versions of an agent-user interaction: Request 1 and Request 2.
15
+ Perform two tasks:
16
+ Task 1: Evaluate if the Request 1 agent has successfully responded to the user based on the success definition below.
17
+ Task 2: Compare Request 1 and Request 2 to determine which better satisfies the success definition.
18
+
19
+ For Task 1 (evaluate Request 1):
20
+ Evaluate if the agent has successfully completed the user's primary requested task by the end of the session.
21
+ The agent may make mistakes or take wrong actions during the session. The user may provide corrections or ask the agent to try differently. These mid-session errors do NOT constitute failure — focus on the final outcome. As long as the user's primary task is completed successfully by the end of the session, set is_success to True.
22
+ Step 1: Identify the user's primary task from the interactions. Then determine if the agent has fulfilled this task by the end of the session based on the success definition. If so, return with is_success equals to True, else set is_success to False and continue to next step.
23
+ Step 2: If the agent did not complete the primary task by the end of the session, determine what is the failure type and failure reason.
24
+ There are four types of failures:
25
+ - 'missing_tool': Agent does not have the right tool or action that it can take to get the sufficient information to answer user's request.
26
+ - 'wrong_tool': Tools or actions are available, but agent should use the right tool or performed the right action.
27
+ - 'insufficient_info_from_tool': Agent has performed the right action and tool use, but the tool or action does not have enough/right information to successfully answer user's request
28
+ - 'wrong_answer': Agent has enough information but still didn't successfully answer user's request
29
+ Step 3: Determine if the user was escalated (handed off to a human agent or another agent). Set is_escalated to True if so, False otherwise. Escalation typically means the agent could not resolve the issue itself. Note: escalated sessions are likely unsuccessful, but unsuccessful sessions are not necessarily escalated.
30
+
31
+ For Task 2 (compare Request 1 vs Request 2):
32
+ Determine which request better satisfies the success definition and whether the difference is significant.
33
+
34
+ [Context]
35
+ {agent_context_prompt}
36
+
37
+ [Success definition]
38
+ {success_definition_prompt}
39
+
40
+ [Request 1]
41
+ {request_1_interactions}
42
+
43
+ [Request 2]
44
+ {request_2_interactions}
45
+
46
+ [Tools]
47
+ {tool_can_use}
48
+
49
+ [Metadata Definition]
50
+ {metadata_definition_prompt}
51
+
52
+ [Output]
53
+ Generate the output in valid JSON format using the following schema:
54
+ # Task 1 success case:
55
+ ```json
56
+ {{
57
+ "is_success": true,
58
+ "is_escalated": false,
59
+ "better_request": "1" or "2" or "tie",
60
+ "is_significantly_better": true or false,
61
+ "comparison_reason": "brief explanation"
62
+ }}
63
+ ```
64
+
65
+ # Task 1 failure case:
66
+ ```json
67
+ {{
68
+ "is_success": false,
69
+ "failure_type": "missing_tool" or "wrong_tool" or "insufficient_info_from_tool" or "wrong_answer",
70
+ "failure_reason": "explain reason for failure, what agent need to do differently",
71
+ "is_escalated": true,
72
+ "better_request": "1" or "2" or "tie",
73
+ "is_significantly_better": true or false,
74
+ "comparison_reason": "brief explanation"
75
+ }}
76
+ ```
@@ -0,0 +1,88 @@
1
+ ---
2
+ active: true
3
+ description: "Answer-LLM system prompt for memory-grounded user questions. Triages retrieved profiles into direct-answer / preference / arithmetic categories, applies counting / date / instance-disambiguation rules, and cites profile_ids as Sources."
4
+ variables: []
5
+ ---
6
+ You are an AI assistant answering questions about a user based on their past conversations. The context below contains:
7
+
8
+ 1. **Retrieved Memories** — extracted profiles (`[profile_id]`-tagged); facts about the user.
9
+ 2. **Original Session Excerpts** (when present) — verbatim transcripts of the most relevant past conversations. Excerpts include BOTH user and assistant turns, so they're the authoritative source when the question asks what YOU previously told the user (e.g. "remind me what you said about X", "what did you recommend for Y"). Profiles often miss assistant statements. When you find the answer in an excerpt, still cite the matching profile_ids in `Sources:` (the excerpt itself has no id).
10
+
11
+ Reasoning template — apply to EVERY question before answering:
12
+
13
+ 1. Triage the retrieved profiles:
14
+ a. Profiles that DIRECTLY answer the question (a fact whose subject and predicate match what's being asked).
15
+ b. Profiles carrying GENERALIZABLE preferences or lifestyle context that could shape an answer (preferences from a past conversation that apply to a new query — e.g., a stored preference about hotel features that can inform a hotel question in a new city; a stored lifestyle constraint that informs a recommendation; a stored role/domain that shapes what's relevant).
16
+ c. Profiles whose DATES OR COUNTS matter for arithmetic (date subtraction, item counting, recency comparison).
17
+
18
+ 2. Compose the answer:
19
+ - If category (a) is non-empty, the question is direct recall; answer using the matching profile and cite its profile_id.
20
+ - If (a) is empty but (b) suggests a tailored answer, apply the preferences and answer. Do NOT refuse just because the specific entity (city, venue, time, person) wasn't mentioned before — generalize the preference, not the entity.
21
+ - If (c) provides values for arithmetic, compute and show the work.
22
+
23
+ 3. **Do not say "I don't have X" without first using everything available.** Refusal is a last resort, not a default. Before declaring absence:
24
+ - Check whether ANY retrieved profile names the topic. If yes, your answer should describe what the profiles DO say and surface what's missing concretely. The user can use partial information; a flat refusal forfeits it.
25
+ - For questions asking the assistant to recall a previous answer ("what did you tell me about X", "remind me of that recommendation"), search retrieved profiles for any phrasing that credits an agent statement (`agent recommended`, `agent said`, `agent described`). The relevant atom may be in a profile that doesn't share keywords with the question's specific noun. If no profile has the literal answer, describe the closest related context the user gave you.
26
+ - For date-arithmetic questions, you have TWO sources of date information per profile: (i) ISO dates inside the profile's content, and (ii) the `(session_date=YYYY-MM-DD)` annotation rendered next to each profile, which is the date of the original conversation. If the user's utterance was a one-time event ("just downloaded", "today", "recently", "got back"), the session_date IS the event date. Compute the arithmetic from that. Do not refuse a date arithmetic question if either source provides usable date(s).
27
+
28
+ 4. For questions about what the user currently thinks/does, use the MOST RECENT information when there are updates or corrections (compare last_modified_timestamp on retrieved profiles, or pick the profile with the most-recent context). For records/bests/goals, a newer "I hope to beat my personal best of X" is evidence X is the current value, even if an older profile stored a different number.
29
+
30
+ 5. Always cite. End your answer with: `Sources: [profile_id_1, profile_id_2, ...]` listing the profile_ids you used. If you used none, write `Sources: []`. This is required.
31
+
32
+ 6. Pay attention to dates and temporal context. The "question date" tells you when the question is being asked. When computing duration arithmetic, prefer ISO dates from profile content; fall back to the `(session_date=YYYY-MM-DD)` annotation on the profile when content lacks an explicit date.
33
+
34
+ 7. Do NOT invent specific facts (named entities, exact quotes, specific dates) that aren't in the context. Preferences and lifestyle context, however, you SHOULD apply liberally — that's what they're for.
35
+
36
+ 8. If after applying all the above you genuinely have no relevant evidence (no topic-naming profile, no preference, no usable date), then answer concisely "I don't have that information" and cite Sources: []. This is the LAST resort, not the default.
37
+
38
+ 9. **Counting questions** (e.g., "how many X", "total Y", "all my Z"): explicitly enumerate every qualifying profile before stating the count. Format:
39
+ - "1. <profile content snippet>"
40
+ - "2. <profile content snippet>"
41
+ - "Total: N"
42
+ Rules:
43
+ - Each enumerated item must come from a distinct profile_id; never count the same profile twice.
44
+ - If two profiles describe the same real-world item (different wordings of the same restaurant/bike/event), dedupe.
45
+ - Distinguish "completed" vs "planned/considered": if the question is "how many X did I", planned-but-not-done items don't count unless the question is explicit about plans.
46
+ - **Action decomposition**: when the question counts ACTIONS rather than physical entities (e.g., "items to pick up OR return", "events I attended OR plan to attend", "places I visited OR booked"), count each distinct action as its own item — even if the same physical entity participates in multiple actions. An EXCHANGE = return-the-old + pick-up-the-new = 2 actions on the same entity. A round-trip flight = 2 flights when the question counts flight legs. Read the question's predicate carefully: if it says "X or Y" with two distinct verbs, count atoms satisfying EITHER verb.
47
+ - If you arrive at a count by inference rather than enumeration (e.g. "I see at least N"), that's a sign you may be guessing — go back and enumerate.
48
+
49
+ 10. **Date arithmetic** (e.g., "how many weeks ago", "between X and Y", "order from earliest to latest"): show your work explicitly:
50
+ - List the relevant dates first: `event_X = YYYY-MM-DD`, `event_Y = YYYY-MM-DD`.
51
+ - Compute the difference in days, then convert to the unit the question asks for.
52
+ - For "how many weeks ago", compute `(question_date - event_date) / 7`.
53
+ - For ordering, sort the events by their dates ascending before stating the order.
54
+ - For "before X / after Y", state which date is earlier/later before naming the event.
55
+ Sanity check: the result should typically be positive and within a reasonable range (years ≤ 10, weeks ≤ 200). If you compute a wildly large duration (e.g., 1000+ days for a recent event), you probably used the wrong date — re-check.
56
+
57
+ 11. **Multi-iteration artifact recall** (when the question asks you to recall a previous assistant-generated artifact like a table, schedule, list, or recommendation):
58
+ - If the rehydrated session excerpts contain MULTIPLE iterations of the same artifact (the assistant regenerated it as the user refined the request), use the LAST iteration as canonical. Earlier iterations are scaffolding; the final one is the answer.
59
+ - Tell-tale signs: the same table reappears with different content; the user said "now use real names" / "make it 7 agents" / similar refinement after an earlier draft.
60
+ - When citing, prefer profile_ids whose content matches the FINAL artifact's slot values (e.g. specific names) over those describing the meta-artifact (e.g. "user is creating a shift rotation sheet").
61
+
62
+ 12. **Instance disambiguation** (when multiple candidates of the same topic appear and the question's specifier picks one):
63
+ - Read the question's distinctive specifier carefully (e.g. "the <CATEGORY> with <DISTINCTIVE_ATTRIBUTE>", "the conversation about <TOPIC>", "the <ITEM> in <PLACE_NAME>").
64
+ - Find the candidate whose retrieved content/excerpt CONTAINS that specifier verbatim or near-verbatim. Do not pick a candidate just because it shares the topic noun (the broad category) — match the specifier.
65
+ - If no candidate matches the specifier, prefer "I don't have that specific instance in the available context" over guessing among candidates.
66
+
67
+ 13. **Presupposition verification** (when the question names a SPECIFIC entity — employer, school, person, place, brand — that anchors the answer):
68
+ - Before computing any numeric answer or substituting a similar entity, verify that the named entity APPEARS LITERALLY in at least one retrieved profile or rehydrated excerpt.
69
+ - If the question says `"my job at <NAMED_EMPLOYER>"` but no profile mentions `<NAMED_EMPLOYER>`, do NOT silently substitute the user's actual employer into the answer. The question's premise is false; respond: `"I don't have any record of you working at <NAMED-ENTITY>; based on the information I have, you currently work at <ACTUAL-ENTITY>."` (or simply `"I don't see <NAMED-ENTITY> in your history"` if no actual-entity context applies).
70
+ - Apply this to specific named places (e.g. `"the <FACILITY> in <CITY>"`), people (`"my colleague <NAME>"`), employers, schools, brands, projects, accounts. If the literal name isn't in your context, surface that fact rather than computing a numeric answer based on assumed-but-unverified premises.
71
+ - This rule does NOT mean refuse generic questions ("how many books have I read") — it applies only when the question references a SPECIFIC named entity.
72
+
73
+ 14. **Time-anchored instance disambiguation** (when the question references an event with a TIME specifier — "two months ago", "in March", "last weekend", "this year", "yesterday", "on YYYY-MM-DD"):
74
+ - **Step 1: Compute the target date FIRST**, before scanning candidates.
75
+ - Relative phrases (X ago / X weeks/months ago): `target_date = question_date − duration`.
76
+ - Period phrases (in March, last year, this week): the date range that matches.
77
+ - Explicit dates: use as-is.
78
+ - **Step 2: Find the candidate whose profile date is CLOSEST to target_date** (within ±2 weeks for "X months ago", within the same month for "in March", within the same week for "last week").
79
+ - **Step 3: Read THAT candidate's attributes to answer the question** — even if it lacks the specific attribute the question is asking about. A negative answer ("no, you did not visit with a friend") IS a valid answer when the matched candidate's profile content doesn't mention that attribute.
80
+ - **DO NOT** pick a different-date candidate just because it has the attribute the question is asking about (e.g. picking the Science Museum visit from 5 months ago because it has "with friend" when the question asks about 2 months ago). The TIME SPECIFIER is the disambiguator; the attribute is what you report ABOUT the disambiguated instance, not the disambiguation criterion.
81
+ - If NO candidate matches the time window, say so explicitly: "I don't see an event around <target_date>".
82
+
83
+ 15. **Category-superlative date-window leniency** (when the question is "which [category] did I [verb] the most/least at" or similar superlative comparison within a category, with a fuzzy time qualifier like "in the past month", "recently", "lately", "in the last few weeks"):
84
+ - The ranking criterion is the superlative (highest spend, most often, longest, etc.) — NOT a strict day-count cutoff. The user wants the winner among recently-mentioned candidates, not a hard chronological filter.
85
+ - Treat fuzzy time phrases as **soft windows with ~2 weeks of buffer** beyond strict interpretation: "in the past month" includes recent purchases up to ~6 weeks back; "recently" / "lately" similarly inclusive.
86
+ - **Compare ALL retrieved candidates by the superlative criterion**, even ones at the edge of the window. Do NOT exclude a candidate solely because its date is e.g. 35 days before the question_date when the question says "past month" — if it's the only candidate with the highest value, it IS the answer.
87
+ - This rule does NOT apply when the question uses an EXPLICIT date or precise period ("on YYYY-MM-DD", "between March and May", "after my birthday"). For those, apply strict filtering per rule 14.
88
+ - When in doubt: if applying strict filtering would leave you with NO valid answer or with a clearly-not-the-best candidate, expand the window first; surfacing the substantive answer beats a strict-but-wrong refusal.
@@ -0,0 +1,31 @@
1
+ ---
2
+ active: true
3
+ description: "Compress raw conversation turns against a query — denoising layer for read_session_text rehydration so downstream agents see signal, not noise. Preserves answer-bearing atoms (counts, dates, named entities, attributes) for category-aggregation, ordering, and comparison questions."
4
+ variables:
5
+ - query
6
+ - raw_turns
7
+ ---
8
+ You are compressing a conversation transcript so a downstream agent can answer a specific question. Your only job is to extract the parts of the transcript that contain evidence relevant to the question — verbatim where possible — and discard everything else.
9
+
10
+ ## Question
11
+
12
+ {query}
13
+
14
+ ## Conversation transcript
15
+
16
+ {raw_turns}
17
+
18
+ ## Output rules
19
+
20
+ Output the smallest possible excerpt that preserves every detail relevant to the question. Follow these rules exactly:
21
+
22
+ - **For counting, aggregation, ordering, comparison, before/after, earliest/latest, duration/elapsed-time, total/sum, relationship lookup, or entity-attribute questions, optimize for recall over brevity.** Keep every transcript atom that could be one candidate item, one excluded item, one event before/after an anchor, one temporal anchor, one start/end/milestone, one amount to add/subtract, one entity being looked up, one attribute/value for that entity, or one reason an item does/does not qualify. Do not stop after the most obvious matches; include all same-category candidates and all mentions of the queried entity or relationship in the retrieved transcript, even if relevance is uncertain. For temporal questions, retain the dates or date-like phrases for the anchor event and for every candidate event/item in the same category, including adjacent turns that connect a relative date to an entity. If the query asks about a person, pet, tank, company, schedule, family member, named object, event, trip, property, book, museum, charity activity, purchase, or appointment, retain every nearby fact that assigns it a count, age, employer, role, shift, cost, date, duration, sequence position, or other attribute.
23
+ - **Keep verbatim quotes for any specific atom that could be the answer or an operand**: prices, dates, counts, names, exact phrases, schedules, durations, locations, identifiers. Do NOT paraphrase numbers, names, or quoted strings — copy them character-for-character.
24
+ - **Keep enough surrounding context** (one or two adjacent sentences) so each retained operand's meaning is unambiguous. If the user said "I paid $800 for them" referring to boots from earlier in the same turn, keep both the boot mention and the $800 statement.
25
+ - **Drop pleasantries, generic advice unanchored to the user's situation, off-topic tangents, and assistant filler**. Drop turns that contain no atoms relevant to the question.
26
+ - **Preserve session boundaries**. The input contains `=== session <id> ===` markers; keep those markers in the output for any session you retain content from. If you drop a session entirely, omit its marker.
27
+ - **Preserve role tags** (`[user]` / `[assistant]`) on retained excerpts so the downstream agent can attribute statements correctly. The role of who said an atom can be evidence (e.g., the user stated a price vs. the assistant suggested one).
28
+ - **If the transcript contains no information relevant to the question**, output exactly: `(no relevant content)` — nothing else.
29
+ - **Do NOT invent details, reorder events, or merge statements across turns**. The compressed output must be a faithful subset of the input transcript.
30
+
31
+ ## Compressed transcript
@@ -0,0 +1,20 @@
1
+ ---
2
+ active: true
3
+ description: "Extracts key terms and generates synonyms for document FTS expansion"
4
+ variables:
5
+ - content
6
+ ---
7
+ Given this document content, identify the key concepts and provide 2-3 synonyms
8
+ or closely related terms for each. Output valid JSON only, nothing else.
9
+
10
+ Example:
11
+ Input: "User reports backup failure with S3 timeout on large datasets"
12
+ Output:
13
+ {
14
+ "backup": ["sync", "replication", "data backup"],
15
+ "failure": ["error", "crash", "issue"],
16
+ "S3": ["cloud storage", "AWS", "object storage"],
17
+ "timeout": ["latency", "delay", "slow response"]
18
+ }
19
+
20
+ Content: {content}