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,176 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from reflexio.lib._base import (
|
|
4
|
+
STORAGE_NOT_CONFIGURED_MSG,
|
|
5
|
+
ReflexioBase,
|
|
6
|
+
_require_storage,
|
|
7
|
+
)
|
|
8
|
+
from reflexio.models.api_schema.service_schemas import (
|
|
9
|
+
ManualPlaybookGenerationRequest,
|
|
10
|
+
ManualPlaybookGenerationResponse,
|
|
11
|
+
ManualProfileGenerationRequest,
|
|
12
|
+
ManualProfileGenerationResponse,
|
|
13
|
+
RerunPlaybookGenerationRequest,
|
|
14
|
+
RerunPlaybookGenerationResponse,
|
|
15
|
+
RerunProfileGenerationRequest,
|
|
16
|
+
RerunProfileGenerationResponse,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class GenerationMixin(ReflexioBase):
|
|
21
|
+
def run_playbook_aggregation(
|
|
22
|
+
self,
|
|
23
|
+
agent_version: str,
|
|
24
|
+
playbook_name: str | None = None, # noqa: ARG002 — deprecated, accepted but ignored
|
|
25
|
+
) -> dict:
|
|
26
|
+
"""Run playbook aggregation for a given agent version.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
agent_version (str): The agent version
|
|
30
|
+
playbook_name (str | None): Deprecated compatibility input. Aggregation is
|
|
31
|
+
singleton (one playbook kind per org), so name-based selection is ignored.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
dict: Aggregation stats (clusters_found, user_playbooks_processed, playbooks_generated)
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
ValueError: If storage is not configured
|
|
38
|
+
"""
|
|
39
|
+
if not self._is_storage_configured():
|
|
40
|
+
raise ValueError(STORAGE_NOT_CONFIGURED_MSG)
|
|
41
|
+
from reflexio.server.services.playbook.playbook_aggregator import (
|
|
42
|
+
PlaybookAggregator,
|
|
43
|
+
)
|
|
44
|
+
from reflexio.server.services.playbook.playbook_service_utils import (
|
|
45
|
+
PlaybookAggregatorRequest,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
playbook_aggregator = PlaybookAggregator(
|
|
49
|
+
llm_client=self.llm_client,
|
|
50
|
+
request_context=self.request_context,
|
|
51
|
+
agent_version=agent_version,
|
|
52
|
+
)
|
|
53
|
+
aggregator_request = PlaybookAggregatorRequest(
|
|
54
|
+
agent_version=agent_version,
|
|
55
|
+
rerun=True,
|
|
56
|
+
)
|
|
57
|
+
return playbook_aggregator.run(aggregator_request)
|
|
58
|
+
|
|
59
|
+
def _run_generation_service(
|
|
60
|
+
self,
|
|
61
|
+
request: Any,
|
|
62
|
+
request_type: type,
|
|
63
|
+
service_cls: type,
|
|
64
|
+
output_pending: bool,
|
|
65
|
+
run_method: str,
|
|
66
|
+
) -> Any:
|
|
67
|
+
"""Shared logic for rerun and manual generation endpoints."""
|
|
68
|
+
if isinstance(request, dict):
|
|
69
|
+
request = request_type(**request)
|
|
70
|
+
service = service_cls(
|
|
71
|
+
llm_client=self.llm_client,
|
|
72
|
+
request_context=self.request_context,
|
|
73
|
+
allow_manual_trigger=True,
|
|
74
|
+
output_pending_status=output_pending,
|
|
75
|
+
)
|
|
76
|
+
return getattr(service, run_method)(request)
|
|
77
|
+
|
|
78
|
+
@_require_storage(RerunProfileGenerationResponse, msg_field="msg")
|
|
79
|
+
def rerun_profile_generation(
|
|
80
|
+
self,
|
|
81
|
+
request: RerunProfileGenerationRequest | dict,
|
|
82
|
+
) -> RerunProfileGenerationResponse:
|
|
83
|
+
"""Rerun profile generation for one or all users with filtered interactions.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
request (Union[RerunProfileGenerationRequest, dict]): The rerun request
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
RerunProfileGenerationResponse: Response containing success status, message, and count of profiles generated
|
|
90
|
+
"""
|
|
91
|
+
from reflexio.server.services.profile.profile_generation_service import (
|
|
92
|
+
ProfileGenerationService,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
return self._run_generation_service(
|
|
96
|
+
request,
|
|
97
|
+
RerunProfileGenerationRequest,
|
|
98
|
+
ProfileGenerationService,
|
|
99
|
+
output_pending=True,
|
|
100
|
+
run_method="run_rerun",
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
@_require_storage(ManualProfileGenerationResponse, msg_field="msg")
|
|
104
|
+
def manual_profile_generation(
|
|
105
|
+
self,
|
|
106
|
+
request: ManualProfileGenerationRequest | dict,
|
|
107
|
+
) -> ManualProfileGenerationResponse:
|
|
108
|
+
"""Manually trigger profile generation with window-sized interactions and CURRENT output.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
request (Union[ManualProfileGenerationRequest, dict]): The request
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
ManualProfileGenerationResponse: Response containing success status, message, and count of profiles generated
|
|
115
|
+
"""
|
|
116
|
+
from reflexio.server.services.profile.profile_generation_service import (
|
|
117
|
+
ProfileGenerationService,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
return self._run_generation_service(
|
|
121
|
+
request,
|
|
122
|
+
ManualProfileGenerationRequest,
|
|
123
|
+
ProfileGenerationService,
|
|
124
|
+
output_pending=False,
|
|
125
|
+
run_method="run_manual_regular",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
@_require_storage(RerunPlaybookGenerationResponse, msg_field="msg")
|
|
129
|
+
def rerun_playbook_generation(
|
|
130
|
+
self,
|
|
131
|
+
request: RerunPlaybookGenerationRequest | dict,
|
|
132
|
+
) -> RerunPlaybookGenerationResponse:
|
|
133
|
+
"""Rerun playbook generation with filtered interactions.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
request (Union[RerunPlaybookGenerationRequest, dict]): The rerun request
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
RerunPlaybookGenerationResponse: Response containing success status, message, and count of playbooks generated
|
|
140
|
+
"""
|
|
141
|
+
from reflexio.server.services.playbook.playbook_generation_service import (
|
|
142
|
+
PlaybookGenerationService,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
return self._run_generation_service(
|
|
146
|
+
request,
|
|
147
|
+
RerunPlaybookGenerationRequest,
|
|
148
|
+
PlaybookGenerationService,
|
|
149
|
+
output_pending=True,
|
|
150
|
+
run_method="run_rerun",
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
@_require_storage(ManualPlaybookGenerationResponse, msg_field="msg")
|
|
154
|
+
def manual_playbook_generation(
|
|
155
|
+
self,
|
|
156
|
+
request: ManualPlaybookGenerationRequest | dict,
|
|
157
|
+
) -> ManualPlaybookGenerationResponse:
|
|
158
|
+
"""Manually trigger playbook generation with window-sized interactions and CURRENT output.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
request (Union[ManualPlaybookGenerationRequest, dict]): The generation request
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
ManualPlaybookGenerationResponse: Response containing success status, message, and count of playbooks generated
|
|
165
|
+
"""
|
|
166
|
+
from reflexio.server.services.playbook.playbook_generation_service import (
|
|
167
|
+
PlaybookGenerationService,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
return self._run_generation_service(
|
|
171
|
+
request,
|
|
172
|
+
ManualPlaybookGenerationRequest,
|
|
173
|
+
PlaybookGenerationService,
|
|
174
|
+
output_pending=False,
|
|
175
|
+
run_method="run_manual_regular",
|
|
176
|
+
)
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
|
|
3
|
+
from reflexio.lib._base import (
|
|
4
|
+
STORAGE_NOT_CONFIGURED_MSG,
|
|
5
|
+
ReflexioBase,
|
|
6
|
+
_require_storage,
|
|
7
|
+
)
|
|
8
|
+
from reflexio.lib._storage_labels import describe_storage
|
|
9
|
+
from reflexio.models.api_schema.retriever_schema import (
|
|
10
|
+
GetInteractionsRequest,
|
|
11
|
+
GetInteractionsResponse,
|
|
12
|
+
SearchInteractionRequest,
|
|
13
|
+
SearchInteractionResponse,
|
|
14
|
+
)
|
|
15
|
+
from reflexio.models.api_schema.service_schemas import (
|
|
16
|
+
BulkDeleteResponse,
|
|
17
|
+
ClearUserDataRequest,
|
|
18
|
+
ClearUserDataResponse,
|
|
19
|
+
DeleteRequestRequest,
|
|
20
|
+
DeleteRequestResponse,
|
|
21
|
+
DeleteRequestsByIdsRequest,
|
|
22
|
+
DeleteSessionRequest,
|
|
23
|
+
DeleteSessionResponse,
|
|
24
|
+
DeleteUserInteractionRequest,
|
|
25
|
+
DeleteUserInteractionResponse,
|
|
26
|
+
PublishUserInteractionRequest,
|
|
27
|
+
PublishUserInteractionResponse,
|
|
28
|
+
)
|
|
29
|
+
from reflexio.server.services.generation_service import GenerationService
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _safe_count(counter: Callable[[], int]) -> int:
|
|
33
|
+
"""Return a storage count, or 0 on failure.
|
|
34
|
+
|
|
35
|
+
Used to snapshot profile/playbook counts around a publish so the CLI
|
|
36
|
+
can report deltas. Never raises — a storage hiccup during counting
|
|
37
|
+
shouldn't block the publish itself from returning a useful response.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
counter (Callable[[], int]): Zero-arg thunk returning an integer
|
|
41
|
+
count (e.g. ``storage.count_all_profiles``).
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
int: The count, or 0 if the thunk raised.
|
|
45
|
+
"""
|
|
46
|
+
try:
|
|
47
|
+
return counter()
|
|
48
|
+
except Exception: # noqa: BLE001
|
|
49
|
+
return 0
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class InteractionsMixin(ReflexioBase):
|
|
53
|
+
def publish_interaction(
|
|
54
|
+
self,
|
|
55
|
+
request: PublishUserInteractionRequest | dict,
|
|
56
|
+
) -> PublishUserInteractionResponse:
|
|
57
|
+
"""Publish user interactions.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
request (Union[PublishUserInteractionRequest, dict]): The publish user interaction request
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
PublishUserInteractionResponse: Response containing success status and message
|
|
64
|
+
"""
|
|
65
|
+
if not self._is_storage_configured():
|
|
66
|
+
return PublishUserInteractionResponse(
|
|
67
|
+
success=False, message=STORAGE_NOT_CONFIGURED_MSG
|
|
68
|
+
)
|
|
69
|
+
# Snapshot profile + playbook totals before the run so we can report
|
|
70
|
+
# how many rows the extraction actually produced. These are best-effort
|
|
71
|
+
# counts — we don't distinguish added vs. updated, only net deltas.
|
|
72
|
+
storage = self._get_storage()
|
|
73
|
+
before_profiles = _safe_count(storage.count_all_profiles)
|
|
74
|
+
before_playbooks = _safe_count(storage.count_user_playbooks)
|
|
75
|
+
|
|
76
|
+
generation_service = GenerationService(
|
|
77
|
+
llm_client=self.llm_client,
|
|
78
|
+
request_context=self.request_context,
|
|
79
|
+
)
|
|
80
|
+
# Describe the storage the server is actually writing to so the CLI
|
|
81
|
+
# can surface it. Computed once, up-front, so the response reflects
|
|
82
|
+
# the resolved config at the moment of the call.
|
|
83
|
+
storage_type, storage_label = describe_storage(
|
|
84
|
+
self.request_context.configurator.get_current_storage_configuration()
|
|
85
|
+
)
|
|
86
|
+
try:
|
|
87
|
+
# Convert dict to PublishUserInteractionRequest if needed
|
|
88
|
+
if isinstance(request, dict):
|
|
89
|
+
request = PublishUserInteractionRequest(**request)
|
|
90
|
+
result = generation_service.run(request)
|
|
91
|
+
after_profiles = _safe_count(storage.count_all_profiles)
|
|
92
|
+
after_playbooks = _safe_count(storage.count_user_playbooks)
|
|
93
|
+
# Don't concatenate warnings into the message field — they
|
|
94
|
+
# already travel through ``result.warnings`` and the CLI
|
|
95
|
+
# renders them separately. Embedding multi-line error
|
|
96
|
+
# strings (e.g. server-side Supabase stack traces) into
|
|
97
|
+
# ``message`` turns the CLI's one-line header into a
|
|
98
|
+
# terminal dump.
|
|
99
|
+
if result.warnings:
|
|
100
|
+
message = (
|
|
101
|
+
f"Interaction published successfully with "
|
|
102
|
+
f"{len(result.warnings)} warning(s)"
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
message = "Interaction published successfully"
|
|
106
|
+
return PublishUserInteractionResponse(
|
|
107
|
+
success=True,
|
|
108
|
+
message=message,
|
|
109
|
+
warnings=result.warnings,
|
|
110
|
+
request_id=result.request_id,
|
|
111
|
+
storage_type=storage_type,
|
|
112
|
+
storage_label=storage_label,
|
|
113
|
+
profiles_added=max(0, after_profiles - before_profiles),
|
|
114
|
+
playbooks_added=max(0, after_playbooks - before_playbooks),
|
|
115
|
+
)
|
|
116
|
+
except Exception as e:
|
|
117
|
+
return PublishUserInteractionResponse(success=False, message=str(e))
|
|
118
|
+
|
|
119
|
+
def search_interactions(
|
|
120
|
+
self,
|
|
121
|
+
request: SearchInteractionRequest | dict,
|
|
122
|
+
) -> SearchInteractionResponse:
|
|
123
|
+
"""Search for user interactions.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
request (SearchInteractionRequest): The search request
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
SearchInteractionResponse: Response containing matching interactions
|
|
130
|
+
"""
|
|
131
|
+
if not self._is_storage_configured():
|
|
132
|
+
return SearchInteractionResponse(
|
|
133
|
+
success=True, interactions=[], msg=STORAGE_NOT_CONFIGURED_MSG
|
|
134
|
+
)
|
|
135
|
+
if isinstance(request, dict):
|
|
136
|
+
request = SearchInteractionRequest(**request)
|
|
137
|
+
query_embedding = self._maybe_get_query_embedding(
|
|
138
|
+
request.query, request.search_mode
|
|
139
|
+
)
|
|
140
|
+
interactions = self._get_storage().search_interaction(
|
|
141
|
+
request, query_embedding=query_embedding
|
|
142
|
+
)
|
|
143
|
+
return SearchInteractionResponse(
|
|
144
|
+
success=True,
|
|
145
|
+
interactions=interactions,
|
|
146
|
+
msg=f"Found {len(interactions)} matching interaction(s)",
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
@_require_storage(DeleteUserInteractionResponse)
|
|
150
|
+
def delete_interaction(
|
|
151
|
+
self,
|
|
152
|
+
request: DeleteUserInteractionRequest | dict,
|
|
153
|
+
) -> DeleteUserInteractionResponse:
|
|
154
|
+
"""Delete user interactions.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
request (DeleteUserInteractionRequest): The delete request
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
DeleteUserInteractionResponse: Response containing success status and message
|
|
161
|
+
"""
|
|
162
|
+
if isinstance(request, dict):
|
|
163
|
+
request = DeleteUserInteractionRequest(**request)
|
|
164
|
+
self._get_storage().delete_user_interaction(request)
|
|
165
|
+
return DeleteUserInteractionResponse(
|
|
166
|
+
success=True, message="Deleted successfully"
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
@_require_storage(DeleteRequestResponse)
|
|
170
|
+
def delete_request(
|
|
171
|
+
self,
|
|
172
|
+
request: DeleteRequestRequest | dict,
|
|
173
|
+
) -> DeleteRequestResponse:
|
|
174
|
+
"""Delete a request and all its associated interactions.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
request (DeleteRequestRequest): The delete request containing request_id
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
DeleteRequestResponse: Response containing success status and message
|
|
181
|
+
"""
|
|
182
|
+
if isinstance(request, dict):
|
|
183
|
+
request = DeleteRequestRequest(**request)
|
|
184
|
+
self._get_storage().delete_request(request.request_id)
|
|
185
|
+
return DeleteRequestResponse(success=True, message="Deleted successfully")
|
|
186
|
+
|
|
187
|
+
@_require_storage(DeleteSessionResponse)
|
|
188
|
+
def delete_session(
|
|
189
|
+
self,
|
|
190
|
+
request: DeleteSessionRequest | dict,
|
|
191
|
+
) -> DeleteSessionResponse:
|
|
192
|
+
"""Delete all requests and interactions in a session.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
request (DeleteSessionRequest): The delete request containing session_id
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
DeleteSessionResponse: Response containing success status, message, and deleted count
|
|
199
|
+
"""
|
|
200
|
+
if isinstance(request, dict):
|
|
201
|
+
request = DeleteSessionRequest(**request)
|
|
202
|
+
deleted_count = self._get_storage().delete_session(request.session_id)
|
|
203
|
+
return DeleteSessionResponse(
|
|
204
|
+
success=True,
|
|
205
|
+
deleted_requests_count=deleted_count,
|
|
206
|
+
message=f"Deleted {deleted_count} item(s)",
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
@_require_storage(BulkDeleteResponse)
|
|
210
|
+
def delete_all_interactions_bulk(self) -> BulkDeleteResponse:
|
|
211
|
+
"""Delete all requests and their associated interactions.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
BulkDeleteResponse: Response containing success status and deleted count
|
|
215
|
+
"""
|
|
216
|
+
self._get_storage().delete_all_requests()
|
|
217
|
+
return BulkDeleteResponse(success=True, message="Deleted successfully")
|
|
218
|
+
|
|
219
|
+
@_require_storage(BulkDeleteResponse)
|
|
220
|
+
def delete_requests_by_ids(
|
|
221
|
+
self,
|
|
222
|
+
request: DeleteRequestsByIdsRequest | dict,
|
|
223
|
+
) -> BulkDeleteResponse:
|
|
224
|
+
"""Delete requests by their IDs.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
request (DeleteRequestsByIdsRequest): The delete request containing request_ids
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
BulkDeleteResponse: Response containing success status and deleted count
|
|
231
|
+
"""
|
|
232
|
+
if isinstance(request, dict):
|
|
233
|
+
request = DeleteRequestsByIdsRequest(**request)
|
|
234
|
+
deleted = self._get_storage().delete_requests_by_ids(request.request_ids)
|
|
235
|
+
return BulkDeleteResponse(
|
|
236
|
+
success=True, deleted_count=deleted, message=f"Deleted {deleted} item(s)"
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
@_require_storage(ClearUserDataResponse)
|
|
240
|
+
def clear_user_data(
|
|
241
|
+
self,
|
|
242
|
+
request: ClearUserDataRequest | dict,
|
|
243
|
+
) -> ClearUserDataResponse:
|
|
244
|
+
"""Delete all rows scoped to a single ``user_id``.
|
|
245
|
+
|
|
246
|
+
Wipes the user's interactions, user playbooks, profiles, and
|
|
247
|
+
requests. Intentionally does NOT touch ``agent_playbooks`` —
|
|
248
|
+
those are the cross-project rollup of skills and have no
|
|
249
|
+
``user_id`` column. Used by paired-protocol harnesses (e.g.
|
|
250
|
+
SWE-bench) to isolate per-task data on a shared backend without
|
|
251
|
+
nuking sibling tasks' rows.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
request (ClearUserDataRequest | dict): Request containing
|
|
255
|
+
the ``user_id`` whose data should be cleared.
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
ClearUserDataResponse: Per-entity deletion counts.
|
|
259
|
+
"""
|
|
260
|
+
if isinstance(request, dict):
|
|
261
|
+
request = ClearUserDataRequest(**request)
|
|
262
|
+
deleted_counts = self._get_storage().clear_user_data(request.user_id)
|
|
263
|
+
total = sum(deleted_counts.values())
|
|
264
|
+
return ClearUserDataResponse(
|
|
265
|
+
success=True,
|
|
266
|
+
deleted_counts=deleted_counts,
|
|
267
|
+
message=f"Cleared {total} row(s) for user {request.user_id!r}",
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
def get_interactions(
|
|
271
|
+
self,
|
|
272
|
+
request: GetInteractionsRequest | dict,
|
|
273
|
+
) -> GetInteractionsResponse:
|
|
274
|
+
"""Get user interactions.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
request (GetInteractionsRequest): The get request
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
GetInteractionsResponse: Response containing user interactions
|
|
281
|
+
"""
|
|
282
|
+
if not self._is_storage_configured():
|
|
283
|
+
return GetInteractionsResponse(
|
|
284
|
+
success=True, interactions=[], msg=STORAGE_NOT_CONFIGURED_MSG
|
|
285
|
+
)
|
|
286
|
+
if isinstance(request, dict):
|
|
287
|
+
request = GetInteractionsRequest(**request)
|
|
288
|
+
interactions = self._get_storage().get_user_interaction(request.user_id)
|
|
289
|
+
interactions = sorted(interactions, key=lambda x: x.created_at, reverse=True)
|
|
290
|
+
|
|
291
|
+
# Apply time filters
|
|
292
|
+
if request.start_time:
|
|
293
|
+
interactions = [
|
|
294
|
+
i
|
|
295
|
+
for i in interactions
|
|
296
|
+
if i.created_at >= int(request.start_time.timestamp())
|
|
297
|
+
]
|
|
298
|
+
if request.end_time:
|
|
299
|
+
interactions = [
|
|
300
|
+
i
|
|
301
|
+
for i in interactions
|
|
302
|
+
if i.created_at <= int(request.end_time.timestamp())
|
|
303
|
+
]
|
|
304
|
+
|
|
305
|
+
# Apply top_k limit
|
|
306
|
+
if request.top_k:
|
|
307
|
+
interactions = interactions[: request.top_k]
|
|
308
|
+
|
|
309
|
+
return GetInteractionsResponse(
|
|
310
|
+
success=True,
|
|
311
|
+
interactions=interactions,
|
|
312
|
+
msg=f"Found {len(interactions)} interaction(s)",
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
def get_all_interactions(self, limit: int = 100) -> GetInteractionsResponse:
|
|
316
|
+
"""Get all user interactions across all users.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
limit (int, optional): Maximum number of interactions to return. Defaults to 100.
|
|
320
|
+
|
|
321
|
+
Returns:
|
|
322
|
+
GetInteractionsResponse: Response containing all user interactions
|
|
323
|
+
"""
|
|
324
|
+
if not self._is_storage_configured():
|
|
325
|
+
return GetInteractionsResponse(
|
|
326
|
+
success=True, interactions=[], msg=STORAGE_NOT_CONFIGURED_MSG
|
|
327
|
+
)
|
|
328
|
+
interactions = self._get_storage().get_all_interactions(limit=limit)
|
|
329
|
+
interactions = sorted(interactions, key=lambda x: x.created_at, reverse=True)
|
|
330
|
+
return GetInteractionsResponse(
|
|
331
|
+
success=True,
|
|
332
|
+
interactions=interactions,
|
|
333
|
+
msg=f"Found {len(interactions)} interaction(s)",
|
|
334
|
+
)
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from reflexio.lib._base import STORAGE_NOT_CONFIGURED_MSG, ReflexioBase
|
|
4
|
+
from reflexio.models.api_schema.service_schemas import (
|
|
5
|
+
CancelOperationRequest,
|
|
6
|
+
CancelOperationResponse,
|
|
7
|
+
GetOperationStatusRequest,
|
|
8
|
+
GetOperationStatusResponse,
|
|
9
|
+
OperationStatus,
|
|
10
|
+
OperationStatusInfo,
|
|
11
|
+
)
|
|
12
|
+
from reflexio.server.services.operation_state_utils import OperationStateManager
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class OperationsMixin(ReflexioBase):
|
|
18
|
+
def get_operation_status(
|
|
19
|
+
self, request: GetOperationStatusRequest | dict
|
|
20
|
+
) -> GetOperationStatusResponse:
|
|
21
|
+
"""Get the status of an operation.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
request (Union[GetOperationStatusRequest, dict]): Request containing service_name
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
GetOperationStatusResponse: Response containing operation status info
|
|
28
|
+
"""
|
|
29
|
+
if not self._is_storage_configured():
|
|
30
|
+
return GetOperationStatusResponse(
|
|
31
|
+
success=True, operation_status=None, msg=STORAGE_NOT_CONFIGURED_MSG
|
|
32
|
+
)
|
|
33
|
+
try:
|
|
34
|
+
# Convert dict to request object if needed
|
|
35
|
+
if isinstance(request, dict):
|
|
36
|
+
request = GetOperationStatusRequest(**request)
|
|
37
|
+
|
|
38
|
+
# Build the progress key: {service_name}::{org_id}::progress
|
|
39
|
+
org_id = self.request_context.org_id
|
|
40
|
+
progress_key = f"{request.service_name}::{org_id}::progress"
|
|
41
|
+
|
|
42
|
+
# Get operation state from storage
|
|
43
|
+
state_entry = self._get_storage().get_operation_state(progress_key)
|
|
44
|
+
|
|
45
|
+
if not state_entry:
|
|
46
|
+
return GetOperationStatusResponse(
|
|
47
|
+
success=False,
|
|
48
|
+
msg=f"No operation found for service: {request.service_name}",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Extract the actual operation_state from the storage wrapper
|
|
52
|
+
# Storage returns: {"service_name": "...", "operation_state": {...}, "updated_at": "..."}
|
|
53
|
+
operation_state = state_entry.get("operation_state", state_entry)
|
|
54
|
+
|
|
55
|
+
# Auto-recover stale IN_PROGRESS operations so the frontend
|
|
56
|
+
# doesn't show "in progress" forever after a crash/restart
|
|
57
|
+
if operation_state.get("status") == OperationStatus.IN_PROGRESS.value:
|
|
58
|
+
from datetime import UTC, datetime
|
|
59
|
+
|
|
60
|
+
from reflexio.server.services.operation_state_utils import (
|
|
61
|
+
BATCH_STALE_PROGRESS_SECONDS,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
started_at = operation_state.get("started_at")
|
|
65
|
+
if started_at is not None:
|
|
66
|
+
current_time = int(datetime.now(UTC).timestamp())
|
|
67
|
+
elapsed = current_time - started_at
|
|
68
|
+
if elapsed > BATCH_STALE_PROGRESS_SECONDS:
|
|
69
|
+
logger.warning(
|
|
70
|
+
"Stale %s operation detected during status poll "
|
|
71
|
+
"(started %d seconds ago), auto-marking as FAILED",
|
|
72
|
+
request.service_name,
|
|
73
|
+
elapsed,
|
|
74
|
+
)
|
|
75
|
+
operation_state["status"] = OperationStatus.FAILED.value
|
|
76
|
+
operation_state["completed_at"] = current_time
|
|
77
|
+
operation_state["error_message"] = (
|
|
78
|
+
f"Auto-recovered: operation was stuck for {elapsed}s "
|
|
79
|
+
f"(threshold: {BATCH_STALE_PROGRESS_SECONDS}s)"
|
|
80
|
+
)
|
|
81
|
+
self._get_storage().update_operation_state(
|
|
82
|
+
progress_key, operation_state
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# Convert to OperationStatusInfo
|
|
86
|
+
operation_status_info = OperationStatusInfo(**operation_state)
|
|
87
|
+
|
|
88
|
+
return GetOperationStatusResponse(
|
|
89
|
+
success=True,
|
|
90
|
+
operation_status=operation_status_info,
|
|
91
|
+
msg="Retrieved operation status successfully",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
except Exception as e:
|
|
95
|
+
return GetOperationStatusResponse(
|
|
96
|
+
success=False, msg=f"Failed to get operation status: {str(e)}"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def cancel_operation(
|
|
100
|
+
self, request: CancelOperationRequest | dict
|
|
101
|
+
) -> CancelOperationResponse:
|
|
102
|
+
"""Cancel an in-progress operation (rerun or manual generation).
|
|
103
|
+
|
|
104
|
+
Sets a cancellation flag so the batch loop stops before the next user.
|
|
105
|
+
The current LLM call finishes, but no new users are started.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
request (Union[CancelOperationRequest, dict]): Request containing optional service_name.
|
|
109
|
+
If service_name is None, cancels both profile_generation and playbook_generation.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
CancelOperationResponse: Response with list of services that were cancelled
|
|
113
|
+
"""
|
|
114
|
+
if not self._is_storage_configured():
|
|
115
|
+
return CancelOperationResponse(
|
|
116
|
+
success=False, msg=STORAGE_NOT_CONFIGURED_MSG
|
|
117
|
+
)
|
|
118
|
+
try:
|
|
119
|
+
if isinstance(request, dict):
|
|
120
|
+
request = CancelOperationRequest(**request)
|
|
121
|
+
|
|
122
|
+
# Determine which services to cancel
|
|
123
|
+
if request.service_name:
|
|
124
|
+
service_names = [request.service_name]
|
|
125
|
+
else:
|
|
126
|
+
service_names = ["profile_generation", "playbook_generation"]
|
|
127
|
+
|
|
128
|
+
cancelled_services = []
|
|
129
|
+
for svc in service_names:
|
|
130
|
+
mgr = OperationStateManager(
|
|
131
|
+
storage=self._get_storage(),
|
|
132
|
+
org_id=self.request_context.org_id,
|
|
133
|
+
service_name=svc,
|
|
134
|
+
)
|
|
135
|
+
if mgr.request_cancellation():
|
|
136
|
+
cancelled_services.append(svc)
|
|
137
|
+
|
|
138
|
+
if cancelled_services:
|
|
139
|
+
return CancelOperationResponse(
|
|
140
|
+
success=True,
|
|
141
|
+
cancelled_services=cancelled_services,
|
|
142
|
+
msg=f"Cancellation requested for: {', '.join(cancelled_services)}",
|
|
143
|
+
)
|
|
144
|
+
return CancelOperationResponse(
|
|
145
|
+
success=True,
|
|
146
|
+
cancelled_services=[],
|
|
147
|
+
msg="No in-progress operations found to cancel",
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
except Exception as e:
|
|
151
|
+
return CancelOperationResponse(
|
|
152
|
+
success=False, msg=f"Failed to cancel operation: {str(e)}"
|
|
153
|
+
)
|