claude-smart 0.2.44 → 0.2.46

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 (323) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/README.md +34 -5
  3. package/bin/claude-smart.js +295 -5
  4. package/package.json +22 -3
  5. package/plugin/.claude-plugin/plugin.json +4 -2
  6. package/plugin/.codex-plugin/plugin.json +1 -1
  7. package/plugin/README.md +22 -2
  8. package/plugin/commands/clear-all.md +1 -0
  9. package/plugin/commands/dashboard.md +1 -0
  10. package/plugin/commands/learn.md +1 -0
  11. package/plugin/commands/restart.md +1 -0
  12. package/plugin/commands/show.md +1 -0
  13. package/plugin/dashboard/app/configure/env/page.tsx +40 -14
  14. package/plugin/dashboard/app/configure/server/page.tsx +51 -1
  15. package/plugin/dashboard/app/preferences/[id]/page.tsx +8 -8
  16. package/plugin/dashboard/app/skills/project/[id]/page.tsx +7 -3
  17. package/plugin/dashboard/app/skills/shared/[id]/page.tsx +10 -3
  18. package/plugin/dashboard/lib/claude-settings-file.ts +20 -10
  19. package/plugin/dashboard/lib/reflexio-client.ts +16 -0
  20. package/plugin/dashboard/lib/status.ts +10 -3
  21. package/plugin/dashboard/lib/types.ts +18 -6
  22. package/plugin/hooks/codex-hooks.json +0 -1
  23. package/plugin/opencode/assistant-buffer.ts +108 -0
  24. package/plugin/opencode/dist/assistant-buffer.js +96 -0
  25. package/plugin/opencode/dist/internal.js +12 -0
  26. package/plugin/opencode/dist/payload.js +85 -0
  27. package/plugin/opencode/dist/server.mjs +158 -0
  28. package/plugin/opencode/internal.ts +18 -0
  29. package/plugin/opencode/package.json +3 -0
  30. package/plugin/opencode/payload.ts +90 -0
  31. package/plugin/opencode/server.mts +174 -0
  32. package/plugin/opencode/tsconfig.json +13 -0
  33. package/plugin/pyproject.toml +20 -3
  34. package/plugin/scripts/_lib.sh +77 -29
  35. package/plugin/scripts/backend-service.sh +27 -5
  36. package/plugin/scripts/dashboard-service.sh +7 -5
  37. package/plugin/scripts/ensure-plugin-root.sh +4 -4
  38. package/plugin/scripts/hook_entry.sh +3 -3
  39. package/plugin/scripts/opencode-claude-compat +4 -0
  40. package/plugin/scripts/opencode-claude-compat.cmd +3 -0
  41. package/plugin/scripts/opencode-claude-compat.js +225 -0
  42. package/plugin/scripts/smart-install.sh +10 -8
  43. package/plugin/src/README.md +1 -1
  44. package/plugin/src/claude_smart/cli.py +304 -6
  45. package/plugin/src/claude_smart/env_config.py +12 -4
  46. package/plugin/src/claude_smart/events/session_start.py +26 -7
  47. package/plugin/src/claude_smart/events/stop.py +1 -1
  48. package/plugin/src/claude_smart/ids.py +1 -1
  49. package/plugin/src/claude_smart/reflexio_adapter.py +5 -5
  50. package/plugin/src/claude_smart/runtime.py +7 -1
  51. package/plugin/uv.lock +1 -1
  52. package/plugin/vendor/reflexio/.env.example +54 -30
  53. package/plugin/vendor/reflexio/README.md +14 -8
  54. package/plugin/vendor/reflexio/pyproject.toml +13 -1
  55. package/plugin/vendor/reflexio/reflexio/README.md +1 -0
  56. package/plugin/vendor/reflexio/reflexio/cli/README.md +9 -7
  57. package/plugin/vendor/reflexio/reflexio/cli/__main__.py +10 -1
  58. package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +22 -5
  59. package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +34 -4
  60. package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +12 -7
  61. package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +13 -6
  62. package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +210 -50
  63. package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +15 -2
  64. package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +292 -22
  65. package/plugin/vendor/reflexio/reflexio/cli/log_format.py +29 -4
  66. package/plugin/vendor/reflexio/reflexio/cli/run_services.py +17 -8
  67. package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +13 -10
  68. package/plugin/vendor/reflexio/reflexio/client/client.py +57 -13
  69. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +135 -257
  70. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/npm/openclaw-smart/bin/openclaw-smart.js +13 -0
  71. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/npm/openclaw-smart/package.json +15 -0
  72. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/README.md +38 -0
  73. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +151 -110
  74. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +20 -10
  75. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +28 -6
  76. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/pyproject.toml +42 -0
  77. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/_lib.sh +371 -0
  78. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/backend-log-runner.sh +33 -0
  79. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/backend-service.sh +271 -0
  80. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/cli.sh +68 -0
  81. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/dashboard-open.sh +15 -0
  82. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/ensure-plugin-root.sh +84 -0
  83. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/hook_entry.sh +106 -0
  84. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/npm-cli.js +219 -0
  85. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/smart-install.sh +269 -0
  86. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/clear-all/SKILL.md +8 -0
  87. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/dashboard/SKILL.md +8 -0
  88. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/learn/SKILL.md +10 -0
  89. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +15 -44
  90. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/restart/SKILL.md +6 -0
  91. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/show/SKILL.md +8 -0
  92. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/cli.py +634 -0
  93. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/context_format.py +224 -0
  94. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/context_inject.py +79 -0
  95. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/__init__.py +0 -0
  96. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/after_tool_call.py +160 -0
  97. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/agent_end.py +187 -0
  98. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/before_prompt_build.py +69 -0
  99. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/before_tool_call.py +30 -0
  100. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/session_end.py +36 -0
  101. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/session_start.py +130 -0
  102. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/hook.py +131 -0
  103. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/ids.py +94 -0
  104. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/internal_call.py +75 -0
  105. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/oc_cite.py +196 -0
  106. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/optimizer_assistant.py +272 -0
  107. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/publish.py +96 -0
  108. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/query_compose.py +66 -0
  109. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/reflexio_adapter.py +336 -0
  110. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/runtime.py +47 -0
  111. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/stall_banner.py +61 -0
  112. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/state.py +323 -0
  113. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/__init__.py +0 -0
  114. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/__init__.py +0 -0
  115. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_e2e_session_loop.py +190 -0
  116. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_publish_to_local_reflexio_integration.py +112 -0
  117. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_recursion_guard_integration.py +86 -0
  118. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_search_inject_integration.py +144 -0
  119. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_cli.py +184 -0
  120. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_after_tool_call.py +142 -0
  121. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_agent_end.py +233 -0
  122. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_before_prompt_build.py +116 -0
  123. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_before_tool_call.py +35 -0
  124. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_session_end.py +47 -0
  125. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_session_start.py +109 -0
  126. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_hook_dispatch.py +117 -0
  127. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_ids.py +41 -0
  128. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_internal_call.py +50 -0
  129. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_oc_cite.py +88 -0
  130. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_publish.py +48 -0
  131. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_query_compose.py +48 -0
  132. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_reflexio_adapter.py +188 -0
  133. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_runtime.py +41 -0
  134. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_state.py +235 -0
  135. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/__mocks__/plugin-entry-stub.ts +6 -0
  136. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/test_npm_cli.test.ts +56 -0
  137. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/test_shim_dispatch.test.ts +171 -0
  138. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tsconfig.build.json +18 -0
  139. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/{tsconfig.json → plugin/tsconfig.json} +2 -2
  140. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/uv.lock +3835 -0
  141. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/vitest.config.ts +18 -0
  142. package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +238 -10
  143. package/plugin/vendor/reflexio/reflexio/lib/_config.py +11 -4
  144. package/plugin/vendor/reflexio/reflexio/lib/_generation.py +16 -5
  145. package/plugin/vendor/reflexio/reflexio/lib/_lineage_parity_readers.py +187 -0
  146. package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +198 -6
  147. package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +1 -1
  148. package/plugin/vendor/reflexio/reflexio/lib/_search.py +29 -20
  149. package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +2 -1
  150. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +127 -38
  151. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +4 -0
  152. package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +64 -41
  153. package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +19 -0
  154. package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +12 -5
  155. package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +52 -0
  156. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +5 -1
  157. package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +5 -1
  158. package/plugin/vendor/reflexio/reflexio/models/config_schema.py +88 -7
  159. package/plugin/vendor/reflexio/reflexio/models/structured_output.py +148 -0
  160. package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +3 -3
  161. package/plugin/vendor/reflexio/reflexio/server/README.md +45 -32
  162. package/plugin/vendor/reflexio/reflexio/server/__init__.py +29 -5
  163. package/plugin/vendor/reflexio/reflexio/server/__main__.py +2 -2
  164. package/plugin/vendor/reflexio/reflexio/server/_auth.py +65 -2
  165. package/plugin/vendor/reflexio/reflexio/server/api.py +734 -85
  166. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +7 -0
  167. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +3 -1
  168. package/plugin/vendor/reflexio/reflexio/server/billing_meter.py +173 -0
  169. package/plugin/vendor/reflexio/reflexio/server/billing_signals.py +64 -0
  170. package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +46 -16
  171. package/plugin/vendor/reflexio/reflexio/server/env_utils.py +65 -0
  172. package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +19 -4
  173. package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +264 -77
  174. package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +69 -7
  175. package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +75 -16
  176. package/plugin/vendor/reflexio/reflexio/server/llm/providers/openclaw_provider.py +280 -0
  177. package/plugin/vendor/reflexio/reflexio/server/llm/token_accounting.py +48 -0
  178. package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +107 -17
  179. package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +360 -4
  180. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.6.0.prompt.md +1 -1
  181. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.7.0.prompt.md +85 -0
  182. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.2.0.prompt.md +1 -1
  183. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.3.0.prompt.md +253 -0
  184. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.2.prompt.md +1 -1
  185. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.3.prompt.md +74 -0
  186. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.3.prompt.md +1 -1
  187. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.3.0.prompt.md +266 -0
  188. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.4.0.prompt.md +266 -0
  189. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +1 -1
  190. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.4.0.prompt.md +137 -0
  191. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +1 -1
  192. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.3.0.prompt.md +34 -0
  193. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +5 -12
  194. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +5 -12
  195. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.2.0.prompt.md +155 -0
  196. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/tagging/v1.0.0.prompt.md +23 -0
  197. package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +89 -32
  198. package/plugin/vendor/reflexio/reflexio/server/services/README.md +26 -11
  199. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/README.md +22 -0
  200. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/__init__.py +1 -0
  201. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +4 -2
  202. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +1 -0
  203. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/components/__init__.py +7 -0
  204. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{agent_success_evaluator.py → components/evaluator.py} +3 -16
  205. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +28 -72
  206. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{group_evaluation_runner.py → runner.py} +12 -10
  207. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{delayed_group_evaluator.py → scheduler.py} +10 -2
  208. package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{agent_success_evaluation_service.py → service.py} +36 -1
  209. package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +160 -0
  210. package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +5 -0
  211. package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +1 -1
  212. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/README.md +9 -0
  213. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/components/__init__.py +0 -0
  214. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{rule_attribution.py → components/rule_attribution.py} +10 -9
  215. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +15 -24
  216. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +238 -164
  217. package/plugin/vendor/reflexio/reflexio/server/services/extraction/README.md +31 -0
  218. package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +13 -3
  219. package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +3 -2
  220. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +32 -118
  221. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +39 -16
  222. package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +105 -23
  223. package/plugin/vendor/reflexio/reflexio/server/services/lineage/__init__.py +0 -0
  224. package/plugin/vendor/reflexio/reflexio/server/services/lineage/gc_scheduler.py +193 -0
  225. package/plugin/vendor/reflexio/reflexio/server/services/lineage/resolve.py +98 -0
  226. package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +26 -0
  227. package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +11 -12
  228. package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/__init__.py +5 -0
  229. package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_aggregator.py → components/aggregator.py} +316 -178
  230. package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_consolidator.py → components/consolidator.py} +168 -62
  231. package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_extractor.py → components/extractor.py} +5 -1
  232. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_edit_apply.py +74 -0
  233. package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +33 -3
  234. package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_generation_service.py → service.py} +121 -19
  235. package/plugin/vendor/reflexio/reflexio/server/services/playbook/user_detail_stripping.py +84 -0
  236. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/README.md +10 -0
  237. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +2 -1
  238. package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +178 -30
  239. package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/README.md +9 -0
  240. package/plugin/vendor/reflexio/reflexio/server/services/profile/components/__init__.py +17 -0
  241. package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_deduplicator.py → components/consolidator.py} +7 -6
  242. package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_extractor.py → components/extractor.py} +30 -22
  243. package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +6 -13
  244. package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_generation_service.py → service.py} +32 -50
  245. package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +4 -8
  246. package/plugin/vendor/reflexio/reflexio/server/services/reflection/components/__init__.py +7 -0
  247. package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +12 -1
  248. package/plugin/vendor/reflexio/reflexio/server/services/reflection/{reflection_service.py → service.py} +36 -16
  249. package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +83 -6
  250. package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +36 -1
  251. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/README.md +8 -0
  252. package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +1 -2
  253. package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +27 -0
  254. package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +9 -9
  255. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +2 -0
  256. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +4 -1
  257. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +642 -197
  258. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +61 -104
  259. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_lineage.py +628 -0
  260. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +38 -6
  261. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +978 -184
  262. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +519 -128
  263. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +77 -3
  264. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +23 -9
  265. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +5 -2
  266. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +131 -20
  267. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +2 -8
  268. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +5 -0
  269. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +36 -53
  270. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_lineage.py +215 -0
  271. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +20 -0
  272. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +243 -7
  273. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +121 -1
  274. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +60 -0
  275. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_retrieval_log.py +51 -0
  276. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +17 -0
  277. package/plugin/vendor/reflexio/reflexio/server/services/tagging/README.md +8 -0
  278. package/plugin/vendor/reflexio/reflexio/server/services/tagging/__init__.py +1 -0
  279. package/plugin/vendor/reflexio/reflexio/server/services/tagging/service.py +200 -0
  280. package/plugin/vendor/reflexio/reflexio/server/services/tagging/tagging_scheduler.py +149 -0
  281. package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +229 -32
  282. package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +2 -1
  283. package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +120 -1
  284. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +4 -0
  285. package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/search_settings.json +5 -0
  286. package/plugin/vendor/reflexio/reflexio/server/tracing.py +30 -0
  287. package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +18 -0
  288. package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +61 -26
  289. package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +41 -4
  290. package/scripts/setup-claude-smart.sh +8 -3
  291. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +0 -517
  292. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +0 -473
  293. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +0 -2156
  294. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +0 -18
  295. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +0 -241
  296. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +0 -140
  297. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +0 -113
  298. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +0 -52
  299. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +0 -103
  300. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +0 -156
  301. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +0 -134
  302. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +0 -24
  303. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +0 -278
  304. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +0 -164
  305. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +0 -36
  306. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +0 -35
  307. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +0 -27
  308. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +0 -31
  309. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +0 -42
  310. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +0 -49
  311. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +0 -91
  312. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +0 -50
  313. package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +0 -13
  314. package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +0 -192
  315. package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +0 -303
  316. package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +0 -138
  317. package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +0 -1125
  318. /package/plugin/vendor/reflexio/reflexio/integrations/{__init__.py → openclaw/plugin/src/openclaw_smart/__init__.py} +0 -0
  319. /package/plugin/vendor/reflexio/reflexio/integrations/openclaw/{types → plugin/types}/openclaw.d.ts +0 -0
  320. /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{distribution.py → components/distribution.py} +0 -0
  321. /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{hero_state.py → components/hero_state.py} +0 -0
  322. /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{shadow_aggregation.py → components/shadow_aggregation.py} +0 -0
  323. /package/plugin/vendor/reflexio/reflexio/server/services/reflection/{reflection_extractor.py → components/extractor.py} +0 -0
@@ -1,17 +1,32 @@
1
- # .env
1
+ # =============================================================================
2
+ # Reflexio (open source) — example environment file
3
+ # =============================================================================
4
+ # Copy to `.env` and fill in the values you need. The open-source CLI runs with
5
+ # SQLite storage and no auth by default, so the only thing you must set is one
6
+ # LLM provider key.
7
+ #
8
+ # LEGEND:
9
+ # (optional) = safe to leave empty; code default shown
10
+ # options: = allowed values for a categorical variable
11
+ # =============================================================================
2
12
 
3
- # ====================
4
- # LLM API Keys
5
- # ====================
13
+ # =============================================================================
14
+ # 1. LLM PROVIDER KEYS
15
+ # =============================================================================
6
16
  # Set at least one API key. The system auto-detects available providers and
7
- # selects appropriate default models per role (generation, evaluation, should_run,
8
- # pre_retrieval, embedding). Provider priority when multiple keys are set:
9
- # Anthropic > Gemini > OpenRouter > DeepSeek > MiniMax > DashScope > xAI > Moonshot > ZAI > OpenAI
17
+ # selects appropriate default models per role (generation, evaluation,
18
+ # should_run, pre_retrieval, embedding).
19
+ #
20
+ # Provider priority when multiple keys are set:
21
+ # Anthropic > Gemini > OpenRouter > DeepSeek > MiniMax > DashScope > xAI >
22
+ # Moonshot > ZAI > OpenAI
10
23
  # For the embedding role, if the top-priority provider has no embedding support,
11
24
  # the next embedding-capable provider is used (currently OpenAI or Gemini).
25
+ #
12
26
  # Model resolution order (highest priority first):
13
27
  # 1. Org-level LLMConfig override
14
- # 2. Non-empty values in reflexio/server/site_var/site_var_sources/llm_model_setting.json
28
+ # 2. Non-empty values in
29
+ # reflexio/server/site_var/site_var_sources/llm_model_setting.json
15
30
  # 3. Auto-detected default for the primary available provider
16
31
  OPENAI_API_KEY=
17
32
  ANTHROPIC_API_KEY=
@@ -24,39 +39,48 @@ ZAI_API_KEY=
24
39
  MOONSHOT_API_KEY=
25
40
  XAI_API_KEY=
26
41
 
27
- # ====================
28
- # Observability (Optional)
29
- # ====================
30
- # Set to enable Braintrust LLM observability (https://www.braintrust.dev)
42
+ # =============================================================================
43
+ # 2. OBSERVABILITY (optional)
44
+ # =============================================================================
45
+ # Set to enable Braintrust LLM observability (https://www.braintrust.dev).
31
46
  # BRAINTRUST_API_KEY=
32
47
  # BRAINTRUST_PROJECT_NAME=reflexio
33
48
 
34
- # ====================
35
- # Local Storage Configuration
36
- # ====================
49
+ # =============================================================================
50
+ # 3. STORAGE
51
+ # =============================================================================
37
52
  # Local storage directory — houses disk-storage artifacts and the SQLite
38
- # database file (reflexio.db). Defaults to ~/.reflexio/data/.
53
+ # database file (reflexio.db). (optional; default ~/.reflexio/data/)
39
54
  LOCAL_STORAGE_PATH=
55
+ # Default org id for no-auth / local mode. Controls the request org, and hence
56
+ # the config file name (config_<org>.json) and the SQLite data scope. Override
57
+ # it to run a second local backend under a distinct org so the two don't collide
58
+ # on the same config file under ~/.reflexio/. (optional; default self-host-org)
59
+ REFLEXIO_DEFAULT_ORG_ID=self-host-org
40
60
 
41
- # ====================
42
- # Extraction
43
- # ====================
61
+ # =============================================================================
62
+ # 4. EXTRACTION
63
+ # =============================================================================
44
64
  # Per-interaction content token budget when formatting interactions into an
45
65
  # extraction/evaluation prompt. When an interaction's content exceeds this many
46
66
  # tokens, the first half and last half are kept (head + tail) and the middle is
47
- # elided. Set to <=0 to disable slicing (pass full content). Default 512.
67
+ # elided. (optional; default 512; set <= 0 to disable slicing and pass full
68
+ # content)
48
69
  REFLEXIO_MAX_INTERACTION_CONTENT_TOKENS=512
70
+ # Inactivity delay in seconds before a quiet session is evaluated by agent-success
71
+ # evaluation. (optional; default 600 = 10 minutes)
72
+ GROUP_EVALUATION_DELAY_SECONDS=600
49
73
 
50
- # ====================
51
- # Testing & Logging
52
- # ====================
53
- # Set to true to enable test environment mode
54
- IS_TEST_ENV=true
55
- # Set to enable debug logging to console
74
+ # =============================================================================
75
+ # 5. TESTING & LOGGING
76
+ # =============================================================================
77
+ # Verbose debug logging to console. options: true | false
56
78
  DEBUG_LOG_TO_CONSOLE=true
57
- # Mock LLM call response
79
+ # Mark the process as a test environment. options: true | false
80
+ IS_TEST_ENV=true
81
+ # Return canned LLM responses instead of calling providers. options: true | false
58
82
  MOCK_LLM_RESPONSE=false
59
- # Override the base directory for log files. The .reflexio/logs suffix is
60
- # always preserved, so e.g. REFLEXIO_LOG_DIR=/tmp/foo writes logs to
61
- # /tmp/foo/.reflexio/logs/. Defaults to $HOME (i.e. ~/.reflexio/logs/).
83
+ # Override the base directory for log files. The .reflexio/logs suffix is always
84
+ # preserved, so e.g. REFLEXIO_LOG_DIR=/tmp/foo writes logs to
85
+ # /tmp/foo/.reflexio/logs/. (optional; default $HOME -> ~/.reflexio/logs/)
62
86
  REFLEXIO_LOG_DIR=
@@ -11,8 +11,9 @@
11
11
  [![Downloads](https://static.pepy.tech/badge/reflexio-ai/month)](https://pepy.tech/project/reflexio-ai)
12
12
  [![Search p50 57ms](https://img.shields.io/badge/search-57ms%20p50-brightgreen)](reflexio/benchmarks/retrieval_latency/results/report.md)
13
13
  [![GitHub stars](https://img.shields.io/github/stars/ReflexioAI/reflexio)](https://github.com/ReflexioAI/reflexio/stargazers)
14
+ [![Discord](https://img.shields.io/badge/Discord-Join%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/7fnCxahase)
14
15
 
15
- [Quick Start](#quick-start) · [Features](#features) · [Integrations](#integrations) · [SDK](#sdk-usage) · [CLI](reflexio/cli/README.md) · [Architecture](#architecture) · [Docs](https://www.reflexio.ai/docs) · [Contributing](#contributing)
16
+ [Quick Start](#quick-start) · [Features](#features) · [Integrations](#integrations) · [SDK](#sdk-usage) · [CLI](reflexio/cli/README.md) · [Architecture](#architecture) · [Docs](https://www.reflexio.ai/docs) · [Community](#community) · [Contributing](#contributing)
16
17
 
17
18
  </div>
18
19
 
@@ -85,6 +86,7 @@ Publish conversations from your agent, and Reflexio closes the self-improvement
85
86
  - [SDK Usage](#sdk-usage)
86
87
  - [Architecture](#architecture)
87
88
  - [Documentation](#documentation)
89
+ - [Community](#community)
88
90
  - [Contributing](#contributing)
89
91
  - [Star History](#star-history)
90
92
  - [License](#license)
@@ -116,7 +118,7 @@ Publish conversations from your agent, and Reflexio closes the self-improvement
116
118
  pip install reflexio-ai
117
119
 
118
120
  # start/stop services. data saved under ~/.reflexio
119
- reflexio services start # API (8081), Docs (8082), SQLite storage
121
+ reflexio services start # API (8061), Docs (8062), SQLite storage
120
122
  reflexio services stop # Stop all services
121
123
  ```
122
124
 
@@ -135,13 +137,13 @@ uv sync # Python (includes workspace packages
135
137
  npm --prefix docs install # API docs
136
138
 
137
139
  # start/stop services. data saved under ~/.reflexio
138
- uv run reflexio services start # API (8081), Docs (8082), SQLite storage
140
+ uv run reflexio services start # API (8061), Docs (8062), SQLite storage
139
141
  uv run reflexio services stop # Stop all services
140
142
  ```
141
143
 
142
144
  > Alternative: `python -m reflexio.cli services start` or `./run_services.sh`
143
145
 
144
- Once running, open **[http://localhost:8082](http://localhost:8082)** to interactively browse and try out the API.
146
+ Once running, open **[http://localhost:8062](http://localhost:8062)** to interactively browse and try out the API.
145
147
  <p align="center">
146
148
  <img src="docs/images/doc_website.png" width="800px" alt="Reflexio Doc Website">
147
149
  </p>
@@ -172,7 +174,7 @@ One conversation, two artifacts: a user profile (`production region is us-west-2
172
174
  import reflexio
173
175
 
174
176
  client = reflexio.ReflexioClient(
175
- url_endpoint="http://localhost:8081/"
177
+ url_endpoint="http://localhost:8061/"
176
178
  )
177
179
 
178
180
  # Publish a multi-turn conversation where the user corrects the agent —
@@ -222,7 +224,7 @@ Reflexio will automatically generate profiles and extract playbooks in the backg
222
224
  - Session-level evaluation triggered automatically (10 min after last request)
223
225
  - Shadow comparison mode: A/B test regular vs shadow agent responses
224
226
  - Tool usage analysis for blocking issue detection
225
- - **Causal measurement of Reflexio's impact** — session-level A/B grouping on the Evaluation page driven by `Request.metadata.reflexio_retrieval_enabled` (with per-turn shadow comparison in development)
227
+ - **Causal measurement of Reflexio's impact** — source-set comparison on the Evaluation page groups evaluated sessions by the first request's `source`
226
228
 
227
229
  [Read more about evaluation →](https://www.reflexio.ai/docs/examples/agent-evaluation)
228
230
 
@@ -254,7 +256,7 @@ pip install reflexio-client
254
256
  import reflexio
255
257
 
256
258
  client = reflexio.ReflexioClient(
257
- url_endpoint="http://localhost:8081/"
259
+ url_endpoint="http://localhost:8061/"
258
260
  )
259
261
 
260
262
  # Publish interactions
@@ -265,7 +267,7 @@ client.publish_interaction(
265
267
  {"role": "assistant", "content": "..."},
266
268
  ],
267
269
  agent_version="v1", # optional: track agent versions
268
- session_id="session-abc", # optional: group requests into sessions
270
+ session_id="session-abc", # required: stable conversation/session id
269
271
  )
270
272
 
271
273
  # Search profiles
@@ -325,6 +327,10 @@ For comprehensive guides, examples, and API reference, visit the **[Reflexio Doc
325
327
 
326
328
  For coding agents adding Reflexio to another agent, see **[Integrating an AI Agent with Reflexio](AI_AGENT_INTEGRATION.md)**.
327
329
 
330
+ ## Community
331
+
332
+ Join the Reflexio community on Discord: [discord.gg/7fnCxahase](https://discord.gg/7fnCxahase).
333
+
328
334
  ## Contributing
329
335
 
330
336
  We welcome contributions! Please see [developer.md](developer.md) for guidelines.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "reflexio-ai"
3
- version = "0.2.24"
3
+ version = "0.2.26"
4
4
  description = "A Python library for the Reflexio"
5
5
  authors = [{name = "Reflexio Team"}]
6
6
  readme = "README.md"
@@ -139,6 +139,9 @@ markers = [
139
139
  "e2e: Full workflow tests with real storage and services",
140
140
  "requires_credentials: Tests that need API keys (costs money)",
141
141
  ]
142
+ filterwarnings = [
143
+ "ignore:This process \\(pid=.*\\) is multi-threaded, use of fork\\(\\) may lead to deadlocks in the child\\.:DeprecationWarning:multiprocessing\\.popen_fork",
144
+ ]
142
145
 
143
146
  [tool.coverage.run]
144
147
  # Measure branch coverage — ensures both if/else paths are tested, not just lines
@@ -217,6 +220,12 @@ ignore = [
217
220
  "reflexio/server/api.py" = ["B008", "ARG001", "ARG002"]
218
221
  "reflexio/server/api_endpoints/**" = ["B008", "ARG001", "ARG002"]
219
222
  "reflexio/integrations/**" = ["ARG002"]
223
+ # The openclaw plugin is a nested package; its tests/scripts/cli are not reached
224
+ # by the top-level "tests/**" / "reflexio/cli/**" globs above (those only match
225
+ # at the tree root), so mirror the same standard test/cli ignores here.
226
+ "reflexio/integrations/openclaw/plugin/tests/**" = ["S101", "ARG001", "ARG002", "ARG005", "PTH", "ANN", "S105", "S106", "S107", "S108", "S310", "N802", "N806"]
227
+ "reflexio/integrations/openclaw/plugin/scripts/**" = ["S101", "G004", "ANN", "S603", "S607"]
228
+ "reflexio/integrations/openclaw/plugin/src/openclaw_smart/cli.py" = ["S603", "S607"]
220
229
  "reflexio/server/services/configurator/test_config_storage.py" = ["S101", "ANN", "S108"]
221
230
  "demo/**" = ["S101", "PTH", "G004", "ANN"]
222
231
  "reflexio/server/services/storage/sqlite_storage/**" = ["S608"]
@@ -261,6 +270,9 @@ version_toml = ["pyproject.toml:project.version"]
261
270
  tag_format = "reflexio-v{version}"
262
271
  commit_message = "chore(release): reflexio v{version}"
263
272
  build_command = "pip install build && python -m build"
273
+ # Pre-1.0 convention: a breaking change bumps the MINOR (0.x.y -> 0.(x+1).0),
274
+ # not MAJOR. So the B3 Task 7 breaking removal releases as 0.3.0, not 1.0.0.
275
+ major_on_zero = false
264
276
 
265
277
  [tool.semantic_release.branches.main]
266
278
  match = "^(main|master)$"
@@ -140,6 +140,7 @@ client (Python SDK)
140
140
  - `evaluation_overview/` - Evaluation-page aggregates and hero metrics
141
141
  - `playbook_optimizer/` - Scenario-based playbook optimization experiments
142
142
  - `braintrust/` - Braintrust eval export/sync support
143
+ - `lineage/` - Resolve current records and schedule tombstone garbage collection for superseded profile/playbook rows
143
144
  - `storage/` - Abstract layer (SQLite prod, LocalJSON test)
144
145
  - `pre_retrieval/` - Query rewriting and document expansion helpers
145
146
  - `configurator/` - YAML config loader
@@ -62,7 +62,7 @@ Example: `uv run reflexio --json search "refund policy"`.
62
62
  Start and stop the backend, docs server, and optional local embedding daemon.
63
63
 
64
64
  ```shell
65
- uv run reflexio services start # backend :8081, docs :8082
65
+ uv run reflexio services start # backend :8061, docs :8062
66
66
  uv run reflexio services start --storage sqlite # sqlite (default) | supabase | postgres
67
67
  uv run reflexio services start --backend-port 9000 --docs-port 9001
68
68
  uv run reflexio services start --only backend --no-reload
@@ -92,6 +92,7 @@ Reflexio learns most from interactions that contain a **signal** — a user corr
92
92
  ```shell
93
93
  uv run reflexio publish \
94
94
  --user-id alice \
95
+ --session-id style-session-1 \
95
96
  --user-message "Stop adding disclaimers and caveats. Give me the answer in one line." \
96
97
  --agent-response "Understood — I'll drop the boilerplate from now on." \
97
98
  --wait
@@ -102,7 +103,7 @@ uv run reflexio publish \
102
103
  For real dialogues (3+ turns, tool calls, corrections mid-conversation), pass a JSON object whose `interactions` field is a list of `{role, content}` items. Each item becomes one turn, in order. Roles are `user` and `assistant`; `system` and `tool` turns are also accepted.
103
104
 
104
105
  ```shell
105
- uv run reflexio publish --user-id alice --wait --data '{
106
+ uv run reflexio publish --user-id alice --session-id deploy-session-1 --wait --data '{
106
107
  "interactions": [
107
108
  {"role": "user", "content": "Deploy the payments service to us-east-1."},
108
109
  {"role": "assistant", "content": "Starting deployment to us-east-1..."},
@@ -123,11 +124,11 @@ You can also load inline JSON from a file with `@`: `--data @conversation.json`.
123
124
  For bulk publishing or conversations you already have on disk, point at a file. A `.json` file should be a single object (or a list of objects); a `.jsonl` file is one JSON object per line, one conversation per line.
124
125
 
125
126
  ```shell
126
- uv run reflexio publish --file conversations.jsonl --user-id alice --wait
127
- cat conversations.jsonl | uv run reflexio publish --stdin --user-id alice
127
+ uv run reflexio publish --file conversations.jsonl --user-id alice --session-id bulk-session --wait
128
+ cat conversations.jsonl | uv run reflexio publish --stdin --user-id alice --session-id bulk-session
128
129
  ```
129
130
 
130
- Each payload object accepts the same fields as Mode 2 (`interactions`, and optionally per-payload overrides for `user_id`, `session_id`, `source`, `agent_version`). A payload's own `user_id` wins over the `--user-id` flag, so you can publish a mixed-user JSONL file in a single call.
131
+ Each payload object accepts the same fields as Mode 2 (`interactions`, `session_id`, and optionally per-payload overrides for `user_id`, `source`, `agent_version`). A payload's own `user_id` and `session_id` win over the corresponding flags, so you can publish a mixed-user or mixed-session JSONL file in a single call.
131
132
 
132
133
  ### Common flags
133
134
 
@@ -136,11 +137,12 @@ Apply to all three modes:
136
137
  | Flag | Purpose |
137
138
  | ------------------- | ----------------------------------------------------------------------- |
138
139
  | `--wait` | Block until server-side extraction finishes (returns real counts). |
139
- | `--session-id` | Group multiple `publish` calls into one session. |
140
+ | `--session-id` | Required unless each payload includes `session_id`; group publishes into one session. |
140
141
  | `--agent-version` | Tag the interaction with an agent version (used by playbook filtering). |
141
142
  | `--source` | Free-form source tag (defaults to `cli`). |
142
143
  | `--skip-aggregation`| Extract profiles/playbooks but skip playbook aggregation. |
143
144
  | `--force-extraction`| Bypass all extraction gates (`stride_size`, cheap pre-filter, LLM `should_run`) and always run extractors. |
145
+ | `--evaluation-only` | Store the request for session-level evaluation only; requires `--session-id` and skips profile/playbook extraction. |
144
146
 
145
147
  Full options via `uv run reflexio interactions publish --help`.
146
148
 
@@ -214,7 +216,7 @@ uv run reflexio config pull # pull server config to
214
216
  ## Auth
215
217
 
216
218
  ```shell
217
- uv run reflexio auth login --api-key $REFLEXIO_API_KEY --server-url http://localhost:8081
219
+ uv run reflexio auth login --api-key $REFLEXIO_API_KEY --server-url http://localhost:8061
218
220
  uv run reflexio auth status
219
221
  uv run reflexio auth logout
220
222
  ```
@@ -36,8 +36,17 @@ def main(argv: list[str] | None = None) -> None:
36
36
  ``reflexio.cli`` entry-point group before falling back to the
37
37
  default open-source app factory.
38
38
  """
39
- from reflexio.cli.env_loader import load_reflexio_env
39
+ from reflexio.cli.env_loader import (
40
+ block_implicit_dotenv_walkup,
41
+ load_reflexio_env,
42
+ )
40
43
 
44
+ # Stop third-party import-time ``load_dotenv()`` calls (notably litellm)
45
+ # from walking UP the tree and loading a parent ``.env`` — e.g. the
46
+ # enterprise-root ``.env`` when the OSS launcher runs from the
47
+ # ``open_source/reflexio`` submodule. Must precede any import that pulls in
48
+ # litellm. Reflexio's own scoped loader runs right after.
49
+ block_implicit_dotenv_walkup()
41
50
  load_reflexio_env()
42
51
 
43
52
  from importlib.metadata import entry_points
@@ -20,6 +20,19 @@ _VALID_STORAGE_BACKENDS = frozenset({"sqlite", "supabase", "postgres"})
20
20
  _DEFAULT_ORG_ID = "self-host-org"
21
21
  _DEFAULT_STORAGE = "sqlite"
22
22
 
23
+
24
+ def default_org_id() -> str:
25
+ """Resolve the default org id, honoring ``REFLEXIO_DEFAULT_ORG_ID``.
26
+
27
+ Mirrors :func:`reflexio.server._auth.default_get_org_id` so the local CLI
28
+ helpers (``setup``, ``config show`` / ``config local``) resolve the same
29
+ ``config_<org>.json`` the running no-auth server reads. Uses ``os.environ``
30
+ directly (not ``env_utils``) to keep this module's import lightweight — see
31
+ the ``_TYPE_TO_BACKEND`` note above.
32
+ """
33
+ return os.environ.get("REFLEXIO_DEFAULT_ORG_ID", "").strip() or _DEFAULT_ORG_ID
34
+
35
+
23
36
  # Maps StorageConfig subclass to backend string. Lazy-imported in functions
24
37
  # that need it so module-level import stays lightweight (no Pydantic at import).
25
38
  _TYPE_TO_BACKEND: dict[type, str] = {} # populated on first use
@@ -71,24 +84,26 @@ def default_config_path(base_dir: str | None = None) -> Path:
71
84
  Returns:
72
85
  Path: Absolute path to the default-org config file (may not exist).
73
86
  """
74
- return _config_dir(base_dir) / f"config_{_DEFAULT_ORG_ID}.json"
87
+ return _config_dir(base_dir) / f"config_{default_org_id()}.json"
75
88
 
76
89
 
77
90
  def load_storage_from_config(
78
- org_id: str = _DEFAULT_ORG_ID,
91
+ org_id: str | None = None,
79
92
  *,
80
93
  base_dir: str | None = None,
81
94
  ) -> str | None:
82
95
  """Read storage type from the local config file.
83
96
 
84
97
  Args:
85
- org_id: Organization ID for the config file name.
98
+ org_id: Organization ID for the config file name. Defaults to the
99
+ ``REFLEXIO_DEFAULT_ORG_ID``-aware default org.
86
100
  base_dir: Override base directory (for testing). If None, uses ~/.reflexio/.
87
101
 
88
102
  Returns:
89
103
  Storage backend string ("sqlite", "supabase", "postgres") or None if
90
104
  no config file exists or storage_config is unset.
91
105
  """
106
+ org_id = org_id or default_org_id()
92
107
  config_path = _config_dir(base_dir) / f"config_{org_id}.json"
93
108
  if not config_path.exists():
94
109
  return None
@@ -114,7 +129,7 @@ def load_storage_from_config(
114
129
 
115
130
  def save_storage_to_config(
116
131
  storage_type: str,
117
- org_id: str = _DEFAULT_ORG_ID,
132
+ org_id: str | None = None,
118
133
  *,
119
134
  base_dir: str | None = None,
120
135
  ) -> None:
@@ -125,7 +140,8 @@ def save_storage_to_config(
125
140
 
126
141
  Args:
127
142
  storage_type: Backend name ("sqlite", "supabase", "postgres").
128
- org_id: Organization ID for the config file name.
143
+ org_id: Organization ID for the config file name. Defaults to the
144
+ ``REFLEXIO_DEFAULT_ORG_ID``-aware default org.
129
145
  base_dir: Override base directory (for testing).
130
146
  """
131
147
  from reflexio.models.config_schema import (
@@ -137,6 +153,7 @@ def save_storage_to_config(
137
153
  LocalFileConfigStorage,
138
154
  )
139
155
 
156
+ org_id = org_id or default_org_id()
140
157
  storage_obj = LocalFileConfigStorage(org_id, base_dir=base_dir)
141
158
  config = storage_obj.load_config()
142
159
 
@@ -122,6 +122,20 @@ def _interactions_from_payload(payload: dict) -> list[InteractionData]:
122
122
  ) from exc
123
123
 
124
124
 
125
+ def _resolve_session_id(raw_session_id: object, *, source_hint: str) -> str:
126
+ """Return a non-empty session id or raise a CLI validation error."""
127
+ if not isinstance(raw_session_id, str) or not raw_session_id.strip():
128
+ raise CliError(
129
+ error_type="validation",
130
+ message=(
131
+ "session_id is required and cannot be empty "
132
+ f"({source_hint}; pass --session-id or include 'session_id' in the payload)"
133
+ ),
134
+ exit_code=EXIT_VALIDATION,
135
+ )
136
+ return raw_session_id.strip()
137
+
138
+
125
139
  def _read_data_arg(data: str) -> str:
126
140
  """Read inline JSON or from a file path prefixed with ``@``.
127
141
 
@@ -233,7 +247,7 @@ def publish(
233
247
  ),
234
248
  ] = None,
235
249
  session_id: Annotated[
236
- str | None, typer.Option(help="Session ID for grouping")
250
+ str | None, typer.Option(help="Required session ID for grouping")
237
251
  ] = None,
238
252
  source: Annotated[str, typer.Option(help="Source tag")] = "cli",
239
253
  agent_version: Annotated[
@@ -265,6 +279,13 @@ def publish(
265
279
  help="Bypass all extraction gates (stride_size, cheap pre-filter, LLM should_run) and always run extractors",
266
280
  ),
267
281
  ] = False,
282
+ evaluation_only: Annotated[
283
+ bool,
284
+ typer.Option(
285
+ "--evaluation-only",
286
+ help="Store for session-level evaluation only and skip profile/playbook extraction",
287
+ ),
288
+ ] = False,
268
289
  override_learning_stall: Annotated[
269
290
  bool,
270
291
  typer.Option(
@@ -310,6 +331,9 @@ def publish(
310
331
  message="--user-id is required with --user-message (or set REFLEXIO_USER_ID)",
311
332
  exit_code=EXIT_VALIDATION,
312
333
  )
334
+ resolved_session_id = _resolve_session_id(
335
+ session_id, source_hint="single-turn publish"
336
+ )
313
337
  interactions: list[InteractionData | dict] = [
314
338
  InteractionData(role="user", content=user_message),
315
339
  InteractionData(role="assistant", content=agent_response),
@@ -319,10 +343,11 @@ def publish(
319
343
  interactions=interactions,
320
344
  source=source,
321
345
  agent_version=resolve_agent_version(agent_version),
322
- session_id=session_id,
346
+ session_id=resolved_session_id,
323
347
  wait_for_response=wait,
324
348
  skip_aggregation=skip_aggregation,
325
349
  force_extraction=force_extraction,
350
+ evaluation_only=evaluation_only,
326
351
  override_learning_stall=override_learning_stall,
327
352
  )
328
353
  if json_mode:
@@ -371,15 +396,20 @@ def publish(
371
396
  ),
372
397
  exit_code=EXIT_VALIDATION,
373
398
  )
399
+ resolved_session_id = _resolve_session_id(
400
+ payload.get("session_id", session_id),
401
+ source_hint="payload publish",
402
+ )
374
403
  result = client.publish_interaction(
375
404
  user_id=resolved_user_id,
376
405
  interactions=interaction_items, # type: ignore[arg-type]
377
406
  source=payload.get("source", source),
378
407
  agent_version=payload.get("agent_version", resolved_version),
379
- session_id=payload.get("session_id", session_id),
408
+ session_id=resolved_session_id,
380
409
  wait_for_response=wait,
381
410
  skip_aggregation=payload.get("skip_aggregation", skip_aggregation),
382
411
  force_extraction=payload.get("force_extraction", force_extraction),
412
+ evaluation_only=payload.get("evaluation_only", evaluation_only),
383
413
  override_learning_stall=payload.get(
384
414
  "override_learning_stall", override_learning_stall
385
415
  ),
@@ -441,7 +471,7 @@ def search(
441
471
  @handle_errors
442
472
  def delete(
443
473
  ctx: typer.Context,
444
- interaction_id: Annotated[str, typer.Option(help="Interaction ID to delete")],
474
+ interaction_id: Annotated[int, typer.Option(help="Interaction ID to delete")],
445
475
  user_id: Annotated[str, typer.Option(help="User ID that owns the interaction")],
446
476
  ) -> None:
447
477
  """Delete a single interaction by ID."""
@@ -157,15 +157,22 @@ def delete(
157
157
  ],
158
158
  profile_id: Annotated[
159
159
  str,
160
- typer.Option("--profile-id", help="Specific profile ID to delete"),
160
+ typer.Option(
161
+ "--profile-id",
162
+ help="Specific profile ID to delete (required; use 'delete-all' for bulk)",
163
+ ),
161
164
  ] = "",
162
165
  ) -> None:
163
- """Delete a user profile.
166
+ """Delete a specific user profile.
167
+
168
+ A ``--profile-id`` is required: the server rejects an empty profile id
169
+ with "Profile id or search query is required". To remove every profile
170
+ for an org, use ``reflexio user-profiles delete-all`` instead.
164
171
 
165
172
  Args:
166
173
  ctx: Typer context with CliState in ctx.obj
167
174
  user_id: User ID owning the profile
168
- profile_id: Specific profile ID to delete (empty string for all user profiles)
175
+ profile_id: Specific profile ID to delete
169
176
  """
170
177
  client = get_client(ctx)
171
178
  resp = client.delete_profile(
@@ -178,10 +185,8 @@ def delete(
178
185
  if json_mode:
179
186
  render(resp, json_mode=True)
180
187
  else:
181
- label = (
182
- f"profile {profile_id}" if profile_id else f"profiles for user {user_id}"
183
- )
184
- print_info(f"Deleted {label}")
188
+ raise_if_failed(resp, default="Failed to delete user profile")
189
+ print_info(f"Deleted profile {profile_id} for user {user_id}")
185
190
 
186
191
 
187
192
  @app.command(name="delete-all")
@@ -123,6 +123,13 @@ def _ensure_llm_configured(env_path: Path) -> None:
123
123
  )
124
124
  _prompt_embedding_provider(env_path, non_embedding_provider)
125
125
 
126
+ # override=True is required here: the wizard wrote the operator's chosen key
127
+ # to the .env FILE only (via set_env_var), never to os.environ. A fresh
128
+ # install ships an empty OPENAI_API_KEY placeholder already in os.environ, so
129
+ # with override=False this reload would skip the (present-but-empty) var and
130
+ # the key just entered would never reach the process env. For this OSS local
131
+ # first-run path the file value must win. (The enterprise mode-file path uses
132
+ # override=False in load_reflexio_env_for_mode and is unaffected.)
126
133
  load_dotenv(dotenv_path=env_path, override=True)
127
134
  typer.echo()
128
135
 
@@ -159,13 +166,13 @@ def validate_storage_backend(storage: str | None) -> None:
159
166
  @app.command()
160
167
  def start(
161
168
  backend_port: Annotated[
162
- int | None, typer.Option(help="Backend server port (default: 8081)")
169
+ int | None, typer.Option(help="Backend server port (default: 8061)")
163
170
  ] = None,
164
171
  docs_port: Annotated[
165
- int | None, typer.Option(help="Docs server port (default: 8082)")
172
+ int | None, typer.Option(help="Docs server port (default: 8062)")
166
173
  ] = None,
167
174
  embedding_port: Annotated[
168
- int | None, typer.Option(help="Embedding service port (default: 8072)")
175
+ int | None, typer.Option(help="Embedding service port (default: 8069)")
169
176
  ] = None,
170
177
  only: Annotated[
171
178
  str | None,
@@ -264,13 +271,13 @@ def start(
264
271
  @app.command()
265
272
  def stop(
266
273
  backend_port: Annotated[
267
- int | None, typer.Option(help="Backend server port (default: 8081)")
274
+ int | None, typer.Option(help="Backend server port (default: 8061)")
268
275
  ] = None,
269
276
  docs_port: Annotated[
270
- int | None, typer.Option(help="Docs server port (default: 8082)")
277
+ int | None, typer.Option(help="Docs server port (default: 8062)")
271
278
  ] = None,
272
279
  embedding_port: Annotated[
273
- int | None, typer.Option(help="Embedding service port (default: 8072)")
280
+ int | None, typer.Option(help="Embedding service port (default: 8069)")
274
281
  ] = None,
275
282
  only: Annotated[
276
283
  str | None,