claude-smart 0.2.41 → 0.2.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (396) hide show
  1. package/.claude-plugin/marketplace.json +17 -0
  2. package/README.md +1 -1
  3. package/bin/claude-smart.js +86 -48
  4. package/package.json +10 -3
  5. package/plugin/.claude-plugin/plugin.json +9 -3
  6. package/plugin/.codex-plugin/plugin.json +1 -1
  7. package/plugin/README.md +2 -2
  8. package/plugin/dashboard/next.config.ts +9 -1
  9. package/plugin/pyproject.toml +2 -2
  10. package/plugin/scripts/_lib.sh +91 -0
  11. package/plugin/scripts/backend-service.sh +46 -15
  12. package/plugin/scripts/cli.sh +29 -1
  13. package/plugin/scripts/codex-hook.js +72 -4
  14. package/plugin/scripts/dashboard-build.sh +1 -0
  15. package/plugin/scripts/dashboard-service.sh +1 -0
  16. package/plugin/scripts/ensure-plugin-root.sh +7 -14
  17. package/plugin/scripts/hook_entry.sh +1 -0
  18. package/plugin/scripts/smart-install.sh +18 -2
  19. package/plugin/src/claude_smart/cli.py +72 -38
  20. package/plugin/src/claude_smart/context_format.py +11 -12
  21. package/plugin/src/claude_smart/cs_cite.py +26 -12
  22. package/plugin/src/claude_smart/ids.py +13 -5
  23. package/plugin/uv.lock +1 -1
  24. package/plugin/vendor/reflexio/.env.example +53 -0
  25. package/plugin/vendor/reflexio/LICENSE +201 -0
  26. package/plugin/vendor/reflexio/README.md +338 -0
  27. package/plugin/vendor/reflexio/pyproject.toml +271 -0
  28. package/plugin/vendor/reflexio/reflexio/README.md +184 -0
  29. package/plugin/vendor/reflexio/reflexio/__init__.py +166 -0
  30. package/plugin/vendor/reflexio/reflexio/benchmarks/__init__.py +1 -0
  31. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/README.md +109 -0
  32. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/__init__.py +1 -0
  33. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/backends.py +175 -0
  34. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/bench.py +642 -0
  35. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/embed_cache.py +330 -0
  36. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/report.py +317 -0
  37. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/report.md +43 -0
  38. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/results.json +4478 -0
  39. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/scenarios.py +134 -0
  40. package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/seed.py +255 -0
  41. package/plugin/vendor/reflexio/reflexio/cli/README.md +287 -0
  42. package/plugin/vendor/reflexio/reflexio/cli/__init__.py +0 -0
  43. package/plugin/vendor/reflexio/reflexio/cli/__main__.py +56 -0
  44. package/plugin/vendor/reflexio/reflexio/cli/_client.py +86 -0
  45. package/plugin/vendor/reflexio/reflexio/cli/app.py +127 -0
  46. package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +266 -0
  47. package/plugin/vendor/reflexio/reflexio/cli/codex_auth.py +503 -0
  48. package/plugin/vendor/reflexio/reflexio/cli/commands/__init__.py +0 -0
  49. package/plugin/vendor/reflexio/reflexio/cli/commands/admin_cmd.py +65 -0
  50. package/plugin/vendor/reflexio/reflexio/cli/commands/agent_playbooks.py +503 -0
  51. package/plugin/vendor/reflexio/reflexio/cli/commands/api.py +114 -0
  52. package/plugin/vendor/reflexio/reflexio/cli/commands/auth.py +109 -0
  53. package/plugin/vendor/reflexio/reflexio/cli/commands/config_cmd.py +511 -0
  54. package/plugin/vendor/reflexio/reflexio/cli/commands/doctor.py +127 -0
  55. package/plugin/vendor/reflexio/reflexio/cli/commands/embeddings.py +53 -0
  56. package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +478 -0
  57. package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +303 -0
  58. package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +289 -0
  59. package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +961 -0
  60. package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +285 -0
  61. package/plugin/vendor/reflexio/reflexio/cli/commands/status_cmd.py +143 -0
  62. package/plugin/vendor/reflexio/reflexio/cli/commands/user_playbooks.py +373 -0
  63. package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +284 -0
  64. package/plugin/vendor/reflexio/reflexio/cli/errors.py +217 -0
  65. package/plugin/vendor/reflexio/reflexio/cli/log_format.py +247 -0
  66. package/plugin/vendor/reflexio/reflexio/cli/output.py +867 -0
  67. package/plugin/vendor/reflexio/reflexio/cli/paths.py +41 -0
  68. package/plugin/vendor/reflexio/reflexio/cli/run_services.py +391 -0
  69. package/plugin/vendor/reflexio/reflexio/cli/state.py +204 -0
  70. package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +96 -0
  71. package/plugin/vendor/reflexio/reflexio/cli/utils.py +329 -0
  72. package/plugin/vendor/reflexio/reflexio/client/__init__.py +3 -0
  73. package/plugin/vendor/reflexio/reflexio/client/cache.py +150 -0
  74. package/plugin/vendor/reflexio/reflexio/client/client.py +2613 -0
  75. package/plugin/vendor/reflexio/reflexio/defaults.py +23 -0
  76. package/plugin/vendor/reflexio/reflexio/integrations/__init__.py +0 -0
  77. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/.clawhubignore +7 -0
  78. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +274 -0
  79. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +517 -0
  80. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +473 -0
  81. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +2156 -0
  82. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +18 -0
  83. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +241 -0
  84. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +140 -0
  85. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +130 -0
  86. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +113 -0
  87. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +52 -0
  88. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +103 -0
  89. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +156 -0
  90. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +134 -0
  91. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +41 -0
  92. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +17 -0
  93. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +24 -0
  94. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +48 -0
  95. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +278 -0
  96. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +164 -0
  97. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +36 -0
  98. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +35 -0
  99. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +27 -0
  100. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +31 -0
  101. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +42 -0
  102. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +49 -0
  103. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +91 -0
  104. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +50 -0
  105. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tsconfig.json +16 -0
  106. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/types/openclaw.d.ts +230 -0
  107. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +13 -0
  108. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/README.md +120 -0
  109. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/TESTING.md +168 -0
  110. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package-lock.json +1657 -0
  111. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package.json +16 -0
  112. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/HEARTBEAT.md +6 -0
  113. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/README.md +84 -0
  114. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/SKILL.md +194 -0
  115. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/_meta.json +6 -0
  116. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/agents/reflexio-extractor.md +45 -0
  117. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/handler.ts +214 -0
  118. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/setup.ts +55 -0
  119. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/index.ts +327 -0
  120. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/consolidate.ts +233 -0
  121. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/dedup.ts +80 -0
  122. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/io.ts +155 -0
  123. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/openclaw-cli.ts +67 -0
  124. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/search.ts +33 -0
  125. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-playbook.ts +76 -0
  126. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-profile.ts +79 -0
  127. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/openclaw.plugin.json +46 -0
  128. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/package.json +18 -0
  129. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/README.md +36 -0
  130. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/full_consolidation.md +56 -0
  131. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/playbook_extraction.md +217 -0
  132. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/profile_extraction.md +132 -0
  133. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-consolidate/SKILL.md +33 -0
  134. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-embedded/SKILL.md +194 -0
  135. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/HOOK.md +18 -0
  136. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/architecture.md +49 -0
  137. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/comparison.md +31 -0
  138. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/future-work.md +47 -0
  139. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/porting-notes.md +52 -0
  140. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/install.sh +52 -0
  141. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/uninstall.sh +36 -0
  142. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/consolidate.test.ts +135 -0
  143. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/dedup.test.ts +104 -0
  144. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/io.test.ts +175 -0
  145. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/search.test.ts +66 -0
  146. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/smoke-test.ts +140 -0
  147. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-playbook.test.ts +93 -0
  148. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-profile.test.ts +174 -0
  149. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tsconfig.json +16 -0
  150. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/types/openclaw.d.ts +230 -0
  151. package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/vitest.config.ts +7 -0
  152. package/plugin/vendor/reflexio/reflexio/lib/__init__.py +23 -0
  153. package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +310 -0
  154. package/plugin/vendor/reflexio/reflexio/lib/_base.py +225 -0
  155. package/plugin/vendor/reflexio/reflexio/lib/_config.py +83 -0
  156. package/plugin/vendor/reflexio/reflexio/lib/_dashboard.py +266 -0
  157. package/plugin/vendor/reflexio/reflexio/lib/_generation.py +176 -0
  158. package/plugin/vendor/reflexio/reflexio/lib/_interactions.py +334 -0
  159. package/plugin/vendor/reflexio/reflexio/lib/_operations.py +153 -0
  160. package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +545 -0
  161. package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +52 -0
  162. package/plugin/vendor/reflexio/reflexio/lib/_search.py +167 -0
  163. package/plugin/vendor/reflexio/reflexio/lib/_storage_labels.py +103 -0
  164. package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +288 -0
  165. package/plugin/vendor/reflexio/reflexio/lib/reflexio_lib.py +27 -0
  166. package/plugin/vendor/reflexio/reflexio/models/__init__.py +0 -0
  167. package/plugin/vendor/reflexio/reflexio/models/api_schema/__init__.py +0 -0
  168. package/plugin/vendor/reflexio/reflexio/models/api_schema/braintrust_schema.py +141 -0
  169. package/plugin/vendor/reflexio/reflexio/models/api_schema/common.py +41 -0
  170. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/__init__.py +3 -0
  171. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +1103 -0
  172. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +63 -0
  173. package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +487 -0
  174. package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +28 -0
  175. package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +83 -0
  176. package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +766 -0
  177. package/plugin/vendor/reflexio/reflexio/models/api_schema/service_schemas.py +9 -0
  178. package/plugin/vendor/reflexio/reflexio/models/api_schema/stall_state_schema.py +32 -0
  179. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/__init__.py +3 -0
  180. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +177 -0
  181. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +129 -0
  182. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/enums.py +25 -0
  183. package/plugin/vendor/reflexio/reflexio/models/api_schema/validators.py +280 -0
  184. package/plugin/vendor/reflexio/reflexio/models/config_schema.py +908 -0
  185. package/plugin/vendor/reflexio/reflexio/models/py.typed +0 -0
  186. package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +90 -0
  187. package/plugin/vendor/reflexio/reflexio/server/README.md +616 -0
  188. package/plugin/vendor/reflexio/reflexio/server/__init__.py +210 -0
  189. package/plugin/vendor/reflexio/reflexio/server/__main__.py +132 -0
  190. package/plugin/vendor/reflexio/reflexio/server/_auth.py +25 -0
  191. package/plugin/vendor/reflexio/reflexio/server/api.py +2714 -0
  192. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/account_api.py +143 -0
  193. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/health_api.py +91 -0
  194. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/pending_tool_call_api.py +572 -0
  195. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +66 -0
  196. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/publisher_api.py +540 -0
  197. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +50 -0
  198. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/stall_state_api.py +100 -0
  199. package/plugin/vendor/reflexio/reflexio/server/cache/__init__.py +15 -0
  200. package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +208 -0
  201. package/plugin/vendor/reflexio/reflexio/server/correlation.py +46 -0
  202. package/plugin/vendor/reflexio/reflexio/server/llm/__init__.py +30 -0
  203. package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +110 -0
  204. package/plugin/vendor/reflexio/reflexio/server/llm/image_utils.py +55 -0
  205. package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +1595 -0
  206. package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +112 -0
  207. package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +469 -0
  208. package/plugin/vendor/reflexio/reflexio/server/llm/providers/__init__.py +1 -0
  209. package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +1122 -0
  210. package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_stream_parser.py +197 -0
  211. package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +210 -0
  212. package/plugin/vendor/reflexio/reflexio/server/llm/providers/local_embedding_provider.py +213 -0
  213. package/plugin/vendor/reflexio/reflexio/server/llm/providers/nomic_embedding_provider.py +255 -0
  214. package/plugin/vendor/reflexio/reflexio/server/llm/rerank/__init__.py +6 -0
  215. package/plugin/vendor/reflexio/reflexio/server/llm/rerank/cross_encoder_reranker.py +177 -0
  216. package/plugin/vendor/reflexio/reflexio/server/llm/rerank/llm_reranker.py +148 -0
  217. package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +699 -0
  218. package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +179 -0
  219. package/plugin/vendor/reflexio/reflexio/server/prompt/__init__.py +0 -0
  220. package/plugin/vendor/reflexio/reflexio/server/prompt/_dispatchers.py +54 -0
  221. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/README.md +121 -0
  222. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation/v1.0.0.prompt.md +58 -0
  223. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation_with_comparison/v1.0.0.prompt.md +76 -0
  224. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/answer_synthesis/v1.5.2.prompt.md +88 -0
  225. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/compress_session_for_query/v1.3.0.prompt.md +31 -0
  226. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/document_expansion/v1.0.0.prompt.md +20 -0
  227. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.0.0.prompt.md +53 -0
  228. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.1.0.prompt.md +57 -0
  229. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.2.0.prompt.md +68 -0
  230. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.3.0.prompt.md +70 -0
  231. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.4.0.prompt.md +77 -0
  232. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.5.0.prompt.md +82 -0
  233. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.6.0.prompt.md +83 -0
  234. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.1.0.prompt.md +193 -0
  235. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.2.0.prompt.md +206 -0
  236. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0-deprecated.prompt.md +66 -0
  237. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0.prompt.md +43 -0
  238. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.1.0.prompt.md +46 -0
  239. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0-deprecated.prompt.md +64 -0
  240. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0.prompt.md +39 -0
  241. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.1.0.prompt.md +39 -0
  242. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.2.0.prompt.md +47 -0
  243. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.0.prompt.md +58 -0
  244. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.0.2.prompt.md +254 -0
  245. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.1.0.prompt.md +274 -0
  246. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.0.prompt.md +279 -0
  247. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v1.0.0.prompt.md +73 -0
  248. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v2.0.0.prompt.md +86 -0
  249. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.0.0.prompt.md +97 -0
  250. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.1.0.prompt.md +119 -0
  251. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.2.0.prompt.md +123 -0
  252. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +127 -0
  253. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.0.0.prompt.md +14 -0
  254. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.1.0.prompt.md +24 -0
  255. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +29 -0
  256. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.0.0.prompt.md +11 -0
  257. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.1.0.prompt.md +21 -0
  258. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.2.0.prompt.md +25 -0
  259. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.0.0.prompt.md +37 -0
  260. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.1.0.prompt.md +40 -0
  261. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.2.0.prompt.md +36 -0
  262. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v1.0.0.prompt.md +45 -0
  263. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v2.0.0.prompt.md +81 -0
  264. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v3.0.0.prompt.md +80 -0
  265. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate_expert/v1.0.0.prompt.md +34 -0
  266. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_deduplication/v1.0.0.prompt.md +116 -0
  267. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate/v1.0.0.prompt.md +33 -0
  268. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate_override/v1.0.0.prompt.md +16 -0
  269. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +140 -0
  270. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +160 -0
  271. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_main/v1.0.0.prompt.md +14 -0
  272. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/query_reformulation/v1.0.0.prompt.md +19 -0
  273. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/rerank_relevance/v1.1.0.prompt.md +44 -0
  274. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_comparison/v1.0.0.prompt.md +43 -0
  275. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_content_evaluation/v1.0.0.prompt.md +33 -0
  276. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/feedback_extraction_main_v1.jsonl +10 -0
  277. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/profile_update_main_v1.jsonl +10 -0
  278. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +280 -0
  279. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_schema.py +11 -0
  280. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/_eval_health.py +131 -0
  281. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +60 -0
  282. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_service.py +228 -0
  283. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +87 -0
  284. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluator.py +372 -0
  285. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/delayed_group_evaluator.py +156 -0
  286. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/group_evaluation_runner.py +340 -0
  287. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +471 -0
  288. package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +1626 -0
  289. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/__init__.py +0 -0
  290. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_cron.py +196 -0
  291. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_encryption.py +101 -0
  292. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/client.py +167 -0
  293. package/plugin/vendor/reflexio/reflexio/server/services/braintrust/service.py +281 -0
  294. package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +179 -0
  295. package/plugin/vendor/reflexio/reflexio/server/services/configurator/config_storage.py +62 -0
  296. package/plugin/vendor/reflexio/reflexio/server/services/configurator/configurator.py +87 -0
  297. package/plugin/vendor/reflexio/reflexio/server/services/configurator/local_file_config_storage.py +187 -0
  298. package/plugin/vendor/reflexio/reflexio/server/services/configurator/test_config_storage.py +162 -0
  299. package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +112 -0
  300. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/__init__.py +0 -0
  301. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/distribution.py +33 -0
  302. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +126 -0
  303. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +192 -0
  304. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/hero_state.py +75 -0
  305. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/rule_attribution.py +97 -0
  306. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +515 -0
  307. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/shadow_aggregation.py +90 -0
  308. package/plugin/vendor/reflexio/reflexio/server/services/extraction/__init__.py +0 -0
  309. package/plugin/vendor/reflexio/reflexio/server/services/extraction/agent_run_records.py +91 -0
  310. package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +303 -0
  311. package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +25 -0
  312. package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +351 -0
  313. package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +138 -0
  314. package/plugin/vendor/reflexio/reflexio/server/services/extraction/prior_answer_search.py +217 -0
  315. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +468 -0
  316. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_scheduler.py +171 -0
  317. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +777 -0
  318. package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +1125 -0
  319. package/plugin/vendor/reflexio/reflexio/server/services/extractor_config_utils.py +91 -0
  320. package/plugin/vendor/reflexio/reflexio/server/services/extractor_interaction_utils.py +251 -0
  321. package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +689 -0
  322. package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +835 -0
  323. package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +89 -0
  324. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_aggregator.py +1388 -0
  325. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_consolidator.py +960 -0
  326. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_extractor.py +436 -0
  327. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_generation_service.py +808 -0
  328. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_constants.py +28 -0
  329. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +362 -0
  330. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/__init__.py +24 -0
  331. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/assistant_webhook.py +246 -0
  332. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/gepa_adapter.py +291 -0
  333. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/judge.py +97 -0
  334. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +96 -0
  335. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +645 -0
  336. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/rollout.py +35 -0
  337. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scenario_resolver.py +93 -0
  338. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scheduler.py +174 -0
  339. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/__init__.py +26 -0
  340. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_document_expander.py +179 -0
  341. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_query_reformulator.py +297 -0
  342. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_deduplicator.py +741 -0
  343. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_extractor.py +462 -0
  344. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service.py +734 -0
  345. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +290 -0
  346. package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +17 -0
  347. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_extractor.py +247 -0
  348. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service.py +800 -0
  349. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +146 -0
  350. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/__init__.py +0 -0
  351. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +70 -0
  352. package/plugin/vendor/reflexio/reflexio/server/services/search/__init__.py +0 -0
  353. package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +671 -0
  354. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/__init__.py +1 -0
  355. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/judge.py +184 -0
  356. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +81 -0
  357. package/plugin/vendor/reflexio/reflexio/server/services/storage/constants.py +2 -0
  358. package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +11 -0
  359. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +154 -0
  360. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention_mixin.py +155 -0
  361. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +59 -0
  362. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +1253 -0
  363. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +1945 -0
  364. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +600 -0
  365. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +346 -0
  366. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +1378 -0
  367. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +747 -0
  368. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +263 -0
  369. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +193 -0
  370. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_share_links.py +166 -0
  371. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +217 -0
  372. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +153 -0
  373. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +372 -0
  374. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +71 -0
  375. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +235 -0
  376. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +170 -0
  377. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +677 -0
  378. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +250 -0
  379. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +154 -0
  380. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +130 -0
  381. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_share_links.py +93 -0
  382. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_stall_state.py +76 -0
  383. package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +568 -0
  384. package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +77 -0
  385. package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +116 -0
  386. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_manager.py +263 -0
  387. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +13 -0
  388. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/llm_model_setting.json +7 -0
  389. package/plugin/vendor/reflexio/reflexio/server/tracing.py +158 -0
  390. package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +113 -0
  391. package/plugin/vendor/reflexio/reflexio/server/uvicorn_logging.py +76 -0
  392. package/plugin/vendor/reflexio/reflexio/test_support/__init__.py +1 -0
  393. package/plugin/vendor/reflexio/reflexio/test_support/llm_fixtures.py +62 -0
  394. package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +242 -0
  395. package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +129 -0
  396. package/plugin/vendor/reflexio/reflexio/test_support/skip_decorators.py +43 -0
@@ -0,0 +1,280 @@
1
+ """
2
+ Prompt management using file system prompt bank with markdown frontmatter files.
3
+ """
4
+
5
+ import logging
6
+ import re
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ from .prompt_schema import Prompt
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ _FRONTMATTER_RE = re.compile(r"\A---\n(.*?\n)---\n(.*)", re.DOTALL)
15
+
16
+
17
+ def _parse_frontmatter(raw: str) -> tuple[dict[str, Any], str]:
18
+ """
19
+ Parse YAML frontmatter from a markdown file using stdlib only.
20
+
21
+ Args:
22
+ raw (str): Raw file content with optional ``---`` delimited frontmatter.
23
+
24
+ Returns:
25
+ tuple[dict[str, Any], str]: Parsed metadata dict and the body content.
26
+
27
+ Raises:
28
+ ValueError: If frontmatter is missing or malformed.
29
+ """
30
+ if not (m := _FRONTMATTER_RE.match(raw)):
31
+ raise ValueError("Missing or malformed YAML frontmatter")
32
+
33
+ meta: dict[str, Any] = {}
34
+ for line in m.group(1).splitlines():
35
+ if ":" not in line:
36
+ continue
37
+ key, _, value = line.partition(":")
38
+ key = key.strip()
39
+ value = value.strip()
40
+
41
+ if not key:
42
+ continue
43
+
44
+ if value.startswith("[") and value.endswith("]"):
45
+ # Simple list: [a, b, c]
46
+ meta[key] = [
47
+ v.strip().strip("'\"") for v in value[1:-1].split(",") if v.strip()
48
+ ]
49
+ elif value.startswith("- "):
50
+ # First item of a block list on the same line — shouldn't happen in our format
51
+ meta[key] = [value[2:].strip()]
52
+ elif value.lower() in ("true", "false"):
53
+ meta[key] = value.lower() == "true"
54
+ elif value == "" or value.lower() == "null":
55
+ meta[key] = None
56
+ else:
57
+ meta[key] = value.strip("'\"")
58
+
59
+ # Handle block-style lists (- item per line)
60
+ current_key: str | None = None
61
+ for line in m.group(1).splitlines():
62
+ stripped = line.strip()
63
+ if ":" in line and not stripped.startswith("- "):
64
+ current_key = line.partition(":")[0].strip()
65
+ elif stripped.startswith("- ") and current_key:
66
+ if not isinstance(meta.get(current_key), list):
67
+ meta[current_key] = []
68
+ meta[current_key].append(stripped[2:].strip().strip("'\""))
69
+
70
+ return meta, m.group(2)
71
+
72
+
73
+ class PromptManager:
74
+ """Prompt management using file system prompt bank."""
75
+
76
+ def __init__(
77
+ self,
78
+ prompt_bank_path: str | None = None,
79
+ version_override: dict[str, str] | None = None,
80
+ ):
81
+ """
82
+ Initialize the PromptManager.
83
+
84
+ Args:
85
+ prompt_bank_path (str, optional): Path to the prompt bank directory.
86
+ version_override (dict[str, str], optional): Map of prompt_id → version string to override the active version.
87
+ """
88
+ if prompt_bank_path is None:
89
+ current_dir = Path(__file__).parent
90
+ self.prompt_bank_path = current_dir / "prompt_bank"
91
+ else:
92
+ self.prompt_bank_path = Path(prompt_bank_path)
93
+
94
+ self.version_override = version_override
95
+
96
+ if not self.prompt_bank_path.exists():
97
+ logger.warning("Prompt bank path does not exist: %s", self.prompt_bank_path)
98
+
99
+ self._cache: dict[str, Prompt] = {}
100
+
101
+ # ==============================
102
+ # Public methods
103
+ # ==============================
104
+
105
+ def render_prompt(self, prompt_id: str, variables: dict[str, Any]) -> str:
106
+ """
107
+ Render prompt template with variables.
108
+
109
+ Args:
110
+ prompt_id (str): ID of the prompt.
111
+ variables (dict[str, Any]): Variables to substitute in template.
112
+
113
+ Returns:
114
+ str: Rendered prompt content.
115
+
116
+ Raises:
117
+ ValueError: If prompt not found or template rendering fails.
118
+ """
119
+ version = (
120
+ self.version_override.get(prompt_id) if self.version_override else None
121
+ )
122
+ prompt = self._get_prompt(prompt_id, version)
123
+ if not prompt:
124
+ raise ValueError(f"Prompt {prompt_id} not found")
125
+
126
+ missing_vars = set(prompt.variables) - set(variables.keys())
127
+ if missing_vars:
128
+ raise ValueError(
129
+ f"Missing required variables {missing_vars} for prompt {prompt_id}"
130
+ )
131
+
132
+ try:
133
+ return prompt.content.format(**variables)
134
+ except KeyError as e:
135
+ raise ValueError(
136
+ f"Missing required variable {e} for prompt {prompt_id}"
137
+ ) from e
138
+ except Exception as e:
139
+ raise ValueError(f"Error rendering prompt {prompt_id}: {e}") from e
140
+
141
+ def list_versions(self, prompt_id: str) -> list[str]:
142
+ """
143
+ List all versions of a prompt.
144
+
145
+ Args:
146
+ prompt_id (str): ID of the prompt.
147
+
148
+ Returns:
149
+ list[str]: List of version strings.
150
+ """
151
+ prompt_dir = self.prompt_bank_path / prompt_id
152
+ if not prompt_dir.is_dir():
153
+ return []
154
+ return [
155
+ p.name.removeprefix("v").removesuffix(".prompt.md")
156
+ for p in sorted(prompt_dir.glob("v*.prompt.md"))
157
+ ]
158
+
159
+ def get_active_version(self, prompt_id: str) -> str | None:
160
+ """
161
+ Get the active version for a prompt (considering overrides).
162
+
163
+ Args:
164
+ prompt_id (str): ID of the prompt.
165
+
166
+ Returns:
167
+ str | None: The active version string, or None if prompt not found.
168
+ """
169
+ if self.version_override and prompt_id in self.version_override:
170
+ return self.version_override[prompt_id]
171
+ return self._find_active_version(prompt_id)
172
+
173
+ def get_all_prompt_ids(self) -> list[str]:
174
+ """
175
+ Get list of all available prompt IDs.
176
+
177
+ Returns:
178
+ list[str]: List of prompt IDs.
179
+ """
180
+ if not self.prompt_bank_path.exists():
181
+ return []
182
+ return [
183
+ item.name
184
+ for item in self.prompt_bank_path.iterdir()
185
+ if item.is_dir() and any(item.glob("v*.prompt.md"))
186
+ ]
187
+
188
+ # ==============================
189
+ # Private methods
190
+ # ==============================
191
+
192
+ def _load_prompt(self, prompt_id: str, version: str) -> Prompt | None:
193
+ """Load a single prompt file by prompt_id and version string."""
194
+ path = self.prompt_bank_path / prompt_id / f"v{version}.prompt.md"
195
+ try:
196
+ raw = path.read_text(encoding="utf-8")
197
+ except FileNotFoundError:
198
+ logger.warning("Prompt file not found: %s", path)
199
+ return None
200
+ except Exception as e:
201
+ logger.error("Error reading prompt file %s: %s", path, e)
202
+ return None
203
+
204
+ try:
205
+ meta, content = _parse_frontmatter(raw)
206
+ except ValueError as e:
207
+ logger.error("Error parsing frontmatter in %s: %s", path, e)
208
+ return None
209
+
210
+ return Prompt(
211
+ active=meta.get("active", False),
212
+ description=meta.get("description"),
213
+ changelog=meta.get("changelog"),
214
+ variables=meta.get("variables", []),
215
+ content=content,
216
+ )
217
+
218
+ def _find_active_version(self, prompt_id: str) -> str | None:
219
+ """Scan .prompt.md files to find the latest one with active: true."""
220
+ prompt_dir = self.prompt_bank_path / prompt_id
221
+ if not prompt_dir.is_dir():
222
+ return None
223
+
224
+ def _semver_key(p: Path) -> tuple[int, ...]:
225
+ """Parse 'vX.Y.Z.prompt.md' into a comparable tuple.
226
+
227
+ Strips the leading 'v' before int parsing so versions sort by
228
+ their numeric semver tuple rather than collapsing to a single
229
+ fallback key. Without the prefix strip every version evaluates
230
+ to the (0,) fallback (because ``int('v1')`` raises) and the
231
+ "latest active" search becomes order-of-glob-dependent.
232
+ """
233
+ try:
234
+ return tuple(
235
+ int(x)
236
+ for x in p.stem.removeprefix("v").removesuffix(".prompt").split(".")
237
+ )
238
+ except ValueError:
239
+ return (0,)
240
+
241
+ latest: str | None = None
242
+ for path in sorted(
243
+ prompt_dir.glob("v*.prompt.md"), key=_semver_key, reverse=True
244
+ ):
245
+ try:
246
+ raw = path.read_text(encoding="utf-8")
247
+ meta, _ = _parse_frontmatter(raw)
248
+ if meta.get("active"):
249
+ latest = path.name.removeprefix("v").removesuffix(".prompt.md")
250
+ break
251
+ except (ValueError, OSError):
252
+ continue
253
+ return latest
254
+
255
+ def _get_prompt(self, prompt_id: str, version: str | None = None) -> Prompt | None:
256
+ """
257
+ Get prompt, using cache for active prompts.
258
+
259
+ Args:
260
+ prompt_id (str): ID of the prompt.
261
+ version (str, optional): Specific version to load.
262
+
263
+ Returns:
264
+ Prompt | None: The prompt, or None if not found.
265
+ """
266
+ if version:
267
+ return self._load_prompt(prompt_id, version)
268
+
269
+ if prompt_id in self._cache:
270
+ return self._cache[prompt_id]
271
+
272
+ active_version = self._find_active_version(prompt_id)
273
+ if not active_version:
274
+ logger.warning("No active version found for prompt %s", prompt_id)
275
+ return None
276
+
277
+ prompt = self._load_prompt(prompt_id, active_version)
278
+ if prompt:
279
+ self._cache[prompt_id] = prompt
280
+ return prompt
@@ -0,0 +1,11 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class Prompt(BaseModel):
5
+ """Self-contained prompt loaded from a .prompt.md file with YAML frontmatter."""
6
+
7
+ active: bool = False
8
+ description: str | None = None
9
+ changelog: str | None = None
10
+ variables: list[str]
11
+ content: str
@@ -0,0 +1,131 @@
1
+ """Process-wide health singleton for the agent-success evaluation pipeline.
2
+
3
+ Tracks three signals that the operator-facing healthcheck surfaces:
4
+
5
+ 1. Scheduler liveness — last tick timestamp (monotonic).
6
+ 2. Per-reason skip counts — why a session was skipped during evaluation.
7
+ 3. Producer failure counts in a rolling 24h window.
8
+
9
+ This is intentionally a global singleton, not a per-request object — the
10
+ healthcheck endpoint needs to read counts that accumulate across the
11
+ process lifetime, and the scheduler / runner / service all need to write
12
+ to the same store.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import enum
18
+ import threading
19
+ import time
20
+ from collections import Counter, deque
21
+ from typing import Any
22
+
23
+
24
+ class SkipReason(enum.StrEnum):
25
+ """Why a session evaluation was skipped.
26
+
27
+ Members are the exact string the healthcheck exposes; do not rename
28
+ casually.
29
+ """
30
+
31
+ ALREADY_EVALUATED = "already_evaluated"
32
+ NO_REQUESTS = "no_requests"
33
+ NOT_YET_COMPLETE = "not_yet_complete"
34
+ NO_INTERACTIONS = "no_interactions"
35
+ NO_DATA_MODELS = "no_data_models"
36
+
37
+
38
+ _FAILURE_WINDOW_SECONDS = 24 * 60 * 60
39
+
40
+
41
+ class EvalHealth:
42
+ """Thread-safe counter store for evaluation-pipeline diagnostics.
43
+
44
+ A module-level singleton is exposed as `_HEALTH`; the public helpers
45
+ `record_skip`, `record_producer_failure`, `record_tick`, and
46
+ `get_status` proxy to it.
47
+ """
48
+
49
+ def __init__(self) -> None:
50
+ self._lock = threading.Lock()
51
+ self._skip_counts: Counter[SkipReason] = Counter()
52
+ self._failures: deque[float] = deque()
53
+ self._last_tick_monotonic: float | None = None
54
+
55
+ def record_skip(self, reason: SkipReason) -> None:
56
+ """Bump the counter for `reason` by one.
57
+
58
+ Args:
59
+ reason (SkipReason): The reason the runner skipped a session.
60
+ """
61
+ with self._lock:
62
+ self._skip_counts[reason] += 1
63
+
64
+ def record_producer_failure(self, at_ts: float | None = None) -> None:
65
+ """Record a producer failure (LLM error or persistent save failure).
66
+
67
+ Args:
68
+ at_ts (float | None): Wall-clock unix timestamp; defaults to now.
69
+ """
70
+ ts = time.time() if at_ts is None else at_ts
71
+ with self._lock:
72
+ self._failures.append(ts)
73
+ self._trim_locked(ts)
74
+
75
+ def record_tick(self, monotonic_ts: float | None = None) -> None:
76
+ """Record that the scheduler loop ticked.
77
+
78
+ Args:
79
+ monotonic_ts (float | None): Monotonic clock reading; defaults to now.
80
+ """
81
+ ts = time.monotonic() if monotonic_ts is None else monotonic_ts
82
+ with self._lock:
83
+ self._last_tick_monotonic = ts
84
+
85
+ def get_status(self, now_ts: float | None = None) -> dict[str, Any]:
86
+ """Return a snapshot of all health counters.
87
+
88
+ Args:
89
+ now_ts (float | None): Unix wall-clock used for the failure window;
90
+ defaults to now.
91
+
92
+ Returns:
93
+ dict[str, Any]: Snapshot suitable for the /healthz/eval payload.
94
+ """
95
+ ts = time.time() if now_ts is None else now_ts
96
+ with self._lock:
97
+ self._trim_locked(ts)
98
+ return {
99
+ "skip_counts": {r.value: self._skip_counts[r] for r in SkipReason},
100
+ "producer_failures_24h": len(self._failures),
101
+ "last_tick_monotonic": self._last_tick_monotonic,
102
+ }
103
+
104
+ def _trim_locked(self, now_ts: float) -> None:
105
+ """Drop failure timestamps older than the 24h window (caller holds lock)."""
106
+ cutoff = now_ts - _FAILURE_WINDOW_SECONDS
107
+ while self._failures and self._failures[0] < cutoff:
108
+ self._failures.popleft()
109
+
110
+
111
+ _HEALTH = EvalHealth()
112
+
113
+
114
+ def record_skip(reason: SkipReason) -> None:
115
+ """Module-level proxy to the singleton."""
116
+ _HEALTH.record_skip(reason)
117
+
118
+
119
+ def record_producer_failure(at_ts: float | None = None) -> None:
120
+ """Module-level proxy to the singleton."""
121
+ _HEALTH.record_producer_failure(at_ts=at_ts)
122
+
123
+
124
+ def record_tick(monotonic_ts: float | None = None) -> None:
125
+ """Module-level proxy to the singleton."""
126
+ _HEALTH.record_tick(monotonic_ts=monotonic_ts)
127
+
128
+
129
+ def get_status(now_ts: float | None = None) -> dict[str, Any]:
130
+ """Module-level proxy to the singleton."""
131
+ return _HEALTH.get_status(now_ts=now_ts)
@@ -0,0 +1,60 @@
1
+ """Constants for agent success evaluation service"""
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Literal
5
+
6
+ from pydantic import BaseModel, ConfigDict, Field
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class AgentSuccessEvaluationConstants:
11
+ """Constants for agent success evaluation prompts and configurations"""
12
+
13
+ # Prompt IDs
14
+ AGENT_SUCCESS_EVALUATION_PROMPT_ID = "agent_success_evaluation"
15
+
16
+
17
+ class AgentSuccessEvaluationOutput(BaseModel):
18
+ """
19
+ Unified output schema for agent success evaluation.
20
+
21
+ For successful evaluations, only is_success=True is required.
22
+ For failed evaluations, all fields are required to provide failure details.
23
+
24
+ Attributes:
25
+ is_success (bool): Indicates whether the agent successfully responded to the user
26
+ failure_type (Optional[str]): Type of failure - 'missing_tool', 'wrong_tool', 'insufficient_info_from_tool', or 'wrong_answer'. Required when is_success=False
27
+ failure_reason (Optional[str]): Explanation for the failure and what the agent needs to do differently. Required when is_success=False
28
+ """
29
+
30
+ is_success: bool = Field(
31
+ description="Indicates whether the agent successfully responded to the user"
32
+ )
33
+ failure_type: (
34
+ Literal[
35
+ "missing_tool", "wrong_tool", "insufficient_info_from_tool", "wrong_answer"
36
+ ]
37
+ | None
38
+ ) = Field(
39
+ default=None,
40
+ description="Type of improvement the agent needs: 'missing_tool' (agent lacks necessary tools), 'wrong_tool' (agent used incorrect tool), 'insufficient_info_from_tool' (tool lacks necessary information), 'wrong_answer' (agent had info but answered incorrectly). Required when is_success=False",
41
+ )
42
+ failure_reason: str | None = Field(
43
+ default=None,
44
+ description="Explanation for the failure and what the agent needs to do differently. Required when is_success=False",
45
+ )
46
+ is_escalated: bool = Field(
47
+ default=False,
48
+ description="Whether the user was handed off to a human agent or another agent during the session.",
49
+ )
50
+ # OpenAI schema parsing requires explicitly forbidding additional properties
51
+ model_config = ConfigDict(
52
+ extra="allow",
53
+ json_schema_extra={"additionalProperties": False},
54
+ )
55
+
56
+
57
+ # F1 cleanup: ``AgentSuccessEvaluationWithComparisonOutput`` (the combined
58
+ # evaluation-plus-comparison schema) was retracted along with the session-level
59
+ # shadow comparison branch in ``AgentSuccessEvaluator``. Per-turn shadow
60
+ # comparison uses dedicated schemas under ``services/shadow_comparison/``.