claude-smart 0.2.42 → 0.2.43
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/package.json +9 -3
- package/plugin/.claude-plugin/plugin.json +9 -3
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/README.md +2 -2
- package/plugin/pyproject.toml +2 -2
- package/plugin/scripts/_lib.sh +91 -0
- package/plugin/scripts/backend-service.sh +1 -0
- package/plugin/scripts/cli.sh +1 -0
- 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/hook_entry.sh +1 -0
- package/plugin/scripts/smart-install.sh +1 -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 +1 -1
- package/plugin/vendor/reflexio/.env.example +53 -0
- package/plugin/vendor/reflexio/LICENSE +201 -0
- package/plugin/vendor/reflexio/README.md +338 -0
- package/plugin/vendor/reflexio/pyproject.toml +271 -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 +266 -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 +961 -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 +1103 -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 +766 -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 +280 -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 +616 -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 +2714 -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 +540 -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 +110 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/image_utils.py +55 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +1595 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/llm_utils.py +112 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +469 -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 +210 -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 +255 -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 +177 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/rerank/llm_reranker.py +148 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/tools.py +699 -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_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 +279 -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 +127 -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/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 +340 -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 +1626 -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/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 +351 -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 +468 -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 +777 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/tools.py +1125 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extractor_config_utils.py +91 -0
- package/plugin/vendor/reflexio/reflexio/server/services/extractor_interaction_utils.py +251 -0
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +689 -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 +960 -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 +741 -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 +734 -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 +800 -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 +70 -0
- package/plugin/vendor/reflexio/reflexio/server/services/search/__init__.py +0 -0
- package/plugin/vendor/reflexio/reflexio/server/services/service_utils.py +671 -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 +1253 -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 +372 -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 +568 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/README.md +77 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/feature_flags.py +116 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_manager.py +263 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/feature_flags.json +13 -0
- package/plugin/vendor/reflexio/reflexio/server/site_var/site_var_sources/llm_model_setting.json +7 -0
- package/plugin/vendor/reflexio/reflexio/server/tracing.py +158 -0
- package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +113 -0
- package/plugin/vendor/reflexio/reflexio/server/uvicorn_logging.py +76 -0
- package/plugin/vendor/reflexio/reflexio/test_support/__init__.py +1 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_fixtures.py +62 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +242 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +129 -0
- package/plugin/vendor/reflexio/reflexio/test_support/skip_decorators.py +43 -0
package/plugin/vendor/reflexio/reflexio/server/services/profile/profile_generation_service_utils.py
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"""Utility functions for the profile generation service"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from datetime import datetime, timedelta
|
|
7
|
+
from typing import Any, Literal
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
10
|
+
|
|
11
|
+
from reflexio.models.api_schema.common import NEVER_EXPIRES_TIMESTAMP
|
|
12
|
+
from reflexio.models.api_schema.internal_schema import RequestInteractionDataModel
|
|
13
|
+
from reflexio.models.api_schema.service_schemas import (
|
|
14
|
+
ProfileTimeToLive,
|
|
15
|
+
UserProfile,
|
|
16
|
+
)
|
|
17
|
+
from reflexio.server.prompt.prompt_manager import PromptManager
|
|
18
|
+
from reflexio.server.services.service_utils import (
|
|
19
|
+
MessageConstructionConfig,
|
|
20
|
+
PromptConfig,
|
|
21
|
+
construct_messages_from_interactions,
|
|
22
|
+
extract_interactions_from_request_interaction_data_models,
|
|
23
|
+
format_sessions_to_history_string,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ProfileUpdates(BaseModel):
|
|
28
|
+
add_profiles: list[UserProfile] = []
|
|
29
|
+
delete_profiles: list[UserProfile] = []
|
|
30
|
+
mention_profiles: list[UserProfile] = []
|
|
31
|
+
|
|
32
|
+
@field_validator(
|
|
33
|
+
"add_profiles", "delete_profiles", "mention_profiles", mode="before"
|
|
34
|
+
)
|
|
35
|
+
@classmethod
|
|
36
|
+
def coerce_none_to_list(cls, v: Any) -> list[UserProfile]:
|
|
37
|
+
return v if v is not None else []
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ProfileGenerationRequest(BaseModel):
|
|
41
|
+
user_id: str
|
|
42
|
+
request_id: str
|
|
43
|
+
source: str | None = None
|
|
44
|
+
rerun_start_time: int | None = None # Unix timestamp for rerun flows
|
|
45
|
+
rerun_end_time: int | None = None # Unix timestamp for rerun flows
|
|
46
|
+
auto_run: bool = (
|
|
47
|
+
True # True for regular flow (checks stride_size), False for rerun/manual
|
|
48
|
+
)
|
|
49
|
+
force_extraction: bool = False # when True, bypass all extraction gates (stride_size, cheap pre-filter, LLM should_run)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(frozen=True)
|
|
53
|
+
class ProfileGenerationServiceConstants:
|
|
54
|
+
PROFILE_EXTRACTORS_CONFIG_NAME = "profile_extractor_config"
|
|
55
|
+
# ===============================
|
|
56
|
+
# prompt ids
|
|
57
|
+
# ===============================
|
|
58
|
+
PROFILE_SHOULD_GENERATE_PROMPT_ID = "profile_should_generate"
|
|
59
|
+
PROFILE_SHOULD_GENERATE_OVERRIDE_PROMPT_ID = "profile_should_generate_override"
|
|
60
|
+
PROFILE_UPDATE_MAIN_PROMPT_ID = "profile_update_main"
|
|
61
|
+
PROFILE_UPDATE_INSTRUCTION_START_PROMPT_ID = "profile_update_instruction_start"
|
|
62
|
+
PROFILE_UPDATE_INSTRUCTION_PROMPT_ID = "profile_update_instruction"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# ===============================
|
|
66
|
+
# Pydantic classes for profile_update_main prompt output schema
|
|
67
|
+
# ===============================
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class ProfileAddItem(BaseModel):
|
|
71
|
+
"""
|
|
72
|
+
Schema for a single profile item to be added.
|
|
73
|
+
|
|
74
|
+
Attributes:
|
|
75
|
+
content (str): The profile content based on content definition
|
|
76
|
+
time_to_live (str): Time to live for the profile - one of: 'one_day', 'one_week', 'one_month', 'one_quarter', 'one_year', 'infinity'
|
|
77
|
+
metadata (str, optional): Metadata extracted for the profile based on metadata definition
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
content: str = Field(description="Profile content based on content definition")
|
|
81
|
+
time_to_live: Literal[
|
|
82
|
+
"one_day", "one_week", "one_month", "one_quarter", "one_year", "infinity"
|
|
83
|
+
] = Field(
|
|
84
|
+
description="Time to live for the profile - determines when the profile expires"
|
|
85
|
+
)
|
|
86
|
+
metadata: str | None = Field(
|
|
87
|
+
default=None,
|
|
88
|
+
description="Metadata extracted for the profile based on metadata definition",
|
|
89
|
+
)
|
|
90
|
+
source_span: str | None = Field(
|
|
91
|
+
default=None,
|
|
92
|
+
description="Verbatim excerpt from the source that most directly supports this profile item",
|
|
93
|
+
)
|
|
94
|
+
notes: str | None = Field(
|
|
95
|
+
default=None,
|
|
96
|
+
description="Free-form extraction notes — confidence, caveats, or alternative readings",
|
|
97
|
+
)
|
|
98
|
+
reader_angle: str | None = Field(
|
|
99
|
+
default=None,
|
|
100
|
+
description="The extraction perspective or reader role that surfaced this item",
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# OpenAI structured output requires explicit schema constraints
|
|
104
|
+
model_config = ConfigDict(
|
|
105
|
+
extra="allow",
|
|
106
|
+
json_schema_extra={"additionalProperties": False},
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class ProfileUpdateOutput(BaseModel):
|
|
111
|
+
"""
|
|
112
|
+
Legacy output schema for profile_update_main prompt (kept for backward compatibility).
|
|
113
|
+
Represents the complete set of profile updates including additions, deletions, and mentions.
|
|
114
|
+
|
|
115
|
+
Attributes:
|
|
116
|
+
add (list[ProfileAddItem], optional): List of new profiles to be added
|
|
117
|
+
delete (list[str], optional): List of existing profile contents to be deleted
|
|
118
|
+
mention (list[str], optional): List of existing profile contents that were mentioned/referenced
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
add: list[ProfileAddItem] | None = Field(
|
|
122
|
+
default=None,
|
|
123
|
+
description="List of new profiles to be added with their content, time to live, and optional metadata",
|
|
124
|
+
)
|
|
125
|
+
delete: list[str] | None = Field(
|
|
126
|
+
default=None,
|
|
127
|
+
description="List of existing profile contents to be deleted (profiles that are contradicted by new interactions)",
|
|
128
|
+
)
|
|
129
|
+
mention: list[str] | None = Field(
|
|
130
|
+
default=None,
|
|
131
|
+
description="List of existing profile contents that were mentioned or referenced in the new interactions",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# OpenAI schema parsing requires explicitly forbidding additional properties
|
|
135
|
+
model_config = ConfigDict(
|
|
136
|
+
extra="allow",
|
|
137
|
+
json_schema_extra={"additionalProperties": False},
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class StructuredProfilesOutput(BaseModel):
|
|
142
|
+
"""
|
|
143
|
+
Output schema for extraction-only profile extraction.
|
|
144
|
+
Only extracts profiles — no delete/mention operations.
|
|
145
|
+
|
|
146
|
+
Attributes:
|
|
147
|
+
profiles (list[ProfileAddItem], optional): List of extracted profiles with content, time_to_live, and optional metadata
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
profiles: list[ProfileAddItem] | None = Field(
|
|
151
|
+
default=None,
|
|
152
|
+
description="List of extracted profiles with content, time_to_live, and optional metadata",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
model_config = ConfigDict(
|
|
156
|
+
extra="allow",
|
|
157
|
+
json_schema_extra={"additionalProperties": False},
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def calculate_expiration_timestamp(
|
|
162
|
+
last_modified_timestamp: int, profile_time_to_live: ProfileTimeToLive
|
|
163
|
+
) -> int:
|
|
164
|
+
"""
|
|
165
|
+
Calculate the expiration timestamp for a profile based on the last modified timestamp and the profile time to live.
|
|
166
|
+
Args:
|
|
167
|
+
last_modified_timestamp (int): The timestamp of the last modification of the profile.
|
|
168
|
+
profile_time_to_live (ProfileTimeToLive): The time to live of the profile.
|
|
169
|
+
Returns:
|
|
170
|
+
The expiration timestamp for the profile.
|
|
171
|
+
"""
|
|
172
|
+
if profile_time_to_live == ProfileTimeToLive.INFINITY:
|
|
173
|
+
return NEVER_EXPIRES_TIMESTAMP
|
|
174
|
+
|
|
175
|
+
last_modified_datetime = datetime.fromtimestamp(last_modified_timestamp)
|
|
176
|
+
if profile_time_to_live == ProfileTimeToLive.ONE_DAY:
|
|
177
|
+
expiration_timestamp = last_modified_datetime + timedelta(days=1)
|
|
178
|
+
elif profile_time_to_live == ProfileTimeToLive.ONE_WEEK:
|
|
179
|
+
expiration_timestamp = last_modified_datetime + timedelta(days=7)
|
|
180
|
+
elif profile_time_to_live == ProfileTimeToLive.ONE_MONTH:
|
|
181
|
+
expiration_timestamp = last_modified_datetime + timedelta(days=30)
|
|
182
|
+
elif profile_time_to_live == ProfileTimeToLive.ONE_QUARTER:
|
|
183
|
+
expiration_timestamp = last_modified_datetime + timedelta(days=90)
|
|
184
|
+
elif profile_time_to_live == ProfileTimeToLive.ONE_YEAR:
|
|
185
|
+
expiration_timestamp = last_modified_datetime + timedelta(days=365)
|
|
186
|
+
else:
|
|
187
|
+
raise ValueError(f"Invalid profile time to live: {profile_time_to_live}")
|
|
188
|
+
return int(expiration_timestamp.timestamp())
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def check_string_token_overlap(str1: str, str2: str, threshold: float = 0.7) -> bool:
|
|
192
|
+
"""
|
|
193
|
+
Check if two strings have significant token overlap, indicating they might be referring to the same thing.
|
|
194
|
+
This is useful for fuzzy matching when exact string matching is too strict.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
str1 (str): First string to compare
|
|
198
|
+
str2 (str): Second string to compare
|
|
199
|
+
threshold (float): Minimum overlap ratio required to consider strings as matching (0.0 to 1.0)
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
bool: True if strings have significant overlap, False otherwise
|
|
203
|
+
"""
|
|
204
|
+
# Normalize strings: lowercase and split into tokens
|
|
205
|
+
tokens1 = set(str1.lower().split())
|
|
206
|
+
tokens2 = set(str2.lower().split())
|
|
207
|
+
|
|
208
|
+
# Calculate overlap
|
|
209
|
+
if not tokens1 or not tokens2:
|
|
210
|
+
return False
|
|
211
|
+
|
|
212
|
+
# Calculate Jaccard similarity
|
|
213
|
+
intersection = len(tokens1.intersection(tokens2))
|
|
214
|
+
|
|
215
|
+
# Calculate overlap ratio
|
|
216
|
+
overlap_ratio = max(intersection / len(tokens1), intersection / len(tokens2))
|
|
217
|
+
|
|
218
|
+
return overlap_ratio >= threshold
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def construct_profile_extraction_messages_from_sessions(
|
|
222
|
+
prompt_manager: PromptManager,
|
|
223
|
+
request_interaction_data_models: list[RequestInteractionDataModel],
|
|
224
|
+
existing_profiles: list[UserProfile],
|
|
225
|
+
agent_context_prompt: str,
|
|
226
|
+
context_prompt: str,
|
|
227
|
+
extraction_definition_prompt: str,
|
|
228
|
+
metadata_definition_prompt: str | None = None,
|
|
229
|
+
) -> list[dict]:
|
|
230
|
+
"""
|
|
231
|
+
Construct LLM messages for profile extraction from sessions.
|
|
232
|
+
|
|
233
|
+
This function uses the shared message construction interface to build messages
|
|
234
|
+
with a system prompt and a final user prompt specific to profile extraction.
|
|
235
|
+
Interactions are formatted grouped by session.
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
prompt_manager: The prompt manager for rendering prompt templates
|
|
239
|
+
request_interaction_data_models: List of request interaction groups to extract profiles from
|
|
240
|
+
existing_profiles: List of existing user profiles for context
|
|
241
|
+
agent_context_prompt: Context about the agent for system message
|
|
242
|
+
context_prompt: Additional context for system message
|
|
243
|
+
extraction_definition_prompt: Definition of what profiles should contain
|
|
244
|
+
metadata_definition_prompt: Optional definition for profile metadata
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
list[dict]: List of messages ready for profile extraction
|
|
248
|
+
"""
|
|
249
|
+
# Format existing profiles for the final prompt
|
|
250
|
+
formatted_existing_profiles = ", ".join(
|
|
251
|
+
[profile.content for profile in existing_profiles]
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
# Configure system message (before interactions)
|
|
255
|
+
# Stable content (instructions, examples, definitions) goes in system message for token caching
|
|
256
|
+
system_config = PromptConfig(
|
|
257
|
+
prompt_id=ProfileGenerationServiceConstants.PROFILE_UPDATE_INSTRUCTION_START_PROMPT_ID,
|
|
258
|
+
variables={
|
|
259
|
+
"agent_context_prompt": agent_context_prompt,
|
|
260
|
+
"context_prompt": context_prompt,
|
|
261
|
+
"extraction_definition_prompt": extraction_definition_prompt,
|
|
262
|
+
"metadata_definition_prompt": metadata_definition_prompt,
|
|
263
|
+
},
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
# Configure final user message (after interactions)
|
|
267
|
+
# Only dynamic per-call data goes in user message
|
|
268
|
+
user_config = PromptConfig(
|
|
269
|
+
prompt_id=ProfileGenerationServiceConstants.PROFILE_UPDATE_MAIN_PROMPT_ID,
|
|
270
|
+
variables={
|
|
271
|
+
"existing_profiles": formatted_existing_profiles,
|
|
272
|
+
"interactions": format_sessions_to_history_string(
|
|
273
|
+
request_interaction_data_models
|
|
274
|
+
),
|
|
275
|
+
},
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
# Extract flat interactions for message construction (needed for image handling)
|
|
279
|
+
interactions = extract_interactions_from_request_interaction_data_models(
|
|
280
|
+
request_interaction_data_models
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
# Use shared message construction
|
|
284
|
+
config = MessageConstructionConfig(
|
|
285
|
+
prompt_manager=prompt_manager,
|
|
286
|
+
system_prompt_config=system_config,
|
|
287
|
+
user_prompt_config=user_config,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
return construct_messages_from_interactions(interactions, config)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""Reflection service: critique-and-revise of cited memories after publish."""
|
|
2
|
+
|
|
3
|
+
from reflexio.server.services.reflection.reflection_service import ReflectionService
|
|
4
|
+
from reflexio.server.services.reflection.reflection_service_utils import (
|
|
5
|
+
ReflectionDecision,
|
|
6
|
+
ReflectionOutput,
|
|
7
|
+
ReflectionResult,
|
|
8
|
+
ReflectionServiceRequest,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"ReflectionService",
|
|
13
|
+
"ReflectionServiceRequest",
|
|
14
|
+
"ReflectionDecision",
|
|
15
|
+
"ReflectionOutput",
|
|
16
|
+
"ReflectionResult",
|
|
17
|
+
]
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"""LLM call that proposes per-citation reflection decisions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import logging
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
9
|
+
from reflexio.server.llm.litellm_client import LiteLLMClient
|
|
10
|
+
from reflexio.server.llm.model_defaults import ModelRole, resolve_model_name
|
|
11
|
+
from reflexio.server.services.reflection.reflection_service_utils import (
|
|
12
|
+
ReflectionOutput,
|
|
13
|
+
)
|
|
14
|
+
from reflexio.server.services.service_utils import (
|
|
15
|
+
log_llm_messages,
|
|
16
|
+
log_model_response,
|
|
17
|
+
)
|
|
18
|
+
from reflexio.server.site_var.site_var_manager import SiteVarManager
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from reflexio.models.api_schema.domain.entities import (
|
|
22
|
+
Interaction,
|
|
23
|
+
UserPlaybook,
|
|
24
|
+
UserProfile,
|
|
25
|
+
)
|
|
26
|
+
from reflexio.server.api_endpoints.request_context import RequestContext
|
|
27
|
+
|
|
28
|
+
logger = logging.getLogger(__name__)
|
|
29
|
+
|
|
30
|
+
REFLECTION_TIMEOUT_SECONDS = 300
|
|
31
|
+
REFLECTION_MAX_RETRIES = 1
|
|
32
|
+
REFLECTION_PROMPT_ID = "memory_reflection"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ReflectionExtractor:
|
|
36
|
+
"""Build the reflection prompt and ask the LLM for decisions.
|
|
37
|
+
|
|
38
|
+
Thin wrapper around one ``LiteLLMClient`` call using
|
|
39
|
+
``ReflectionOutput`` as the structured-output schema. Does not touch
|
|
40
|
+
storage.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
request_context: RequestContext,
|
|
46
|
+
llm_client: LiteLLMClient,
|
|
47
|
+
agent_context: str,
|
|
48
|
+
model_override: str | None,
|
|
49
|
+
):
|
|
50
|
+
"""Build a new extractor.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
request_context (RequestContext): For prompt manager and
|
|
54
|
+
config access.
|
|
55
|
+
llm_client (LiteLLMClient): Shared LLM client.
|
|
56
|
+
agent_context (str): Agent-context prompt fragment from
|
|
57
|
+
config (free-form text describing the agent).
|
|
58
|
+
model_override (str | None): If set, used directly. Otherwise
|
|
59
|
+
falls back to ``LLMConfig.generation_model_name`` and the
|
|
60
|
+
site default for ``ModelRole.GENERATION``.
|
|
61
|
+
"""
|
|
62
|
+
self.request_context = request_context
|
|
63
|
+
self.client = llm_client
|
|
64
|
+
self.agent_context = agent_context
|
|
65
|
+
self.model_name = self._resolve_model(model_override)
|
|
66
|
+
|
|
67
|
+
def _resolve_model(self, model_override: str | None) -> str:
|
|
68
|
+
config = self.request_context.configurator.get_config()
|
|
69
|
+
llm_config = config.llm_config if config else None
|
|
70
|
+
api_key_config = config.api_key_config if config else None
|
|
71
|
+
model_setting = SiteVarManager().get_site_var("llm_model_setting")
|
|
72
|
+
site_var = model_setting if isinstance(model_setting, dict) else {}
|
|
73
|
+
return resolve_model_name(
|
|
74
|
+
ModelRole.GENERATION,
|
|
75
|
+
site_var_value=site_var.get("default_generation_model_name"),
|
|
76
|
+
config_override=(
|
|
77
|
+
model_override
|
|
78
|
+
or (llm_config.generation_model_name if llm_config else None)
|
|
79
|
+
),
|
|
80
|
+
api_key_config=api_key_config,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def run(
|
|
84
|
+
self,
|
|
85
|
+
*,
|
|
86
|
+
window_interactions: list[Interaction],
|
|
87
|
+
cited_profiles: list[UserProfile],
|
|
88
|
+
cited_user_playbooks: list[UserPlaybook],
|
|
89
|
+
horizon_by_key: dict[tuple[str, str], bool] | None = None,
|
|
90
|
+
) -> ReflectionOutput:
|
|
91
|
+
"""Render the prompt, call the LLM, return parsed output.
|
|
92
|
+
|
|
93
|
+
Returns an empty ``ReflectionOutput`` when nothing to consider
|
|
94
|
+
or when the LLM response cannot be parsed. LLM exceptions
|
|
95
|
+
propagate — the calling service decides whether to swallow.
|
|
96
|
+
"""
|
|
97
|
+
if not cited_profiles and not cited_user_playbooks:
|
|
98
|
+
return ReflectionOutput()
|
|
99
|
+
|
|
100
|
+
per_citation_context = _build_per_citation_context(
|
|
101
|
+
cited_profiles=cited_profiles,
|
|
102
|
+
cited_user_playbooks=cited_user_playbooks,
|
|
103
|
+
horizon_by_key=horizon_by_key or {},
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
rendered = self.request_context.prompt_manager.render_prompt(
|
|
107
|
+
REFLECTION_PROMPT_ID,
|
|
108
|
+
{
|
|
109
|
+
"agent_context": self.agent_context or "",
|
|
110
|
+
"window_interactions_json": _interactions_to_json(window_interactions),
|
|
111
|
+
"cited_profiles_json": _profiles_to_json(cited_profiles),
|
|
112
|
+
"cited_user_playbooks_json": _playbooks_to_json(cited_user_playbooks),
|
|
113
|
+
"per_citation_context_json": per_citation_context,
|
|
114
|
+
},
|
|
115
|
+
)
|
|
116
|
+
messages = [{"role": "user", "content": rendered}]
|
|
117
|
+
|
|
118
|
+
logger.info(
|
|
119
|
+
"event=reflection_llm_start cited_profiles=%d cited_playbooks=%d "
|
|
120
|
+
"window_interactions=%d model=%s",
|
|
121
|
+
len(cited_profiles),
|
|
122
|
+
len(cited_user_playbooks),
|
|
123
|
+
len(window_interactions),
|
|
124
|
+
self.model_name,
|
|
125
|
+
)
|
|
126
|
+
log_llm_messages(logger, "Memory reflection", messages)
|
|
127
|
+
|
|
128
|
+
response = self.client.generate_chat_response(
|
|
129
|
+
messages=messages,
|
|
130
|
+
model=self.model_name,
|
|
131
|
+
response_format=ReflectionOutput,
|
|
132
|
+
timeout=REFLECTION_TIMEOUT_SECONDS,
|
|
133
|
+
max_retries=REFLECTION_MAX_RETRIES,
|
|
134
|
+
)
|
|
135
|
+
log_model_response(logger, "Memory reflection model response", response)
|
|
136
|
+
|
|
137
|
+
if isinstance(response, ReflectionOutput):
|
|
138
|
+
return response
|
|
139
|
+
logger.warning(
|
|
140
|
+
"event=reflection_llm_unparsed response_type=%s",
|
|
141
|
+
type(response).__name__,
|
|
142
|
+
)
|
|
143
|
+
return ReflectionOutput()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _interactions_to_json(interactions: list[Interaction]) -> str:
|
|
147
|
+
payload: list[dict[str, Any]] = [
|
|
148
|
+
{
|
|
149
|
+
"interaction_id": i.interaction_id,
|
|
150
|
+
"request_id": i.request_id,
|
|
151
|
+
"role": i.role,
|
|
152
|
+
"content": i.content,
|
|
153
|
+
"tools_used": (
|
|
154
|
+
[t.model_dump() for t in i.tools_used] if i.tools_used else []
|
|
155
|
+
),
|
|
156
|
+
"citations": [c.model_dump() for c in i.citations] if i.citations else [],
|
|
157
|
+
"created_at": i.created_at,
|
|
158
|
+
}
|
|
159
|
+
for i in interactions
|
|
160
|
+
]
|
|
161
|
+
return json.dumps(payload, ensure_ascii=False, indent=2)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _profiles_to_json(profiles: list[UserProfile]) -> str:
|
|
165
|
+
payload = [
|
|
166
|
+
{
|
|
167
|
+
"profile_id": p.profile_id,
|
|
168
|
+
"content": p.content,
|
|
169
|
+
"profile_time_to_live": p.profile_time_to_live.value,
|
|
170
|
+
"custom_features": p.custom_features,
|
|
171
|
+
"source": p.source,
|
|
172
|
+
"last_modified_timestamp": p.last_modified_timestamp,
|
|
173
|
+
}
|
|
174
|
+
for p in profiles
|
|
175
|
+
]
|
|
176
|
+
return json.dumps(payload, ensure_ascii=False, indent=2)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def _playbooks_to_json(playbooks: list[UserPlaybook]) -> str:
|
|
180
|
+
"""Serialize cited playbooks for the reflection prompt.
|
|
181
|
+
|
|
182
|
+
The prompt reads each rule's orientation directly from its ``content``
|
|
183
|
+
wording — no derived ``polarity`` hint is injected (that would re-derive
|
|
184
|
+
polarity, which is retired under LLM-judged orientation).
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
playbooks (list[UserPlaybook]): The cited playbooks to serialize.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
str: JSON array string with one object per cited playbook.
|
|
191
|
+
"""
|
|
192
|
+
payload = [
|
|
193
|
+
{
|
|
194
|
+
"user_playbook_id": p.user_playbook_id,
|
|
195
|
+
"playbook_name": p.playbook_name,
|
|
196
|
+
"content": p.content,
|
|
197
|
+
"trigger": p.trigger,
|
|
198
|
+
"rationale": p.rationale,
|
|
199
|
+
"source": p.source,
|
|
200
|
+
}
|
|
201
|
+
for p in playbooks
|
|
202
|
+
]
|
|
203
|
+
return json.dumps(payload, ensure_ascii=False, indent=2)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def _build_per_citation_context(
|
|
207
|
+
*,
|
|
208
|
+
cited_profiles: list[UserProfile],
|
|
209
|
+
cited_user_playbooks: list[UserPlaybook],
|
|
210
|
+
horizon_by_key: dict[tuple[str, str], bool],
|
|
211
|
+
) -> str:
|
|
212
|
+
"""Serialize per-citation horizon flags into a JSON string for the prompt.
|
|
213
|
+
|
|
214
|
+
For each cited profile/playbook, emits an object with target_kind,
|
|
215
|
+
target_id, and has_full_horizon. ``has_full_horizon`` defaults to
|
|
216
|
+
True when the citation key isn't in ``horizon_by_key`` (defensive
|
|
217
|
+
fallback — the caller normally populates the dict from
|
|
218
|
+
_filter_citations_by_horizon).
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
cited_profiles (list[UserProfile]): Profile citations to include.
|
|
222
|
+
cited_user_playbooks (list[UserPlaybook]): Playbook citations to include.
|
|
223
|
+
horizon_by_key (dict[tuple[str, str], bool]): Maps (kind, id) to
|
|
224
|
+
has_full_horizon flag.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
str: JSON array string with per-citation horizon context.
|
|
228
|
+
"""
|
|
229
|
+
payload: list[dict[str, Any]] = [
|
|
230
|
+
{
|
|
231
|
+
"target_kind": "profile",
|
|
232
|
+
"target_id": p.profile_id,
|
|
233
|
+
"has_full_horizon": horizon_by_key.get(("profile", p.profile_id), True),
|
|
234
|
+
}
|
|
235
|
+
for p in cited_profiles
|
|
236
|
+
]
|
|
237
|
+
payload.extend(
|
|
238
|
+
{
|
|
239
|
+
"target_kind": "playbook",
|
|
240
|
+
"target_id": str(pb.user_playbook_id),
|
|
241
|
+
"has_full_horizon": horizon_by_key.get(
|
|
242
|
+
("playbook", str(pb.user_playbook_id)), True
|
|
243
|
+
),
|
|
244
|
+
}
|
|
245
|
+
for pb in cited_user_playbooks
|
|
246
|
+
)
|
|
247
|
+
return json.dumps(payload, ensure_ascii=False, indent=2)
|