claude-smart 0.2.42 → 0.2.44
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 +1 -1
- package/bin/claude-smart.js +2 -2
- package/package.json +9 -3
- package/plugin/.claude-plugin/plugin.json +9 -3
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/README.md +23 -3
- package/plugin/pyproject.toml +3 -3
- package/plugin/scripts/_lib.sh +91 -0
- package/plugin/scripts/backend-service.sh +51 -4
- package/plugin/scripts/cli.sh +3 -1
- package/plugin/scripts/codex-hook.js +72 -4
- package/plugin/scripts/dashboard-build.sh +1 -0
- package/plugin/scripts/dashboard-service.sh +1 -0
- package/plugin/scripts/ensure-plugin-root.sh +1 -0
- package/plugin/scripts/hook_entry.sh +6 -3
- package/plugin/scripts/smart-install.sh +3 -2
- package/plugin/src/README.md +57 -0
- package/plugin/src/claude_smart/context_format.py +11 -12
- package/plugin/src/claude_smart/cs_cite.py +26 -12
- package/plugin/src/claude_smart/ids.py +13 -5
- package/plugin/uv.lock +126 -5
- package/plugin/vendor/reflexio/.env.example +62 -0
- package/plugin/vendor/reflexio/LICENSE +201 -0
- package/plugin/vendor/reflexio/README.md +338 -0
- package/plugin/vendor/reflexio/pyproject.toml +274 -0
- package/plugin/vendor/reflexio/reflexio/README.md +184 -0
- package/plugin/vendor/reflexio/reflexio/__init__.py +166 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/README.md +109 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/backends.py +175 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/bench.py +642 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/embed_cache.py +330 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/report.py +317 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/report.md +43 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/results/results.json +4478 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/scenarios.py +134 -0
- package/plugin/vendor/reflexio/reflexio/benchmarks/retrieval_latency/seed.py +255 -0
- package/plugin/vendor/reflexio/reflexio/cli/README.md +287 -0
- package/plugin/vendor/reflexio/reflexio/cli/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/cli/__main__.py +56 -0
- package/plugin/vendor/reflexio/reflexio/cli/_client.py +86 -0
- package/plugin/vendor/reflexio/reflexio/cli/app.py +127 -0
- package/plugin/vendor/reflexio/reflexio/cli/bootstrap_config.py +265 -0
- package/plugin/vendor/reflexio/reflexio/cli/codex_auth.py +503 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/admin_cmd.py +65 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/agent_playbooks.py +503 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/api.py +114 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/auth.py +109 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/config_cmd.py +511 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/doctor.py +127 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/embeddings.py +53 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/interactions.py +478 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/profiles.py +303 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/services.py +289 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/setup_cmd.py +964 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/shortcuts.py +285 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/status_cmd.py +143 -0
- package/plugin/vendor/reflexio/reflexio/cli/commands/user_playbooks.py +373 -0
- package/plugin/vendor/reflexio/reflexio/cli/env_loader.py +284 -0
- package/plugin/vendor/reflexio/reflexio/cli/errors.py +217 -0
- package/plugin/vendor/reflexio/reflexio/cli/log_format.py +247 -0
- package/plugin/vendor/reflexio/reflexio/cli/output.py +867 -0
- package/plugin/vendor/reflexio/reflexio/cli/paths.py +41 -0
- package/plugin/vendor/reflexio/reflexio/cli/run_services.py +391 -0
- package/plugin/vendor/reflexio/reflexio/cli/state.py +204 -0
- package/plugin/vendor/reflexio/reflexio/cli/stop_services.py +96 -0
- package/plugin/vendor/reflexio/reflexio/cli/utils.py +329 -0
- package/plugin/vendor/reflexio/reflexio/client/__init__.py +3 -0
- package/plugin/vendor/reflexio/reflexio/client/cache.py +150 -0
- package/plugin/vendor/reflexio/reflexio/client/client.py +2613 -0
- package/plugin/vendor/reflexio/reflexio/defaults.py +23 -0
- package/plugin/vendor/reflexio/reflexio/integrations/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/.clawhubignore +7 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/README.md +274 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/TESTING.md +517 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/hook/handler.js +473 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package-lock.json +2156 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/package.json +18 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/handler.ts +241 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/hook/setup.ts +140 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/index.ts +130 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/publish.ts +113 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/search.ts +52 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/server.ts +103 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/sqlite-buffer.ts +156 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/lib/user-id.ts +134 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/openclaw.plugin.json +41 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/package.json +17 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/rules/reflexio.md +24 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/skills/reflexio/SKILL.md +48 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/publish_clawhub.sh +278 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/references/HOOK.md +164 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/install.sh +36 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/scripts/uninstall.sh +35 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/publish.test.ts +27 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/search.test.ts +31 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/server.test.ts +42 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/setup.test.ts +49 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/sqlite-buffer.test.ts +91 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tests/user-id.test.ts +50 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/tsconfig.json +16 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/types/openclaw.d.ts +230 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/vitest.config.ts +13 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/README.md +120 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/TESTING.md +168 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package-lock.json +1657 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/package.json +16 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/HEARTBEAT.md +6 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/README.md +84 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/SKILL.md +194 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/_meta.json +6 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/agents/reflexio-extractor.md +45 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/handler.ts +214 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/hook/setup.ts +55 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/index.ts +327 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/consolidate.ts +233 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/dedup.ts +80 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/io.ts +155 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/openclaw-cli.ts +67 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/search.ts +33 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-playbook.ts +76 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/lib/write-profile.ts +79 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/openclaw.plugin.json +46 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/package.json +18 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/README.md +36 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/full_consolidation.md +56 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/playbook_extraction.md +217 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/prompts/profile_extraction.md +132 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-consolidate/SKILL.md +33 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/plugin/skills/reflexio-embedded/SKILL.md +194 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/HOOK.md +18 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/architecture.md +49 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/comparison.md +31 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/future-work.md +47 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/references/porting-notes.md +52 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/install.sh +52 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/scripts/uninstall.sh +36 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/consolidate.test.ts +135 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/dedup.test.ts +104 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/io.test.ts +175 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/search.test.ts +66 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/smoke-test.ts +140 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-playbook.test.ts +93 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tests/write-profile.test.ts +174 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/tsconfig.json +16 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/types/openclaw.d.ts +230 -0
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw-embedded/vitest.config.ts +7 -0
- package/plugin/vendor/reflexio/reflexio/lib/__init__.py +23 -0
- package/plugin/vendor/reflexio/reflexio/lib/_agent_playbook.py +310 -0
- package/plugin/vendor/reflexio/reflexio/lib/_base.py +225 -0
- package/plugin/vendor/reflexio/reflexio/lib/_config.py +83 -0
- package/plugin/vendor/reflexio/reflexio/lib/_dashboard.py +266 -0
- package/plugin/vendor/reflexio/reflexio/lib/_generation.py +176 -0
- package/plugin/vendor/reflexio/reflexio/lib/_interactions.py +334 -0
- package/plugin/vendor/reflexio/reflexio/lib/_operations.py +153 -0
- package/plugin/vendor/reflexio/reflexio/lib/_profiles.py +545 -0
- package/plugin/vendor/reflexio/reflexio/lib/_reflection.py +52 -0
- package/plugin/vendor/reflexio/reflexio/lib/_search.py +167 -0
- package/plugin/vendor/reflexio/reflexio/lib/_storage_labels.py +103 -0
- package/plugin/vendor/reflexio/reflexio/lib/_user_playbook.py +288 -0
- package/plugin/vendor/reflexio/reflexio/lib/reflexio_lib.py +27 -0
- package/plugin/vendor/reflexio/reflexio/models/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/braintrust_schema.py +141 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/common.py +41 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/__init__.py +3 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +1112 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +63 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +487 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +28 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/pending_tool_call_schema.py +83 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +768 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/service_schemas.py +9 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/stall_state_schema.py +32 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/__init__.py +3 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +177 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +129 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/enums.py +25 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/validators.py +333 -0
- package/plugin/vendor/reflexio/reflexio/models/config_schema.py +908 -0
- package/plugin/vendor/reflexio/reflexio/models/py.typed +0 -0
- package/plugin/vendor/reflexio/reflexio/server/OVERVIEW.md +90 -0
- package/plugin/vendor/reflexio/reflexio/server/README.md +622 -0
- package/plugin/vendor/reflexio/reflexio/server/__init__.py +210 -0
- package/plugin/vendor/reflexio/reflexio/server/__main__.py +132 -0
- package/plugin/vendor/reflexio/reflexio/server/_auth.py +25 -0
- package/plugin/vendor/reflexio/reflexio/server/api.py +2868 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/README.md +34 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/account_api.py +143 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/health_api.py +91 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/pending_tool_call_api.py +572 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/precondition_checks.py +66 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/publisher_api.py +562 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/request_context.py +50 -0
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/stall_state_api.py +100 -0
- package/plugin/vendor/reflexio/reflexio/server/cache/__init__.py +15 -0
- package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +208 -0
- package/plugin/vendor/reflexio/reflexio/server/correlation.py +46 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/__init__.py +30 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +359 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/image_utils.py +55 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +1871 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +140 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +479 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +1122 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_stream_parser.py +197 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +338 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/local_embedding_provider.py +213 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/nomic_embedding_provider.py +288 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/rerank/__init__.py +6 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/rerank/cross_encoder_reranker.py +187 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/rerank/llm_reranker.py +148 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +716 -0
- package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +179 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/_dispatchers.py +54 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/README.md +121 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation/v1.0.0.prompt.md +58 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/agent_success_evaluation_with_comparison/v1.0.0.prompt.md +76 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/answer_synthesis/v1.5.2.prompt.md +88 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/compress_session_for_query/v1.3.0.prompt.md +31 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/document_expansion/v1.0.0.prompt.md +20 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.0.0.prompt.md +53 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.1.0.prompt.md +57 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.2.0.prompt.md +68 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.3.0.prompt.md +70 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.4.0.prompt.md +77 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.5.0.prompt.md +82 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/memory_reflection/v1.6.0.prompt.md +83 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.1.0.prompt.md +193 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_aggregation/v2.2.0.prompt.md +206 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0-deprecated.prompt.md +66 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.0.0.prompt.md +43 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v1.1.0.prompt.md +46 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0-deprecated.prompt.md +64 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.0.0.prompt.md +39 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.1.0.prompt.md +39 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.2.0.prompt.md +47 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.0.prompt.md +58 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.1.prompt.md +69 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.2.prompt.md +71 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.0.2.prompt.md +254 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.1.0.prompt.md +274 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.0.prompt.md +283 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.2.prompt.md +234 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context/v4.2.3.prompt.md +244 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v1.0.0.prompt.md +73 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v2.0.0.prompt.md +86 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.0.0.prompt.md +97 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.1.0.prompt.md +119 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.2.0.prompt.md +123 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_context_expert/v3.3.0.prompt.md +137 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.0.0.prompt.md +14 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.1.0.prompt.md +24 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main/v1.2.0.prompt.md +29 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.0.0.prompt.md +11 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.1.0.prompt.md +21 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_extraction_main_expert/v1.2.0.prompt.md +25 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.0.0.prompt.md +37 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.1.0.prompt.md +40 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_optimizer_judge/v1.2.0.prompt.md +36 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v1.0.0.prompt.md +45 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v2.0.0.prompt.md +81 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate/v3.0.0.prompt.md +80 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_should_generate_expert/v1.0.0.prompt.md +34 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_deduplication/v1.0.0.prompt.md +116 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate/v1.0.0.prompt.md +33 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_should_generate_override/v1.0.0.prompt.md +16 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.0.0.prompt.md +140 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_instruction_start/v1.1.0.prompt.md +160 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/profile_update_main/v1.0.0.prompt.md +14 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/query_reformulation/v1.0.0.prompt.md +19 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/rerank_relevance/v1.1.0.prompt.md +44 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_comparison/v1.0.0.prompt.md +43 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_content_evaluation/v1.0.0.prompt.md +33 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/feedback_extraction_main_v1.jsonl +10 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_evaluation/prompt_evaluation_dataset/profile_update_main_v1.jsonl +10 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_manager.py +280 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_schema.py +11 -0
- package/plugin/vendor/reflexio/reflexio/server/services/README.md +58 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/_eval_health.py +131 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_constants.py +60 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_service.py +228 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluation_utils.py +87 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/agent_success_evaluator.py +372 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/delayed_group_evaluator.py +156 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/group_evaluation_runner.py +336 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +471 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +1668 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_cron.py +196 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/_encryption.py +101 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/client.py +167 -0
- package/plugin/vendor/reflexio/reflexio/server/services/braintrust/service.py +281 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/base_configurator.py +179 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/config_storage.py +62 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/configurator.py +87 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/local_file_config_storage.py +187 -0
- package/plugin/vendor/reflexio/reflexio/server/services/configurator/test_config_storage.py +162 -0
- package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +112 -0
- package/plugin/vendor/reflexio/reflexio/server/services/embedding_text.py +62 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/distribution.py +33 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/eval_sampler.py +126 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py +192 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/hero_state.py +75 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/rule_attribution.py +97 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +515 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/shadow_aggregation.py +90 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/agent_run_records.py +91 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/invariants.py +303 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +25 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/pending_tool_call_dispatch.py +358 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/plan.py +138 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/prior_answer_search.py +217 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +535 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_scheduler.py +171 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +779 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +1125 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extractor_config_utils.py +94 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extractor_interaction_utils.py +251 -0
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +702 -0
- package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +835 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/README.md +89 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_aggregator.py +1388 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_consolidator.py +1045 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_extractor.py +436 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_generation_service.py +808 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_constants.py +28 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_service_utils.py +362 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/__init__.py +24 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/assistant_webhook.py +246 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/gepa_adapter.py +291 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/judge.py +97 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/models.py +96 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +645 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/rollout.py +35 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scenario_resolver.py +93 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scheduler.py +174 -0
- package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/__init__.py +26 -0
- package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_document_expander.py +179 -0
- package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_query_reformulator.py +297 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_deduplicator.py +772 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_extractor.py +462 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service.py +737 -0
- package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py +290 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/__init__.py +17 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_extractor.py +247 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service.py +803 -0
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/reflection_service_utils.py +146 -0
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/relevance_floor.py +80 -0
- package/plugin/vendor/reflexio/reflexio/server/services/search/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +756 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/judge.py +184 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/outcome.py +81 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/constants.py +2 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/error.py +11 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +154 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/retention_mixin.py +155 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +59 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +1298 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +1945 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +600 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_operations.py +346 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_playbook.py +1378 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +747 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +263 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +193 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_share_links.py +166 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_stall_state.py +217 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +153 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +384 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_base.py +71 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +235 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +170 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_playbook.py +677 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_profiles.py +250 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_requests.py +154 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +130 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_share_links.py +93 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_stall_state.py +76 -0
- package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +572 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +77 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +116 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_manager.py +263 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +13 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/llm_model_setting.json +7 -0
- package/plugin/vendor/reflexio/reflexio/server/tracing.py +158 -0
- package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +113 -0
- package/plugin/vendor/reflexio/reflexio/server/uvicorn_logging.py +76 -0
- package/plugin/vendor/reflexio/reflexio/test_support/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_fixtures.py +62 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +242 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +129 -0
- package/plugin/vendor/reflexio/reflexio/test_support/skip_decorators.py +43 -0
package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/group_aggregation.py
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Pure aggregation helpers for F2's session-level A/B groups.
|
|
2
|
+
|
|
3
|
+
These functions are deliberately DB-free and LLM-free so they can be unit
|
|
4
|
+
tested in milliseconds and exercised by mutmut. The storage layer hands
|
|
5
|
+
in raw tuples; we hand back SuccessRateTrendByGroup.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import math
|
|
11
|
+
from collections import defaultdict
|
|
12
|
+
from collections.abc import Iterable
|
|
13
|
+
from enum import StrEnum
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from reflexio.models.api_schema.eval_overview_schema import (
|
|
17
|
+
SuccessRateTrendByGroup,
|
|
18
|
+
TrendPoint,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# Z-value for a 95% Wald CI on a binomial proportion (two-sided).
|
|
22
|
+
_Z_95 = 1.96
|
|
23
|
+
|
|
24
|
+
# Cap on the lift CI half-width. With very small sample sizes the Wald CI
|
|
25
|
+
# computes to absurd widths (e.g., ±70pp), and rendering that on a
|
|
26
|
+
# dashboard implies false precision. 0.5 (= ±50pp) is the product-meaningful
|
|
27
|
+
# threshold: any wider than that, the user should think "we don't know"
|
|
28
|
+
# and the frontend should consider rendering a low-confidence indicator.
|
|
29
|
+
_MAX_CI_HALF_WIDTH = 0.5
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class GroupAssignment(StrEnum):
|
|
33
|
+
"""Group label derived from `Request.metadata.reflexio_retrieval_enabled`."""
|
|
34
|
+
|
|
35
|
+
TREATMENT = "treatment"
|
|
36
|
+
CONTROL = "control"
|
|
37
|
+
UNTAGGED = "untagged"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def assign_group_from_metadata(metadata: dict[str, Any]) -> GroupAssignment:
|
|
41
|
+
"""
|
|
42
|
+
Bucket a session by its first request's metadata.
|
|
43
|
+
|
|
44
|
+
Reads ``metadata.reflexio_retrieval_enabled`` as a true bool. Anything
|
|
45
|
+
else (missing, string, int, None) maps to UNTAGGED — we never silently
|
|
46
|
+
coerce non-bool values, so customers see how many of their sessions
|
|
47
|
+
are tagged inconsistently.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
metadata (dict[str, Any]): The first request's metadata dict. Non-dict
|
|
51
|
+
input is tolerated and routed to UNTAGGED (defensive — the caller
|
|
52
|
+
may pass a value read from a JSON column with no type guarantee).
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
GroupAssignment: TREATMENT, CONTROL, or UNTAGGED.
|
|
56
|
+
"""
|
|
57
|
+
if not isinstance(metadata, dict):
|
|
58
|
+
return GroupAssignment.UNTAGGED
|
|
59
|
+
value = metadata.get("reflexio_retrieval_enabled")
|
|
60
|
+
if value is True:
|
|
61
|
+
return GroupAssignment.TREATMENT
|
|
62
|
+
if value is False:
|
|
63
|
+
return GroupAssignment.CONTROL
|
|
64
|
+
return GroupAssignment.UNTAGGED
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def group_session_outcomes_by_metadata(
|
|
68
|
+
outcomes: Iterable[tuple[str, int, bool, dict[str, Any]]],
|
|
69
|
+
) -> dict[GroupAssignment, list[tuple[str, int, bool]]]:
|
|
70
|
+
"""
|
|
71
|
+
Split (session_id, ts, is_success, metadata) tuples into three groups.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
outcomes (Iterable[tuple[str, int, bool, dict[str, Any]]]): Tuples of
|
|
75
|
+
(session_id, ts, is_success, first_request_metadata).
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
dict[GroupAssignment, list[tuple[str, int, bool]]]: Dict keyed by every
|
|
79
|
+
GroupAssignment member (TREATMENT, CONTROL, UNTAGGED) — always present,
|
|
80
|
+
possibly empty list — with values being (session_id, ts, is_success)
|
|
81
|
+
tuples (metadata dropped after binning).
|
|
82
|
+
"""
|
|
83
|
+
out: dict[GroupAssignment, list[tuple[str, int, bool]]] = {
|
|
84
|
+
GroupAssignment.TREATMENT: [],
|
|
85
|
+
GroupAssignment.CONTROL: [],
|
|
86
|
+
GroupAssignment.UNTAGGED: [],
|
|
87
|
+
}
|
|
88
|
+
for session_id, ts, is_success, metadata in outcomes:
|
|
89
|
+
group = assign_group_from_metadata(metadata)
|
|
90
|
+
out[group].append((session_id, ts, is_success))
|
|
91
|
+
return out
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def bucket_outcomes(
|
|
95
|
+
outcomes: Iterable[tuple[str, int, bool]],
|
|
96
|
+
bucket_seconds: int,
|
|
97
|
+
) -> list[dict[str, int]]:
|
|
98
|
+
"""
|
|
99
|
+
Bucket outcomes by time, returning one dict per bucket.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
outcomes (Iterable[tuple[str, int, bool]]): Tuples of (session_id, ts,
|
|
103
|
+
is_success). ``session_id`` is unused at this stage; kept for future
|
|
104
|
+
per-session breakdowns.
|
|
105
|
+
bucket_seconds (int): Bucket width in seconds (e.g., 86400 for daily,
|
|
106
|
+
604800 for weekly). Must be positive.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
list[dict[str, int]]: List of ``{"ts": bucket_start, "n": int,
|
|
110
|
+
"successes": int}``, sorted by ``ts`` ascending. Empty buckets are
|
|
111
|
+
omitted.
|
|
112
|
+
|
|
113
|
+
Raises:
|
|
114
|
+
ValueError: When ``bucket_seconds`` is not positive.
|
|
115
|
+
"""
|
|
116
|
+
if bucket_seconds <= 0:
|
|
117
|
+
raise ValueError(f"bucket_seconds must be positive, got {bucket_seconds}")
|
|
118
|
+
counts: dict[int, dict[str, int]] = defaultdict(lambda: {"n": 0, "successes": 0})
|
|
119
|
+
for _, ts, is_success in outcomes:
|
|
120
|
+
bucket_start = (ts // bucket_seconds) * bucket_seconds
|
|
121
|
+
counts[bucket_start]["n"] += 1
|
|
122
|
+
if is_success:
|
|
123
|
+
counts[bucket_start]["successes"] += 1
|
|
124
|
+
return [
|
|
125
|
+
{"ts": bucket_start, "n": d["n"], "successes": d["successes"]}
|
|
126
|
+
for bucket_start, d in sorted(counts.items())
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def compute_trend_by_group(
|
|
131
|
+
outcomes: Iterable[tuple[str, int, bool, dict[str, Any]]],
|
|
132
|
+
bucket_seconds: int,
|
|
133
|
+
) -> SuccessRateTrendByGroup:
|
|
134
|
+
"""
|
|
135
|
+
Build the dual+untagged-curve trend payload from raw session outcomes.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
outcomes (Iterable[tuple[str, int, bool, dict[str, Any]]]): Tuples of
|
|
139
|
+
(session_id, ts, is_success, first_request_metadata).
|
|
140
|
+
bucket_seconds (int): Bucket width passed to :func:`bucket_outcomes`.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
SuccessRateTrendByGroup: Three curves (any of which may be empty).
|
|
144
|
+
"""
|
|
145
|
+
grouped = group_session_outcomes_by_metadata(outcomes)
|
|
146
|
+
return SuccessRateTrendByGroup(
|
|
147
|
+
treatment=_to_trend_points(grouped[GroupAssignment.TREATMENT], bucket_seconds),
|
|
148
|
+
control=_to_trend_points(grouped[GroupAssignment.CONTROL], bucket_seconds),
|
|
149
|
+
untagged=_to_trend_points(grouped[GroupAssignment.UNTAGGED], bucket_seconds),
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _to_trend_points(
|
|
154
|
+
outcomes: list[tuple[str, int, bool]],
|
|
155
|
+
bucket_seconds: int,
|
|
156
|
+
) -> list[TrendPoint]:
|
|
157
|
+
"""Convert raw outcomes into bucketed TrendPoints; omit empty buckets."""
|
|
158
|
+
return [
|
|
159
|
+
TrendPoint(ts=b["ts"], rate=b["successes"] / b["n"], n=b["n"])
|
|
160
|
+
for b in bucket_outcomes(outcomes, bucket_seconds)
|
|
161
|
+
if b["n"] > 0
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def compute_lift_with_ci(
|
|
166
|
+
n_t: int, p_t: float, n_c: int, p_c: float
|
|
167
|
+
) -> tuple[float | None, float | None]:
|
|
168
|
+
"""
|
|
169
|
+
Compute success-rate lift (treatment − control) and a 95% CI half-width.
|
|
170
|
+
|
|
171
|
+
Uses the Wald approximation for the difference of two binomial
|
|
172
|
+
proportions. Returns ``(None, None)`` if either group has zero samples —
|
|
173
|
+
surfaces honest "no estimate" rather than fake zeros.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
n_t (int): Treatment group size.
|
|
177
|
+
p_t (float): Treatment success rate, in ``[0.0, 1.0]``.
|
|
178
|
+
n_c (int): Control group size.
|
|
179
|
+
p_c (float): Control success rate, in ``[0.0, 1.0]``.
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
tuple[float | None, float | None]: ``(lift, ci_half_width)`` — both in
|
|
183
|
+
proportion units (e.g., 0.14 for 14pp), or ``(None, None)`` when there
|
|
184
|
+
isn't enough data.
|
|
185
|
+
"""
|
|
186
|
+
if n_t <= 0 or n_c <= 0:
|
|
187
|
+
return None, None
|
|
188
|
+
lift = p_t - p_c
|
|
189
|
+
var = (p_t * (1 - p_t)) / n_t + (p_c * (1 - p_c)) / n_c
|
|
190
|
+
ci_half = _Z_95 * math.sqrt(var)
|
|
191
|
+
ci_half = min(ci_half, _MAX_CI_HALF_WIDTH)
|
|
192
|
+
return lift, ci_half
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Pure functions deriving the /evaluations hero block state and delta.
|
|
2
|
+
|
|
3
|
+
These have no IO; they're invoked from EvaluationOverviewService with already-
|
|
4
|
+
loaded aggregate numbers. Separated so the spec's 4-state machine can be
|
|
5
|
+
unit-tested cheaply.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from enum import StrEnum
|
|
11
|
+
|
|
12
|
+
_FULL_MIN_DAYS = 14
|
|
13
|
+
_FULL_MIN_SHADOW_N = 500
|
|
14
|
+
_SHADOW_OFF_MIN_DAYS = 7
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class HeroState(StrEnum):
|
|
18
|
+
"""The four mutually exclusive hero block configurations from spec §3.2.
|
|
19
|
+
|
|
20
|
+
Members serialize to the snake_case strings the frontend switches on.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
FULL = "full"
|
|
24
|
+
EARLY = "early"
|
|
25
|
+
SHADOW_OFF = "shadow_off"
|
|
26
|
+
EMPTY = "empty"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def compute_hero_state(
|
|
30
|
+
*,
|
|
31
|
+
shadow_enabled: bool,
|
|
32
|
+
days_since_first_eval: int | None,
|
|
33
|
+
n_shadow_in_window: int,
|
|
34
|
+
total_results: int,
|
|
35
|
+
) -> HeroState:
|
|
36
|
+
"""Return the hero state for the current org and time window.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
shadow_enabled (bool): Value of `Config.shadow_mode_enabled`.
|
|
40
|
+
days_since_first_eval (int | None): Wall-clock days since the first
|
|
41
|
+
ever evaluated session for this org. None when no results exist.
|
|
42
|
+
n_shadow_in_window (int): Count of evaluation results that have a
|
|
43
|
+
shadow grade inside the trend window. Caller is responsible for
|
|
44
|
+
filtering; this function only consumes the count.
|
|
45
|
+
Why graded-only: prevents the FULL gate from tripping mid-window-
|
|
46
|
+
flag-flip when sessions exist with shadow_content but no shadow
|
|
47
|
+
grade. (Note: the direct-grade `shadow_is_success` /
|
|
48
|
+
`shadow_is_escalated` columns added briefly in May 2026 were
|
|
49
|
+
retracted before any production deploy — see the deleted
|
|
50
|
+
migration pair in supabase/data/supabase/migrations/. The
|
|
51
|
+
per-turn shadow grade in F1 lives on a different surface.)
|
|
52
|
+
total_results (int): Total AgentSuccessEvaluationResult rows in the
|
|
53
|
+
trend window (used only to differentiate EMPTY from SHADOW_OFF).
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
HeroState: The single applicable state. Empty wins over everything;
|
|
57
|
+
after that the order is shadow_off → early → full per spec.
|
|
58
|
+
"""
|
|
59
|
+
if total_results == 0:
|
|
60
|
+
return HeroState.EMPTY
|
|
61
|
+
if not shadow_enabled:
|
|
62
|
+
if (
|
|
63
|
+
days_since_first_eval is not None
|
|
64
|
+
and days_since_first_eval >= _SHADOW_OFF_MIN_DAYS
|
|
65
|
+
):
|
|
66
|
+
return HeroState.SHADOW_OFF
|
|
67
|
+
# <7 days since first eval AND shadow off → still onboarding;
|
|
68
|
+
# render as EMPTY so the frontend shows onboarding rather than a
|
|
69
|
+
# partly-formed trend.
|
|
70
|
+
return HeroState.EMPTY
|
|
71
|
+
if days_since_first_eval is None or days_since_first_eval < _FULL_MIN_DAYS:
|
|
72
|
+
return HeroState.EARLY
|
|
73
|
+
if n_shadow_in_window < _FULL_MIN_SHADOW_N:
|
|
74
|
+
return HeroState.EARLY
|
|
75
|
+
return HeroState.FULL
|
package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/rule_attribution.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Join PlaybookApplicationStat citations with session success outcomes.
|
|
2
|
+
|
|
3
|
+
Replaces the spec's proposed `rule_application` table with a join against
|
|
4
|
+
the existing `Interaction.citations` data, computing "net sessions" per
|
|
5
|
+
rule = successes_with_rule_fired - failures_with_rule_fired.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from collections.abc import Mapping
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
|
|
13
|
+
CitationKey = tuple[str, str] # (kind, real_id) — matches PlaybookApplicationStat
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class RuleAttribution:
|
|
18
|
+
"""One row of the "rules that moved the needle" panel."""
|
|
19
|
+
|
|
20
|
+
rule_id: str
|
|
21
|
+
kind: str
|
|
22
|
+
title: str
|
|
23
|
+
successes_with: int
|
|
24
|
+
failures_with: int
|
|
25
|
+
cited_session_ids: tuple[str, ...] = ()
|
|
26
|
+
"""Session IDs (within the trend window) that cited this rule. Tuple so
|
|
27
|
+
the dataclass stays hashable / frozen. The frontend uses this to filter
|
|
28
|
+
the /evaluations detail band to show only sessions where the rule
|
|
29
|
+
actually fired — answering 'which sessions did this rule help/hurt?'
|
|
30
|
+
without a second roundtrip."""
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def net_sessions(self) -> int:
|
|
34
|
+
return self.successes_with - self.failures_with
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def compute_net_sessions(
|
|
38
|
+
*,
|
|
39
|
+
citations_by_session: Mapping[str, list[CitationKey]],
|
|
40
|
+
is_success_by_session: Mapping[str, bool],
|
|
41
|
+
rule_titles: Mapping[CitationKey, str],
|
|
42
|
+
top_n: int,
|
|
43
|
+
) -> list[RuleAttribution]:
|
|
44
|
+
"""Aggregate net sessions per rule and return the top N by net_sessions.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
citations_by_session (Mapping[str, list[CitationKey]]): For each
|
|
48
|
+
session in the window, the list of `(kind, real_id)` citations
|
|
49
|
+
harvested from its interactions.
|
|
50
|
+
is_success_by_session (Mapping[str, bool]): The session's evaluated
|
|
51
|
+
outcome. Sessions not in this map are skipped on both sides.
|
|
52
|
+
rule_titles (Mapping[CitationKey, str]): Pre-loaded display titles
|
|
53
|
+
for each rule (empty string when the underlying row is gone).
|
|
54
|
+
top_n (int): How many rows to return at most. Ordering: net_sessions
|
|
55
|
+
desc, then total fires desc.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
list[RuleAttribution]: At most `top_n` rows in the order described.
|
|
59
|
+
Each row carries the session ids that cited the rule so the
|
|
60
|
+
frontend can drill from a rule into the sessions it fired in.
|
|
61
|
+
"""
|
|
62
|
+
successes: dict[CitationKey, int] = {}
|
|
63
|
+
failures: dict[CitationKey, int] = {}
|
|
64
|
+
# Map (kind, real_id) -> ordered list of session_ids that cited this rule.
|
|
65
|
+
# Ordering preserves caller-provided iteration order; the frontend sorts
|
|
66
|
+
# the detail band by created_at when displaying.
|
|
67
|
+
sessions_by_rule: dict[CitationKey, list[str]] = {}
|
|
68
|
+
for session_id, citations in citations_by_session.items():
|
|
69
|
+
outcome = is_success_by_session.get(session_id)
|
|
70
|
+
if outcome is None:
|
|
71
|
+
continue
|
|
72
|
+
# A rule cited multiple times in the same session counts once.
|
|
73
|
+
unique_cites = set(citations)
|
|
74
|
+
for key in unique_cites:
|
|
75
|
+
if outcome:
|
|
76
|
+
successes[key] = successes.get(key, 0) + 1
|
|
77
|
+
else:
|
|
78
|
+
failures[key] = failures.get(key, 0) + 1
|
|
79
|
+
sessions_by_rule.setdefault(key, []).append(session_id)
|
|
80
|
+
|
|
81
|
+
all_keys = set(successes) | set(failures)
|
|
82
|
+
rows = [
|
|
83
|
+
RuleAttribution(
|
|
84
|
+
rule_id=real_id,
|
|
85
|
+
kind=kind,
|
|
86
|
+
title=rule_titles.get((kind, real_id), ""),
|
|
87
|
+
successes_with=successes.get((kind, real_id), 0),
|
|
88
|
+
failures_with=failures.get((kind, real_id), 0),
|
|
89
|
+
cited_session_ids=tuple(sessions_by_rule.get((kind, real_id), [])),
|
|
90
|
+
)
|
|
91
|
+
for (kind, real_id) in all_keys
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
rows.sort(
|
|
95
|
+
key=lambda r: (-r.net_sessions, -(r.successes_with + r.failures_with)),
|
|
96
|
+
)
|
|
97
|
+
return rows[:top_n]
|