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,18 @@
1
+ {
2
+ "name": "openclaw-federated-dev",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "test": "vitest run",
8
+ "test:watch": "vitest",
9
+ "typecheck": "tsc --noEmit"
10
+ },
11
+ "devDependencies": {
12
+ "@types/better-sqlite3": "^7.0.0",
13
+ "@types/node": "^20.0.0",
14
+ "better-sqlite3": "^11.0.0",
15
+ "typescript": "^5.0.0",
16
+ "vitest": "^3.0.0"
17
+ }
18
+ }
@@ -0,0 +1,241 @@
1
+ // Core hook logic: search injection, message buffering, session flush.
2
+ //
3
+ // Decoupled from the Plugin SDK so each handler can be tested independently.
4
+ // The SDK wiring in index.ts calls these functions with injected deps.
5
+ import * as os from "node:os";
6
+ import * as path from "node:path";
7
+ import type Database from "better-sqlite3";
8
+ import {
9
+ openDb,
10
+ insertTurn,
11
+ countUnpublished,
12
+ cleanupOldTurns,
13
+ getOldUnpublishedSessions,
14
+ } from "../lib/sqlite-buffer.ts";
15
+ import { publishSession } from "../lib/publish.ts";
16
+ import { shouldSkipSearch, runSearch, isConnectionError } from "../lib/search.ts";
17
+ import { ensureServerRunning, type CommandRunner } from "../lib/server.ts";
18
+ import { resolveUserId, resolveAgentVersion } from "../lib/user-id.ts";
19
+ import { runSetupCheck, type SetupGuidance } from "./setup.ts";
20
+
21
+ type Logger = {
22
+ info?: (msg: string) => void;
23
+ warn?: (msg: string) => void;
24
+ error?: (msg: string) => void;
25
+ };
26
+
27
+ export interface PluginConfig {
28
+ publish: { batch_size: number; max_retries: number; max_content_length: number };
29
+ search: { timeout_ms: number; top_k: number; min_prompt_length: number };
30
+ server: { health_check_timeout_ms: number; stale_flag_ms: number };
31
+ }
32
+
33
+ export const DEFAULT_CONFIG: PluginConfig = {
34
+ publish: { batch_size: 10, max_retries: 3, max_content_length: 10_000 },
35
+ search: { timeout_ms: 5_000, top_k: 5, min_prompt_length: 5 },
36
+ server: { health_check_timeout_ms: 3_000, stale_flag_ms: 120_000 },
37
+ };
38
+
39
+ const DB_PATH = path.join(os.homedir(), ".reflexio", "sessions.db");
40
+ const MAX_INTERACTIONS = 200;
41
+ const MAX_OLD_SESSIONS = 5;
42
+
43
+ let _db: Database.Database | null = null;
44
+
45
+ function getDb(): Database.Database {
46
+ if (!_db) {
47
+ _db = openDb(DB_PATH);
48
+ cleanupOldTurns(_db, 7);
49
+ process.on("exit", () => {
50
+ if (_db) _db.close();
51
+ });
52
+ }
53
+ return _db;
54
+ }
55
+
56
+ /**
57
+ * Handle before_prompt_build: auto-setup, search injection, retry old sessions.
58
+ * Returns prependSystemContext string if search results found.
59
+ */
60
+ export async function handleBeforePromptBuild(
61
+ sessionKey: string,
62
+ agentId: string,
63
+ prompt: string | undefined,
64
+ runner: CommandRunner,
65
+ config: PluginConfig = DEFAULT_CONFIG,
66
+ log?: Logger,
67
+ ): Promise<{ prependSystemContext?: string; setupGuidance?: SetupGuidance }> {
68
+ // 1. Auto-setup check
69
+ let guidance: SetupGuidance | null = null;
70
+ try {
71
+ guidance = await runSetupCheck(agentId);
72
+ } catch (err) {
73
+ log?.error?.(`[reflexio] Setup check failed: ${err}`);
74
+ }
75
+ if (guidance) {
76
+ return {
77
+ prependSystemContext: `# Reflexio Setup Required\n\n${guidance.message}`,
78
+ setupGuidance: guidance,
79
+ };
80
+ }
81
+
82
+ // 2. Ensure server is running
83
+ try {
84
+ await ensureServerRunning(runner, {
85
+ staleFlagMs: config.server.stale_flag_ms,
86
+ log,
87
+ });
88
+ } catch (err) {
89
+ log?.error?.(`[reflexio] Server check failed: ${err}`);
90
+ }
91
+
92
+ // 3. Retry unpublished turns from old sessions
93
+ try {
94
+ const db = getDb();
95
+ const agentVersion = resolveAgentVersion();
96
+ const oldSessions = getOldUnpublishedSessions(
97
+ db,
98
+ sessionKey,
99
+ config.publish.max_retries,
100
+ MAX_OLD_SESSIONS,
101
+ );
102
+ for (const sid of oldSessions) {
103
+ const userId = resolveUserId(sid);
104
+ publishSession(
105
+ db,
106
+ sid,
107
+ userId,
108
+ agentVersion,
109
+ config.publish.max_retries,
110
+ MAX_INTERACTIONS,
111
+ log,
112
+ );
113
+ }
114
+ } catch (err) {
115
+ log?.error?.(`[reflexio] Old session retry failed: ${err}`);
116
+ }
117
+
118
+ // 4. Search injection
119
+ if (!prompt || shouldSkipSearch(prompt, config.search.min_prompt_length)) {
120
+ return {};
121
+ }
122
+
123
+ try {
124
+ const userId = resolveUserId(sessionKey);
125
+ const context = await runSearch(
126
+ prompt,
127
+ userId,
128
+ config.search.top_k,
129
+ config.search.timeout_ms,
130
+ runner,
131
+ );
132
+ if (context) {
133
+ return { prependSystemContext: context };
134
+ }
135
+ } catch (err) {
136
+ const errMsg = String(err);
137
+ log?.error?.(`[reflexio] Search failed: ${errMsg}`);
138
+ if (isConnectionError(errMsg)) {
139
+ try {
140
+ await ensureServerRunning(runner, { staleFlagMs: config.server.stale_flag_ms, log });
141
+ } catch {}
142
+ }
143
+ }
144
+
145
+ return {};
146
+ }
147
+
148
+ /**
149
+ * Handle message_sent: buffer turn to SQLite, trigger incremental publish.
150
+ */
151
+ export function handleMessageSent(
152
+ sessionKey: string,
153
+ userMessage: string | undefined,
154
+ agentResponse: string | undefined,
155
+ runner: CommandRunner,
156
+ config: PluginConfig = DEFAULT_CONFIG,
157
+ log?: Logger,
158
+ ): void {
159
+ if (!userMessage && !agentResponse) return;
160
+
161
+ try {
162
+ const db = getDb();
163
+ const maxLen = config.publish.max_content_length;
164
+ if (userMessage) insertTurn(db, sessionKey, "user", userMessage, maxLen);
165
+ if (agentResponse) insertTurn(db, sessionKey, "assistant", agentResponse, maxLen);
166
+
167
+ // Incremental publish at batch threshold
168
+ const count = countUnpublished(db, sessionKey);
169
+ if (count >= config.publish.batch_size * 2) {
170
+ const userId = resolveUserId(sessionKey);
171
+ const agentVersion = resolveAgentVersion();
172
+ publishSession(
173
+ db,
174
+ sessionKey,
175
+ userId,
176
+ agentVersion,
177
+ config.publish.max_retries,
178
+ MAX_INTERACTIONS,
179
+ log,
180
+ );
181
+ }
182
+ } catch (err) {
183
+ log?.error?.(`[reflexio] Failed to buffer turn: ${err}`);
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Handle session end / compaction / reset: flush all unpublished turns.
189
+ */
190
+ export function handleSessionFlush(
191
+ sessionKey: string,
192
+ log?: Logger,
193
+ config: PluginConfig = DEFAULT_CONFIG,
194
+ ): void {
195
+ try {
196
+ const db = getDb();
197
+ const userId = resolveUserId(sessionKey);
198
+ const agentVersion = resolveAgentVersion();
199
+ publishSession(
200
+ db,
201
+ sessionKey,
202
+ userId,
203
+ agentVersion,
204
+ config.publish.max_retries,
205
+ MAX_INTERACTIONS,
206
+ log,
207
+ );
208
+ } catch (err) {
209
+ log?.error?.(`[reflexio] Session flush failed: ${err}`);
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Handle reflexio_publish tool: immediate flush of current session.
215
+ */
216
+ export function handleToolPublish(
217
+ sessionKey: string,
218
+ log?: Logger,
219
+ config: PluginConfig = DEFAULT_CONFIG,
220
+ ): string {
221
+ try {
222
+ const db = getDb();
223
+ const count = countUnpublished(db, sessionKey);
224
+ if (count === 0) return "No unpublished turns to flush.";
225
+
226
+ const userId = resolveUserId(sessionKey);
227
+ const agentVersion = resolveAgentVersion();
228
+ publishSession(
229
+ db,
230
+ sessionKey,
231
+ userId,
232
+ agentVersion,
233
+ config.publish.max_retries,
234
+ MAX_INTERACTIONS,
235
+ log,
236
+ );
237
+ return `Flushing ${count} turns to Reflexio server.`;
238
+ } catch (err) {
239
+ return `Publish failed: ${err}`;
240
+ }
241
+ }
@@ -0,0 +1,140 @@
1
+ // Runtime auto-setup: check reflexio CLI, check config, check server.
2
+ //
3
+ // Runs on before_prompt_build. Gated by per-agent marker file.
4
+ // Each step that fails returns a guidance message for the agent to present
5
+ // to the user with options — the user picks, Openclaw executes.
6
+ import * as fs from "node:fs";
7
+ import * as os from "node:os";
8
+ import * as path from "node:path";
9
+ import { execFile, execFileSync } from "node:child_process";
10
+
11
+ export interface SetupGuidance {
12
+ /** Message for the agent to present to the user. */
13
+ message: string;
14
+ /** Whether the plugin can function without resolving this. */
15
+ blocking: boolean;
16
+ }
17
+
18
+ const REFLEXIO_DIR = path.join(os.homedir(), ".reflexio");
19
+
20
+ /** Sanitize agentId for safe use in filesystem paths. */
21
+ function sanitizeAgentId(agentId: string): string {
22
+ return agentId.replace(/[^a-zA-Z0-9_-]/g, "_");
23
+ }
24
+
25
+ /** Check if setup has been completed for a given agent. */
26
+ export function isSetupComplete(reflexioDir: string, agentId: string): boolean {
27
+ const safeId = sanitizeAgentId(agentId);
28
+ const marker = path.join(reflexioDir, `.setup_complete_${safeId}`);
29
+ return fs.existsSync(marker);
30
+ }
31
+
32
+ /** Create the setup-complete marker for an agent. */
33
+ export function markSetupComplete(reflexioDir: string, agentId: string): void {
34
+ const safeId = sanitizeAgentId(agentId);
35
+ fs.mkdirSync(reflexioDir, { recursive: true });
36
+ fs.writeFileSync(
37
+ path.join(reflexioDir, `.setup_complete_${safeId}`),
38
+ new Date().toISOString(),
39
+ );
40
+ }
41
+
42
+ /** Check if `reflexio` CLI is available on PATH. */
43
+ export function checkReflexioInstalled(): Promise<boolean> {
44
+ return new Promise((resolve) => {
45
+ execFile(
46
+ "reflexio",
47
+ ["--version"],
48
+ { timeout: 5_000 },
49
+ (err) => { resolve(err === null); },
50
+ );
51
+ });
52
+ }
53
+
54
+ /** Detect which Python package installer is available. */
55
+ export function detectInstaller(): "pipx" | "pip" | null {
56
+ try {
57
+ execFileSync("pipx", ["--version"], { timeout: 3_000, stdio: ["ignore", "pipe", "pipe"] });
58
+ return "pipx";
59
+ } catch {
60
+ // pipx not found
61
+ }
62
+ try {
63
+ execFileSync("pip", ["--version"], { timeout: 3_000, stdio: ["ignore", "pipe", "pipe"] });
64
+ return "pip";
65
+ } catch {
66
+ // pip not found
67
+ }
68
+ return null;
69
+ }
70
+
71
+ /** Check if Reflexio has been configured (~/.reflexio/.env with REFLEXIO_URL). */
72
+ export function checkReflexioConfigured(reflexioDir: string = REFLEXIO_DIR): boolean {
73
+ try {
74
+ const envPath = path.join(reflexioDir, ".env");
75
+ const content = fs.readFileSync(envPath, "utf-8");
76
+ return content.split("\n").some((line) => {
77
+ const trimmed = line.trim();
78
+ if (trimmed.startsWith("#")) return false;
79
+ const match = trimmed.match(/^REFLEXIO_URL\s*=\s*"?([^"\s]+)/);
80
+ return match !== null && match[1].length > 0;
81
+ });
82
+ } catch {
83
+ return false;
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Run the full setup check chain. Returns guidance for the agent if setup
89
+ * is incomplete, or null if everything is ready.
90
+ */
91
+ export async function runSetupCheck(
92
+ agentId: string,
93
+ reflexioDir: string = REFLEXIO_DIR,
94
+ ): Promise<SetupGuidance | null> {
95
+ // Gate: already set up?
96
+ if (isSetupComplete(reflexioDir, agentId)) return null;
97
+
98
+ // Step 1: Is reflexio installed?
99
+ const installed = await checkReflexioInstalled();
100
+ if (!installed) {
101
+ const installer = detectInstaller();
102
+ if (installer === "pipx") {
103
+ return {
104
+ message:
105
+ "Reflexio CLI is required but not found. " +
106
+ "I can install it via pipx. OK if I run `pipx install reflexio-ai`?",
107
+ blocking: true,
108
+ };
109
+ }
110
+ if (installer === "pip") {
111
+ return {
112
+ message:
113
+ "Reflexio CLI is required but not found. " +
114
+ "I can install it via pip. OK if I run `pip install reflexio-ai`? " +
115
+ "(If this fails on macOS, I'll guide you through pipx instead.)",
116
+ blocking: true,
117
+ };
118
+ }
119
+ return {
120
+ message:
121
+ "Reflexio CLI is required but not found, and neither pipx nor pip is available. " +
122
+ "Please install pipx first (https://pipx.pypa.io/), then I can install Reflexio for you.",
123
+ blocking: true,
124
+ };
125
+ }
126
+
127
+ // Step 2: Is Reflexio configured?
128
+ if (!checkReflexioConfigured(reflexioDir)) {
129
+ return {
130
+ message:
131
+ "Reflexio needs initial configuration (storage backend, LLM provider). " +
132
+ "OK if I run `reflexio setup init` to start the setup wizard?",
133
+ blocking: true,
134
+ };
135
+ }
136
+
137
+ // All checks passed — create marker
138
+ markSetupComplete(reflexioDir, agentId);
139
+ return null;
140
+ }
@@ -0,0 +1,130 @@
1
+ // Reflexio Federated — Openclaw plugin entry.
2
+ //
3
+ // Registers lifecycle hooks and one tool against the Openclaw Plugin API:
4
+ // - before_prompt_build: auto-setup, search injection, retry old sessions
5
+ // - message_sent: buffer turn to SQLite, incremental publish
6
+ // - before_compaction: flush unpublished turns before transcript is lost
7
+ // - before_reset: flush unpublished turns before transcript is wiped
8
+ // - session_end: final flush of all remaining turns
9
+ // - reflexio_publish: agent-invoked immediate flush
10
+ //
11
+ // All core logic lives in ./hook/handler.ts — this file is only SDK wiring.
12
+ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
13
+
14
+ import {
15
+ handleBeforePromptBuild,
16
+ handleMessageSent,
17
+ handleSessionFlush,
18
+ handleToolPublish,
19
+ DEFAULT_CONFIG,
20
+ type PluginConfig,
21
+ } from "./hook/handler.ts";
22
+
23
+ // Track the most recently active session key, updated by before_prompt_build and message_sent.
24
+ //
25
+ // LIMITATION: This is a process-global variable. The Openclaw Plugin SDK does not pass session
26
+ // context into the tool `execute` callback, so `reflexio_publish` can only target the most
27
+ // recently active session. If multiple sessions run concurrently in the same process, this value
28
+ // will reflect whichever session fired last — meaning `reflexio_publish` may flush the wrong
29
+ // session's turns. This plugin is designed for single-session use. Concurrent multi-session
30
+ // support would require the Plugin SDK to expose session context in the tool execute callback.
31
+ let _activeSessionKey = "";
32
+
33
+ export default definePluginEntry({
34
+ id: "reflexio-federated",
35
+ name: "Reflexio Federated",
36
+ description:
37
+ "Cross-session memory via Reflexio server. Publishes conversations for extraction, injects relevant profiles and playbooks before each response.",
38
+ register(api) {
39
+ const log = api.logger;
40
+ const runner = api.runtime.system.runCommandWithTimeout;
41
+
42
+ // Merge user config with defaults
43
+ const rawConfig = (api.pluginConfig ?? {}) as Record<string, unknown>;
44
+ const config: PluginConfig = {
45
+ publish: { ...DEFAULT_CONFIG.publish, ...((rawConfig.publish as Record<string, number>) ?? {}) },
46
+ search: { ...DEFAULT_CONFIG.search, ...((rawConfig.search as Record<string, number>) ?? {}) },
47
+ server: { ...DEFAULT_CONFIG.server, ...((rawConfig.server as Record<string, number>) ?? {}) },
48
+ };
49
+
50
+ // before_prompt_build: setup, search, retry
51
+ api.on("before_prompt_build", async (_event: unknown, ctx: unknown) => {
52
+ const context = ctx as { agentId?: string; sessionKey?: string };
53
+ const sessionKey = context.sessionKey ?? "";
54
+ const agentId = context.agentId ?? "main";
55
+ if (sessionKey) _activeSessionKey = sessionKey;
56
+
57
+ // Extract prompt from event (best-effort)
58
+ const eventObj = _event as { prompt?: string; messages?: { role?: string; content?: unknown }[] };
59
+ let prompt = eventObj.prompt;
60
+ if (!prompt && Array.isArray(eventObj.messages)) {
61
+ const lastUser = [...eventObj.messages].reverse().find((m) => m.role === "user");
62
+ if (lastUser) {
63
+ prompt = typeof lastUser.content === "string"
64
+ ? lastUser.content
65
+ : JSON.stringify(lastUser.content);
66
+ }
67
+ }
68
+
69
+ const result = await handleBeforePromptBuild(
70
+ sessionKey,
71
+ agentId,
72
+ prompt,
73
+ runner,
74
+ config,
75
+ log,
76
+ );
77
+
78
+ if (result.prependSystemContext) {
79
+ return { prependSystemContext: result.prependSystemContext };
80
+ }
81
+ });
82
+
83
+ // message_sent: buffer turn to SQLite
84
+ api.on("message_sent", (_event: unknown, ctx: unknown) => {
85
+ const context = ctx as { sessionKey?: string };
86
+ const event = _event as { userMessage?: string; agentResponse?: string; content?: string; role?: string };
87
+ const sessionKey = context.sessionKey ?? "";
88
+ if (sessionKey) _activeSessionKey = sessionKey;
89
+ handleMessageSent(
90
+ sessionKey,
91
+ event.userMessage,
92
+ event.agentResponse ?? (event.role === "assistant" ? (typeof event.content === "string" ? event.content : undefined) : undefined),
93
+ runner,
94
+ config,
95
+ log,
96
+ );
97
+ });
98
+
99
+ // before_compaction: flush before transcript is compacted
100
+ api.on("before_compaction", async (_event, ctx) => {
101
+ handleSessionFlush(ctx.sessionKey ?? "", log, config);
102
+ });
103
+
104
+ // before_reset: flush before transcript is wiped
105
+ api.on("before_reset", async (_event, ctx) => {
106
+ handleSessionFlush(ctx.sessionKey ?? "", log, config);
107
+ });
108
+
109
+ // session_end: final flush
110
+ api.on("session_end", async (event, ctx) => {
111
+ handleSessionFlush(ctx.sessionKey ?? event.sessionKey ?? "", log, config);
112
+ });
113
+
114
+ // reflexio_publish tool: agent-invoked immediate flush
115
+ api.registerTool({
116
+ name: "reflexio_publish",
117
+ description:
118
+ "Immediately publish all buffered conversation turns to the Reflexio server. " +
119
+ "Use after user corrections, key milestones, or high-signal moments when you " +
120
+ "don't want to wait for the automatic session-end publish.",
121
+ parameters: { type: "object", properties: {} },
122
+ optional: true,
123
+ async execute(_id: string, _params: Record<string, unknown>) {
124
+ // Use the module-level active session key tracked by before_prompt_build and message_sent.
125
+ const result = handleToolPublish(_activeSessionKey, log, config);
126
+ return { content: [{ type: "text" as const, text: result }] };
127
+ },
128
+ });
129
+ },
130
+ });
@@ -0,0 +1,113 @@
1
+ // Build payload and spawn `reflexio interactions publish`.
2
+ import * as fs from "node:fs";
3
+ import * as os from "node:os";
4
+ import * as path from "node:path";
5
+ import { spawn } from "node:child_process";
6
+ import type Database from "better-sqlite3";
7
+ import type { Turn } from "./sqlite-buffer.ts";
8
+ import {
9
+ getUnpublished,
10
+ markInFlight,
11
+ markPublished,
12
+ markFailed,
13
+ } from "./sqlite-buffer.ts";
14
+
15
+ type Logger = {
16
+ info?: (msg: string) => void;
17
+ error?: (msg: string) => void;
18
+ };
19
+
20
+ const PAYLOAD_DIR = path.join(os.homedir(), ".reflexio", "tmp");
21
+
22
+ /** Build a JSON payload string from turns. */
23
+ export function buildPayload(
24
+ turns: Turn[],
25
+ userId: string,
26
+ agentVersion: string,
27
+ sessionId: string,
28
+ ): string {
29
+ return JSON.stringify({
30
+ user_id: userId,
31
+ source: "openclaw",
32
+ agent_version: agentVersion,
33
+ session_id: sessionId,
34
+ interactions: turns.map((t) => ({ role: t.role, content: t.content })),
35
+ });
36
+ }
37
+
38
+ /** Sanitize a string for use in a filename. */
39
+ function sanitizeFilename(name: string): string {
40
+ return name.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/^-+/, "").slice(0, 100) || "unnamed";
41
+ }
42
+
43
+ /**
44
+ * Publish unpublished turns for a session. Fire-and-forget spawn of CLI.
45
+ * Marks turns in-flight before spawning, then published/failed on exit.
46
+ */
47
+ export function publishSession(
48
+ db: Database.Database,
49
+ sessionId: string,
50
+ userId: string,
51
+ agentVersion: string,
52
+ maxRetries: number,
53
+ maxInteractions: number,
54
+ log?: Logger,
55
+ ): void {
56
+ const turns = getUnpublished(db, sessionId, maxRetries, maxInteractions);
57
+ if (turns.length === 0) return;
58
+
59
+ const maxId = turns[turns.length - 1].id;
60
+ markInFlight(db, sessionId, maxId, maxRetries);
61
+
62
+ const payload = buildPayload(turns, userId, agentVersion, sessionId);
63
+
64
+ fs.mkdirSync(PAYLOAD_DIR, { recursive: true, mode: 0o700 });
65
+ const payloadFile = path.join(
66
+ PAYLOAD_DIR,
67
+ `publish-${sanitizeFilename(sessionId)}-${Date.now()}.json`,
68
+ );
69
+ fs.writeFileSync(payloadFile, payload, { mode: 0o600 });
70
+
71
+ const child = spawn(
72
+ "reflexio",
73
+ ["interactions", "publish", "--file", payloadFile],
74
+ { stdio: ["ignore", "ignore", "ignore"], detached: true },
75
+ );
76
+
77
+ child.on("error", (err) => {
78
+ log?.error?.(`[reflexio] Failed to spawn reflexio binary: ${err.message}`);
79
+ try {
80
+ markFailed(db, sessionId, maxId);
81
+ } catch (dbErr) {
82
+ log?.error?.(`[reflexio] Failed to update retry count after spawn error: ${dbErr}`);
83
+ }
84
+ try {
85
+ fs.unlinkSync(payloadFile);
86
+ } catch {}
87
+ });
88
+
89
+ child.on("close", (code) => {
90
+ if (code === 0) {
91
+ try {
92
+ markPublished(db, sessionId, maxId);
93
+ } catch (err) {
94
+ log?.error?.(`[reflexio] Failed to mark turns published: ${err}`);
95
+ }
96
+ } else {
97
+ log?.error?.(`[reflexio] Publish failed (exit ${code}), incrementing retry`);
98
+ try {
99
+ markFailed(db, sessionId, maxId);
100
+ } catch (err) {
101
+ log?.error?.(`[reflexio] Failed to update retry count: ${err}`);
102
+ }
103
+ }
104
+ try {
105
+ fs.unlinkSync(payloadFile);
106
+ } catch {}
107
+ });
108
+ child.unref();
109
+
110
+ log?.info?.(
111
+ `[reflexio] Queued ${turns.length} turns for publish (session ${sessionId})`,
112
+ );
113
+ }
@@ -0,0 +1,52 @@
1
+ // Search Reflexio and format results for context injection.
2
+ import type { CommandRunner } from "./server.ts";
3
+
4
+ const TRIVIAL_RE = /^(yes|no|ok|okay|sure|thanks|thank you|yep|nope|right|correct|got it|done|good|great|fine|lgtm|y|n|k|ty|thx|ack|np)$/i;
5
+
6
+ /** Decide whether to skip search for a given message. */
7
+ export function shouldSkipSearch(prompt: string, minLength: number): boolean {
8
+ if (!prompt || prompt.length < minLength) return true;
9
+ return TRIVIAL_RE.test(prompt.trim());
10
+ }
11
+
12
+ /** Format raw search output for context injection. Returns null if empty/no results. */
13
+ export function formatSearchContext(raw: string): string | null {
14
+ const trimmed = raw.trim();
15
+ if (!trimmed) return null;
16
+ if (trimmed.includes("Found 0 profiles, 0 playbooks")) return null;
17
+ return trimmed;
18
+ }
19
+
20
+ /**
21
+ * Run `reflexio search` and return formatted context string.
22
+ * Returns null if no results.
23
+ * Throws an Error (with stderr as message) on non-zero exit code so callers can
24
+ * distinguish connection/binary errors from empty-results.
25
+ */
26
+ export async function runSearch(
27
+ prompt: string,
28
+ userId: string,
29
+ topK: number,
30
+ timeoutMs: number,
31
+ runner: CommandRunner,
32
+ ): Promise<string | null> {
33
+ const result = await runner(
34
+ ["reflexio", "search", prompt.slice(0, 4096), "--user-id", userId, "--top-k", String(topK)],
35
+ { timeoutMs },
36
+ );
37
+ if (result.code !== 0) {
38
+ throw new Error(result.stderr || `reflexio search exited with code ${result.code}`);
39
+ }
40
+ return formatSearchContext(result.stdout);
41
+ }
42
+
43
+ /**
44
+ * Check if a search failure looks like a connection error.
45
+ */
46
+ export function isConnectionError(errMsg: string): boolean {
47
+ return (
48
+ errMsg.includes("Cannot reach server") ||
49
+ errMsg.includes("Connection refused") ||
50
+ errMsg.includes("ECONNREFUSED")
51
+ );
52
+ }