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
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import time
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from reflexio.models.api_schema.internal_schema import RequestInteractionDataModel
|
|
6
|
+
from reflexio.models.config_schema import AgentSuccessConfig
|
|
7
|
+
from reflexio.server.api_endpoints.request_context import RequestContext
|
|
8
|
+
from reflexio.server.llm.litellm_client import LiteLLMClient
|
|
9
|
+
from reflexio.server.services.agent_success_evaluation import _eval_health
|
|
10
|
+
from reflexio.server.services.agent_success_evaluation.agent_success_evaluation_utils import (
|
|
11
|
+
AgentSuccessEvaluationRequest,
|
|
12
|
+
)
|
|
13
|
+
from reflexio.server.services.agent_success_evaluation.agent_success_evaluator import (
|
|
14
|
+
AgentSuccessEvaluator,
|
|
15
|
+
)
|
|
16
|
+
from reflexio.server.services.base_generation_service import BaseGenerationService
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class AgentSuccessGenerationServiceConfig:
|
|
23
|
+
"""Runtime configuration for agent success evaluation service shared across all extractors.
|
|
24
|
+
|
|
25
|
+
Attributes:
|
|
26
|
+
session_id: The session being evaluated
|
|
27
|
+
agent_version: The agent version
|
|
28
|
+
request_interaction_data_models: The interactions to evaluate
|
|
29
|
+
source: Source of the interactions
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
session_id: str
|
|
33
|
+
agent_version: str
|
|
34
|
+
request_interaction_data_models: list[RequestInteractionDataModel]
|
|
35
|
+
source: str | None = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class AgentSuccessEvaluationService(
|
|
39
|
+
BaseGenerationService[
|
|
40
|
+
AgentSuccessConfig,
|
|
41
|
+
AgentSuccessEvaluator,
|
|
42
|
+
AgentSuccessGenerationServiceConfig,
|
|
43
|
+
AgentSuccessEvaluationRequest,
|
|
44
|
+
]
|
|
45
|
+
):
|
|
46
|
+
"""
|
|
47
|
+
Service for evaluating agent success with the configured evaluator.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self, llm_client: LiteLLMClient, request_context: RequestContext
|
|
52
|
+
) -> None:
|
|
53
|
+
"""Initialize service and reset per-run outcome flags."""
|
|
54
|
+
super().__init__(llm_client=llm_client, request_context=request_context)
|
|
55
|
+
self.last_run_result_count = 0
|
|
56
|
+
self.last_run_saved_result_count = 0
|
|
57
|
+
self.last_run_save_failed = False
|
|
58
|
+
|
|
59
|
+
def run(self, request: AgentSuccessEvaluationRequest) -> None:
|
|
60
|
+
"""Run evaluation and reset run outcome flags for this invocation."""
|
|
61
|
+
self.last_run_result_count = 0
|
|
62
|
+
self.last_run_saved_result_count = 0
|
|
63
|
+
self.last_run_save_failed = False
|
|
64
|
+
super().run(request)
|
|
65
|
+
|
|
66
|
+
def _load_generation_service_config(
|
|
67
|
+
self, request: AgentSuccessEvaluationRequest
|
|
68
|
+
) -> AgentSuccessGenerationServiceConfig:
|
|
69
|
+
"""
|
|
70
|
+
Extract request parameters from AgentSuccessEvaluationRequest.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
request: AgentSuccessEvaluationRequest containing evaluation parameters
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
AgentSuccessGenerationServiceConfig object
|
|
77
|
+
"""
|
|
78
|
+
return AgentSuccessGenerationServiceConfig(
|
|
79
|
+
session_id=request.session_id,
|
|
80
|
+
agent_version=request.agent_version,
|
|
81
|
+
request_interaction_data_models=request.request_interaction_data_models,
|
|
82
|
+
source=request.source,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def _load_extractor_config(self) -> AgentSuccessConfig | None:
|
|
86
|
+
"""
|
|
87
|
+
Load agent success config from configurator.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
AgentSuccessConfig | None: Configured evaluator, or None when disabled.
|
|
91
|
+
"""
|
|
92
|
+
root_config = self.configurator.get_config()
|
|
93
|
+
return getattr(root_config, "agent_success_config", None)
|
|
94
|
+
|
|
95
|
+
def _create_extractor(
|
|
96
|
+
self,
|
|
97
|
+
extractor_config: AgentSuccessConfig,
|
|
98
|
+
service_config: AgentSuccessGenerationServiceConfig,
|
|
99
|
+
) -> AgentSuccessEvaluator:
|
|
100
|
+
"""
|
|
101
|
+
Create an AgentSuccessEvaluator instance from configuration.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
extractor_config: AgentSuccessConfig configuration object from YAML
|
|
105
|
+
service_config: AgentSuccessGenerationServiceConfig containing runtime parameters
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
AgentSuccessEvaluator instance
|
|
109
|
+
"""
|
|
110
|
+
return AgentSuccessEvaluator(
|
|
111
|
+
request_context=self.request_context,
|
|
112
|
+
llm_client=self.client,
|
|
113
|
+
extractor_config=extractor_config,
|
|
114
|
+
service_config=service_config,
|
|
115
|
+
agent_context=self.configurator.get_agent_context(),
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
def _process_results(self, results: list) -> None:
|
|
119
|
+
"""
|
|
120
|
+
Process and save agent success evaluation results.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
results: List of AgentSuccessEvaluationResult results from extractors
|
|
124
|
+
"""
|
|
125
|
+
# Flatten results (each extractor returns list[AgentSuccessEvaluationResult])
|
|
126
|
+
all_results = []
|
|
127
|
+
for result in results:
|
|
128
|
+
if isinstance(result, list):
|
|
129
|
+
all_results.extend(result)
|
|
130
|
+
self.last_run_result_count = len(all_results)
|
|
131
|
+
|
|
132
|
+
logger.info(
|
|
133
|
+
"Successfully completed %d %s evaluations for session: %s",
|
|
134
|
+
len(all_results),
|
|
135
|
+
self._get_service_name(),
|
|
136
|
+
self.service_config.session_id, # type: ignore[reportOptionalMemberAccess]
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# Save results with retry+backoff. After the final attempt the producer
|
|
140
|
+
# failure is recorded into EvalHealth so the operator-facing healthcheck
|
|
141
|
+
# surfaces persistent storage problems.
|
|
142
|
+
if all_results:
|
|
143
|
+
backoffs = [1, 4]
|
|
144
|
+
attempt = 0
|
|
145
|
+
saved = False
|
|
146
|
+
while True:
|
|
147
|
+
attempt += 1
|
|
148
|
+
try:
|
|
149
|
+
self.storage.save_agent_success_evaluation_results(all_results) # type: ignore[reportOptionalMemberAccess]
|
|
150
|
+
self.last_run_saved_result_count = len(all_results)
|
|
151
|
+
logger.info(
|
|
152
|
+
"Saved %d agent success evaluation results for session: %s (attempt %d)",
|
|
153
|
+
len(all_results),
|
|
154
|
+
self.service_config.session_id, # type: ignore[reportOptionalMemberAccess]
|
|
155
|
+
attempt,
|
|
156
|
+
)
|
|
157
|
+
saved = True
|
|
158
|
+
break
|
|
159
|
+
except Exception as e:
|
|
160
|
+
logger.warning(
|
|
161
|
+
"Save attempt %d/%d failed for session %s: %s",
|
|
162
|
+
attempt,
|
|
163
|
+
len(backoffs) + 1,
|
|
164
|
+
self.service_config.session_id, # type: ignore[reportOptionalMemberAccess]
|
|
165
|
+
e,
|
|
166
|
+
)
|
|
167
|
+
if attempt > len(backoffs):
|
|
168
|
+
break
|
|
169
|
+
time.sleep(backoffs[attempt - 1])
|
|
170
|
+
|
|
171
|
+
if not saved:
|
|
172
|
+
self.last_run_save_failed = True
|
|
173
|
+
_eval_health.record_producer_failure()
|
|
174
|
+
logger.error(
|
|
175
|
+
"Failed to save %s results for session %s after %d attempts",
|
|
176
|
+
self._get_service_name(),
|
|
177
|
+
self.service_config.session_id, # type: ignore[reportOptionalMemberAccess]
|
|
178
|
+
attempt,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
def has_run_failures(self) -> bool:
|
|
182
|
+
"""Return True if extractor execution or result persistence failed."""
|
|
183
|
+
extractor_failed_count = self._last_extractor_run_stats.get("failed", 0)
|
|
184
|
+
return extractor_failed_count > 0 or self.last_run_save_failed
|
|
185
|
+
|
|
186
|
+
def _get_service_name(self) -> str:
|
|
187
|
+
"""
|
|
188
|
+
Get the name of the service for logging.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Service name string
|
|
192
|
+
"""
|
|
193
|
+
return "agent_success_evaluation"
|
|
194
|
+
|
|
195
|
+
def _get_base_service_name(self) -> str:
|
|
196
|
+
"""
|
|
197
|
+
Get the base service name for OperationStateManager keys.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
str: "agent_success_evaluation"
|
|
201
|
+
"""
|
|
202
|
+
return "agent_success_evaluation"
|
|
203
|
+
|
|
204
|
+
def _should_track_in_progress(self) -> bool:
|
|
205
|
+
"""
|
|
206
|
+
Agent success evaluation does NOT track in-progress state.
|
|
207
|
+
|
|
208
|
+
Agent success evaluation is tied to specific requests and doesn't have
|
|
209
|
+
the sliding window duplication issue that profile/feedback have.
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
bool: False - agent success evaluation does not track in-progress state
|
|
213
|
+
"""
|
|
214
|
+
return False
|
|
215
|
+
|
|
216
|
+
def _get_lock_scope_id(self, request: AgentSuccessEvaluationRequest) -> str | None:
|
|
217
|
+
"""
|
|
218
|
+
Not used since _should_track_in_progress returns False.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
request: The AgentSuccessEvaluationRequest
|
|
222
|
+
|
|
223
|
+
Raises:
|
|
224
|
+
NotImplementedError: This method is not used for this service
|
|
225
|
+
"""
|
|
226
|
+
raise NotImplementedError(
|
|
227
|
+
"AgentSuccessEvaluationService does not track in-progress state"
|
|
228
|
+
)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Utility functions for agent success evaluation service"""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
from reflexio.models.api_schema.internal_schema import RequestInteractionDataModel
|
|
6
|
+
from reflexio.server.prompt.prompt_manager import PromptManager
|
|
7
|
+
from reflexio.server.services.agent_success_evaluation.agent_success_evaluation_constants import (
|
|
8
|
+
AgentSuccessEvaluationConstants,
|
|
9
|
+
)
|
|
10
|
+
from reflexio.server.services.service_utils import (
|
|
11
|
+
MessageConstructionConfig,
|
|
12
|
+
PromptConfig,
|
|
13
|
+
construct_messages_from_interactions,
|
|
14
|
+
extract_interactions_from_request_interaction_data_models,
|
|
15
|
+
format_sessions_to_history_string,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AgentSuccessEvaluationRequest(BaseModel):
|
|
20
|
+
"""Request schema for agent success evaluation"""
|
|
21
|
+
|
|
22
|
+
session_id: str
|
|
23
|
+
agent_version: str
|
|
24
|
+
request_interaction_data_models: list[RequestInteractionDataModel]
|
|
25
|
+
source: str | None = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def construct_agent_success_evaluation_messages_from_sessions(
|
|
29
|
+
prompt_manager: PromptManager,
|
|
30
|
+
request_interaction_data_models: list[RequestInteractionDataModel],
|
|
31
|
+
agent_context_prompt: str,
|
|
32
|
+
success_definition_prompt: str,
|
|
33
|
+
tool_can_use: str,
|
|
34
|
+
metadata_definition_prompt: str | None = None,
|
|
35
|
+
) -> list[dict]:
|
|
36
|
+
"""
|
|
37
|
+
Construct LLM messages for agent success evaluation from request interaction groups.
|
|
38
|
+
|
|
39
|
+
This function uses the shared message construction interface to build messages
|
|
40
|
+
with a final user prompt specific to agent success evaluation.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
prompt_manager: The prompt manager for rendering prompt templates
|
|
44
|
+
request_interaction_data_models: List of request interaction groups to evaluate
|
|
45
|
+
agent_context_prompt: Context about the agent
|
|
46
|
+
success_definition_prompt: Definition of what constitutes agent success
|
|
47
|
+
tool_can_use: Description of tools available to the agent
|
|
48
|
+
metadata_definition_prompt: Optional additional metadata definition
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
list[dict]: List of messages ready for agent success evaluation
|
|
52
|
+
"""
|
|
53
|
+
# Configure final user message (after interactions)
|
|
54
|
+
# Note: This evaluation doesn't use a system message, just interactions followed by evaluation prompt
|
|
55
|
+
user_config = PromptConfig(
|
|
56
|
+
prompt_id=AgentSuccessEvaluationConstants.AGENT_SUCCESS_EVALUATION_PROMPT_ID,
|
|
57
|
+
variables={
|
|
58
|
+
"agent_context_prompt": agent_context_prompt,
|
|
59
|
+
"success_definition_prompt": success_definition_prompt,
|
|
60
|
+
"tool_can_use": tool_can_use,
|
|
61
|
+
"metadata_definition_prompt": metadata_definition_prompt or "",
|
|
62
|
+
"interactions": format_sessions_to_history_string(
|
|
63
|
+
request_interaction_data_models
|
|
64
|
+
),
|
|
65
|
+
},
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
# Extract flat interactions for image attachment
|
|
69
|
+
interactions = extract_interactions_from_request_interaction_data_models(
|
|
70
|
+
request_interaction_data_models
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Use shared message construction (no system prompt for this use case)
|
|
74
|
+
config = MessageConstructionConfig(
|
|
75
|
+
prompt_manager=prompt_manager,
|
|
76
|
+
system_prompt_config=None, # No system message needed
|
|
77
|
+
user_prompt_config=user_config,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return construct_messages_from_interactions(interactions, config)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# F1 cleanup: ``has_shadow_content``, ``format_interactions_for_request``, and
|
|
84
|
+
# ``construct_agent_success_evaluation_with_comparison_messages`` were retracted
|
|
85
|
+
# along with the session-level shadow comparison branch. Per-turn shadow
|
|
86
|
+
# comparison reads ``Interaction.shadow_content`` directly inside the dedicated
|
|
87
|
+
# ``services/shadow_comparison/`` judge.
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import random
|
|
5
|
+
from datetime import UTC, datetime
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
# Roles considered as agent/system-side (not user turns) when counting user turns.
|
|
9
|
+
_AGENT_ROLES = {"agent", "assistant", "system", "tool", "internal"}
|
|
10
|
+
|
|
11
|
+
from reflexio.models.api_schema.internal_schema import RequestInteractionDataModel
|
|
12
|
+
from reflexio.models.api_schema.service_schemas import (
|
|
13
|
+
AgentSuccessEvaluationResult,
|
|
14
|
+
)
|
|
15
|
+
from reflexio.models.config_schema import AgentSuccessConfig
|
|
16
|
+
from reflexio.server.api_endpoints.request_context import RequestContext
|
|
17
|
+
from reflexio.server.llm.litellm_client import LiteLLMClient
|
|
18
|
+
from reflexio.server.llm.model_defaults import ModelRole, resolve_model_name
|
|
19
|
+
from reflexio.server.services.agent_success_evaluation.agent_success_evaluation_constants import (
|
|
20
|
+
AgentSuccessEvaluationOutput,
|
|
21
|
+
)
|
|
22
|
+
from reflexio.server.services.agent_success_evaluation.agent_success_evaluation_utils import (
|
|
23
|
+
construct_agent_success_evaluation_messages_from_sessions,
|
|
24
|
+
)
|
|
25
|
+
from reflexio.server.services.extractor_config_utils import get_extractor_name
|
|
26
|
+
from reflexio.server.services.extractor_interaction_utils import (
|
|
27
|
+
filter_interactions_by_source,
|
|
28
|
+
get_effective_source_filter,
|
|
29
|
+
)
|
|
30
|
+
from reflexio.server.services.service_utils import (
|
|
31
|
+
log_llm_messages,
|
|
32
|
+
log_model_response,
|
|
33
|
+
)
|
|
34
|
+
from reflexio.server.site_var.site_var_manager import SiteVarManager
|
|
35
|
+
|
|
36
|
+
if TYPE_CHECKING:
|
|
37
|
+
from reflexio.server.services.agent_success_evaluation.agent_success_evaluation_service import (
|
|
38
|
+
AgentSuccessGenerationServiceConfig,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
logger = logging.getLogger(__name__)
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
Extract playbooks from user interactions for developers to improve the agent on next iteration.
|
|
45
|
+
Identify missing features, tools, etc.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class AgentSuccessEvaluator:
|
|
50
|
+
"""
|
|
51
|
+
Evaluate agent success based on user interactions.
|
|
52
|
+
|
|
53
|
+
This class analyzes agent-user interactions to determine if the agent
|
|
54
|
+
successfully completed its task and identifies areas for improvement.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def __init__(
|
|
58
|
+
self,
|
|
59
|
+
request_context: RequestContext,
|
|
60
|
+
llm_client: LiteLLMClient,
|
|
61
|
+
extractor_config: AgentSuccessConfig,
|
|
62
|
+
service_config: AgentSuccessGenerationServiceConfig,
|
|
63
|
+
agent_context: str,
|
|
64
|
+
):
|
|
65
|
+
"""
|
|
66
|
+
Initialize the agent success evaluator.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
request_context: Request context with storage and prompt manager
|
|
70
|
+
llm_client: Unified LLM client supporting both OpenAI and Claude
|
|
71
|
+
extractor_config: Agent success evaluation configuration from YAML
|
|
72
|
+
service_config: Runtime service configuration with request data
|
|
73
|
+
agent_context: Context about the agent
|
|
74
|
+
"""
|
|
75
|
+
self.request_context: RequestContext = request_context
|
|
76
|
+
self.client: LiteLLMClient = llm_client
|
|
77
|
+
self.config: AgentSuccessConfig = extractor_config
|
|
78
|
+
self.service_config: AgentSuccessGenerationServiceConfig = service_config
|
|
79
|
+
self.agent_context: str = agent_context
|
|
80
|
+
|
|
81
|
+
# Get LLM config overrides from configuration
|
|
82
|
+
config = self.request_context.configurator.get_config()
|
|
83
|
+
llm_config = config.llm_config if config else None
|
|
84
|
+
|
|
85
|
+
# Resolve model name: config override → site var → auto-detect
|
|
86
|
+
model_setting = SiteVarManager().get_site_var("llm_model_setting")
|
|
87
|
+
site_var = model_setting if isinstance(model_setting, dict) else {}
|
|
88
|
+
api_key_config = self.request_context.configurator.get_config().api_key_config
|
|
89
|
+
|
|
90
|
+
self.default_evaluate_model_name = resolve_model_name(
|
|
91
|
+
ModelRole.EVALUATION,
|
|
92
|
+
site_var_value=site_var.get("default_evaluate_model_name"),
|
|
93
|
+
config_override=llm_config.generation_model_name if llm_config else None,
|
|
94
|
+
api_key_config=api_key_config,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# ===============================
|
|
98
|
+
# public methods
|
|
99
|
+
# ===============================
|
|
100
|
+
|
|
101
|
+
def run(self) -> list[AgentSuccessEvaluationResult]:
|
|
102
|
+
"""
|
|
103
|
+
Evaluate agent success at the session level.
|
|
104
|
+
|
|
105
|
+
Treats all request_interaction_data_models as a single conversation.
|
|
106
|
+
Applies source filtering based on extractor config.
|
|
107
|
+
Applies sampling rate once per group.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
List of AgentSuccessEvaluationResult objects (single result for the group)
|
|
111
|
+
"""
|
|
112
|
+
# Get interactions from service config (required)
|
|
113
|
+
request_interaction_data_models = (
|
|
114
|
+
self.service_config.request_interaction_data_models
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Filter by source based on extractor config
|
|
118
|
+
should_skip, source_filter = get_effective_source_filter(
|
|
119
|
+
self.config,
|
|
120
|
+
self.service_config.source,
|
|
121
|
+
)
|
|
122
|
+
if should_skip:
|
|
123
|
+
return []
|
|
124
|
+
|
|
125
|
+
request_interaction_data_models = filter_interactions_by_source(
|
|
126
|
+
request_interaction_data_models,
|
|
127
|
+
source_filter,
|
|
128
|
+
)
|
|
129
|
+
if not request_interaction_data_models:
|
|
130
|
+
# No matching interactions after source filter
|
|
131
|
+
return []
|
|
132
|
+
|
|
133
|
+
# Check sampling rate once per group
|
|
134
|
+
if self.config.sampling_rate < 1.0:
|
|
135
|
+
random_value = random.random() # noqa: S311
|
|
136
|
+
if random_value >= self.config.sampling_rate:
|
|
137
|
+
logger.info(
|
|
138
|
+
"Skipping evaluation for session %s due to sampling rate. "
|
|
139
|
+
"sampling_rate=%s, random_value=%.3f",
|
|
140
|
+
self.service_config.session_id,
|
|
141
|
+
self.config.sampling_rate,
|
|
142
|
+
random_value,
|
|
143
|
+
)
|
|
144
|
+
return []
|
|
145
|
+
|
|
146
|
+
result = self._evaluate_group(request_interaction_data_models)
|
|
147
|
+
return [result] if result else []
|
|
148
|
+
|
|
149
|
+
def _evaluate_group(
|
|
150
|
+
self, request_interaction_data_models: list[RequestInteractionDataModel]
|
|
151
|
+
) -> AgentSuccessEvaluationResult | None:
|
|
152
|
+
"""
|
|
153
|
+
Evaluate agent success for the entire session.
|
|
154
|
+
|
|
155
|
+
F1 cleanup: session-level shadow comparison was retracted because
|
|
156
|
+
multi-turn shadow content suffers from trajectory contamination
|
|
157
|
+
(turn 2+ user messages react to the regular response, not the
|
|
158
|
+
shadow). Per-turn shadow comparison lives in
|
|
159
|
+
services/shadow_comparison/ — see the F1 spec. The legacy
|
|
160
|
+
combined-prompt branch is gone; this method now always runs the
|
|
161
|
+
standalone is_success evaluation.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
request_interaction_data_models: All request interaction data models in the group
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Optional[AgentSuccessEvaluationResult]: Evaluation result or None if evaluation fails
|
|
168
|
+
"""
|
|
169
|
+
# Read tool_can_use from root config
|
|
170
|
+
root_config = self.request_context.configurator.get_config()
|
|
171
|
+
tool_can_use_str = ""
|
|
172
|
+
if root_config and root_config.tool_can_use:
|
|
173
|
+
tool_can_use_str = "\n".join(
|
|
174
|
+
[
|
|
175
|
+
f"{tool.tool_name}: {tool.tool_description}"
|
|
176
|
+
for tool in root_config.tool_can_use
|
|
177
|
+
]
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
return self._evaluate_regular(
|
|
181
|
+
request_interaction_data_models,
|
|
182
|
+
tool_can_use_str,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
def _evaluate_regular(
|
|
186
|
+
self,
|
|
187
|
+
request_interaction_data_models: list[RequestInteractionDataModel],
|
|
188
|
+
tool_can_use_str: str,
|
|
189
|
+
) -> AgentSuccessEvaluationResult | None:
|
|
190
|
+
"""
|
|
191
|
+
Evaluate agent success for the group without shadow comparison.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
request_interaction_data_models: All request interaction data models in the group
|
|
195
|
+
tool_can_use_str: Formatted string of available tools
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Optional[AgentSuccessEvaluationResult]: Evaluation result or None if evaluation fails
|
|
199
|
+
"""
|
|
200
|
+
messages = construct_agent_success_evaluation_messages_from_sessions(
|
|
201
|
+
prompt_manager=self.request_context.prompt_manager,
|
|
202
|
+
request_interaction_data_models=request_interaction_data_models,
|
|
203
|
+
agent_context_prompt=self.agent_context,
|
|
204
|
+
success_definition_prompt=(
|
|
205
|
+
self.config.success_definition_prompt.strip()
|
|
206
|
+
if self.config.success_definition_prompt
|
|
207
|
+
else ""
|
|
208
|
+
),
|
|
209
|
+
tool_can_use=tool_can_use_str,
|
|
210
|
+
metadata_definition_prompt=(
|
|
211
|
+
self.config.metadata_definition_prompt.strip()
|
|
212
|
+
if self.config.metadata_definition_prompt
|
|
213
|
+
else None
|
|
214
|
+
),
|
|
215
|
+
)
|
|
216
|
+
messages_dict = messages
|
|
217
|
+
|
|
218
|
+
session_request_count = len(request_interaction_data_models)
|
|
219
|
+
interaction_count = sum(
|
|
220
|
+
len(rdm.interactions) for rdm in request_interaction_data_models
|
|
221
|
+
)
|
|
222
|
+
logger.info(
|
|
223
|
+
"event=agent_success_eval_llm_start session_id=%s evaluation_name=%s "
|
|
224
|
+
"requests=%d interactions=%d model=%s",
|
|
225
|
+
self.service_config.session_id,
|
|
226
|
+
get_extractor_name(self.config),
|
|
227
|
+
session_request_count,
|
|
228
|
+
interaction_count,
|
|
229
|
+
self.default_evaluate_model_name,
|
|
230
|
+
)
|
|
231
|
+
log_llm_messages(logger, "Agent success evaluation", messages_dict)
|
|
232
|
+
|
|
233
|
+
# Use Pydantic model for structured output
|
|
234
|
+
evaluation_response = self.client.generate_chat_response(
|
|
235
|
+
messages=messages_dict,
|
|
236
|
+
model=self.default_evaluate_model_name,
|
|
237
|
+
response_format=AgentSuccessEvaluationOutput,
|
|
238
|
+
)
|
|
239
|
+
if not evaluation_response:
|
|
240
|
+
logger.info(
|
|
241
|
+
"No evaluation can be generated for session %s",
|
|
242
|
+
self.service_config.session_id,
|
|
243
|
+
)
|
|
244
|
+
return None
|
|
245
|
+
|
|
246
|
+
log_model_response(
|
|
247
|
+
logger, "Agent success evaluation response", evaluation_response
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
if not isinstance(evaluation_response, AgentSuccessEvaluationOutput):
|
|
251
|
+
logger.warning(
|
|
252
|
+
"Unexpected response type from evaluation LLM: %s",
|
|
253
|
+
type(evaluation_response),
|
|
254
|
+
)
|
|
255
|
+
return None
|
|
256
|
+
|
|
257
|
+
return self._build_evaluation_result(
|
|
258
|
+
evaluation_response=evaluation_response,
|
|
259
|
+
request_interaction_data_models=request_interaction_data_models,
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
def _build_evaluation_result(
|
|
263
|
+
self,
|
|
264
|
+
evaluation_response: AgentSuccessEvaluationOutput,
|
|
265
|
+
request_interaction_data_models: list[RequestInteractionDataModel],
|
|
266
|
+
) -> AgentSuccessEvaluationResult:
|
|
267
|
+
"""
|
|
268
|
+
Build an AgentSuccessEvaluationResult from LLM evaluation response and session data.
|
|
269
|
+
|
|
270
|
+
F1 cleanup: ``regular_vs_shadow`` is always ``None`` on rows produced by
|
|
271
|
+
this evaluator. The column is preserved on the result row for historical
|
|
272
|
+
audit purposes, but per-turn shadow comparison now writes its verdicts
|
|
273
|
+
to a dedicated table — see ``services/shadow_comparison/``.
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
evaluation_response: The parsed LLM evaluation output
|
|
277
|
+
request_interaction_data_models: All request interaction data models in the session
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
AgentSuccessEvaluationResult: The constructed evaluation result
|
|
281
|
+
"""
|
|
282
|
+
# Anchor created_at on the *session's* original time, not on now().
|
|
283
|
+
# Without this, every regenerate writes new rows with created_at = now()
|
|
284
|
+
# which makes the trend chart bucketize by "when the eval ran" instead
|
|
285
|
+
# of "when the session happened" — collapsing all regenerated history
|
|
286
|
+
# into the current week and breaking the trend story.
|
|
287
|
+
session_created_at = self._earliest_request_created_at(
|
|
288
|
+
request_interaction_data_models
|
|
289
|
+
)
|
|
290
|
+
return AgentSuccessEvaluationResult(
|
|
291
|
+
session_id=self.service_config.session_id,
|
|
292
|
+
agent_version=self.service_config.agent_version,
|
|
293
|
+
evaluation_name=get_extractor_name(self.config),
|
|
294
|
+
is_success=evaluation_response.is_success,
|
|
295
|
+
failure_type=evaluation_response.failure_type or "",
|
|
296
|
+
failure_reason=evaluation_response.failure_reason or "",
|
|
297
|
+
regular_vs_shadow=None,
|
|
298
|
+
number_of_correction_per_session=self._get_correction_count(),
|
|
299
|
+
user_turns_to_resolution=(
|
|
300
|
+
self._count_user_turns(request_interaction_data_models)
|
|
301
|
+
if evaluation_response.is_success
|
|
302
|
+
else None
|
|
303
|
+
),
|
|
304
|
+
is_escalated=evaluation_response.is_escalated,
|
|
305
|
+
created_at=session_created_at,
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
@staticmethod
|
|
309
|
+
def _earliest_request_created_at(
|
|
310
|
+
request_interaction_data_models: list[RequestInteractionDataModel],
|
|
311
|
+
) -> int:
|
|
312
|
+
"""Return the earliest request.created_at across the session's requests.
|
|
313
|
+
|
|
314
|
+
Falls back to the current epoch time when no request carries a
|
|
315
|
+
non-zero timestamp — this is mostly defensive: a published session
|
|
316
|
+
without any request timestamps would also have nothing to bucketize
|
|
317
|
+
against.
|
|
318
|
+
"""
|
|
319
|
+
timestamps = [
|
|
320
|
+
rdm.request.created_at
|
|
321
|
+
for rdm in request_interaction_data_models
|
|
322
|
+
if rdm.request.created_at
|
|
323
|
+
]
|
|
324
|
+
if timestamps:
|
|
325
|
+
return min(timestamps)
|
|
326
|
+
return int(datetime.now(UTC).timestamp())
|
|
327
|
+
|
|
328
|
+
def _count_user_turns(
|
|
329
|
+
self,
|
|
330
|
+
request_interaction_data_models: list[RequestInteractionDataModel],
|
|
331
|
+
) -> int:
|
|
332
|
+
"""
|
|
333
|
+
Count user-side turns across all interactions in the session.
|
|
334
|
+
|
|
335
|
+
A user-side turn is any interaction whose role is NOT one of the agent/system roles.
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
request_interaction_data_models: All request interaction data models in the session
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
int: Number of user-side turns
|
|
342
|
+
"""
|
|
343
|
+
agent_roles = _AGENT_ROLES
|
|
344
|
+
count = 0
|
|
345
|
+
for rdm in request_interaction_data_models:
|
|
346
|
+
for interaction in rdm.interactions:
|
|
347
|
+
if interaction.role.lower() not in agent_roles:
|
|
348
|
+
count += 1
|
|
349
|
+
return count
|
|
350
|
+
|
|
351
|
+
def _get_correction_count(self) -> int:
|
|
352
|
+
"""
|
|
353
|
+
Count user playbooks linked to the current session.
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
int: Number of user playbooks for the session, defaulting to 0 on error.
|
|
357
|
+
"""
|
|
358
|
+
try:
|
|
359
|
+
count = self.request_context.storage.count_user_playbooks_by_session( # type: ignore[reportOptionalMemberAccess]
|
|
360
|
+
self.service_config.session_id
|
|
361
|
+
)
|
|
362
|
+
return count if count is not None else 0
|
|
363
|
+
except Exception:
|
|
364
|
+
logger.warning(
|
|
365
|
+
"Failed to count user playbooks for session %s, defaulting to 0",
|
|
366
|
+
self.service_config.session_id,
|
|
367
|
+
)
|
|
368
|
+
return 0
|
|
369
|
+
|
|
370
|
+
# F1 cleanup: ``_map_comparison_to_enum`` was retracted along with
|
|
371
|
+
# ``_evaluate_with_shadow_comparison``. Per-turn shadow comparison has its
|
|
372
|
+
# own mapping helpers in ``services/shadow_comparison/``.
|