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.
- package/.claude-plugin/marketplace.json +3 -3
- package/README.md +34 -5
- package/bin/claude-smart.js +295 -5
- 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 +22 -2
- 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/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 +158 -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 +174 -0
- package/plugin/opencode/tsconfig.json +13 -0
- package/plugin/pyproject.toml +20 -3
- package/plugin/scripts/_lib.sh +77 -29
- package/plugin/scripts/backend-service.sh +27 -5
- package/plugin/scripts/dashboard-service.sh +7 -5
- package/plugin/scripts/ensure-plugin-root.sh +4 -4
- package/plugin/scripts/hook_entry.sh +3 -3
- 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 +10 -8
- package/plugin/src/README.md +1 -1
- package/plugin/src/claude_smart/cli.py +304 -6
- 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 +1 -1
- package/plugin/vendor/reflexio/.env.example +54 -30
- package/plugin/vendor/reflexio/README.md +14 -8
- package/plugin/vendor/reflexio/pyproject.toml +13 -1
- package/plugin/vendor/reflexio/reflexio/README.md +1 -0
- 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 +210 -50
- 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/client/client.py +57 -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 +238 -10
- package/plugin/vendor/reflexio/reflexio/lib/_config.py +11 -4
- package/plugin/vendor/reflexio/reflexio/lib/_generation.py +16 -5
- package/plugin/vendor/reflexio/reflexio/lib/_lineage_parity_readers.py +187 -0
- package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +198 -6
- package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +1 -1
- package/plugin/vendor/reflexio/reflexio/lib/_search.py +29 -20
- package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +2 -1
- 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/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 +52 -0
- 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 +88 -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 +45 -32
- 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/_auth.py +65 -2
- package/plugin/vendor/reflexio/reflexio/server/api.py +734 -85
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +7 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +3 -1
- 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/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/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/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 +266 -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 +26 -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 +39 -16
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +105 -23
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/gc_scheduler.py +193 -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 +11 -12
- 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} +316 -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/user_detail_stripping.py +84 -0
- 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} +30 -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/relevance_floor.py +83 -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 +27 -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 +2 -0
- 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 +642 -197
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +61 -104
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_lineage.py +628 -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 +978 -184
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +519 -128
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +77 -3
- 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/storage_base/__init__.py +131 -20
- 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 +36 -53
- 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 +243 -7
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +121 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +60 -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/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 +229 -32
- 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/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
|
@@ -40,15 +40,8 @@ if TYPE_CHECKING:
|
|
|
40
40
|
|
|
41
41
|
logger = logging.getLogger(__name__)
|
|
42
42
|
|
|
43
|
-
FINISH_EXTRACTION_TOOL_NAME = "finish_extraction"
|
|
44
43
|
PROFILE_EXTRACTOR_KIND = "profile"
|
|
45
44
|
|
|
46
|
-
# Max in-process retries when the model returns a plain-text turn with no tool
|
|
47
|
-
# call (finished_reason="no_tool_call"). tool_choice="required" is not always
|
|
48
|
-
# honored by every provider/model, so a single bad turn would otherwise drop the
|
|
49
|
-
# extraction entirely. Retries re-issue the same prompt from scratch.
|
|
50
|
-
_NO_TOOL_CALL_MAX_RETRIES = 2
|
|
51
|
-
|
|
52
45
|
|
|
53
46
|
def _record_agent_usage_event(
|
|
54
47
|
*,
|
|
@@ -85,17 +78,6 @@ class AgentRunResult:
|
|
|
85
78
|
finished_reason: str
|
|
86
79
|
|
|
87
80
|
|
|
88
|
-
@dataclass(slots=True)
|
|
89
|
-
class _FinishExtractionContext:
|
|
90
|
-
output: BaseModel | None = None
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
@dataclass(slots=True)
|
|
94
|
-
class _ExtractionAgentToolContext:
|
|
95
|
-
finish_context: _FinishExtractionContext
|
|
96
|
-
extra_tool_context: Any | None = None
|
|
97
|
-
|
|
98
|
-
|
|
99
81
|
def _format_resolved_tool_result(record: PendingToolCallRecord) -> str:
|
|
100
82
|
resolved_at = record.resolved_at.isoformat() if record.resolved_at else "unknown"
|
|
101
83
|
return (
|
|
@@ -106,7 +88,7 @@ def _format_resolved_tool_result(record: PendingToolCallRecord) -> str:
|
|
|
106
88
|
f"Result: {record.result or {}}\n\n"
|
|
107
89
|
"Use this Agent Builder feedback only if it is relevant to the "
|
|
108
90
|
"current extraction window. If it adds or corrects durable profile or "
|
|
109
|
-
"playbook information, include that in
|
|
91
|
+
"playbook information, include that in your structured extraction result."
|
|
110
92
|
)
|
|
111
93
|
|
|
112
94
|
|
|
@@ -128,22 +110,6 @@ def append_resolved_tool_result_context(
|
|
|
128
110
|
]
|
|
129
111
|
|
|
130
112
|
|
|
131
|
-
def _finish_handler(args: BaseModel, ctx: Any) -> dict[str, Any]:
|
|
132
|
-
ctx = getattr(ctx, "finish_context", ctx)
|
|
133
|
-
if not isinstance(ctx, _FinishExtractionContext):
|
|
134
|
-
raise TypeError(f"Expected _FinishExtractionContext, got {type(ctx).__name__}")
|
|
135
|
-
ctx.output = args
|
|
136
|
-
return {"status": "completed"}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def create_finish_extraction_tool(output_schema: type[BaseModel]) -> Tool:
|
|
140
|
-
return Tool(
|
|
141
|
-
name=FINISH_EXTRACTION_TOOL_NAME,
|
|
142
|
-
args_model=output_schema,
|
|
143
|
-
handler=_finish_handler,
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
|
|
147
113
|
def _pending_tool_call_config(request_context: RequestContext) -> Any | None:
|
|
148
114
|
root_config = request_context.configurator.get_config()
|
|
149
115
|
return (
|
|
@@ -361,90 +327,38 @@ class ResumableExtractionAgent:
|
|
|
361
327
|
if run.max_steps_remaining is not None:
|
|
362
328
|
max_steps = min(max_steps, max(0, run.max_steps_remaining))
|
|
363
329
|
|
|
364
|
-
#
|
|
365
|
-
#
|
|
366
|
-
#
|
|
367
|
-
#
|
|
330
|
+
# The extractor delivers its result as a native structured response
|
|
331
|
+
# (response_format=output_schema): a turn with no tool call IS the
|
|
332
|
+
# committed output, parsed into output_schema. ask_human /
|
|
333
|
+
# attach_pending_info_request stay real tools the model may call
|
|
334
|
+
# mid-run, so tool_choice="auto" — forcing a tool would suppress the
|
|
335
|
+
# structured finish and is what produced the no_tool_call failures.
|
|
368
336
|
#
|
|
369
|
-
#
|
|
370
|
-
#
|
|
371
|
-
#
|
|
372
|
-
#
|
|
373
|
-
#
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
337
|
+
# No retry loop: a plain (no-tool) turn is now the SUCCESS terminus
|
|
338
|
+
# (finished_reason="structured_output"), not a dropped output, and the
|
|
339
|
+
# client already retries once on a malformed structured parse. The
|
|
340
|
+
# async-info tool handlers read ctx via getattr(ctx, "extra_tool_context",
|
|
341
|
+
# ctx), so the bare context object can be passed directly.
|
|
342
|
+
registry = ToolRegistry(list(extra_tools or []))
|
|
343
|
+
result = run_tool_loop(
|
|
344
|
+
client=self.client,
|
|
345
|
+
messages=messages,
|
|
346
|
+
registry=registry,
|
|
347
|
+
model_role=self.model_role,
|
|
348
|
+
max_steps=max_steps,
|
|
349
|
+
ctx=extra_tool_context,
|
|
350
|
+
response_format=output_schema,
|
|
351
|
+
tool_choice="auto",
|
|
352
|
+
log_label=log_label,
|
|
382
353
|
)
|
|
383
354
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
# prompt is safe. Each attempt uses a fresh finish_ctx/registry so no
|
|
387
|
-
# partial state leaks across attempts. We do NOT retry once the model has
|
|
388
|
-
# already registered async tool calls (e.g. attach_pending_info_request)
|
|
389
|
-
# — restarting from scratch would discard them.
|
|
390
|
-
for attempt in range(_NO_TOOL_CALL_MAX_RETRIES + 1):
|
|
391
|
-
finish_ctx = _FinishExtractionContext()
|
|
392
|
-
ctx: Any = (
|
|
393
|
-
_ExtractionAgentToolContext(
|
|
394
|
-
finish_context=finish_ctx,
|
|
395
|
-
extra_tool_context=extra_tool_context,
|
|
396
|
-
)
|
|
397
|
-
if extra_tool_context is not None
|
|
398
|
-
else finish_ctx
|
|
399
|
-
)
|
|
400
|
-
registry = ToolRegistry(
|
|
401
|
-
[*(extra_tools or []), create_finish_extraction_tool(output_schema)]
|
|
402
|
-
)
|
|
403
|
-
|
|
404
|
-
result = run_tool_loop(
|
|
405
|
-
client=self.client,
|
|
406
|
-
messages=messages,
|
|
407
|
-
registry=registry,
|
|
408
|
-
model_role=self.model_role,
|
|
409
|
-
max_steps=max_steps,
|
|
410
|
-
ctx=ctx,
|
|
411
|
-
finish_tool_name=FINISH_EXTRACTION_TOOL_NAME,
|
|
412
|
-
tool_choice=tool_choice,
|
|
413
|
-
log_label=log_label,
|
|
414
|
-
)
|
|
415
|
-
|
|
416
|
-
should_retry = (
|
|
417
|
-
result.finished_reason == "no_tool_call"
|
|
418
|
-
and not result.pending_tool_call_ids
|
|
419
|
-
and attempt < _NO_TOOL_CALL_MAX_RETRIES
|
|
420
|
-
)
|
|
421
|
-
if not should_retry:
|
|
422
|
-
break
|
|
423
|
-
logger.warning(
|
|
424
|
-
"event=extraction_agent_retry org_id=%s user_id=%s "
|
|
425
|
-
"extractor_kind=%s run_id=%s request_id=%s "
|
|
426
|
-
"finished_reason=%s attempt=%d max_retries=%d",
|
|
427
|
-
run.binding.org_id,
|
|
428
|
-
run.binding.user_id,
|
|
429
|
-
run.binding.extractor_kind,
|
|
430
|
-
run.id,
|
|
431
|
-
run.binding.request_id,
|
|
432
|
-
result.finished_reason,
|
|
433
|
-
attempt + 1,
|
|
434
|
-
_NO_TOOL_CALL_MAX_RETRIES,
|
|
435
|
-
)
|
|
436
|
-
_record_agent_usage_event(
|
|
437
|
-
run=run,
|
|
438
|
-
event_name="extraction_agent_retry",
|
|
439
|
-
error_kind=result.finished_reason,
|
|
440
|
-
metadata={"attempt": attempt + 1},
|
|
441
|
-
)
|
|
442
|
-
|
|
443
|
-
committed_output = (
|
|
444
|
-
finish_ctx.output.model_dump() if finish_ctx.output is not None else None
|
|
445
|
-
)
|
|
355
|
+
output = result.structured_output
|
|
356
|
+
committed_output = output.model_dump() if output is not None else None
|
|
446
357
|
active_statuses = (AgentRunStatus.RUNNING, AgentRunStatus.RESUMING)
|
|
447
|
-
if
|
|
358
|
+
if (
|
|
359
|
+
result.finished_reason == "structured_output"
|
|
360
|
+
and committed_output is not None
|
|
361
|
+
):
|
|
448
362
|
stored_run = self.storage.update_agent_run_status(
|
|
449
363
|
run.id,
|
|
450
364
|
AgentRunStatus.AGENT_COMPLETED,
|
|
@@ -515,19 +429,19 @@ class ResumableExtractionAgent:
|
|
|
515
429
|
run.id,
|
|
516
430
|
run.binding.request_id,
|
|
517
431
|
result.finished_reason,
|
|
518
|
-
|
|
432
|
+
output is not None,
|
|
519
433
|
)
|
|
520
434
|
_record_agent_usage_event(
|
|
521
435
|
run=run,
|
|
522
436
|
event_name="extraction_agent_failed",
|
|
523
437
|
outcome="failed",
|
|
524
438
|
error_kind=result.finished_reason,
|
|
525
|
-
metadata={"has_output":
|
|
439
|
+
metadata={"has_output": output is not None},
|
|
526
440
|
)
|
|
527
441
|
|
|
528
442
|
return AgentRunResult(
|
|
529
443
|
run_id=run.id,
|
|
530
|
-
output=
|
|
444
|
+
output=output,
|
|
531
445
|
pending_tool_call_ids=result.pending_tool_call_ids,
|
|
532
446
|
messages=result.messages,
|
|
533
447
|
trace=result.trace,
|
|
@@ -28,29 +28,29 @@ from reflexio.server.services.extraction.resumable_agent import (
|
|
|
28
28
|
ResumableExtractionAgent,
|
|
29
29
|
create_pending_info_tools_for_extractor_kind,
|
|
30
30
|
)
|
|
31
|
-
from reflexio.server.services.playbook.
|
|
32
|
-
from reflexio.server.services.playbook.playbook_generation_service import (
|
|
33
|
-
PlaybookGenerationService,
|
|
34
|
-
PlaybookGenerationServiceConfig,
|
|
35
|
-
)
|
|
31
|
+
from reflexio.server.services.playbook.components.extractor import PlaybookExtractor
|
|
36
32
|
from reflexio.server.services.playbook.playbook_service_utils import (
|
|
37
33
|
StructuredPlaybookList,
|
|
38
34
|
construct_expert_playbook_extraction_messages,
|
|
39
35
|
construct_playbook_extraction_messages_from_sessions,
|
|
40
36
|
has_expert_content,
|
|
41
37
|
)
|
|
42
|
-
from reflexio.server.services.
|
|
38
|
+
from reflexio.server.services.playbook.service import (
|
|
39
|
+
PlaybookGenerationService,
|
|
40
|
+
PlaybookGenerationServiceConfig,
|
|
41
|
+
)
|
|
42
|
+
from reflexio.server.services.profile.components.extractor import (
|
|
43
43
|
MAX_EXISTING_PROFILES_FOR_CONTEXT,
|
|
44
44
|
ProfileExtractor,
|
|
45
45
|
)
|
|
46
|
-
from reflexio.server.services.profile.profile_generation_service import (
|
|
47
|
-
ProfileGenerationService,
|
|
48
|
-
ProfileGenerationServiceConfig,
|
|
49
|
-
)
|
|
50
46
|
from reflexio.server.services.profile.profile_generation_service_utils import (
|
|
51
47
|
StructuredProfilesOutput,
|
|
52
48
|
construct_profile_extraction_messages_from_sessions,
|
|
53
49
|
)
|
|
50
|
+
from reflexio.server.services.profile.service import (
|
|
51
|
+
ProfileGenerationService,
|
|
52
|
+
ProfileGenerationServiceConfig,
|
|
53
|
+
)
|
|
54
54
|
from reflexio.server.services.service_utils import (
|
|
55
55
|
extract_interactions_from_request_interaction_data_models,
|
|
56
56
|
)
|
|
@@ -61,6 +61,7 @@ from reflexio.server.services.storage.storage_base import (
|
|
|
61
61
|
PendingToolCallRecord,
|
|
62
62
|
PendingToolCallStatus,
|
|
63
63
|
)
|
|
64
|
+
from reflexio.server.services.tagging.tagging_scheduler import schedule_tagging
|
|
64
65
|
from reflexio.server.site_var.site_var_manager import SiteVarManager
|
|
65
66
|
from reflexio.server.tracing import sentry_tags
|
|
66
67
|
|
|
@@ -133,7 +134,7 @@ def _request_interaction_models_from_ids(
|
|
|
133
134
|
)
|
|
134
135
|
models.append(
|
|
135
136
|
RequestInteractionDataModel(
|
|
136
|
-
session_id=request.session_id
|
|
137
|
+
session_id=request.session_id,
|
|
137
138
|
request=request,
|
|
138
139
|
interactions=ordered,
|
|
139
140
|
)
|
|
@@ -272,6 +273,7 @@ class ExtractionResumeWorker:
|
|
|
272
273
|
try:
|
|
273
274
|
self.storage.update_agent_run_status(run.id, AgentRunStatus.FINALIZING)
|
|
274
275
|
self._finalize_items(run, items)
|
|
276
|
+
self._schedule_finalized_tagging(run)
|
|
275
277
|
self.storage.consume_run_tool_dependencies(run.id)
|
|
276
278
|
finalized_status = (
|
|
277
279
|
AgentRunStatus.FINALIZED_PENDING_TOOL
|
|
@@ -315,6 +317,7 @@ class ExtractionResumeWorker:
|
|
|
315
317
|
try:
|
|
316
318
|
items, pending_tool_call_ids = self._items_from_committed_output(run)
|
|
317
319
|
self._finalize_items(run, items)
|
|
320
|
+
self._schedule_finalized_tagging(run)
|
|
318
321
|
self.storage.consume_run_tool_dependencies(run.id)
|
|
319
322
|
finalized_status = (
|
|
320
323
|
AgentRunStatus.FINALIZED_PENDING_TOOL
|
|
@@ -460,11 +463,6 @@ class ExtractionResumeWorker:
|
|
|
460
463
|
else ""
|
|
461
464
|
),
|
|
462
465
|
extraction_definition_prompt=extractor_config.extraction_definition_prompt.strip(),
|
|
463
|
-
metadata_definition_prompt=(
|
|
464
|
-
extractor_config.metadata_definition_prompt.strip()
|
|
465
|
-
if extractor_config.metadata_definition_prompt
|
|
466
|
-
else None
|
|
467
|
-
),
|
|
468
466
|
existing_profiles=context_profiles,
|
|
469
467
|
)
|
|
470
468
|
result = self._resume_agent(
|
|
@@ -777,3 +775,28 @@ class ExtractionResumeWorker:
|
|
|
777
775
|
raise ResumeWorkerError(
|
|
778
776
|
f"Unsupported extractor kind {run.binding.extractor_kind!r}"
|
|
779
777
|
)
|
|
778
|
+
|
|
779
|
+
def _schedule_finalized_tagging(self, run: AgentRunRecord) -> None:
|
|
780
|
+
user_id = run.binding.user_id
|
|
781
|
+
if not user_id:
|
|
782
|
+
return
|
|
783
|
+
if run.binding.extractor_kind not in ("profile", "playbook"):
|
|
784
|
+
return
|
|
785
|
+
|
|
786
|
+
# Defer tagging off this worker's drain loop. The pass is idempotent
|
|
787
|
+
# (skips already-tagged entities), so running both profile and playbook
|
|
788
|
+
# tagging is safe regardless of this run's extractor kind.
|
|
789
|
+
try:
|
|
790
|
+
schedule_tagging(
|
|
791
|
+
org_id=self.request_context.org_id,
|
|
792
|
+
user_id=user_id,
|
|
793
|
+
agent_version=run.binding.agent_version or "",
|
|
794
|
+
request_context=self.request_context,
|
|
795
|
+
llm_client=self.client,
|
|
796
|
+
)
|
|
797
|
+
except Exception:
|
|
798
|
+
logger.exception(
|
|
799
|
+
"Failed to schedule tagging for finalized %s run %s",
|
|
800
|
+
run.binding.extractor_kind,
|
|
801
|
+
run.id,
|
|
802
|
+
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import contextvars
|
|
4
|
+
import hashlib
|
|
4
5
|
import logging
|
|
5
6
|
import os
|
|
6
7
|
import threading
|
|
@@ -21,33 +22,34 @@ from reflexio.models.api_schema.service_schemas import (
|
|
|
21
22
|
from reflexio.models.config_schema import Config
|
|
22
23
|
from reflexio.server.api_endpoints.request_context import RequestContext
|
|
23
24
|
from reflexio.server.llm.litellm_client import LiteLLMClient
|
|
24
|
-
from reflexio.server.services.agent_success_evaluation.
|
|
25
|
-
GroupEvaluationScheduler,
|
|
26
|
-
)
|
|
27
|
-
from reflexio.server.services.agent_success_evaluation.group_evaluation_runner import (
|
|
25
|
+
from reflexio.server.services.agent_success_evaluation.runner import (
|
|
28
26
|
run_group_evaluation,
|
|
29
27
|
)
|
|
30
|
-
from reflexio.server.services.
|
|
31
|
-
|
|
32
|
-
PlaybookGenerationService,
|
|
28
|
+
from reflexio.server.services.agent_success_evaluation.scheduler import (
|
|
29
|
+
GroupEvaluationScheduler,
|
|
33
30
|
)
|
|
31
|
+
from reflexio.server.services.operation_state_utils import OperationStateManager
|
|
34
32
|
from reflexio.server.services.playbook.playbook_service_utils import (
|
|
35
33
|
PlaybookGenerationRequest,
|
|
36
34
|
)
|
|
37
|
-
from reflexio.server.services.
|
|
38
|
-
|
|
35
|
+
from reflexio.server.services.playbook.service import (
|
|
36
|
+
PlaybookGenerationService,
|
|
39
37
|
)
|
|
40
38
|
from reflexio.server.services.profile.profile_generation_service_utils import (
|
|
41
39
|
ProfileGenerationRequest,
|
|
42
40
|
)
|
|
43
|
-
from reflexio.server.services.
|
|
41
|
+
from reflexio.server.services.profile.service import (
|
|
42
|
+
ProfileGenerationService,
|
|
43
|
+
)
|
|
44
44
|
from reflexio.server.services.reflection.reflection_service_utils import (
|
|
45
45
|
ReflectionServiceRequest,
|
|
46
46
|
)
|
|
47
|
+
from reflexio.server.services.reflection.service import ReflectionService
|
|
47
48
|
from reflexio.server.services.storage.retention import (
|
|
48
49
|
delete_count_for_retention,
|
|
49
50
|
get_row_retention_limits,
|
|
50
51
|
)
|
|
52
|
+
from reflexio.server.services.tagging.tagging_scheduler import schedule_tagging
|
|
51
53
|
from reflexio.server.tracing import sentry_tags
|
|
52
54
|
from reflexio.server.usage_metrics import record_usage_event
|
|
53
55
|
|
|
@@ -79,6 +81,15 @@ _retention_cleanup_last_run: dict[tuple[str, str], float] = {}
|
|
|
79
81
|
_retention_cleanup_lock = threading.Lock()
|
|
80
82
|
|
|
81
83
|
|
|
84
|
+
def _stable_group_sampling_fraction(
|
|
85
|
+
org_id: str, user_id: str, session_id: str
|
|
86
|
+
) -> float:
|
|
87
|
+
"""Return a deterministic [0, 1) sample value for one session."""
|
|
88
|
+
key = f"{org_id}\0{user_id}\0{session_id}".encode()
|
|
89
|
+
digest = hashlib.sha256(key).digest()
|
|
90
|
+
return int.from_bytes(digest[:8], "big") / 2**64
|
|
91
|
+
|
|
92
|
+
|
|
82
93
|
@dataclass
|
|
83
94
|
class GenerationServiceResult:
|
|
84
95
|
"""Result of a GenerationService.run call.
|
|
@@ -204,7 +215,7 @@ class GenerationService:
|
|
|
204
215
|
org_id=self.org_id,
|
|
205
216
|
user_id=user_id,
|
|
206
217
|
request_id=request_id,
|
|
207
|
-
session_id=publish_user_interaction_request.session_id
|
|
218
|
+
session_id=publish_user_interaction_request.session_id,
|
|
208
219
|
source=publish_user_interaction_request.source,
|
|
209
220
|
agent_version=agent_version,
|
|
210
221
|
event_name="publish_request_received",
|
|
@@ -213,16 +224,15 @@ class GenerationService:
|
|
|
213
224
|
count_value=len(new_interactions),
|
|
214
225
|
)
|
|
215
226
|
|
|
216
|
-
# Store Request
|
|
217
|
-
#
|
|
218
|
-
# back from the first request of each session.
|
|
227
|
+
# Store Request before adding interactions so downstream workers can
|
|
228
|
+
# resolve the session's source and evaluation-only status.
|
|
219
229
|
new_request = Request(
|
|
220
230
|
request_id=request_id,
|
|
221
231
|
user_id=user_id,
|
|
222
232
|
source=publish_user_interaction_request.source,
|
|
223
233
|
agent_version=agent_version,
|
|
224
|
-
session_id=publish_user_interaction_request.session_id
|
|
225
|
-
|
|
234
|
+
session_id=publish_user_interaction_request.session_id,
|
|
235
|
+
evaluation_only=publish_user_interaction_request.evaluation_only,
|
|
226
236
|
)
|
|
227
237
|
self.storage.add_request(new_request) # type: ignore[reportOptionalMemberAccess]
|
|
228
238
|
|
|
@@ -234,6 +244,33 @@ class GenerationService:
|
|
|
234
244
|
# Extract source (empty string treated as None)
|
|
235
245
|
source = publish_user_interaction_request.source or None
|
|
236
246
|
|
|
247
|
+
if publish_user_interaction_request.evaluation_only:
|
|
248
|
+
self._schedule_group_evaluation_if_needed(
|
|
249
|
+
new_request=new_request,
|
|
250
|
+
user_id=user_id,
|
|
251
|
+
agent_version=agent_version,
|
|
252
|
+
source=source,
|
|
253
|
+
)
|
|
254
|
+
record_usage_event(
|
|
255
|
+
org_id=self.org_id,
|
|
256
|
+
user_id=user_id,
|
|
257
|
+
request_id=request_id,
|
|
258
|
+
session_id=new_request.session_id,
|
|
259
|
+
source=source,
|
|
260
|
+
agent_version=agent_version,
|
|
261
|
+
backend="evaluation_only",
|
|
262
|
+
event_name="publish_request_succeeded",
|
|
263
|
+
event_category="publish",
|
|
264
|
+
outcome="success",
|
|
265
|
+
count_value=len(new_interactions),
|
|
266
|
+
duration_ms=int((time.perf_counter() - publish_start) * 1000),
|
|
267
|
+
metadata={
|
|
268
|
+
"evaluation_only": True,
|
|
269
|
+
"warning_count": len(result.warnings),
|
|
270
|
+
},
|
|
271
|
+
)
|
|
272
|
+
return result
|
|
273
|
+
|
|
237
274
|
if (
|
|
238
275
|
not publish_user_interaction_request.override_learning_stall
|
|
239
276
|
and (stall_warning := self._active_learning_stall_warning()) is not None
|
|
@@ -262,7 +299,10 @@ class GenerationService:
|
|
|
262
299
|
# profile/playbook context. Wrapped in a broad except so a
|
|
263
300
|
# reflection bug never breaks the publish.
|
|
264
301
|
self._maybe_run_reflection(
|
|
265
|
-
user_id=user_id,
|
|
302
|
+
user_id=user_id,
|
|
303
|
+
request_id=request_id,
|
|
304
|
+
agent_version=agent_version,
|
|
305
|
+
source=source,
|
|
266
306
|
)
|
|
267
307
|
|
|
268
308
|
# Create generation services and requests
|
|
@@ -343,7 +383,24 @@ class GenerationService:
|
|
|
343
383
|
finally:
|
|
344
384
|
executor.shutdown(wait=False, cancel_futures=True)
|
|
345
385
|
|
|
346
|
-
#
|
|
386
|
+
# Tagging runs an LLM call per newly generated entity, so defer it off
|
|
387
|
+
# the publish path. The scheduler debounces bursts and is idempotent
|
|
388
|
+
# (already-tagged entities are skipped).
|
|
389
|
+
try:
|
|
390
|
+
schedule_tagging(
|
|
391
|
+
org_id=self.org_id,
|
|
392
|
+
user_id=user_id,
|
|
393
|
+
agent_version=agent_version,
|
|
394
|
+
request_context=self.request_context,
|
|
395
|
+
llm_client=self.client,
|
|
396
|
+
)
|
|
397
|
+
except Exception:
|
|
398
|
+
logger.exception(
|
|
399
|
+
"Failed to schedule tagging for publish request %s",
|
|
400
|
+
request_id,
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
# Schedule delayed group evaluation for the required session.
|
|
347
404
|
self._schedule_group_evaluation_if_needed(
|
|
348
405
|
new_request=new_request,
|
|
349
406
|
user_id=user_id,
|
|
@@ -373,7 +430,7 @@ class GenerationService:
|
|
|
373
430
|
org_id=self.org_id,
|
|
374
431
|
user_id=user_id,
|
|
375
432
|
request_id=result.request_id,
|
|
376
|
-
session_id=publish_user_interaction_request.session_id
|
|
433
|
+
session_id=publish_user_interaction_request.session_id,
|
|
377
434
|
source=publish_user_interaction_request.source,
|
|
378
435
|
agent_version=agent_version,
|
|
379
436
|
event_name="publish_request_failed",
|
|
@@ -408,7 +465,7 @@ class GenerationService:
|
|
|
408
465
|
agent_version: str,
|
|
409
466
|
source: str | None,
|
|
410
467
|
) -> None:
|
|
411
|
-
"""Enqueue agent-success evaluation for this session
|
|
468
|
+
"""Enqueue agent-success evaluation for this session.
|
|
412
469
|
|
|
413
470
|
Must be called once per publish — from BOTH the classic and the agentic
|
|
414
471
|
extraction code paths — so that ``AgentSuccessEvaluationResult`` records
|
|
@@ -417,13 +474,20 @@ class GenerationService:
|
|
|
417
474
|
|
|
418
475
|
Args:
|
|
419
476
|
new_request (Request): The just-stored request whose session is being
|
|
420
|
-
published into.
|
|
477
|
+
published into.
|
|
421
478
|
user_id (str): The user owning the session.
|
|
422
479
|
agent_version (str): Agent version string carried into the evaluator.
|
|
423
480
|
source (str | None): Optional source label.
|
|
424
481
|
"""
|
|
425
482
|
session_id = new_request.session_id
|
|
426
|
-
if not
|
|
483
|
+
if not self._should_sample_group_evaluation(
|
|
484
|
+
user_id=user_id, session_id=session_id
|
|
485
|
+
):
|
|
486
|
+
logger.info(
|
|
487
|
+
"Skipping group evaluation scheduling for unsampled session=%s user=%s",
|
|
488
|
+
session_id,
|
|
489
|
+
user_id,
|
|
490
|
+
)
|
|
427
491
|
return
|
|
428
492
|
|
|
429
493
|
scheduler = GroupEvaluationScheduler.get_instance()
|
|
@@ -464,8 +528,25 @@ class GenerationService:
|
|
|
464
528
|
),
|
|
465
529
|
)
|
|
466
530
|
|
|
531
|
+
def _should_sample_group_evaluation(self, *, user_id: str, session_id: str) -> bool:
|
|
532
|
+
config = self.configurator.get_config()
|
|
533
|
+
agent_success_config = getattr(config, "agent_success_config", None)
|
|
534
|
+
if agent_success_config is None:
|
|
535
|
+
return False
|
|
536
|
+
|
|
537
|
+
sampling_rate = agent_success_config.sampling_rate
|
|
538
|
+
if sampling_rate >= 1.0:
|
|
539
|
+
return True
|
|
540
|
+
if sampling_rate <= 0.0:
|
|
541
|
+
return False
|
|
542
|
+
|
|
543
|
+
return (
|
|
544
|
+
_stable_group_sampling_fraction(self.org_id, user_id, session_id)
|
|
545
|
+
< sampling_rate
|
|
546
|
+
)
|
|
547
|
+
|
|
467
548
|
def _maybe_run_reflection(
|
|
468
|
-
self, *, user_id: str, agent_version: str, source: str | None
|
|
549
|
+
self, *, user_id: str, request_id: str, agent_version: str, source: str | None
|
|
469
550
|
) -> None:
|
|
470
551
|
"""Best-effort reflection pass before extraction.
|
|
471
552
|
|
|
@@ -480,6 +561,7 @@ class GenerationService:
|
|
|
480
561
|
service.run(
|
|
481
562
|
ReflectionServiceRequest(
|
|
482
563
|
user_id=user_id,
|
|
564
|
+
request_id=request_id,
|
|
483
565
|
agent_version=agent_version,
|
|
484
566
|
source=source,
|
|
485
567
|
)
|
|
File without changes
|