claude-smart 0.2.45 → 0.2.47
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.
- package/.claude-plugin/marketplace.json +3 -3
- package/README.md +47 -10
- package/bin/claude-smart.js +535 -23
- package/package.json +22 -3
- package/plugin/.claude-plugin/plugin.json +4 -2
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/README.md +27 -6
- package/plugin/commands/clear-all.md +1 -0
- package/plugin/commands/dashboard.md +1 -0
- package/plugin/commands/learn.md +1 -0
- package/plugin/commands/restart.md +1 -0
- package/plugin/commands/show.md +1 -0
- package/plugin/dashboard/app/configure/env/page.tsx +40 -14
- package/plugin/dashboard/app/configure/server/page.tsx +51 -1
- package/plugin/dashboard/app/layout.tsx +20 -0
- package/plugin/dashboard/app/preferences/[id]/page.tsx +8 -8
- package/plugin/dashboard/app/skills/project/[id]/page.tsx +7 -3
- package/plugin/dashboard/app/skills/shared/[id]/page.tsx +10 -3
- package/plugin/dashboard/lib/claude-settings-file.ts +20 -10
- package/plugin/dashboard/lib/reflexio-client.ts +16 -0
- package/plugin/dashboard/lib/status.ts +10 -3
- package/plugin/dashboard/lib/types.ts +18 -6
- package/plugin/hooks/codex-hooks.json +0 -1
- package/plugin/opencode/assistant-buffer.ts +108 -0
- package/plugin/opencode/dist/assistant-buffer.js +96 -0
- package/plugin/opencode/dist/internal.js +12 -0
- package/plugin/opencode/dist/payload.js +85 -0
- package/plugin/opencode/dist/server.mjs +232 -0
- package/plugin/opencode/internal.ts +18 -0
- package/plugin/opencode/package.json +3 -0
- package/plugin/opencode/payload.ts +90 -0
- package/plugin/opencode/server.mts +251 -0
- package/plugin/opencode/tsconfig.json +13 -0
- package/plugin/pyproject.toml +25 -4
- package/plugin/scripts/_lib.sh +5 -1
- package/plugin/scripts/backend-service.sh +22 -2
- package/plugin/scripts/ensure-plugin-root.sh +4 -4
- package/plugin/scripts/hook_entry.sh +1 -1
- package/plugin/scripts/opencode-claude-compat +4 -0
- package/plugin/scripts/opencode-claude-compat.cmd +3 -0
- package/plugin/scripts/opencode-claude-compat.js +225 -0
- package/plugin/scripts/smart-install.sh +17 -9
- package/plugin/src/README.md +1 -1
- package/plugin/src/claude_smart/cli.py +498 -12
- package/plugin/src/claude_smart/context_format.py +9 -9
- package/plugin/src/claude_smart/cs_cite.py +66 -19
- package/plugin/src/claude_smart/env_config.py +12 -4
- package/plugin/src/claude_smart/events/session_start.py +26 -7
- package/plugin/src/claude_smart/events/stop.py +1 -1
- package/plugin/src/claude_smart/ids.py +1 -1
- package/plugin/src/claude_smart/reflexio_adapter.py +5 -5
- package/plugin/src/claude_smart/runtime.py +7 -1
- package/plugin/uv.lock +5 -5
- package/plugin/vendor/reflexio/.env.example +54 -30
- package/plugin/vendor/reflexio/README.md +17 -11
- package/plugin/vendor/reflexio/pyproject.toml +13 -1
- package/plugin/vendor/reflexio/reflexio/README.md +4 -1
- package/plugin/vendor/reflexio/reflexio/cli/README.md +9 -7
- package/plugin/vendor/reflexio/reflexio/cli/__main__.py +10 -1
- package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +22 -5
- package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +34 -4
- package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +12 -7
- package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +13 -6
- package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +212 -52
- package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +15 -2
- package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +292 -22
- package/plugin/vendor/reflexio/reflexio/cli/log_format.py +29 -4
- package/plugin/vendor/reflexio/reflexio/cli/run_services.py +17 -8
- package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +13 -10
- package/plugin/vendor/reflexio/reflexio/cli/utils.py +44 -1
- package/plugin/vendor/reflexio/reflexio/client/client.py +154 -13
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +135 -257
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/npm/openclaw-smart/bin/openclaw-smart.js +13 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/npm/openclaw-smart/package.json +15 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/README.md +38 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +151 -110
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +20 -10
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +28 -6
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/pyproject.toml +42 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/_lib.sh +371 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/backend-log-runner.sh +33 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/backend-service.sh +271 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/cli.sh +68 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/dashboard-open.sh +15 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/ensure-plugin-root.sh +84 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/hook_entry.sh +106 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/npm-cli.js +219 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/scripts/smart-install.sh +269 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/clear-all/SKILL.md +8 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/dashboard/SKILL.md +8 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/learn/SKILL.md +10 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +15 -44
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/restart/SKILL.md +6 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/show/SKILL.md +8 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/cli.py +634 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/context_format.py +224 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/context_inject.py +79 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/after_tool_call.py +160 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/agent_end.py +187 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/before_prompt_build.py +69 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/before_tool_call.py +30 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/session_end.py +36 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/events/session_start.py +130 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/hook.py +131 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/ids.py +94 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/internal_call.py +75 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/oc_cite.py +196 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/optimizer_assistant.py +272 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/publish.py +96 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/query_compose.py +66 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/reflexio_adapter.py +336 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/runtime.py +47 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/stall_banner.py +61 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/state.py +323 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_e2e_session_loop.py +190 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_publish_to_local_reflexio_integration.py +112 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_recursion_guard_integration.py +86 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/integration/test_search_inject_integration.py +144 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_cli.py +184 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_after_tool_call.py +142 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_agent_end.py +233 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_before_prompt_build.py +116 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_before_tool_call.py +35 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_session_end.py +47 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_events_session_start.py +109 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_hook_dispatch.py +117 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_ids.py +41 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_internal_call.py +50 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_oc_cite.py +88 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_publish.py +48 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_query_compose.py +48 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_reflexio_adapter.py +188 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_runtime.py +41 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_state.py +235 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/__mocks__/plugin-entry-stub.ts +6 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/test_npm_cli.test.ts +56 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests-ts/test_shim_dispatch.test.ts +171 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tsconfig.build.json +18 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/{tsconfig.json → plugin/tsconfig.json} +2 -2
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/uv.lock +3835 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/vitest.config.ts +18 -0
- package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +246 -10
- package/plugin/vendor/reflexio/reflexio/lib/_base.py +15 -0
- package/plugin/vendor/reflexio/reflexio/lib/_config.py +11 -4
- package/plugin/vendor/reflexio/reflexio/lib/_generation.py +17 -5
- package/plugin/vendor/reflexio/reflexio/lib/_lineage_parity_readers.py +187 -0
- package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +224 -21
- package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +1 -1
- package/plugin/vendor/reflexio/reflexio/lib/_search.py +52 -25
- package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +11 -1
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +127 -38
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +4 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/governance.py +117 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +64 -41
- package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +19 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +12 -5
- package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +97 -3
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +5 -1
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +5 -1
- package/plugin/vendor/reflexio/reflexio/models/config_schema.py +104 -7
- package/plugin/vendor/reflexio/reflexio/models/structured_output.py +148 -0
- package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +3 -3
- package/plugin/vendor/reflexio/reflexio/server/README.md +58 -33
- package/plugin/vendor/reflexio/reflexio/server/__init__.py +29 -5
- package/plugin/vendor/reflexio/reflexio/server/__main__.py +2 -2
- package/plugin/vendor/reflexio/reflexio/server/api.py +899 -103
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +7 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +4 -2
- package/plugin/vendor/reflexio/reflexio/server/auth.py +90 -0
- package/plugin/vendor/reflexio/reflexio/server/billing_meter.py +173 -0
- package/plugin/vendor/reflexio/reflexio/server/billing_signals.py +64 -0
- package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +46 -16
- package/plugin/vendor/reflexio/reflexio/server/env_utils.py +65 -0
- package/plugin/vendor/reflexio/reflexio/server/extensions.py +213 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +19 -4
- package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +264 -77
- package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +69 -7
- package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +4 -4
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +1 -1
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +75 -16
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/openclaw_provider.py +280 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/rerank/cross_encoder_reranker.py +12 -1
- package/plugin/vendor/reflexio/reflexio/server/llm/token_accounting.py +48 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +107 -17
- package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +360 -4
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.6.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.7.0.prompt.md +85 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.2.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.3.0.prompt.md +253 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.2.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.3.prompt.md +74 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.3.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.3.0.prompt.md +266 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.4.0.prompt.md +278 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.4.0.prompt.md +137 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.3.0.prompt.md +34 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +5 -12
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +5 -12
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.2.0.prompt.md +155 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/tagging/v1.0.0.prompt.md +23 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +89 -32
- package/plugin/vendor/reflexio/reflexio/server/services/README.md +28 -11
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/README.md +22 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +4 -2
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/components/__init__.py +7 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{agent_success_evaluator.py → components/evaluator.py} +3 -16
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +28 -72
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{group_evaluation_runner.py → runner.py} +12 -10
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{delayed_group_evaluator.py → scheduler.py} +10 -2
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/{agent_success_evaluation_service.py → service.py} +36 -1
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +160 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +5 -0
- package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +1 -1
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/README.md +9 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/components/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{rule_attribution.py → components/rule_attribution.py} +10 -9
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +15 -24
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +238 -164
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/README.md +31 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +13 -3
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +3 -2
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +32 -118
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +47 -16
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +105 -23
- package/plugin/vendor/reflexio/reflexio/server/services/governance/config.py +52 -0
- package/plugin/vendor/reflexio/reflexio/server/services/governance/service.py +378 -0
- package/plugin/vendor/reflexio/reflexio/server/services/governance/subject_refs.py +34 -0
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/gc_scheduler.py +219 -0
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/resolve.py +98 -0
- package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +26 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +18 -11
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/aggregation_prompt_processing.py +100 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/__init__.py +5 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_aggregator.py → components/aggregator.py} +334 -178
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_consolidator.py → components/consolidator.py} +168 -62
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_extractor.py → components/extractor.py} +5 -1
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_edit_apply.py +74 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +33 -3
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/{playbook_generation_service.py → service.py} +121 -19
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/README.md +10 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +2 -1
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +178 -30
- package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/README.md +9 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/components/__init__.py +17 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_deduplicator.py → components/consolidator.py} +7 -6
- package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_extractor.py → components/extractor.py} +31 -22
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +6 -13
- package/plugin/vendor/reflexio/reflexio/server/services/profile/{profile_generation_service.py → service.py} +32 -50
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +4 -8
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/components/__init__.py +7 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +12 -1
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/{reflection_service.py → service.py} +36 -16
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/recency.py +211 -0
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +99 -6
- package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +36 -1
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/README.md +8 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +1 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +31 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/governance_validation.py +681 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +9 -9
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +16 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +4 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +644 -197
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +106 -119
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_governance.py +1965 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_lineage.py +630 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +38 -6
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +31 -1369
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +756 -210
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +148 -34
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +23 -9
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +5 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/__init__.py +13 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_agent.py +952 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_eval_results.py +189 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_optimization.py +247 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_source_linkage.py +145 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_user.py +838 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +150 -23
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +2 -8
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +5 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +40 -57
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_governance.py +148 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_lineage.py +215 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +20 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +4 -677
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +134 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +62 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_retrieval_log.py +51 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +17 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/__init__.py +13 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_agent.py +365 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_eval_results.py +124 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_optimization.py +85 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_source_linkage.py +47 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_user.py +333 -0
- package/plugin/vendor/reflexio/reflexio/server/services/tagging/README.md +8 -0
- package/plugin/vendor/reflexio/reflexio/server/services/tagging/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/services/tagging/service.py +200 -0
- package/plugin/vendor/reflexio/reflexio/server/services/tagging/tagging_scheduler.py +149 -0
- package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +372 -34
- package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +2 -1
- package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +120 -1
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +4 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/search_settings.json +5 -0
- package/plugin/vendor/reflexio/reflexio/server/tracing.py +30 -0
- package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +18 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +61 -26
- package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +41 -4
- package/scripts/setup-claude-smart.sh +8 -3
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +0 -517
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +0 -473
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +0 -2156
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +0 -18
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +0 -241
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +0 -140
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +0 -113
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +0 -52
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +0 -103
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +0 -156
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +0 -134
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +0 -24
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +0 -278
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +0 -164
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +0 -36
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +0 -35
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +0 -27
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +0 -31
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +0 -42
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +0 -49
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +0 -91
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +0 -50
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +0 -13
- package/plugin/vendor/reflexio/reflexio/server/_auth.py +0 -25
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +0 -192
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +0 -303
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +0 -138
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +0 -1125
- /package/plugin/vendor/reflexio/reflexio/integrations/{__init__.py → openclaw/plugin/src/openclaw_smart/__init__.py} +0 -0
- /package/plugin/vendor/reflexio/reflexio/integrations/openclaw/{types → plugin/types}/openclaw.d.ts +0 -0
- /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{distribution.py → components/distribution.py} +0 -0
- /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{hero_state.py → components/hero_state.py} +0 -0
- /package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/{shadow_aggregation.py → components/shadow_aggregation.py} +0 -0
- /package/plugin/vendor/reflexio/reflexio/server/services/reflection/{reflection_extractor.py → components/extractor.py} +0 -0
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from collections import defaultdict
|
|
2
3
|
|
|
3
4
|
logger = logging.getLogger(__name__)
|
|
4
5
|
|
|
5
6
|
from datetime import UTC, datetime
|
|
7
|
+
from typing import Protocol
|
|
6
8
|
|
|
7
9
|
from reflexio.lib._base import (
|
|
8
10
|
STORAGE_NOT_CONFIGURED_MSG,
|
|
9
11
|
ReflexioBase,
|
|
10
12
|
_require_storage,
|
|
11
13
|
)
|
|
14
|
+
from reflexio.models.api_schema.domain.entities import (
|
|
15
|
+
LineageEvent,
|
|
16
|
+
ProfileChangeLog,
|
|
17
|
+
UserProfile,
|
|
18
|
+
)
|
|
12
19
|
from reflexio.models.api_schema.retriever_schema import (
|
|
13
20
|
GetProfileStatisticsResponse,
|
|
14
21
|
GetUserProfilesRequest,
|
|
@@ -36,7 +43,7 @@ from reflexio.models.api_schema.service_schemas import (
|
|
|
36
43
|
UpgradeProfilesRequest,
|
|
37
44
|
UpgradeProfilesResponse,
|
|
38
45
|
)
|
|
39
|
-
from reflexio.server.services.profile.
|
|
46
|
+
from reflexio.server.services.profile.service import (
|
|
40
47
|
ProfileGenerationService,
|
|
41
48
|
)
|
|
42
49
|
from reflexio.server.tracing import profile_step
|
|
@@ -199,15 +206,21 @@ class ProfilesMixin(ReflexioBase):
|
|
|
199
206
|
)
|
|
200
207
|
|
|
201
208
|
def get_profile_change_logs(self) -> ProfileChangeLogResponse:
|
|
202
|
-
"""Get profile change logs.
|
|
209
|
+
"""Get profile change logs, served from the lineage reconstruction.
|
|
210
|
+
|
|
211
|
+
The change-log view is rebuilt on demand from ``lineage_event`` linkage
|
|
212
|
+
joined to survivor/tombstone content via
|
|
213
|
+
:func:`reconstruct_profile_change_log`. The legacy ``profile_change_logs``
|
|
214
|
+
table is no longer written (B3 Task 6) or read (B3 Task 7); it is retained
|
|
215
|
+
frozen until its removal in Task 8.
|
|
203
216
|
|
|
204
217
|
Returns:
|
|
205
|
-
ProfileChangeLogResponse: Response containing
|
|
218
|
+
ProfileChangeLogResponse: Response containing the reconstructed
|
|
219
|
+
profile change logs.
|
|
206
220
|
"""
|
|
207
221
|
if not self._is_storage_configured():
|
|
208
222
|
return ProfileChangeLogResponse(success=True, profile_change_logs=[])
|
|
209
|
-
|
|
210
|
-
return ProfileChangeLogResponse(success=True, profile_change_logs=changelogs)
|
|
223
|
+
return reconstruct_profile_change_log(self._get_storage())
|
|
211
224
|
|
|
212
225
|
@_require_storage(DeleteUserProfileResponse)
|
|
213
226
|
def delete_profile(
|
|
@@ -401,26 +414,22 @@ class ProfilesMixin(ReflexioBase):
|
|
|
401
414
|
status_filter = [None] # Default to current profiles
|
|
402
415
|
|
|
403
416
|
profiles = self._get_storage().get_user_profile(
|
|
404
|
-
request.user_id,
|
|
417
|
+
request.user_id,
|
|
418
|
+
status_filter=status_filter,
|
|
419
|
+
tags=request.tags,
|
|
420
|
+
profile_id=request.profile_id,
|
|
421
|
+
query=request.query,
|
|
422
|
+
source=request.source,
|
|
423
|
+
profile_time_to_live=request.profile_time_to_live,
|
|
424
|
+
start_time=(
|
|
425
|
+
int(request.start_time.timestamp()) if request.start_time else None
|
|
426
|
+
),
|
|
427
|
+
end_time=int(request.end_time.timestamp()) if request.end_time else None,
|
|
405
428
|
)
|
|
406
429
|
profiles = sorted(
|
|
407
430
|
profiles, key=lambda x: x.last_modified_timestamp, reverse=True
|
|
408
431
|
)
|
|
409
432
|
|
|
410
|
-
# Apply time filters
|
|
411
|
-
if request.start_time:
|
|
412
|
-
profiles = [
|
|
413
|
-
p
|
|
414
|
-
for p in profiles
|
|
415
|
-
if p.last_modified_timestamp >= int(request.start_time.timestamp())
|
|
416
|
-
]
|
|
417
|
-
if request.end_time:
|
|
418
|
-
profiles = [
|
|
419
|
-
p
|
|
420
|
-
for p in profiles
|
|
421
|
-
if p.last_modified_timestamp <= int(request.end_time.timestamp())
|
|
422
|
-
]
|
|
423
|
-
|
|
424
433
|
# Apply top_k limit
|
|
425
434
|
if request.top_k:
|
|
426
435
|
profiles = sorted(
|
|
@@ -437,6 +446,13 @@ class ProfilesMixin(ReflexioBase):
|
|
|
437
446
|
self,
|
|
438
447
|
limit: int = 100,
|
|
439
448
|
status_filter: list[Status | None] | None = None,
|
|
449
|
+
user_id: str | None = None,
|
|
450
|
+
profile_id: str | None = None,
|
|
451
|
+
query: str | None = None,
|
|
452
|
+
source: str | None = None,
|
|
453
|
+
profile_time_to_live: str | None = None,
|
|
454
|
+
start_time: int | None = None,
|
|
455
|
+
end_time: int | None = None,
|
|
440
456
|
) -> GetUserProfilesResponse:
|
|
441
457
|
"""Get all user profiles across all users.
|
|
442
458
|
|
|
@@ -454,7 +470,15 @@ class ProfilesMixin(ReflexioBase):
|
|
|
454
470
|
if status_filter is None:
|
|
455
471
|
status_filter = [None] # Default to current profiles
|
|
456
472
|
profiles = self._get_storage().get_all_profiles(
|
|
457
|
-
limit=limit,
|
|
473
|
+
limit=limit,
|
|
474
|
+
status_filter=status_filter,
|
|
475
|
+
user_id=user_id,
|
|
476
|
+
profile_id=profile_id,
|
|
477
|
+
query=query,
|
|
478
|
+
source=source,
|
|
479
|
+
profile_time_to_live=profile_time_to_live,
|
|
480
|
+
start_time=start_time,
|
|
481
|
+
end_time=end_time,
|
|
458
482
|
)
|
|
459
483
|
profiles = sorted(
|
|
460
484
|
profiles, key=lambda x: x.last_modified_timestamp, reverse=True
|
|
@@ -543,3 +567,182 @@ class ProfilesMixin(ReflexioBase):
|
|
|
543
567
|
return GetProfileStatisticsResponse(
|
|
544
568
|
success=False, msg=f"Failed to get profile statistics: {str(e)}"
|
|
545
569
|
)
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
# ---------------------------------------------------------------------------
|
|
573
|
+
# Standalone read-side reconstruction (Phase B3 Task 2)
|
|
574
|
+
# ---------------------------------------------------------------------------
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
class ChangeLogReadStorage(Protocol):
|
|
578
|
+
"""The storage read surface ``reconstruct_profile_change_log`` requires.
|
|
579
|
+
|
|
580
|
+
Both the real ``BaseStorage`` backends and the read-only
|
|
581
|
+
``RestStorageReader`` satisfy this structurally — no inheritance required —
|
|
582
|
+
so reconstruction can run against either without an unsound ``cast`` to
|
|
583
|
+
``BaseStorage``.
|
|
584
|
+
"""
|
|
585
|
+
|
|
586
|
+
org_id: str
|
|
587
|
+
|
|
588
|
+
def get_lineage_events(
|
|
589
|
+
self,
|
|
590
|
+
*,
|
|
591
|
+
entity_type: str | None = ...,
|
|
592
|
+
entity_id: str | None = ...,
|
|
593
|
+
org_id: str | None = ...,
|
|
594
|
+
request_id: str | None = ...,
|
|
595
|
+
) -> list[LineageEvent]: ...
|
|
596
|
+
|
|
597
|
+
def get_distinct_generated_from_request_ids(self) -> list[str]: ...
|
|
598
|
+
|
|
599
|
+
def get_profiles_by_generated_from_request_id(
|
|
600
|
+
self, request_id: str
|
|
601
|
+
) -> list[UserProfile]: ...
|
|
602
|
+
|
|
603
|
+
def get_all_generated_profiles(self) -> list[UserProfile]: ...
|
|
604
|
+
|
|
605
|
+
def get_profile_by_id(
|
|
606
|
+
self, profile_id: str, *, include_tombstones: bool = ...
|
|
607
|
+
) -> UserProfile | None: ...
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
def reconstruct_profile_change_log(
|
|
611
|
+
storage: ChangeLogReadStorage,
|
|
612
|
+
*,
|
|
613
|
+
limit: int = 100,
|
|
614
|
+
) -> ProfileChangeLogResponse:
|
|
615
|
+
"""Rebuild the ProfileChangeLog view using time-travel-stable signals.
|
|
616
|
+
|
|
617
|
+
Uses two immutable / stable signals to classify every dedup run:
|
|
618
|
+
|
|
619
|
+
* **added(R)** — profiles whose ``generated_from_request_id == R``. This
|
|
620
|
+
column is set at creation and never changes, so it correctly classifies
|
|
621
|
+
a profile as "added in run R" even if it is later tombstoned in run R2.
|
|
622
|
+
Tombstones are included so the content is available.
|
|
623
|
+
|
|
624
|
+
* **removed(R)** — entity_ids of ``status_change`` lineage events with
|
|
625
|
+
``to_status == "superseded"`` and ``request_id == R``. This is the
|
|
626
|
+
exact signature emitted by ``supersede_profiles_by_ids`` (the dedup
|
|
627
|
+
soft-delete path). It is distinct from reflection which emits
|
|
628
|
+
``op="revise"``, so reflection events are never mis-counted as removals.
|
|
629
|
+
|
|
630
|
+
Groups are formed over the union of request_ids from both signals.
|
|
631
|
+
Request_id ``""`` is skipped — it would merge unrelated runs.
|
|
632
|
+
A row is emitted only when ``added or removed`` is non-empty (matching
|
|
633
|
+
legacy semantics: the legacy table was written only when
|
|
634
|
+
``all_new_profiles or superseded_profiles``).
|
|
635
|
+
|
|
636
|
+
When a removed profile's tombstone has been physically purged (GDPR GC),
|
|
637
|
+
it is silently omitted from ``removed_profiles`` rather than crashing.
|
|
638
|
+
|
|
639
|
+
Args:
|
|
640
|
+
storage (ChangeLogReadStorage): Storage read surface to query (any
|
|
641
|
+
BaseStorage backend or the read-only ``RestStorageReader``).
|
|
642
|
+
limit (int): Maximum number of reconstructed entries to return.
|
|
643
|
+
Defaults to 100.
|
|
644
|
+
|
|
645
|
+
Returns:
|
|
646
|
+
ProfileChangeLogResponse: ``success=True`` with reconstructed rows
|
|
647
|
+
ordered most-recent first (by max event ``created_at`` in each
|
|
648
|
+
request_id group), capped at ``limit``.
|
|
649
|
+
"""
|
|
650
|
+
if limit <= 0:
|
|
651
|
+
return ProfileChangeLogResponse(success=True, profile_change_logs=[])
|
|
652
|
+
|
|
653
|
+
all_events = storage.get_lineage_events(
|
|
654
|
+
entity_type="profile", org_id=storage.org_id
|
|
655
|
+
)
|
|
656
|
+
|
|
657
|
+
# Dedup soft-delete signature: status_change to_status=="superseded".
|
|
658
|
+
# Each such event records one profile removed in the dedup run ``request_id``.
|
|
659
|
+
# Distinct from reflection which emits op="revise" — so revise events are
|
|
660
|
+
# never counted as removals here.
|
|
661
|
+
removal_by_req: dict[str, list[str]] = defaultdict(list)
|
|
662
|
+
sort_key: dict[str, tuple[int, int]] = {} # request_id -> (created_at, event_id)
|
|
663
|
+
for evt in all_events:
|
|
664
|
+
key = evt.request_id
|
|
665
|
+
if not key:
|
|
666
|
+
continue # skip empty-string request_ids — never merge unrelated runs
|
|
667
|
+
cur = sort_key.get(key, (0, 0))
|
|
668
|
+
if (evt.created_at, evt.event_id) > cur:
|
|
669
|
+
sort_key[key] = (evt.created_at, evt.event_id)
|
|
670
|
+
if evt.op == "status_change" and evt.to_status == "superseded":
|
|
671
|
+
removal_by_req[key].append(evt.entity_id)
|
|
672
|
+
|
|
673
|
+
# Resolve the "added" side for every run in ONE bulk read, grouped by each
|
|
674
|
+
# profile's immutable generated_from_request_id. This replaces a read per
|
|
675
|
+
# candidate request_id, which fanned out over the org's whole dedup history
|
|
676
|
+
# before the limit slice below — a hot-path N+1 on network-backed storage now
|
|
677
|
+
# that the live endpoint serves this reconstruction.
|
|
678
|
+
added_by_req: dict[str, list] = defaultdict(list)
|
|
679
|
+
for profile in storage.get_all_generated_profiles():
|
|
680
|
+
added_by_req[profile.generated_from_request_id].append(profile)
|
|
681
|
+
|
|
682
|
+
# Candidate request_ids are the UNION of:
|
|
683
|
+
# (a) lineage EVENT request_ids — runs that produced a dedup removal
|
|
684
|
+
# (status_change/superseded event); and
|
|
685
|
+
# (b) request_ids stamped on profile rows (the keys of added_by_req) —
|
|
686
|
+
# discovers ADD-ONLY dedup runs (new profiles, nothing superseded) that
|
|
687
|
+
# emit no lineage event. ``get_all_generated_profiles`` already excludes
|
|
688
|
+
# the empty-string sentinel, so unrelated runs are never merged.
|
|
689
|
+
#
|
|
690
|
+
# This closes the reconstruction-completeness gap for add-only runs: the
|
|
691
|
+
# legacy `add_profile_change_log` fired whenever `all_new_profiles or
|
|
692
|
+
# superseded_profiles` was non-empty, so a run with only adds was still
|
|
693
|
+
# recorded. The (b) path mirrors that.
|
|
694
|
+
#
|
|
695
|
+
# For add-only runs (in set (b) but not (a)), no event timestamp exists.
|
|
696
|
+
# We derive their sort key from the max `last_modified_timestamp` of the
|
|
697
|
+
# profiles in that group — set at creation, giving a sensible most-recent-first
|
|
698
|
+
# ordering relative to event-timestamped runs. The secondary key is 0.
|
|
699
|
+
candidate_req_ids: set[str] = set(sort_key.keys()) | set(added_by_req.keys())
|
|
700
|
+
|
|
701
|
+
def _effective_sort_key(req_id: str) -> tuple[int, int]:
|
|
702
|
+
"""Return (timestamp, event_id) for sorting; for add-only runs fall back to
|
|
703
|
+
the max last_modified_timestamp of the profiles in that group."""
|
|
704
|
+
if req_id in sort_key:
|
|
705
|
+
return sort_key[req_id]
|
|
706
|
+
profiles = added_by_req.get(req_id, [])
|
|
707
|
+
max_ts = max((p.last_modified_timestamp for p in profiles), default=0)
|
|
708
|
+
return (max_ts, 0)
|
|
709
|
+
|
|
710
|
+
sorted_keys = sorted(
|
|
711
|
+
candidate_req_ids,
|
|
712
|
+
key=_effective_sort_key,
|
|
713
|
+
reverse=True,
|
|
714
|
+
)[:limit]
|
|
715
|
+
|
|
716
|
+
logs: list[ProfileChangeLog] = []
|
|
717
|
+
for req_id in sorted_keys:
|
|
718
|
+
# added: profiles whose generated_from_request_id == req_id (any status,
|
|
719
|
+
# include tombstones — a profile added in R1 and tombstoned in R2 is still
|
|
720
|
+
# "added in R1").
|
|
721
|
+
added = added_by_req[req_id]
|
|
722
|
+
|
|
723
|
+
# removed: dedup-superseded profiles from this run's lineage events.
|
|
724
|
+
removed: list = []
|
|
725
|
+
for entity_id in removal_by_req.get(req_id, []):
|
|
726
|
+
profile = storage.get_profile_by_id(entity_id, include_tombstones=True)
|
|
727
|
+
if profile is not None:
|
|
728
|
+
removed.append(profile)
|
|
729
|
+
# Tombstone physically purged (GDPR GC) → silently omit; no crash.
|
|
730
|
+
|
|
731
|
+
if not added and not removed:
|
|
732
|
+
# No dedup activity for this request_id — skip to match legacy semantics.
|
|
733
|
+
continue
|
|
734
|
+
|
|
735
|
+
ts, _ = _effective_sort_key(req_id)
|
|
736
|
+
user_id = added[0].user_id if added else removed[0].user_id
|
|
737
|
+
logs.append(
|
|
738
|
+
ProfileChangeLog(
|
|
739
|
+
id=0,
|
|
740
|
+
user_id=user_id,
|
|
741
|
+
request_id=req_id,
|
|
742
|
+
created_at=ts,
|
|
743
|
+
added_profiles=added,
|
|
744
|
+
removed_profiles=removed,
|
|
745
|
+
)
|
|
746
|
+
)
|
|
747
|
+
|
|
748
|
+
return ProfileChangeLogResponse(success=True, profile_change_logs=logs)
|
|
@@ -41,7 +41,7 @@ class ReflectionMixin(ReflexioBase):
|
|
|
41
41
|
|
|
42
42
|
# Local import keeps the heavy service module out of facade
|
|
43
43
|
# cold-start when reflection is disabled.
|
|
44
|
-
from reflexio.server.services.reflection.
|
|
44
|
+
from reflexio.server.services.reflection.service import (
|
|
45
45
|
ReflectionService,
|
|
46
46
|
)
|
|
47
47
|
|
|
@@ -13,6 +13,7 @@ from reflexio.models.api_schema.retriever_schema import (
|
|
|
13
13
|
)
|
|
14
14
|
from reflexio.server.llm.model_defaults import ModelRole, resolve_model_name
|
|
15
15
|
from reflexio.server.site_var.site_var_manager import SiteVarManager
|
|
16
|
+
from reflexio.server.tracing import profile_step
|
|
16
17
|
|
|
17
18
|
_LOGGER = logging.getLogger(__name__)
|
|
18
19
|
|
|
@@ -40,9 +41,23 @@ class SearchMixin(ReflexioBase):
|
|
|
40
41
|
request = GetAgentSuccessEvaluationResultsRequest(**request)
|
|
41
42
|
|
|
42
43
|
try:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
if request.start_time or request.end_time:
|
|
45
|
+
results = self._get_storage().get_agent_success_evaluation_results_in_window(
|
|
46
|
+
from_ts=(
|
|
47
|
+
int(request.start_time.timestamp()) if request.start_time else 0
|
|
48
|
+
),
|
|
49
|
+
to_ts=(
|
|
50
|
+
int(request.end_time.timestamp())
|
|
51
|
+
if request.end_time
|
|
52
|
+
else 2**31 - 1
|
|
53
|
+
),
|
|
54
|
+
limit=request.limit or 100,
|
|
55
|
+
agent_version=request.agent_version,
|
|
56
|
+
)
|
|
57
|
+
else:
|
|
58
|
+
results = self._get_storage().get_agent_success_evaluation_results(
|
|
59
|
+
limit=request.limit or 100, agent_version=request.agent_version
|
|
60
|
+
)
|
|
46
61
|
return GetAgentSuccessEvaluationResultsResponse(
|
|
47
62
|
success=True,
|
|
48
63
|
agent_success_evaluation_results=results,
|
|
@@ -78,6 +93,7 @@ class SearchMixin(ReflexioBase):
|
|
|
78
93
|
user_id=request.user_id,
|
|
79
94
|
request_id=request.request_id,
|
|
80
95
|
session_id=request.session_id,
|
|
96
|
+
source=request.source,
|
|
81
97
|
start_time=(
|
|
82
98
|
int(request.start_time.timestamp()) if request.start_time else None
|
|
83
99
|
),
|
|
@@ -103,10 +119,11 @@ class SearchMixin(ReflexioBase):
|
|
|
103
119
|
Session(session_id=group_name, requests=request_data_list)
|
|
104
120
|
)
|
|
105
121
|
|
|
106
|
-
#
|
|
122
|
+
# Pagination is session-based (top_k counts sessions): there may be
|
|
123
|
+
# more pages when this page filled the session limit.
|
|
107
124
|
total_returned = sum(len(s.requests) for s in sessions)
|
|
108
125
|
effective_limit = request.top_k or 100
|
|
109
|
-
has_more =
|
|
126
|
+
has_more = len(sessions) >= effective_limit
|
|
110
127
|
|
|
111
128
|
return GetRequestsResponse(
|
|
112
129
|
success=True,
|
|
@@ -136,32 +153,42 @@ class SearchMixin(ReflexioBase):
|
|
|
136
153
|
if isinstance(request, dict):
|
|
137
154
|
request = UnifiedSearchRequest(**request)
|
|
138
155
|
|
|
139
|
-
|
|
156
|
+
with profile_step(
|
|
157
|
+
"search.prepare",
|
|
158
|
+
enabled=bool(request.enable_reformulation),
|
|
159
|
+
has_conversation_history=bool(request.conversation_history),
|
|
160
|
+
search_mode=request.search_mode,
|
|
161
|
+
):
|
|
162
|
+
config = self.request_context.configurator.get_config()
|
|
163
|
+
config_llm_config = config.llm_config if config else None
|
|
164
|
+
|
|
165
|
+
# Resolve pre_retrieval_model_name: config override -> site var -> auto-detect.
|
|
166
|
+
model_setting = SiteVarManager().get_site_var("llm_model_setting")
|
|
167
|
+
site_var = model_setting if isinstance(model_setting, dict) else {}
|
|
168
|
+
api_key_config = config.api_key_config if config else None
|
|
169
|
+
|
|
170
|
+
pre_retrieval_model_name = resolve_model_name(
|
|
171
|
+
ModelRole.PRE_RETRIEVAL,
|
|
172
|
+
site_var_value=site_var.get("pre_retrieval_model_name"),
|
|
173
|
+
config_override=config_llm_config.pre_retrieval_model_name
|
|
174
|
+
if config_llm_config
|
|
175
|
+
else None,
|
|
176
|
+
api_key_config=api_key_config,
|
|
177
|
+
)
|
|
178
|
+
storage = self._get_storage()
|
|
179
|
+
prompt_manager = self.request_context.prompt_manager
|
|
180
|
+
retrieval_floor = config.retrieval_floor if config else None
|
|
181
|
+
recency = getattr(storage, "recency", None)
|
|
140
182
|
|
|
141
183
|
from reflexio.server.services.unified_search_service import run_unified_search
|
|
142
184
|
|
|
143
|
-
config_llm_config = config.llm_config if config else None
|
|
144
|
-
|
|
145
|
-
# Resolve pre_retrieval_model_name: config override → site var → auto-detect
|
|
146
|
-
model_setting = SiteVarManager().get_site_var("llm_model_setting")
|
|
147
|
-
site_var = model_setting if isinstance(model_setting, dict) else {}
|
|
148
|
-
api_key_config = config.api_key_config if config else None
|
|
149
|
-
|
|
150
|
-
pre_retrieval_model_name = resolve_model_name(
|
|
151
|
-
ModelRole.PRE_RETRIEVAL,
|
|
152
|
-
site_var_value=site_var.get("pre_retrieval_model_name"),
|
|
153
|
-
config_override=config_llm_config.pre_retrieval_model_name
|
|
154
|
-
if config_llm_config
|
|
155
|
-
else None,
|
|
156
|
-
api_key_config=api_key_config,
|
|
157
|
-
)
|
|
158
|
-
|
|
159
185
|
return run_unified_search(
|
|
160
186
|
request=request,
|
|
161
187
|
org_id=org_id,
|
|
162
|
-
storage=
|
|
188
|
+
storage=storage,
|
|
163
189
|
llm_client=self.llm_client,
|
|
164
|
-
prompt_manager=
|
|
190
|
+
prompt_manager=prompt_manager,
|
|
165
191
|
pre_retrieval_model_name=pre_retrieval_model_name,
|
|
166
|
-
retrieval_floor=
|
|
192
|
+
retrieval_floor=retrieval_floor,
|
|
193
|
+
recency=recency,
|
|
167
194
|
)
|
|
@@ -24,7 +24,7 @@ from reflexio.models.api_schema.service_schemas import (
|
|
|
24
24
|
UpgradeUserPlaybooksResponse,
|
|
25
25
|
)
|
|
26
26
|
from reflexio.models.config_schema import SearchOptions
|
|
27
|
-
from reflexio.server.services.playbook.
|
|
27
|
+
from reflexio.server.services.playbook.service import (
|
|
28
28
|
PlaybookGenerationService,
|
|
29
29
|
)
|
|
30
30
|
from reflexio.server.tracing import profile_step
|
|
@@ -53,10 +53,20 @@ class UserPlaybookMixin(ReflexioBase):
|
|
|
53
53
|
try:
|
|
54
54
|
user_playbooks = self._get_storage().get_user_playbooks(
|
|
55
55
|
limit=request.limit or 100,
|
|
56
|
+
user_playbook_id=request.user_playbook_id,
|
|
56
57
|
user_id=request.user_id,
|
|
58
|
+
request_id=request.request_id,
|
|
59
|
+
query=request.query,
|
|
57
60
|
playbook_name=request.playbook_name,
|
|
58
61
|
agent_version=request.agent_version,
|
|
59
62
|
status_filter=request.status_filter,
|
|
63
|
+
start_time=(
|
|
64
|
+
int(request.start_time.timestamp()) if request.start_time else None
|
|
65
|
+
),
|
|
66
|
+
end_time=(
|
|
67
|
+
int(request.end_time.timestamp()) if request.end_time else None
|
|
68
|
+
),
|
|
69
|
+
tags=request.tags,
|
|
60
70
|
)
|
|
61
71
|
return GetUserPlaybooksResponse(
|
|
62
72
|
success=True,
|