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
|
@@ -50,6 +50,11 @@ class SearchInteractionRequest(BaseModel):
|
|
|
50
50
|
class SearchUserProfileRequest(BaseModel):
|
|
51
51
|
user_id: NonEmptyStr
|
|
52
52
|
generated_from_request_id: str | None = None
|
|
53
|
+
# Caller correlation IDs for billing attribution on the Application line.
|
|
54
|
+
# Optional; when populated they flow into the usage event request_id /
|
|
55
|
+
# session_id columns via _meter_applied_learnings in server/api.py.
|
|
56
|
+
request_id: str | None = None
|
|
57
|
+
session_id: str | None = None
|
|
53
58
|
query: str | None = None
|
|
54
59
|
start_time: datetime | None = None
|
|
55
60
|
end_time: datetime | None = None
|
|
@@ -59,6 +64,7 @@ class SearchUserProfileRequest(BaseModel):
|
|
|
59
64
|
extractor_name: str | None = (
|
|
60
65
|
None # Deprecated compatibility field; accepted but ignored.
|
|
61
66
|
)
|
|
67
|
+
tags: list[str] | None = None
|
|
62
68
|
threshold: float | None = Field(default=0.4, ge=0.0, le=1.0)
|
|
63
69
|
enable_reformulation: bool | None = False
|
|
64
70
|
search_mode: SearchMode = SearchMode.HYBRID
|
|
@@ -181,10 +187,15 @@ class GetInteractionsResponse(BaseModel):
|
|
|
181
187
|
|
|
182
188
|
class GetUserProfilesRequest(BaseModel):
|
|
183
189
|
user_id: NonEmptyStr
|
|
190
|
+
profile_id: str | None = None
|
|
191
|
+
query: str | None = None
|
|
184
192
|
start_time: datetime | None = None
|
|
185
193
|
end_time: datetime | None = None
|
|
186
194
|
top_k: int | None = Field(default=30, gt=0)
|
|
195
|
+
source: str | None = None
|
|
196
|
+
profile_time_to_live: str | None = None
|
|
187
197
|
status_filter: list[Status | None] | None = None
|
|
198
|
+
tags: list[str] | None = None
|
|
188
199
|
|
|
189
200
|
@model_validator(mode="after")
|
|
190
201
|
def check_time_range(self) -> Self:
|
|
@@ -215,10 +226,22 @@ class SetConfigResponse(BaseModel):
|
|
|
215
226
|
|
|
216
227
|
class GetUserPlaybooksRequest(BaseModel):
|
|
217
228
|
limit: int | None = Field(default=100, gt=0)
|
|
229
|
+
user_playbook_id: int | None = Field(default=None, gt=0)
|
|
218
230
|
user_id: str | None = None
|
|
231
|
+
request_id: str | None = None
|
|
232
|
+
query: str | None = None
|
|
219
233
|
playbook_name: str | None = None
|
|
220
234
|
agent_version: str | None = None
|
|
235
|
+
start_time: datetime | None = None
|
|
236
|
+
end_time: datetime | None = None
|
|
221
237
|
status_filter: list[Status | None] | None = None
|
|
238
|
+
tags: list[str] | None = None
|
|
239
|
+
|
|
240
|
+
@model_validator(mode="after")
|
|
241
|
+
def check_time_range(self) -> Self:
|
|
242
|
+
"""Validate that end_time is after start_time."""
|
|
243
|
+
TimeRangeValidatorMixin.validate_time_range(self.start_time, self.end_time)
|
|
244
|
+
return self
|
|
222
245
|
|
|
223
246
|
|
|
224
247
|
class GetUserPlaybooksResponse(BaseModel):
|
|
@@ -229,10 +252,25 @@ class GetUserPlaybooksResponse(BaseModel):
|
|
|
229
252
|
|
|
230
253
|
class GetAgentPlaybooksRequest(BaseModel):
|
|
231
254
|
limit: int | None = Field(default=100, gt=0)
|
|
255
|
+
agent_playbook_id: int | None = Field(default=None, gt=0)
|
|
256
|
+
query: str | None = None
|
|
232
257
|
playbook_name: str | None = None
|
|
233
258
|
agent_version: str | None = None
|
|
259
|
+
start_time: datetime | None = None
|
|
260
|
+
end_time: datetime | None = None
|
|
234
261
|
status_filter: list[Status | None] | None = None
|
|
235
262
|
playbook_status_filter: PlaybookStatus | None = None
|
|
263
|
+
tags: list[str] | None = None
|
|
264
|
+
# Caller correlation IDs for billing attribution on the Application line.
|
|
265
|
+
# Optional; consumed by _meter_applied_learnings in server/api.py.
|
|
266
|
+
request_id: str | None = None
|
|
267
|
+
session_id: str | None = None
|
|
268
|
+
|
|
269
|
+
@model_validator(mode="after")
|
|
270
|
+
def check_time_range(self) -> Self:
|
|
271
|
+
"""Validate that end_time is after start_time."""
|
|
272
|
+
TimeRangeValidatorMixin.validate_time_range(self.start_time, self.end_time)
|
|
273
|
+
return self
|
|
236
274
|
|
|
237
275
|
|
|
238
276
|
class GetAgentPlaybooksResponse(BaseModel):
|
|
@@ -241,6 +279,30 @@ class GetAgentPlaybooksResponse(BaseModel):
|
|
|
241
279
|
msg: str | None = None
|
|
242
280
|
|
|
243
281
|
|
|
282
|
+
class GetLearningProvenanceRequest(BaseModel):
|
|
283
|
+
kind: Literal["profile", "user_playbook", "agent_playbook"]
|
|
284
|
+
id: str
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
class SourceUserPlaybookProvenanceView(BaseModel):
|
|
288
|
+
user_playbook: UserPlaybookView
|
|
289
|
+
interactions: list[InteractionView] = Field(default_factory=list)
|
|
290
|
+
source_interaction_ids: list[int] = Field(default_factory=list)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class LearningProvenanceViewResponse(BaseModel):
|
|
294
|
+
success: bool
|
|
295
|
+
target_kind: Literal["profile", "user_playbook", "agent_playbook"]
|
|
296
|
+
target_id: str
|
|
297
|
+
provenance_status: Literal["exact", "best_effort", "unavailable"] = "unavailable"
|
|
298
|
+
trigger_request_id: str | None = None
|
|
299
|
+
interactions: list[InteractionView] = Field(default_factory=list)
|
|
300
|
+
source_user_playbooks: list[SourceUserPlaybookProvenanceView] = Field(
|
|
301
|
+
default_factory=list
|
|
302
|
+
)
|
|
303
|
+
msg: str | None = None
|
|
304
|
+
|
|
305
|
+
|
|
244
306
|
class SearchUserPlaybookRequest(BaseModel):
|
|
245
307
|
"""Request for searching user playbooks with semantic/text search and filtering.
|
|
246
308
|
|
|
@@ -263,10 +325,15 @@ class SearchUserPlaybookRequest(BaseModel):
|
|
|
263
325
|
start_time: datetime | None = None
|
|
264
326
|
end_time: datetime | None = None
|
|
265
327
|
status_filter: list[Status | None] | None = None
|
|
328
|
+
tags: list[str] | None = None
|
|
266
329
|
top_k: int | None = Field(default=10, gt=0)
|
|
267
330
|
threshold: float | None = Field(default=0.4, ge=0.0, le=1.0)
|
|
268
331
|
enable_reformulation: bool | None = False
|
|
269
332
|
search_mode: SearchMode = SearchMode.HYBRID
|
|
333
|
+
# Caller correlation IDs for billing attribution on the Application line.
|
|
334
|
+
# Optional; consumed by _meter_applied_learnings in server/api.py.
|
|
335
|
+
request_id: str | None = None
|
|
336
|
+
session_id: str | None = None
|
|
270
337
|
|
|
271
338
|
@model_validator(mode="after")
|
|
272
339
|
def check_time_range(self) -> Self:
|
|
@@ -316,10 +383,15 @@ class SearchAgentPlaybookRequest(BaseModel):
|
|
|
316
383
|
end_time: datetime | None = None
|
|
317
384
|
status_filter: list[Status | None] | None = None
|
|
318
385
|
playbook_status_filter: PlaybookStatus | list[PlaybookStatus] | None = None
|
|
386
|
+
tags: list[str] | None = None
|
|
319
387
|
top_k: int | None = Field(default=10, gt=0)
|
|
320
388
|
threshold: float | None = Field(default=0.4, ge=0.0, le=1.0)
|
|
321
389
|
enable_reformulation: bool | None = False
|
|
322
390
|
search_mode: SearchMode = SearchMode.HYBRID
|
|
391
|
+
# Caller correlation IDs for billing attribution on the Application line.
|
|
392
|
+
# Optional; consumed by _meter_applied_learnings in server/api.py.
|
|
393
|
+
request_id: str | None = None
|
|
394
|
+
session_id: str | None = None
|
|
323
395
|
|
|
324
396
|
@model_validator(mode="after")
|
|
325
397
|
def check_time_range(self) -> Self:
|
|
@@ -345,6 +417,14 @@ class SearchAgentPlaybookResponse(BaseModel):
|
|
|
345
417
|
class GetAgentSuccessEvaluationResultsRequest(BaseModel):
|
|
346
418
|
limit: int | None = Field(default=100, gt=0)
|
|
347
419
|
agent_version: str | None = None
|
|
420
|
+
start_time: datetime | None = None
|
|
421
|
+
end_time: datetime | None = None
|
|
422
|
+
|
|
423
|
+
@model_validator(mode="after")
|
|
424
|
+
def check_time_range(self) -> Self:
|
|
425
|
+
"""Validate that end_time is after start_time."""
|
|
426
|
+
TimeRangeValidatorMixin.validate_time_range(self.start_time, self.end_time)
|
|
427
|
+
return self
|
|
348
428
|
|
|
349
429
|
|
|
350
430
|
class GetAgentSuccessEvaluationResultsResponse(BaseModel):
|
|
@@ -357,10 +437,18 @@ class GetRequestsRequest(BaseModel):
|
|
|
357
437
|
user_id: str | None = None
|
|
358
438
|
request_id: str | None = None
|
|
359
439
|
session_id: str | None = None
|
|
440
|
+
source: str | None = None
|
|
360
441
|
start_time: datetime | None = None
|
|
361
442
|
end_time: datetime | None = None
|
|
362
|
-
top_k: int | None = Field(
|
|
363
|
-
|
|
443
|
+
top_k: int | None = Field(
|
|
444
|
+
default=30,
|
|
445
|
+
gt=0,
|
|
446
|
+
description="Maximum number of sessions to return. Pagination is "
|
|
447
|
+
"per-session: every returned session includes all of its requests.",
|
|
448
|
+
)
|
|
449
|
+
offset: int | None = Field(
|
|
450
|
+
default=0, ge=0, description="Number of sessions to skip for pagination."
|
|
451
|
+
)
|
|
364
452
|
|
|
365
453
|
@model_validator(mode="after")
|
|
366
454
|
def check_time_range(self) -> Self:
|
|
@@ -450,7 +538,8 @@ class TimeSeriesDataPoint(BaseModel):
|
|
|
450
538
|
"""A single data point in a time series."""
|
|
451
539
|
|
|
452
540
|
timestamp: int = Field(gt=0) # Unix timestamp
|
|
453
|
-
value:
|
|
541
|
+
value: float = Field(ge=0) # Count or metric value
|
|
542
|
+
count: int | None = Field(default=None, ge=0) # Optional weight for rate metrics
|
|
454
543
|
|
|
455
544
|
|
|
456
545
|
class PeriodStats(BaseModel):
|
|
@@ -621,6 +710,11 @@ class UnifiedSearchRequest(BaseModel):
|
|
|
621
710
|
enable_reformulation: bool | None = False
|
|
622
711
|
enable_agent_answer: bool | None = False
|
|
623
712
|
search_mode: SearchMode = SearchMode.HYBRID
|
|
713
|
+
# Caller correlation IDs for billing attribution on the Application line.
|
|
714
|
+
# Optional; consumed by _meter_applied_learnings in server/api.py.
|
|
715
|
+
request_id: str | None = None
|
|
716
|
+
session_id: str | None = None
|
|
717
|
+
interaction_id: int | None = Field(default=None, gt=0)
|
|
624
718
|
|
|
625
719
|
|
|
626
720
|
class UnifiedSearchResponse(BaseModel):
|
|
@@ -78,6 +78,8 @@ def to_profile_view(profile: UserProfile) -> ProfileView:
|
|
|
78
78
|
status=profile.status,
|
|
79
79
|
extractor_names=profile.extractor_names,
|
|
80
80
|
source_span=profile.source_span,
|
|
81
|
+
source_interaction_ids=profile.source_interaction_ids,
|
|
82
|
+
tags=profile.tags or [],
|
|
81
83
|
)
|
|
82
84
|
|
|
83
85
|
|
|
@@ -104,6 +106,7 @@ def to_user_playbook_view(rf: UserPlaybook) -> UserPlaybookView:
|
|
|
104
106
|
source=rf.source,
|
|
105
107
|
source_interaction_ids=rf.source_interaction_ids,
|
|
106
108
|
source_span=rf.source_span,
|
|
109
|
+
tags=rf.tags or [],
|
|
107
110
|
)
|
|
108
111
|
|
|
109
112
|
|
|
@@ -127,6 +130,7 @@ def to_agent_playbook_view(fb: AgentPlaybook) -> AgentPlaybookView:
|
|
|
127
130
|
playbook_status=fb.playbook_status,
|
|
128
131
|
playbook_metadata=fb.playbook_metadata,
|
|
129
132
|
status=fb.status,
|
|
133
|
+
tags=fb.tags or [],
|
|
130
134
|
)
|
|
131
135
|
|
|
132
136
|
|
|
@@ -143,6 +147,7 @@ def to_evaluation_result_view(
|
|
|
143
147
|
"""
|
|
144
148
|
return EvaluationResultView(
|
|
145
149
|
result_id=result.result_id,
|
|
150
|
+
user_id=result.user_id,
|
|
146
151
|
agent_version=result.agent_version,
|
|
147
152
|
session_id=result.session_id,
|
|
148
153
|
is_success=result.is_success,
|
|
@@ -173,5 +178,4 @@ def to_profile_change_log_view(log: ProfileChangeLog) -> ProfileChangeLogView:
|
|
|
173
178
|
created_at=log.created_at,
|
|
174
179
|
added_profiles=[to_profile_view(p) for p in log.added_profiles],
|
|
175
180
|
removed_profiles=[to_profile_view(p) for p in log.removed_profiles],
|
|
176
|
-
mentioned_profiles=[to_profile_view(p) for p in log.mentioned_profiles],
|
|
177
181
|
)
|
|
@@ -65,6 +65,8 @@ class ProfileView(BaseModel):
|
|
|
65
65
|
status: Status | None = None
|
|
66
66
|
extractor_names: list[str] | None = None
|
|
67
67
|
source_span: str | None = None
|
|
68
|
+
source_interaction_ids: list[int] = Field(default_factory=list)
|
|
69
|
+
tags: list[str] = Field(default_factory=list)
|
|
68
70
|
|
|
69
71
|
|
|
70
72
|
class UserPlaybookView(BaseModel):
|
|
@@ -83,6 +85,7 @@ class UserPlaybookView(BaseModel):
|
|
|
83
85
|
source: str | None = None
|
|
84
86
|
source_interaction_ids: list[int] = Field(default_factory=list)
|
|
85
87
|
source_span: str | None = None
|
|
88
|
+
tags: list[str] = Field(default_factory=list)
|
|
86
89
|
|
|
87
90
|
|
|
88
91
|
class AgentPlaybookView(BaseModel):
|
|
@@ -98,12 +101,14 @@ class AgentPlaybookView(BaseModel):
|
|
|
98
101
|
playbook_status: PlaybookStatus = PlaybookStatus.PENDING
|
|
99
102
|
playbook_metadata: str = ""
|
|
100
103
|
status: Status | None = None
|
|
104
|
+
tags: list[str] = Field(default_factory=list)
|
|
101
105
|
|
|
102
106
|
|
|
103
107
|
class EvaluationResultView(BaseModel):
|
|
104
108
|
"""User-facing AgentSuccessEvaluationResult — excludes embedding."""
|
|
105
109
|
|
|
106
110
|
result_id: int = 0
|
|
111
|
+
user_id: str = ""
|
|
107
112
|
agent_version: str
|
|
108
113
|
session_id: str
|
|
109
114
|
is_success: bool
|
|
@@ -126,4 +131,3 @@ class ProfileChangeLogView(BaseModel):
|
|
|
126
131
|
created_at: int = Field(default_factory=lambda: int(datetime.now(UTC).timestamp()))
|
|
127
132
|
added_profiles: list[ProfileView]
|
|
128
133
|
removed_profiles: list[ProfileView]
|
|
129
|
-
mentioned_profiles: list[ProfileView]
|
|
@@ -95,7 +95,13 @@ def _migrate_dict(data: Any, mapping: dict[str, str]) -> Any:
|
|
|
95
95
|
if isinstance(data, dict):
|
|
96
96
|
data = dict(data)
|
|
97
97
|
for old, new in mapping.items():
|
|
98
|
-
if old
|
|
98
|
+
if old not in data:
|
|
99
|
+
continue
|
|
100
|
+
# New name wins when both are present; always drop the old key so it
|
|
101
|
+
# doesn't survive into validation and trip ``extra="forbid"``.
|
|
102
|
+
if new in data:
|
|
103
|
+
data.pop(old)
|
|
104
|
+
else:
|
|
99
105
|
data[new] = data.pop(old)
|
|
100
106
|
return data
|
|
101
107
|
|
|
@@ -397,6 +403,16 @@ class DeduplicationConfig(BaseModel):
|
|
|
397
403
|
SINGLETON_PROFILE_EXTRACTOR_NAME = "profile"
|
|
398
404
|
SINGLETON_USER_PLAYBOOK_NAME = "playbook"
|
|
399
405
|
SINGLETON_AGENT_SUCCESS_EVALUATION_NAME = "agent_success"
|
|
406
|
+
DEFAULT_AGENT_SUCCESS_SAMPLING_RATE = 0.05
|
|
407
|
+
DEFAULT_AGENT_SUCCESS_DEFINITION_PROMPT = (
|
|
408
|
+
"Evaluate whether the AI agent successfully handled the user's session.\n\n"
|
|
409
|
+
"Mark the session successful when, by the end of the conversation, the agent:\n"
|
|
410
|
+
"1. Identified and addressed the user's main goal or question.\n"
|
|
411
|
+
"2. Provided a correct, useful, and actionable response or completed the requested action.\n"
|
|
412
|
+
"Mark the session unsuccessful when the agent failed to understand the request,\n"
|
|
413
|
+
"gave incorrect or unhelpful guidance, did not complete an available action,\n"
|
|
414
|
+
"ignored important constraints, or left the user unsatisfied."
|
|
415
|
+
)
|
|
400
416
|
|
|
401
417
|
|
|
402
418
|
class ProfileExtractorConfig(_ExtractorWindowOverrideCompatMixin, BaseModel):
|
|
@@ -405,7 +421,7 @@ class ProfileExtractorConfig(_ExtractorWindowOverrideCompatMixin, BaseModel):
|
|
|
405
421
|
extractor_name: NonEmptyStr | None = None
|
|
406
422
|
extraction_definition_prompt: SanitizedNonEmptyStr
|
|
407
423
|
context_prompt: str | None = None
|
|
408
|
-
|
|
424
|
+
tagging_definition_prompt: str | None = None
|
|
409
425
|
should_extract_profile_prompt_override: str | None = None
|
|
410
426
|
request_sources_enabled: list[str] | None = (
|
|
411
427
|
None # default enabled for all sources, if set, only extract profiles from the enabled request sources
|
|
@@ -456,7 +472,7 @@ class UserPlaybookExtractorConfig(_ExtractorWindowOverrideCompatMixin, BaseModel
|
|
|
456
472
|
extractor_name: NonEmptyStr | None = None
|
|
457
473
|
extraction_definition_prompt: SanitizedNonEmptyStr
|
|
458
474
|
context_prompt: str | None = None
|
|
459
|
-
|
|
475
|
+
tagging_definition_prompt: str | None = None
|
|
460
476
|
aggregation_config: PlaybookAggregatorConfig | None = None
|
|
461
477
|
deduplication_config: DeduplicationConfig | None = None
|
|
462
478
|
request_sources_enabled: list[str] | None = (
|
|
@@ -488,9 +504,15 @@ class AgentSuccessConfig(_ExtractorWindowOverrideCompatMixin, BaseModel):
|
|
|
488
504
|
evaluation_name: NonEmptyStr | None = None
|
|
489
505
|
success_definition_prompt: SanitizedNonEmptyStr
|
|
490
506
|
metadata_definition_prompt: str | None = None
|
|
507
|
+
request_sources_enabled: list[str] | None = (
|
|
508
|
+
None # default enabled for all sources, if set, only evaluate requests from the enabled request sources
|
|
509
|
+
)
|
|
491
510
|
sampling_rate: float = Field(
|
|
492
|
-
default=
|
|
493
|
-
|
|
511
|
+
default=DEFAULT_AGENT_SUCCESS_SAMPLING_RATE,
|
|
512
|
+
ge=0.0,
|
|
513
|
+
le=1.0,
|
|
514
|
+
description="Fraction of sessions to evaluate automatically.",
|
|
515
|
+
)
|
|
494
516
|
window_size_override: int | None = Field(default=None, gt=0)
|
|
495
517
|
stride_size_override: int | None = Field(default=None, gt=0)
|
|
496
518
|
|
|
@@ -500,6 +522,14 @@ class AgentSuccessConfig(_ExtractorWindowOverrideCompatMixin, BaseModel):
|
|
|
500
522
|
return _migrate_dict(data, _EXTRACTOR_OVERRIDE_MIGRATION)
|
|
501
523
|
|
|
502
524
|
|
|
525
|
+
def _default_agent_success_config() -> AgentSuccessConfig:
|
|
526
|
+
return AgentSuccessConfig(
|
|
527
|
+
evaluation_name=SINGLETON_AGENT_SUCCESS_EVALUATION_NAME,
|
|
528
|
+
success_definition_prompt=DEFAULT_AGENT_SUCCESS_DEFINITION_PROMPT,
|
|
529
|
+
sampling_rate=DEFAULT_AGENT_SUCCESS_SAMPLING_RATE,
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
|
|
503
533
|
class ReflectionConfig(BaseModel):
|
|
504
534
|
"""Configuration for the sliding-window reflection step.
|
|
505
535
|
|
|
@@ -559,7 +589,7 @@ class RetrievalFloorConfig(BaseModel):
|
|
|
559
589
|
weak tail that drives false-positive citations. Calibrate per arm on real data.
|
|
560
590
|
"""
|
|
561
591
|
|
|
562
|
-
enabled: bool =
|
|
592
|
+
enabled: bool = False
|
|
563
593
|
pool_size: int = Field(
|
|
564
594
|
default=30,
|
|
565
595
|
gt=0,
|
|
@@ -634,6 +664,62 @@ class PlaybookOptimizerConfig(BaseModel):
|
|
|
634
664
|
return self
|
|
635
665
|
|
|
636
666
|
|
|
667
|
+
class LineageGCConfig(BaseModel):
|
|
668
|
+
"""Configuration for the tombstone garbage-collection job (enabled by default).
|
|
669
|
+
|
|
670
|
+
Purpose
|
|
671
|
+
-------
|
|
672
|
+
Retains tombstone content for ``tombstone_grace_window_days`` days after the
|
|
673
|
+
row's *retirement instant* (``retired_at``) to support audit, replay of dedup
|
|
674
|
+
and aggregation runs, and rollback. After the window expires the row is
|
|
675
|
+
hard-deleted and a ``hard_delete`` lineage event is recorded.
|
|
676
|
+
|
|
677
|
+
Age basis
|
|
678
|
+
---------
|
|
679
|
+
The GC ages on ``retired_at`` — the INTEGER epoch set when a row is tombstoned
|
|
680
|
+
(merged, superseded, or archived). Rows with ``retired_at = NULL`` (created
|
|
681
|
+
before the column was added) are never eligible; they have no retirement clock.
|
|
682
|
+
|
|
683
|
+
Grace window
|
|
684
|
+
------------
|
|
685
|
+
90 days is the default grace window. This matches common 90-day soft-delete
|
|
686
|
+
retention policies and satisfies GDPR Art. 5(1)(e) storage-limitation for
|
|
687
|
+
personal data in profiles. The value is a per-deployment policy knob; ratify
|
|
688
|
+
with your DPO before shortening it in production. The 90-day floor also
|
|
689
|
+
preserves tombstones long enough for B3 changelog replay and rollback
|
|
690
|
+
consumers — raise ``tombstone_grace_window_days`` further if your replay
|
|
691
|
+
horizon exceeds 90 days.
|
|
692
|
+
|
|
693
|
+
Enabled by default
|
|
694
|
+
------------------
|
|
695
|
+
GC is ON by default so tombstones created by the soft-delete flags (also ON by
|
|
696
|
+
default) are reclaimed automatically. Disabling GC while soft-delete is enabled
|
|
697
|
+
allows tombstone counts to grow without bound — only do this deliberately (e.g.
|
|
698
|
+
extended audit hold) and with a plan to re-enable.
|
|
699
|
+
|
|
700
|
+
Disabling
|
|
701
|
+
---------
|
|
702
|
+
Set ``enabled = False`` in your deployment config to hold all tombstones
|
|
703
|
+
indefinitely (e.g. for an extended audit window or rollback standby period).
|
|
704
|
+
"""
|
|
705
|
+
|
|
706
|
+
enabled: bool = True
|
|
707
|
+
tombstone_grace_window_days: int = Field(default=90, gt=0)
|
|
708
|
+
poll_interval_seconds: int = Field(default=86400, gt=0)
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
class GovernanceRetentionConfig(BaseModel):
|
|
712
|
+
"""Audit-event retention policy. **Enterprise-only:** reclamation is performed
|
|
713
|
+
by the reflexio_ext GovernanceRetentionCapability. In an OSS-only deployment
|
|
714
|
+
these knobs are accepted but inert (the OSS lineage scheduler does not reclaim
|
|
715
|
+
audit events) and the server logs a startup warning when retention is enabled.
|
|
716
|
+
"""
|
|
717
|
+
|
|
718
|
+
audit_events_retention_enabled: bool = False
|
|
719
|
+
audit_events_retention_days: int = Field(default=365, gt=0)
|
|
720
|
+
audit_events_delete_batch_limit: int = Field(default=500, gt=0)
|
|
721
|
+
|
|
722
|
+
|
|
637
723
|
@dataclass(frozen=True)
|
|
638
724
|
class EffectivePendingToolCallConfig:
|
|
639
725
|
"""Resolved pending-tool-call settings after applying tool overrides."""
|
|
@@ -733,6 +819,8 @@ def _default_user_playbook_extractor_config() -> UserPlaybookExtractorConfig:
|
|
|
733
819
|
|
|
734
820
|
|
|
735
821
|
class Config(BaseModel):
|
|
822
|
+
model_config = ConfigDict(extra="forbid")
|
|
823
|
+
|
|
736
824
|
# define where user configuration is stored at
|
|
737
825
|
storage_config: StorageConfig
|
|
738
826
|
storage_config_test: StorageConfigTest | None = StorageConfigTest.UNKNOWN
|
|
@@ -749,7 +837,9 @@ class Config(BaseModel):
|
|
|
749
837
|
default_factory=_default_user_playbook_extractor_config
|
|
750
838
|
)
|
|
751
839
|
# agent level success
|
|
752
|
-
agent_success_config: AgentSuccessConfig | None =
|
|
840
|
+
agent_success_config: AgentSuccessConfig | None = Field(
|
|
841
|
+
default_factory=_default_agent_success_config
|
|
842
|
+
)
|
|
753
843
|
# extraction preset — selects bundled window_size/stride_size values
|
|
754
844
|
extraction_preset: ExtractionPreset | None = None
|
|
755
845
|
# extraction parameters
|
|
@@ -767,6 +857,11 @@ class Config(BaseModel):
|
|
|
767
857
|
playbook_optimizer_config: PlaybookOptimizerConfig = Field(
|
|
768
858
|
default_factory=PlaybookOptimizerConfig
|
|
769
859
|
)
|
|
860
|
+
# Tombstone GC job gate (opt-in, off by default — see LineageGCConfig)
|
|
861
|
+
lineage_gc: LineageGCConfig = Field(default_factory=LineageGCConfig)
|
|
862
|
+
governance_retention: GovernanceRetentionConfig = Field(
|
|
863
|
+
default_factory=GovernanceRetentionConfig
|
|
864
|
+
)
|
|
770
865
|
# Optional non-blocking async information tools for classic extraction.
|
|
771
866
|
pending_tool_call_config: PendingToolCallConfig = Field(
|
|
772
867
|
default_factory=PendingToolCallConfig
|
|
@@ -824,6 +919,8 @@ class Config(BaseModel):
|
|
|
824
919
|
"stride_size",
|
|
825
920
|
"reflection_config",
|
|
826
921
|
"playbook_optimizer_config",
|
|
922
|
+
"lineage_gc",
|
|
923
|
+
"governance_retention",
|
|
827
924
|
"pending_tool_call_config",
|
|
828
925
|
"retrieval_floor",
|
|
829
926
|
):
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""Provider-safe base class for LLM structured-output Pydantic models.
|
|
2
|
+
|
|
3
|
+
Every Pydantic model sent to an LLM as a structured-output schema (a
|
|
4
|
+
``response_format`` or a tool's parameter schema) should inherit
|
|
5
|
+
``StrictStructuredOutput``. It carries a ``__get_pydantic_json_schema__`` hook
|
|
6
|
+
(via ``ProviderSafeUnionMixin``) that folds a discriminated union's ``oneOf`` into
|
|
7
|
+
``anyOf`` and drops ``discriminator`` in the *emitted* JSON schema, so strict
|
|
8
|
+
structured-output endpoints (OpenAI, minimax) accept it **by construction** — with
|
|
9
|
+
no provider-detection gate and no post-processing. Only the wire schema is
|
|
10
|
+
rewritten; the core (validation) schema keeps the discriminator, so keyed dispatch
|
|
11
|
+
and precise per-variant errors are preserved.
|
|
12
|
+
|
|
13
|
+
This module lives under ``models/`` (depending only on pydantic) so both
|
|
14
|
+
``models/api_schema/`` schemas and ``server/services/*`` models can inherit the
|
|
15
|
+
base without a layering inversion (a ``models/`` file importing from
|
|
16
|
+
``server/llm/`` would invert the dependency direction).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from typing import TYPE_CHECKING, Any
|
|
20
|
+
|
|
21
|
+
from pydantic import BaseModel, GetJsonSchemaHandler
|
|
22
|
+
from pydantic.json_schema import JsonSchemaValue
|
|
23
|
+
from pydantic_core import CoreSchema
|
|
24
|
+
|
|
25
|
+
# Keys whose *values* are name→subschema maps: their entries are user-chosen names
|
|
26
|
+
# (field names, $def names), not JSON-Schema keywords. Traversals must recurse into
|
|
27
|
+
# the subschemas but never treat the names themselves as keywords — otherwise a
|
|
28
|
+
# model with a field literally named ``oneOf`` would be mishandled.
|
|
29
|
+
_SCHEMA_NAME_MAP_KEYS = ("properties", "$defs", "definitions", "patternProperties")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _fold_oneof_to_anyof(node: Any) -> None:
|
|
33
|
+
"""Rewrite ``oneOf`` to ``anyOf`` and drop ``discriminator`` in place (recursive).
|
|
34
|
+
|
|
35
|
+
Pydantic emits ``oneOf`` + ``discriminator`` for a discriminated union, which
|
|
36
|
+
strict structured-output endpoints (OpenAI, minimax) reject. Folding into
|
|
37
|
+
``anyOf`` keeps the identical variant set so generation stays constrained;
|
|
38
|
+
Pydantic still enforces the discriminator after parse, so semantics are
|
|
39
|
+
preserved.
|
|
40
|
+
|
|
41
|
+
Structure-aware: under a name→subschema map (``properties``/``$defs``/…) it
|
|
42
|
+
recurses into the subschemas but does NOT treat a property/``$def`` *name* as a
|
|
43
|
+
keyword — so a model field literally named ``oneOf``/``discriminator`` is
|
|
44
|
+
preserved (only keyword-position occurrences are folded). Precondition:
|
|
45
|
+
``node`` is a finite acyclic tree, as produced by ``model_json_schema()``
|
|
46
|
+
(which expresses recursion via ``$ref``/``$defs`` strings, never in-memory
|
|
47
|
+
cycles) — there is no cycle guard.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
node (Any): A JSON-schema fragment (dict, list, or scalar); mutated in place.
|
|
51
|
+
"""
|
|
52
|
+
if isinstance(node, dict):
|
|
53
|
+
one_of = node.pop("oneOf", None)
|
|
54
|
+
node.pop("discriminator", None)
|
|
55
|
+
if isinstance(one_of, list):
|
|
56
|
+
node["anyOf"] = node.get("anyOf", []) + one_of
|
|
57
|
+
for key, value in node.items():
|
|
58
|
+
if key in _SCHEMA_NAME_MAP_KEYS and isinstance(value, dict):
|
|
59
|
+
for sub in value.values():
|
|
60
|
+
_fold_oneof_to_anyof(sub)
|
|
61
|
+
else:
|
|
62
|
+
_fold_oneof_to_anyof(value)
|
|
63
|
+
elif isinstance(node, list):
|
|
64
|
+
for item in node:
|
|
65
|
+
_fold_oneof_to_anyof(item)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# Statically the mixin must appear to derive from ``BaseModel`` so the ``super()``
|
|
69
|
+
# call below type-checks; at runtime it is a bare mixin (``object`` base), and
|
|
70
|
+
# ``super()`` resolves to ``BaseModel.__get_pydantic_json_schema__`` via the MRO
|
|
71
|
+
# of the concrete model (e.g. ``class X(ProviderSafeUnionMixin, BaseModel)``).
|
|
72
|
+
_ProviderSafeUnionBase = BaseModel if TYPE_CHECKING else object
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class ProviderSafeUnionMixin(_ProviderSafeUnionBase):
|
|
76
|
+
"""Make a model emit a provider-safe JSON schema by construction.
|
|
77
|
+
|
|
78
|
+
A model containing a Pydantic discriminated union serializes to JSON Schema
|
|
79
|
+
with ``oneOf`` + ``discriminator``, which strict structured-output endpoints
|
|
80
|
+
reject (the Sentry ``PYTHON-FASTAPI-9J`` incident). Mixing this in folds
|
|
81
|
+
``oneOf`` into ``anyOf`` (and drops ``discriminator``) at the model boundary,
|
|
82
|
+
so every caller of ``model_json_schema()`` — litellm, instructor, our own
|
|
83
|
+
path — gets a provider-safe schema **unconditionally**, without depending on
|
|
84
|
+
a provider-detection gate (e.g. ``litellm.supports_response_schema``, which
|
|
85
|
+
under-reports some providers). Only the JSON (wire) schema is rewritten; the
|
|
86
|
+
core validation schema keeps the discriminator, so keyed dispatch and precise
|
|
87
|
+
per-variant errors are preserved.
|
|
88
|
+
|
|
89
|
+
Prefer inheriting ``StrictStructuredOutput`` (below) on output models rather
|
|
90
|
+
than mixing this in directly.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
def __get_pydantic_json_schema__(
|
|
95
|
+
cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
|
|
96
|
+
) -> JsonSchemaValue:
|
|
97
|
+
# Chain via super() (not handler() directly) so a cooperative base that
|
|
98
|
+
# also customizes __get_pydantic_json_schema__ is not silently shadowed;
|
|
99
|
+
# BaseModel's default impl just invokes handler(core_schema).
|
|
100
|
+
schema = super().__get_pydantic_json_schema__(core_schema, handler)
|
|
101
|
+
_fold_oneof_to_anyof(schema)
|
|
102
|
+
return schema
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class StrictStructuredOutput(ProviderSafeUnionMixin, BaseModel):
|
|
106
|
+
"""Base for every Pydantic model sent to an LLM as a structured-output schema.
|
|
107
|
+
|
|
108
|
+
Inherits the provider-safe schema hook from ``ProviderSafeUnionMixin`` so the
|
|
109
|
+
emitted JSON schema folds any discriminated union (``oneOf``→``anyOf``, drop
|
|
110
|
+
``discriminator``) by construction — accepted by strict structured-output
|
|
111
|
+
providers with no provider gate, including any *future* discriminated union.
|
|
112
|
+
|
|
113
|
+
Deliberately adds NO ``model_config``: each model keeps its own ``extra=`` and
|
|
114
|
+
``json_schema_extra`` exactly as before. This base unifies the *provider-safety
|
|
115
|
+
guarantee*, not the per-model config (centralizing config is a separate change —
|
|
116
|
+
``extra=`` is not uniform across models, so a blanket dedup would silently shift
|
|
117
|
+
validation/serialization behavior).
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def find_schema_keyword(node: Any, keyword: str) -> bool:
|
|
122
|
+
"""Report whether ``keyword`` appears as a JSON-Schema *keyword* anywhere in ``node``.
|
|
123
|
+
|
|
124
|
+
Structure-aware: an occurrence of ``keyword`` as a property/``$defs`` *name*
|
|
125
|
+
(e.g. a model field literally named ``oneOf``) is NOT a match — only an
|
|
126
|
+
occurrence in JSON-Schema keyword position counts. Use this (not a blind
|
|
127
|
+
``in``-walk) to check a schema for provider-unsafe keywords.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
node (Any): A JSON-schema fragment (dict, list, or scalar).
|
|
131
|
+
keyword (str): The JSON-Schema keyword to search for (e.g. ``"oneOf"``).
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
bool: True if ``keyword`` appears in keyword position, else False.
|
|
135
|
+
"""
|
|
136
|
+
if isinstance(node, dict):
|
|
137
|
+
if keyword in node:
|
|
138
|
+
return True
|
|
139
|
+
for key, value in node.items():
|
|
140
|
+
if key in _SCHEMA_NAME_MAP_KEYS and isinstance(value, dict):
|
|
141
|
+
if any(find_schema_keyword(sub, keyword) for sub in value.values()):
|
|
142
|
+
return True
|
|
143
|
+
elif find_schema_keyword(value, keyword):
|
|
144
|
+
return True
|
|
145
|
+
return False
|
|
146
|
+
if isinstance(node, list):
|
|
147
|
+
return any(find_schema_keyword(item, keyword) for item in node)
|
|
148
|
+
return False
|
|
@@ -23,7 +23,7 @@ Client (SDK/Web)
|
|
|
23
23
|
-> GenerationService (server/services/)
|
|
24
24
|
├─> ProfileGenerationService -> ProfileExtractor(s) -> Storage
|
|
25
25
|
├─> PlaybookGenerationService -> PlaybookExtractor(s) -> Storage
|
|
26
|
-
└─> GroupEvaluationScheduler (deferred 10 min) ->
|
|
26
|
+
└─> agent_success_evaluation/scheduler.py:GroupEvaluationScheduler (deferred 10 min) -> agent_success_evaluation/runner.py:run_group_evaluation -> agent_success_evaluation/service.py -> agent_success_evaluation/components/evaluator.py -> Storage
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
## Prerequisites
|
|
@@ -41,7 +41,7 @@ cp .env.example .env # Configure environment (set at lea
|
|
|
41
41
|
uv sync # Install Python dependencies (includes workspace packages)
|
|
42
42
|
npm --prefix src/website install # Install frontend dependencies
|
|
43
43
|
npm --prefix src/public_docs install # Install docs dependencies
|
|
44
|
-
./run_services.sh # Starts API (
|
|
44
|
+
./run_services.sh # Starts API (8061), Website (8080), Docs (8062)
|
|
45
45
|
./stop_services.sh # Stop all services
|
|
46
46
|
```
|
|
47
47
|
|
|
@@ -56,7 +56,7 @@ npm --prefix src/public_docs install # Install docs dependencies
|
|
|
56
56
|
**Testing:**
|
|
57
57
|
```python
|
|
58
58
|
import reflexio
|
|
59
|
-
client = reflexio.ReflexioClient(api_key="your-api-key", url_endpoint="http://127.0.0.1:
|
|
59
|
+
client = reflexio.ReflexioClient(api_key="your-api-key", url_endpoint="http://127.0.0.1:8061/")
|
|
60
60
|
```
|
|
61
61
|
See `notebooks/reflexio_cookbook.ipynb` and `src/tests/readme.md`
|
|
62
62
|
|