sovara 0.2.8__tar.gz → 0.2.9__tar.gz
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.
- {sovara-0.2.8 → sovara-0.2.9}/PKG-INFO +1 -1
- {sovara-0.2.8 → sovara-0.2.9}/pyproject.toml +1 -1
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/cli/so_tool.py +1 -71
- sovara-0.2.9/src/sovara/common/run_logs.py +74 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/connection.py +24 -2
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/main.py +40 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/tools/__init__.py +6 -0
- sovara-0.2.9/src/sovara/server/graph_analysis/trace_chat/tools/logs.py +84 -0
- sovara-0.2.9/src/sovara/server/graph_analysis/trace_chat/tools/priors.py +636 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/routes.py +5 -1
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara.egg-info/PKG-INFO +1 -1
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara.egg-info/SOURCES.txt +3 -0
- {sovara-0.2.8 → sovara-0.2.9}/LICENSE +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/README.md +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/docs/release/PYPI_DESC.md +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/setup.cfg +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/SKILL.md +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/AttachmentPreview-C-SDQn_c.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/AttachmentPreview-CFrNMdfC.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/DocumentPreviewModal-DLcTPg47.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/LayoutBreadcrumb-CPgbqAJg.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/LayoutBreadcrumb-DrZRF2Sb.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/OrgRoute-Da3YLHXR.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/OrgRoute-Syy1k3se.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/PriorsRoute-B1nxA9L9.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/PriorsRoute-C-kIcXqp.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/ProjectRoute-BTYfMx0l.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/ProjectRoute-C3Jzk4jL.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/ProjectRunsRoute-ChqTPgDi.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/ProjectRunsRoute-DnTtW5z2.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/RunRoute-BokXQNmB.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/RunRoute-CjnawiLF.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/SettingsRoute-BsJ1s1Xa.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/api-VlLy9MpQ.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/arrow_lr-ByI2ndPB.png +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/arrow_spiral_tr_bl-XHIpf338.png +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/codicon-BYm2YbZ6.ttf +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/eye-U4_eeOX-.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/index-NbFqPLEC.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/index-TU6o79pU.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/pdf.worker.min-qwK7q_zL.mjs +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/plus-B1NOTICQ.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/prismTheme-nMW1SONA.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/runtime-B1TGbSkq.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/runtime-CCiRiliL.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/settings-BS_NcxJU.css +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/settings-BrSnAN-D.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/sovara_wordmark-CjkpVR0a.png +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/tierState-BVmlAt4E.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/tiny-invariant-BCXflckp.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/trash-2-DhTFZ-Hl.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/useTheme-BMbBHOjM.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/assets/value-Bqe5DuYT.js +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/favicon.png +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/index.html +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/assets/web_app/marketplace_icon.png +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/cli/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/cli/so_config.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/cli/so_record.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/cli/so_server.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/config.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/constants.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/custom_metrics.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/lifecycle.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/log_redaction.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/logger.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/priors_block.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/project.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/runtime.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/user.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/common/utils.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/agent_runner.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/context_manager.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/api_parser.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/api_parsers/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/api_parsers/aiohttp_api_parser.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/api_parsers/claude_code_messages_api_parser.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/api_parsers/httpx_api_parser.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/api_parsers/mcp_api_parser.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/api_parsers/requests_api_parser.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/api_parsers/sse_utils.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/api_parsers/urllib3_api_parser.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/apply_monkey_patches.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/async_streaming.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/edit_io_filters.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/endpoint_whitelist.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/node_naming.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/adk_patch.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/aiohttp_patch.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/claude_sdk_patch.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/httpx_patch.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/langchain_patch.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/mcp_patches.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/openai_agents_patch.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/randomness_patch.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/requests_patch.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patches/urllib3_patch.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/patching_utils.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/monkey_patching/tool_trace_utils.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/node_execution.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/priors.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/priors_pipeline.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/run_log_capture.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/runtime_client.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/runner/string_matching.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/app.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/claude_proxy_utils.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/_shared.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/backend_protocol.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/blob_storage.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/llm_calls.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/manager.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/mongodb/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/mongodb/backend.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/mongodb/connection.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/postgresql/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/postgresql/backend.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/postgresql/connection.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/postgresql/schema.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/prior_models.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/priors.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/projects.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/runs.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/backend.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/llm_calls.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/prior_embeddings.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/prior_records.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/priors.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/projects.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/runs.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/schema.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/sqlite/users.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/database/users.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/inference_server.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/cancel.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/tools/ask_step.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/tools/edit_content.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/tools/get_step_overview.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/tools/get_step_snapshot.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/tools/get_trace_overview.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/tools/search.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/tools/summarize_trace.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/tools/verify.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/utils/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/utils/content_utils.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/utils/context.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/utils/edit_persist.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/utils/step_content_view.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/utils/step_ids.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/utils/trace.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_analysis/trace_chat/utils/verdict_persist.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/graph_models.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/handlers/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/handlers/cli_handlers.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/handlers/handler_utils.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/handlers/runner_handlers.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/handlers/ui_handlers.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/llm_backend.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/llm_provider_catalog.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/llm_settings.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/llm_settings_verification.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/package_version.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/prior_display.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/constants.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/embeddings.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm/folder_rebalancer.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm/lesson_restructurer.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm/lesson_retriever.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm/lesson_summarizer.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm/lesson_validator.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm/prior_content_polisher.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm/prior_metadata_suggester.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm/prior_quality.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/llm_client.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/logger.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/path_utils.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/retrieval_service.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/storage.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/tools/adjudication.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/tools/bm25_search.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/tools/dense_search.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/tools/folder_groups.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/tools/keyword_search.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/tools/parallel_search.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/tools/preprocess_context.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/tools/rerank.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_backend/tools/utils.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/priors_scope.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/claude_proxy.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/events.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/internal.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/runner.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/ui.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/ui_common.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/ui_projects.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/ui_runs.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/routes/ui_trace_chat.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/services/__init__.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/services/trace_chat_service.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/state.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/third_party_model_catalog.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara/server/web_app_assets.py +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara.egg-info/dependency_links.txt +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara.egg-info/entry_points.txt +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara.egg-info/requires.txt +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/src/sovara.egg-info/top_level.txt +0 -0
- {sovara-0.2.8 → sovara-0.2.9}/tests/test_graph_payloads.py +0 -0
|
@@ -12,6 +12,7 @@ import subprocess
|
|
|
12
12
|
from argparse import ArgumentParser, REMAINDER
|
|
13
13
|
from typing import Any
|
|
14
14
|
from sovara.common.constants import HOST, PORT, PRIORS_SERVER_URL, PRIORS_SERVER_TIMEOUT
|
|
15
|
+
from sovara.common.run_logs import format_log_output
|
|
15
16
|
|
|
16
17
|
RUN_WAIT_TIMEOUT = 30 # Max seconds to wait for run_id from agent_runner
|
|
17
18
|
SOVARA_SERVER_URL = f"http://{HOST}:{PORT}"
|
|
@@ -495,77 +496,6 @@ def _inspect_local_status(path: str | None) -> dict[str, Any]:
|
|
|
495
496
|
}
|
|
496
497
|
|
|
497
498
|
|
|
498
|
-
def format_log_output(
|
|
499
|
-
log_text: str,
|
|
500
|
-
*,
|
|
501
|
-
tail: int | None = None,
|
|
502
|
-
grep: str | None = None,
|
|
503
|
-
context: int = 0,
|
|
504
|
-
line_numbers: bool = False,
|
|
505
|
-
) -> str:
|
|
506
|
-
"""Render persisted run logs with optional filtering and line-number formatting."""
|
|
507
|
-
if tail is not None and tail < 0:
|
|
508
|
-
raise ValueError("--tail must be greater than or equal to 0")
|
|
509
|
-
if context < 0:
|
|
510
|
-
raise ValueError("--context must be greater than or equal to 0")
|
|
511
|
-
|
|
512
|
-
if grep is None and tail is None and context == 0 and not line_numbers:
|
|
513
|
-
return log_text
|
|
514
|
-
|
|
515
|
-
lines = log_text.splitlines()
|
|
516
|
-
entries: list[tuple[int, str] | None]
|
|
517
|
-
|
|
518
|
-
if grep:
|
|
519
|
-
try:
|
|
520
|
-
pattern = re.compile(grep)
|
|
521
|
-
except re.error as exc:
|
|
522
|
-
raise ValueError(f"Invalid regex: {exc}") from exc
|
|
523
|
-
|
|
524
|
-
ranges: list[tuple[int, int]] = []
|
|
525
|
-
for index, line in enumerate(lines):
|
|
526
|
-
if not pattern.search(line):
|
|
527
|
-
continue
|
|
528
|
-
|
|
529
|
-
start = max(0, index - context)
|
|
530
|
-
end = min(len(lines) - 1, index + context)
|
|
531
|
-
if ranges and start <= ranges[-1][1] + 1:
|
|
532
|
-
ranges[-1] = (ranges[-1][0], max(ranges[-1][1], end))
|
|
533
|
-
else:
|
|
534
|
-
ranges.append((start, end))
|
|
535
|
-
|
|
536
|
-
entries = []
|
|
537
|
-
for range_index, (start, end) in enumerate(ranges):
|
|
538
|
-
if range_index > 0:
|
|
539
|
-
entries.append(None)
|
|
540
|
-
for line_index in range(start, end + 1):
|
|
541
|
-
entries.append((line_index + 1, lines[line_index]))
|
|
542
|
-
else:
|
|
543
|
-
entries = [(index + 1, line) for index, line in enumerate(lines)]
|
|
544
|
-
|
|
545
|
-
if tail is not None:
|
|
546
|
-
entries = entries[-tail:] if tail > 0 else []
|
|
547
|
-
|
|
548
|
-
if not entries:
|
|
549
|
-
return ""
|
|
550
|
-
|
|
551
|
-
numbered_lines = [entry for entry in entries if entry is not None]
|
|
552
|
-
number_width = len(str(max((line_number for line_number, _line in numbered_lines), default=1)))
|
|
553
|
-
|
|
554
|
-
rendered_lines: list[str] = []
|
|
555
|
-
for entry in entries:
|
|
556
|
-
if entry is None:
|
|
557
|
-
rendered_lines.append("--")
|
|
558
|
-
continue
|
|
559
|
-
|
|
560
|
-
line_number, line = entry
|
|
561
|
-
if line_numbers:
|
|
562
|
-
rendered_lines.append(f"{line_number:>{number_width}}: {line}")
|
|
563
|
-
else:
|
|
564
|
-
rendered_lines.append(line)
|
|
565
|
-
|
|
566
|
-
return "\n".join(rendered_lines) + "\n"
|
|
567
|
-
|
|
568
|
-
|
|
569
499
|
def _spawn_rerun(prepared: dict, timeout: float | None = None) -> dict:
|
|
570
500
|
"""
|
|
571
501
|
Spawn a rerun process for a run and block until completion.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def format_log_output(
|
|
7
|
+
log_text: str,
|
|
8
|
+
*,
|
|
9
|
+
tail: int | None = None,
|
|
10
|
+
grep: str | None = None,
|
|
11
|
+
context: int = 0,
|
|
12
|
+
line_numbers: bool = False,
|
|
13
|
+
) -> str:
|
|
14
|
+
"""Render persisted run logs with optional filtering and line-number formatting."""
|
|
15
|
+
if tail is not None and tail < 0:
|
|
16
|
+
raise ValueError("--tail must be greater than or equal to 0")
|
|
17
|
+
if context < 0:
|
|
18
|
+
raise ValueError("--context must be greater than or equal to 0")
|
|
19
|
+
|
|
20
|
+
if grep is None and tail is None and context == 0 and not line_numbers:
|
|
21
|
+
return log_text
|
|
22
|
+
|
|
23
|
+
lines = log_text.splitlines()
|
|
24
|
+
entries: list[tuple[int, str] | None]
|
|
25
|
+
|
|
26
|
+
if grep:
|
|
27
|
+
try:
|
|
28
|
+
pattern = re.compile(grep)
|
|
29
|
+
except re.error as exc:
|
|
30
|
+
raise ValueError(f"Invalid regex: {exc}") from exc
|
|
31
|
+
|
|
32
|
+
ranges: list[tuple[int, int]] = []
|
|
33
|
+
for index, line in enumerate(lines):
|
|
34
|
+
if not pattern.search(line):
|
|
35
|
+
continue
|
|
36
|
+
|
|
37
|
+
start = max(0, index - context)
|
|
38
|
+
end = min(len(lines) - 1, index + context)
|
|
39
|
+
if ranges and start <= ranges[-1][1] + 1:
|
|
40
|
+
ranges[-1] = (ranges[-1][0], max(ranges[-1][1], end))
|
|
41
|
+
else:
|
|
42
|
+
ranges.append((start, end))
|
|
43
|
+
|
|
44
|
+
entries = []
|
|
45
|
+
for range_index, (start, end) in enumerate(ranges):
|
|
46
|
+
if range_index > 0:
|
|
47
|
+
entries.append(None)
|
|
48
|
+
for line_index in range(start, end + 1):
|
|
49
|
+
entries.append((line_index + 1, lines[line_index]))
|
|
50
|
+
else:
|
|
51
|
+
entries = [(index + 1, line) for index, line in enumerate(lines)]
|
|
52
|
+
|
|
53
|
+
if tail is not None:
|
|
54
|
+
entries = entries[-tail:] if tail > 0 else []
|
|
55
|
+
|
|
56
|
+
if not entries:
|
|
57
|
+
return ""
|
|
58
|
+
|
|
59
|
+
numbered_lines = [entry for entry in entries if entry is not None]
|
|
60
|
+
number_width = len(str(max((line_number for line_number, _line in numbered_lines), default=1)))
|
|
61
|
+
|
|
62
|
+
rendered_lines: list[str] = []
|
|
63
|
+
for entry in entries:
|
|
64
|
+
if entry is None:
|
|
65
|
+
rendered_lines.append("--")
|
|
66
|
+
continue
|
|
67
|
+
|
|
68
|
+
line_number, line = entry
|
|
69
|
+
if line_numbers:
|
|
70
|
+
rendered_lines.append(f"{line_number:>{number_width}}: {line}")
|
|
71
|
+
else:
|
|
72
|
+
rendered_lines.append(line)
|
|
73
|
+
|
|
74
|
+
return "\n".join(rendered_lines) + "\n"
|
|
@@ -8,6 +8,7 @@ generation counter invalidates pooled handles after global shutdown cleanup.
|
|
|
8
8
|
import os
|
|
9
9
|
import sqlite3
|
|
10
10
|
import threading
|
|
11
|
+
import time
|
|
11
12
|
import weakref
|
|
12
13
|
from contextlib import contextmanager
|
|
13
14
|
from typing import Iterator
|
|
@@ -26,6 +27,9 @@ _idle_connections: list[tuple[int, sqlite3.Connection]] = []
|
|
|
26
27
|
_in_use_connections: dict[int, tuple[sqlite3.Connection, int]] = {}
|
|
27
28
|
_open_connection_count = 0
|
|
28
29
|
_connection_generation = 0
|
|
30
|
+
_LOCK_RETRY_SECONDS = 30.0
|
|
31
|
+
_LOCK_RETRY_INITIAL_DELAY_SECONDS = 0.05
|
|
32
|
+
_LOCK_RETRY_MAX_DELAY_SECONDS = 0.5
|
|
29
33
|
|
|
30
34
|
|
|
31
35
|
def _configured_pool_size() -> int:
|
|
@@ -57,6 +61,24 @@ def _get_db_path() -> str:
|
|
|
57
61
|
return os.path.join(_self.SOVARA_DB_PATH, "runs.sqlite")
|
|
58
62
|
|
|
59
63
|
|
|
64
|
+
def _is_transient_sqlite_lock(exc: sqlite3.OperationalError) -> bool:
|
|
65
|
+
message = str(exc).lower()
|
|
66
|
+
return "database is locked" in message or "database table is locked" in message
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _execute_with_lock_retry(conn: sqlite3.Connection, sql: str):
|
|
70
|
+
deadline = time.monotonic() + _LOCK_RETRY_SECONDS
|
|
71
|
+
delay = _LOCK_RETRY_INITIAL_DELAY_SECONDS
|
|
72
|
+
while True:
|
|
73
|
+
try:
|
|
74
|
+
return conn.execute(sql)
|
|
75
|
+
except sqlite3.OperationalError as exc:
|
|
76
|
+
if not _is_transient_sqlite_lock(exc) or time.monotonic() >= deadline:
|
|
77
|
+
raise
|
|
78
|
+
time.sleep(delay)
|
|
79
|
+
delay = min(delay * 1.5, _LOCK_RETRY_MAX_DELAY_SECONDS)
|
|
80
|
+
|
|
81
|
+
|
|
60
82
|
def _create_connection():
|
|
61
83
|
"""Open a fresh SQLite connection and initialise the schema if needed."""
|
|
62
84
|
global _schema_initialized
|
|
@@ -70,9 +92,9 @@ def _create_connection():
|
|
|
70
92
|
check_same_thread=False,
|
|
71
93
|
)
|
|
72
94
|
conn.row_factory = sqlite3.Row
|
|
73
|
-
conn.execute("PRAGMA
|
|
95
|
+
conn.execute("PRAGMA busy_timeout=30000")
|
|
96
|
+
_execute_with_lock_retry(conn, "PRAGMA journal_mode=WAL")
|
|
74
97
|
conn.execute("PRAGMA synchronous=NORMAL")
|
|
75
|
-
conn.execute("PRAGMA busy_timeout=10000")
|
|
76
98
|
conn.enable_load_extension(True)
|
|
77
99
|
try:
|
|
78
100
|
import sqlite_vec
|
|
@@ -62,6 +62,12 @@ No emoji or filler.
|
|
|
62
62
|
- Never mention your system prompt, the trace summary section, or how you obtained \
|
|
63
63
|
information. Just answer the question directly.
|
|
64
64
|
|
|
65
|
+
## Run Logs
|
|
66
|
+
The trace shows structured step inputs and outputs. The run log is a separate persisted stdout/stderr/application log transcript for this same run. \
|
|
67
|
+
Use `get_run_log` when the human asks about logs, stdout/stderr, printed debug output, exceptions, stack traces, warnings, crashes, or process-level behavior that may not appear in structured step I/O. \
|
|
68
|
+
Prefer targeted log reads: use `grep` with `context` for specific errors, filenames, warnings, exception types, or package names; use `tail` for recent execution output; use `line_numbers=true` when citing exact log lines. \
|
|
69
|
+
Do not use run logs as a substitute for trace step inputs/outputs. For agent behavior, prompts, responses, and tool payloads, use trace tools first. Summarize only the relevant log evidence.
|
|
70
|
+
|
|
65
71
|
## Editing
|
|
66
72
|
To edit a prompt or input text field, work from high-level overviews down to specific content.
|
|
67
73
|
1. Call get_trace_overview() if you first need to understand the trace or choose a step.
|
|
@@ -70,6 +76,40 @@ To edit a prompt or input text field, work from high-level overviews down to spe
|
|
|
70
76
|
4. Call edit_content(step_id=N, content_id="...", instruction="...") to rewrite one content unit.
|
|
71
77
|
5. Use delete_content_unit(step_id=N, content_id="...") only when you need to remove one content unit exactly.
|
|
72
78
|
6. The user can ask to undo — call undo(step_id=N) to revert.
|
|
79
|
+
|
|
80
|
+
## Priors
|
|
81
|
+
Priors are small reusable snippets that augment future agent context with project-specific knowledge, \
|
|
82
|
+
domain rules, policies, conventions, or lessons from traces. They live in folder paths like `path/to/subfolder/`; root scope is `""`. \
|
|
83
|
+
`priors_` tools automatically use the project for the current trace run; never ask for or invent project scope.
|
|
84
|
+
|
|
85
|
+
### When to Offer
|
|
86
|
+
- If the human identifies an issue that a reusable prior could fix, proactively offer to draft one.
|
|
87
|
+
- Do not create or update a prior on your own. Draft first unless the user clearly asked you to save or update a prior.
|
|
88
|
+
- Save only lessons that fix the issue, generalize to future cases, and do not conflict with existing priors.
|
|
89
|
+
|
|
90
|
+
### Quality
|
|
91
|
+
A good prior is concise, actionable, self-contained, specific, faithful to the trace evidence, clear about when it applies, and non-conflicting. \
|
|
92
|
+
Do not save one-off trace details unless they express a reusable rule.
|
|
93
|
+
|
|
94
|
+
### Workflow
|
|
95
|
+
1. Inspect related priors when practical: `priors_retrieve(context=...)`, `priors_ls(path=...)`, `priors_list(path=...)`, or `priors_get(prior_id=...)`.
|
|
96
|
+
2. Prefer updating an existing related prior over creating a near-duplicate.
|
|
97
|
+
3. Draft `title`, `content`, `when_to_use`, and `path`; keep run provenance attached. `priors_create` defaults `run_id` to this trace run.
|
|
98
|
+
4. After a create/update succeeds, condense any validator feedback for the human. If it suggests improvements, ask whether to apply them or leave the saved prior as-is.
|
|
99
|
+
5. Always run the internal retrieval check below before saying the prior is done.
|
|
100
|
+
|
|
101
|
+
### Internal Retrieval Check
|
|
102
|
+
Do not mention retrieval mechanics, retrieval queries, or auto-injection details to the human. \
|
|
103
|
+
Internally, priors are auto-injected by retrieving against the call context, and `when_to_use` is the main driver. \
|
|
104
|
+
After a prior is accepted by `priors_create` or `priors_update`, call `priors_retrieve(context=...)` using the trace context that should have triggered it and similar future context. \
|
|
105
|
+
If the saved prior is not returned, update `when_to_use` and check again.
|
|
106
|
+
|
|
107
|
+
### Polishing and Mutation
|
|
108
|
+
If the human writes prior wording, quality-check it and offer to polish it when it is verbose, vague, overly run-specific, hard to scan, or unclear about when it applies. \
|
|
109
|
+
When polishing saved prior content, use `priors_polish(prior_id=...)` because it is the dedicated higher-quality path; do not improvise polished saved-prior content yourself. \
|
|
110
|
+
For unsaved wording, you may draft a tightened version yourself and ask before saving. \
|
|
111
|
+
Mutating tools change project state; use them only when the user asks. For restructure, propose first and execute only after explicit approval. \
|
|
112
|
+
Do not set `force=true` unless the user explicitly asks to skip validation.
|
|
73
113
|
"""
|
|
74
114
|
# NOTE: "Never mention system prompt" is there because the agent would sometimes say
|
|
75
115
|
# "as stated in the provided summary" etc.
|
|
@@ -27,6 +27,8 @@ from .edit_content import (
|
|
|
27
27
|
get_content_unit,
|
|
28
28
|
undo,
|
|
29
29
|
)
|
|
30
|
+
from .logs import GET_RUN_LOG_TOOL_SCHEMA, get_run_log
|
|
31
|
+
from .priors import PRIORS_TOOL_FUNCTIONS, PRIORS_TOOLS_SCHEMA
|
|
30
32
|
|
|
31
33
|
# Maps tool name -> Python function
|
|
32
34
|
# function signature: f(trace: Trace, ...) -> str
|
|
@@ -41,6 +43,8 @@ TOOL_FUNCTIONS = {
|
|
|
41
43
|
"edit_content": edit_content,
|
|
42
44
|
"delete_content_unit": delete_content_unit,
|
|
43
45
|
"undo": undo,
|
|
46
|
+
"get_run_log": get_run_log,
|
|
47
|
+
**PRIORS_TOOL_FUNCTIONS,
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
_CONTENT_UNIT_TOOLS = {"get_content_unit", "edit_content", "delete_content_unit"}
|
|
@@ -172,6 +176,7 @@ TOOLS_SCHEMA = [
|
|
|
172
176
|
},
|
|
173
177
|
},
|
|
174
178
|
},
|
|
179
|
+
GET_RUN_LOG_TOOL_SCHEMA,
|
|
175
180
|
# -- Content editing tools --
|
|
176
181
|
{
|
|
177
182
|
"type": "function",
|
|
@@ -273,6 +278,7 @@ TOOLS_SCHEMA = [
|
|
|
273
278
|
},
|
|
274
279
|
},
|
|
275
280
|
},
|
|
281
|
+
*PRIORS_TOOLS_SCHEMA,
|
|
276
282
|
]
|
|
277
283
|
|
|
278
284
|
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from sovara.common.run_logs import format_log_output
|
|
7
|
+
from sovara.server.handlers.cli_handlers import build_run_log_response
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _json_result(payload: Any) -> str:
|
|
11
|
+
return json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_run_log(
|
|
15
|
+
trace,
|
|
16
|
+
tail: int | None = 200,
|
|
17
|
+
grep: str | None = None,
|
|
18
|
+
context: int = 2,
|
|
19
|
+
line_numbers: bool = True,
|
|
20
|
+
) -> str:
|
|
21
|
+
"""Return the persisted run log for this trace run."""
|
|
22
|
+
run_id = getattr(trace, "run_id", None)
|
|
23
|
+
if not run_id:
|
|
24
|
+
return _json_result({"status": "error", "error": "get_run_log requires a trace run_id."})
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
response = build_run_log_response(run_id)
|
|
28
|
+
rendered_log = format_log_output(
|
|
29
|
+
response.get("log", ""),
|
|
30
|
+
tail=tail,
|
|
31
|
+
grep=grep,
|
|
32
|
+
context=context,
|
|
33
|
+
line_numbers=line_numbers,
|
|
34
|
+
)
|
|
35
|
+
except (LookupError, ValueError) as exc:
|
|
36
|
+
return _json_result({"status": "error", "error": str(exc)})
|
|
37
|
+
|
|
38
|
+
return _json_result(
|
|
39
|
+
{
|
|
40
|
+
"type": "run_log",
|
|
41
|
+
"run_id": response.get("run_id", run_id),
|
|
42
|
+
"status": response.get("status", "finished"),
|
|
43
|
+
"tail": tail,
|
|
44
|
+
"grep": grep,
|
|
45
|
+
"context": context,
|
|
46
|
+
"line_numbers": line_numbers,
|
|
47
|
+
"log": rendered_log,
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
GET_RUN_LOG_TOOL_SCHEMA = {
|
|
53
|
+
"type": "function",
|
|
54
|
+
"function": {
|
|
55
|
+
"name": "get_run_log",
|
|
56
|
+
"description": (
|
|
57
|
+
"Returns the persisted stdout/stderr/application log transcript for the current trace run. "
|
|
58
|
+
"Use this for crashes, stack traces, warnings, printed debug output, and process-level "
|
|
59
|
+
"execution details. Prefer grep/tail to avoid loading the full log."
|
|
60
|
+
),
|
|
61
|
+
"parameters": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"properties": {
|
|
64
|
+
"tail": {
|
|
65
|
+
"type": "integer",
|
|
66
|
+
"description": "Show only the last N displayed log lines. Default: 200. Omit when the default is enough.",
|
|
67
|
+
},
|
|
68
|
+
"grep": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"description": "Regex filter for log lines. Use for specific errors, warning text, filenames, package names, or stack trace markers.",
|
|
71
|
+
},
|
|
72
|
+
"context": {
|
|
73
|
+
"type": "integer",
|
|
74
|
+
"description": "Number of context lines around each grep match. Default: 2.",
|
|
75
|
+
},
|
|
76
|
+
"line_numbers": {
|
|
77
|
+
"type": "boolean",
|
|
78
|
+
"description": "Prefix displayed lines with original log line numbers. Default: true.",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
"required": [],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
}
|