kolega-code 0.26.2__tar.gz → 0.26.4__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.
- {kolega_code-0.26.2 → kolega_code-0.26.4}/CHANGELOG.md +34 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/PKG-INFO +1 -1
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/__init__.py +1 -1
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/__init__.py +1 -1
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/baseagent.py +14 -6
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/browseragent.py +19 -2
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/coder.py +2 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/context.py +2 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/planningagent.py +2 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_codebase_tool.py +121 -30
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/terminal_tool.py +1 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/think_hard_tool.py +2 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/web_fetch_tool.py +1 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tools.py +29 -5
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/main.py +7 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/client.py +24 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/instrumented_client.py +4 -1
- kolega_code-0.26.4/kolega_code/llm/providers/deepseek_responses.py +66 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/deepseek.py +6 -1
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/memory/manager.py +49 -5
- kolega_code-0.26.4/kolega_code/tools/core.py +71 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/pyproject.toml +8 -2
- kolega_code-0.26.2/kolega_code/tools/core.py +0 -33
- {kolega_code-0.26.2 → kolega_code-0.26.4}/.gitignore +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/CONTRIBUTING.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/LICENSE +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/MIGRATION.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/README.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/RELEASING.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/LICENSE +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/manifest.json +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/deep-research/SKILL.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/deep-research/references/evidence-and-reporting.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/deep-research/references/gigacode-workflow.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/deep-research/scripts/deep-research.workflow +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/deep-research/scripts/materialize_report.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/docx/LICENSE +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/docx/SKILL.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/docx/references/examples.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/docx/references/limitations.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/docx/references/operations.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/docx/references/quality.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/docx/requirements.txt +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/docx/scripts/docx_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/docx/scripts/smoke_test.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/humanizer/LICENSE +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/humanizer/SKILL.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/LICENSE +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/SKILL.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/references/examples.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/references/limitations.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/references/ocr.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/references/operations.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/references/quality.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/references/redaction.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-paddle.txt +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-surya.txt +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/requirements.txt +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/scripts/pdf_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pdf/scripts/smoke_test.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pptx/LICENSE +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pptx/SKILL.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pptx/references/examples.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pptx/references/limitations.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pptx/references/operations.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pptx/requirements.txt +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pptx/scripts/pptx_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/pptx/scripts/smoke_test.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/review/SKILL.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/review/references/github-publishing.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/skill-authoring/SKILL.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/skill-authoring/references/review-checklist.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/xlsx/LICENSE +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/xlsx/SKILL.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/xlsx/references/examples.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/xlsx/references/limitations.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/xlsx/references/operations.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/xlsx/references/quality.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/xlsx/requirements.txt +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/xlsx/scripts/smoke_test.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/_bundled_skills/skills/xlsx/scripts/xlsx_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/common.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/compression.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/conversation.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/custom_agents.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/edit_protocols.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/errors.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/bridge.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/bundle-requirements.in +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/bundle-requirements.txt +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/env.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/js_kernel.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/kernel.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/prelude.js +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/prelude.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/protocol.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/py_kernel.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/runner.js +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/eval/runner.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/generalagent.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/goal.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/investigationagent.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/model_routing.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/accounting.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/budget.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/context.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/errors.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/executor.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/guide.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/journal.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/runtime.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/orchestration/types.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_dump.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_overrides.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_provider.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/extensions/cli/build_questions.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/extensions/cli/current_plan_artifact.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/extensions/cli/scratchpad.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list_readonly.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/extensions/cli/worktree_control.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/includes/context_updates.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/prompts.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/agent_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/base_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/build_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/codex_patch.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/edit_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/eval_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/glob_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/hashline_v2.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/list_directory_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/lsp_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/snapshot_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/web_fetch/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/web_fetch/answering.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/web_fetch/documents.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/web_fetch/extractors.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/web_fetch/pipeline.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/web_fetch/retrieval.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/workflow_tool.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/utils/commands.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/volatile_context.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/auth/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/auth/_jwt.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/auth/chatgpt_oauth.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/auth/constants.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/auth/tokens.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/browser_extension/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/browser_extension/framing.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/browser_extension/installer.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/browser_extension/manager.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/browser_extension/multiplex.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/browser_extension/native_host.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/browser_extension/protocol.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/browser_extension/registry.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/browser_extension/runtime.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/app.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/browser_backend.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/clipboard_image.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/config.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/connection.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/cron.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/diagnostics.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/file_index.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/goal.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/loop.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/mentions.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/messages.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/model_catalog.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/model_connection.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/plan_artifacts.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/provider_registry.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/session_event_store.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/session_journal.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/session_store.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/settings.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/skills.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/slash_commands.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/theme.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/agent_runtime.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/app_base.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/changes_screen.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/command_handlers.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/constants.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/custom_model.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/loop_runtime.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/memory_screen.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/onboarding_screen.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/prompt_flows.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/session_diff.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/settings_panel.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/settings_screen.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/state.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/status_dashboard.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/styles.tcss +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/sub_agent_screen.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/terminal_display.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/transcript.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/tui/widgets.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/cli/updater.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/config.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/events.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/git_env.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/hooks/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/hooks/backends.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/hooks/config.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/hooks/dispatcher.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/hooks/events.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/hooks/matcher.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/hooks/outcome.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/exceptions.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/models.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/providers/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/providers/anthropic.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/providers/base.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/providers/google.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/providers/models.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/providers/openai.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/providers/openai_responses.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/providers/responses_common.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/ratelimit.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/accessors.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/anthropic.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/dashscope.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/fireworks.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/google.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/kimi_coding.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/moonshot.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/ollama_cloud.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/openai.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/openai_chatgpt.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/openrouter.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/together.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/xai.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/catalog/zai.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/openrouter_catalog.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/thinking.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/specs/types.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/timeouts.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/llm/tool_execution_ids.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/local_state.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/mcp/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/mcp/config.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/mcp/oauth.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/mcp/service.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/mcp/state.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/mcp/tools.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/mcp/transport.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/memory/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/memory/identity.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/memory/manifest.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/memory/markdown.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/memory/models.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/memory/protocol.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/memory/registry.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/models/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/models/sandbox_terminal_state.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/permissions.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/runtime.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/README.md +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/async_filesystem.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/base.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/browser.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/event_loop.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/filesystem.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/local.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/serializer.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/terminal.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/sandbox/utils.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/scratchpad.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/security/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/security/secrets.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/base.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/browser.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/file_system.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/html.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/lsp/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/lsp/client.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/lsp/config.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/lsp/detector.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/lsp/diagnostics.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/lsp/edits.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/lsp/manager.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/lsp/registry.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/lsp/registry.yaml +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/snapshots.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/terminal.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/terminal_buffer.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/services/workspace_scan.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/session/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/session/control.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/session/inmemory.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/session/projection.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/session/recording.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/session/runtime.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/session/store.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/testing/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/testing/store_conformance.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/tools/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/tools/definitions.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/tools/registry.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/utils/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/utils/images.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/__init__.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/assets/fold.js +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/assets/player.css +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/assets/player.html +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/assets/player.js +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/bundle.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/hosting.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/redaction.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/server.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/singlefile.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/web/theme_css.py +0 -0
- {kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/worktrees.py +0 -0
|
@@ -6,6 +6,40 @@ This project uses GitHub Releases for detailed generated release notes. This fil
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.26.4 - 2026-08-02
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- `deepseek-v4-flash` now connects over DeepSeek's **Responses API**
|
|
14
|
+
(`https://api.deepseek.com`) for its native tool-calling format and graded
|
|
15
|
+
reasoning effort. Every other DeepSeek model (including `deepseek-v4-pro`)
|
|
16
|
+
continues to use the OpenAI-compatible Chat Completions endpoint. This is a
|
|
17
|
+
per-model routing decision; no configuration change is required.
|
|
18
|
+
|
|
19
|
+
## 0.26.3 - 2026-08-02
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- `kolega-code ask --no-memory-tools` disables the persistent project-memory
|
|
24
|
+
tools (read/list/write/edit/delete memory) and their prompt guidance for a
|
|
25
|
+
run — useful for headless or benchmark use where there is no durable memory
|
|
26
|
+
store.
|
|
27
|
+
- `search_codebase` accepts `path` to restrict the search to a subdirectory and
|
|
28
|
+
`max_results` to cap how many files are returned.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- `eval` now defaults `language` to `py`, so a call that omits the language runs
|
|
33
|
+
Python instead of failing.
|
|
34
|
+
- A tool call made with the wrong arguments now returns a clear message naming
|
|
35
|
+
the expected signature (for example `Usage: eval(code, language='py', …)`) and
|
|
36
|
+
no longer exposes internal class or method names.
|
|
37
|
+
- "Memory off" now has a single, consistent representation: a non-local host,
|
|
38
|
+
the new `--no-memory-tools` flag, and the memory toggle all behave the same
|
|
39
|
+
way, hiding both the memory tools and the memory prompt section.
|
|
40
|
+
- The browser agent's dispatch tool is now hidden when the model configured for
|
|
41
|
+
the browser agent cannot accept images, instead of failing only when invoked.
|
|
42
|
+
|
|
9
43
|
## 0.26.2 - 2026-07-31
|
|
10
44
|
|
|
11
45
|
### Added
|
|
@@ -170,6 +170,7 @@ class BaseAgent(LogMixin):
|
|
|
170
170
|
custom_agent_catalog: Optional[Any] = None,
|
|
171
171
|
memory_manager: Optional[Any] = None,
|
|
172
172
|
memory_project_path: Optional[Path] = None,
|
|
173
|
+
memory_enabled: bool = True,
|
|
173
174
|
) -> None:
|
|
174
175
|
"""
|
|
175
176
|
Initialize a new BaseAgent instance.
|
|
@@ -308,15 +309,21 @@ class BaseAgent(LogMixin):
|
|
|
308
309
|
from kolega_code.memory import MemoryAccessScope
|
|
309
310
|
|
|
310
311
|
self.memory_manager = self.memory_manager.with_scope(MemoryAccessScope.SUBAGENT)
|
|
311
|
-
|
|
312
|
-
# Keep non-local/sandbox hosts unchanged unless they inject a manager.
|
|
312
|
+
elif self.memory_manager is None and not sub_agent:
|
|
313
313
|
from kolega_code.cli.session_store import default_state_dir
|
|
314
314
|
from kolega_code.memory import ProjectMemoryManager
|
|
315
315
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
316
|
+
project = memory_project_path if memory_project_path is not None else self.project_path
|
|
317
|
+
# "Memory off" has one representation everywhere: a present-but-disabled
|
|
318
|
+
# manager, never a None. Memory is live only for a local project with the
|
|
319
|
+
# per-run opt-out unset; a non-local/sandbox host (whose storage would be a
|
|
320
|
+
# local state dir, disconnected from the remote project) or an explicit
|
|
321
|
+
# `--no-memory-tools` opt-out gets an inert, storage-inert manager that
|
|
322
|
+
# writes nothing. Dispatched sub-agents inherit whichever it is.
|
|
323
|
+
if memory_enabled and isinstance(self.filesystem, LocalFileSystem):
|
|
324
|
+
self.memory_manager = ProjectMemoryManager(project, default_state_dir())
|
|
325
|
+
else:
|
|
326
|
+
self.memory_manager = ProjectMemoryManager.disabled(project, default_state_dir())
|
|
320
327
|
self.context.services.memory_manager = self.memory_manager
|
|
321
328
|
self._owns_memory_manager = True
|
|
322
329
|
|
|
@@ -1392,6 +1399,7 @@ class BaseAgent(LogMixin):
|
|
|
1392
1399
|
client = LLMClient(
|
|
1393
1400
|
provider=model_config.provider.value,
|
|
1394
1401
|
api_key=self.config.get_api_key(model_config.provider) or "",
|
|
1402
|
+
model=model_config.model,
|
|
1395
1403
|
max_retries=model_config.rate_limits.max_retries,
|
|
1396
1404
|
requests_per_minute=model_config.rate_limits.requests_per_minute,
|
|
1397
1405
|
tokens_per_minute=model_config.rate_limits.tokens_per_minute,
|
|
@@ -19,13 +19,30 @@ class BrowserAgent(BaseAgent):
|
|
|
19
19
|
|
|
20
20
|
agent_name = "browser-agent"
|
|
21
21
|
|
|
22
|
+
@classmethod
|
|
23
|
+
def resolved_model_supports_vision(cls, config: AgentConfig) -> bool:
|
|
24
|
+
"""True if the model resolved for the browser-agent role accepts image input.
|
|
25
|
+
|
|
26
|
+
The browser agent may run on its own ``agent_models`` override, so this is
|
|
27
|
+
deliberately keyed on the browser-agent's resolved model — not the main
|
|
28
|
+
coding model, which can differ in either direction.
|
|
29
|
+
"""
|
|
30
|
+
model_config = config.model_config_for_agent(cls.agent_name)
|
|
31
|
+
provider = getattr(model_config.provider, "value", model_config.provider)
|
|
32
|
+
try:
|
|
33
|
+
return model_supports_vision(provider, model_config.model)
|
|
34
|
+
except ValueError:
|
|
35
|
+
# Unknown model → can't confirm image support → treat as no vision.
|
|
36
|
+
# This runs on every tool-list build, so it must never raise.
|
|
37
|
+
return False
|
|
38
|
+
|
|
22
39
|
@classmethod
|
|
23
40
|
def validate_model_capabilities(cls, config: AgentConfig) -> None:
|
|
24
41
|
"""Require the resolved browser-agent model to accept image input."""
|
|
42
|
+
if cls.resolved_model_supports_vision(config):
|
|
43
|
+
return
|
|
25
44
|
model_config = config.model_config_for_agent(cls.agent_name)
|
|
26
45
|
provider = getattr(model_config.provider, "value", model_config.provider)
|
|
27
|
-
if model_supports_vision(provider, model_config.model):
|
|
28
|
-
return
|
|
29
46
|
raise ValueError(
|
|
30
47
|
"BrowserAgent requires a vision-capable model, but "
|
|
31
48
|
f"{provider}/{model_config.model} does not support image input. "
|
|
@@ -53,6 +53,7 @@ class CoderAgent(BaseAgent, LogMixin):
|
|
|
53
53
|
custom_agent_catalog: Optional[Any] = None,
|
|
54
54
|
memory_manager: Optional[Any] = None,
|
|
55
55
|
memory_project_path: Optional[Path] = None,
|
|
56
|
+
memory_enabled: bool = True,
|
|
56
57
|
) -> None:
|
|
57
58
|
"""
|
|
58
59
|
Initialize a new CoderAgent instance.
|
|
@@ -117,6 +118,7 @@ class CoderAgent(BaseAgent, LogMixin):
|
|
|
117
118
|
custom_agent_catalog=custom_agent_catalog,
|
|
118
119
|
memory_manager=memory_manager,
|
|
119
120
|
memory_project_path=memory_project_path,
|
|
121
|
+
memory_enabled=memory_enabled,
|
|
120
122
|
)
|
|
121
123
|
|
|
122
124
|
# Configure tool collection with custom coder agent tools
|
|
@@ -109,6 +109,7 @@ class AgentContext:
|
|
|
109
109
|
return InstrumentedLLMClient(
|
|
110
110
|
provider=model_config.provider,
|
|
111
111
|
api_key=self.config.get_api_key(model_config.provider) or "",
|
|
112
|
+
model=model_config.model,
|
|
112
113
|
max_retries=model_config.rate_limits.max_retries,
|
|
113
114
|
requests_per_minute=model_config.rate_limits.requests_per_minute,
|
|
114
115
|
tokens_per_minute=model_config.rate_limits.tokens_per_minute,
|
|
@@ -126,6 +127,7 @@ class AgentContext:
|
|
|
126
127
|
return LLMClient(
|
|
127
128
|
provider=model_config.provider,
|
|
128
129
|
api_key=self.config.get_api_key(model_config.provider) or "",
|
|
130
|
+
model=model_config.model,
|
|
129
131
|
max_retries=model_config.rate_limits.max_retries,
|
|
130
132
|
requests_per_minute=model_config.rate_limits.requests_per_minute,
|
|
131
133
|
tokens_per_minute=model_config.rate_limits.tokens_per_minute,
|
|
@@ -47,6 +47,7 @@ class PlanningAgent(BaseAgent):
|
|
|
47
47
|
max_iterations: Optional[int] = None,
|
|
48
48
|
custom_agent_catalog: Optional[Any] = None,
|
|
49
49
|
memory_manager: Optional[Any] = None,
|
|
50
|
+
memory_enabled: bool = True,
|
|
50
51
|
) -> None:
|
|
51
52
|
if custom_agent_catalog is not None:
|
|
52
53
|
custom_agent_catalog = custom_agent_catalog.for_mode("plan")
|
|
@@ -81,6 +82,7 @@ class PlanningAgent(BaseAgent):
|
|
|
81
82
|
max_iterations=max_iterations,
|
|
82
83
|
custom_agent_catalog=custom_agent_catalog,
|
|
83
84
|
memory_manager=memory_manager,
|
|
85
|
+
memory_enabled=memory_enabled,
|
|
84
86
|
)
|
|
85
87
|
|
|
86
88
|
self._completed_plan: Optional[str] = None
|
{kolega_code-0.26.2 → kolega_code-0.26.4}/kolega_code/agent/tool_backend/search_codebase_tool.py
RENAMED
|
@@ -22,6 +22,8 @@ _RC_MARKER = "__KOLEGA_RG_RC"
|
|
|
22
22
|
|
|
23
23
|
# Display caps (shared by every engine via the single formatter).
|
|
24
24
|
_MAX_FILES = 128
|
|
25
|
+
# Ceiling for a caller-supplied ``max_results`` so a huge request can't flood context.
|
|
26
|
+
_MAX_FILES_CEILING = 512
|
|
25
27
|
_MAX_LINES_PER_FILE = 5
|
|
26
28
|
_MAX_LINE_LENGTH = 200
|
|
27
29
|
_MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
|
|
@@ -46,6 +48,10 @@ class _EngineUnavailable(Exception):
|
|
|
46
48
|
flag, non-regex error) so the caller falls back to the next engine tier."""
|
|
47
49
|
|
|
48
50
|
|
|
51
|
+
class _InvalidSearchPath(Exception):
|
|
52
|
+
"""A caller-supplied ``path`` that escapes the project or isn't a directory."""
|
|
53
|
+
|
|
54
|
+
|
|
49
55
|
class _SearchTimedOut(Exception):
|
|
50
56
|
"""Raised when an otherwise valid search exceeds its execution budget."""
|
|
51
57
|
|
|
@@ -147,6 +153,31 @@ class SearchCodebaseTool(BaseTool):
|
|
|
147
153
|
excluded.update(_BROAD_ROOT_EXCLUDE_DIRS)
|
|
148
154
|
return excluded
|
|
149
155
|
|
|
156
|
+
def _resolve_search_target(self, path: Optional[str]) -> str:
|
|
157
|
+
"""Validate a caller-supplied ``path`` and return a project-relative search
|
|
158
|
+
root (``.`` for the whole project). Rejects absolute paths, parent escapes,
|
|
159
|
+
and non-directories so the search can never wander outside the project."""
|
|
160
|
+
if not path or path.strip() in ("", ".", "./"):
|
|
161
|
+
return "."
|
|
162
|
+
candidate = Path(path.strip())
|
|
163
|
+
if candidate.is_absolute() or ".." in candidate.parts:
|
|
164
|
+
raise _InvalidSearchPath(f"path must be a relative directory inside the project, got '{path}'")
|
|
165
|
+
rel = candidate.as_posix().strip("/")
|
|
166
|
+
if not rel:
|
|
167
|
+
return "."
|
|
168
|
+
try:
|
|
169
|
+
exists = self.filesystem.exists(rel)
|
|
170
|
+
is_dir = exists and self.filesystem.is_dir(rel)
|
|
171
|
+
except Exception:
|
|
172
|
+
# If the filesystem can't answer (e.g. an exotic sandbox), let the
|
|
173
|
+
# engine handle the path rather than blocking a legitimate search.
|
|
174
|
+
return rel
|
|
175
|
+
if not exists:
|
|
176
|
+
raise _InvalidSearchPath(f"path '{path}' was not found in the project")
|
|
177
|
+
if not is_dir:
|
|
178
|
+
raise _InvalidSearchPath(f"path '{path}' is not a directory; use file_pattern to filter files")
|
|
179
|
+
return rel
|
|
180
|
+
|
|
150
181
|
async def search_codebase(
|
|
151
182
|
self,
|
|
152
183
|
pattern: str,
|
|
@@ -154,6 +185,8 @@ class SearchCodebaseTool(BaseTool):
|
|
|
154
185
|
case_sensitive: bool = False,
|
|
155
186
|
literal: bool = False,
|
|
156
187
|
*,
|
|
188
|
+
path: Optional[str] = None,
|
|
189
|
+
max_results: int = _MAX_FILES,
|
|
157
190
|
line_formatter: Optional[Callable[[int, str], str]] = None,
|
|
158
191
|
) -> str:
|
|
159
192
|
"""
|
|
@@ -170,9 +203,11 @@ class SearchCodebaseTool(BaseTool):
|
|
|
170
203
|
file_pattern: Optional glob to filter which files to search (default: all files)
|
|
171
204
|
case_sensitive: Whether the search is case-sensitive (default: False)
|
|
172
205
|
literal: Treat the pattern as plain text instead of a regular expression (default: False)
|
|
206
|
+
path: Optional directory (relative to the project root) to restrict the search to; searches the whole project when omitted
|
|
207
|
+
max_results: Maximum number of matching files to return (default 128, capped at 512)
|
|
173
208
|
|
|
174
209
|
Returns:
|
|
175
|
-
Markdown formatted list of files and matches,
|
|
210
|
+
Markdown formatted list of files and matches, capped at ``max_results`` files
|
|
176
211
|
|
|
177
212
|
Raises:
|
|
178
213
|
Exception: If any error occurs during the search operation
|
|
@@ -198,10 +233,16 @@ class SearchCodebaseTool(BaseTool):
|
|
|
198
233
|
await self.log_error(error_msg, sender=self.caller.agent_name)
|
|
199
234
|
return f"Error: {error_msg}"
|
|
200
235
|
|
|
236
|
+
limit = max(1, min(int(max_results), _MAX_FILES_CEILING))
|
|
237
|
+
try:
|
|
238
|
+
search_target = self._resolve_search_target(path)
|
|
239
|
+
except _InvalidSearchPath as exc:
|
|
240
|
+
return f"Error: {exc}"
|
|
241
|
+
|
|
201
242
|
# Run the first available engine; fall back down the tiers on failure.
|
|
202
243
|
for runner in await self._engine_chain():
|
|
203
244
|
try:
|
|
204
|
-
run = await runner(pattern, file_pattern, case_sensitive, literal, regex)
|
|
245
|
+
run = await runner(pattern, file_pattern, case_sensitive, literal, regex, search_target, limit)
|
|
205
246
|
except _EngineUnavailable:
|
|
206
247
|
continue
|
|
207
248
|
except _SearchTimedOut:
|
|
@@ -213,7 +254,7 @@ class SearchCodebaseTool(BaseTool):
|
|
|
213
254
|
f"elapsed={run.elapsed_seconds:.2f}s)",
|
|
214
255
|
sender=self.caller.agent_name,
|
|
215
256
|
)
|
|
216
|
-
return self._format_results(run, pattern, line_formatter=line_formatter)
|
|
257
|
+
return self._format_results(run, pattern, limit=limit, line_formatter=line_formatter)
|
|
217
258
|
|
|
218
259
|
# The Python tier never raises _EngineUnavailable, so this is unreachable.
|
|
219
260
|
return f"No matches found for pattern '{pattern}'"
|
|
@@ -266,7 +307,9 @@ class SearchCodebaseTool(BaseTool):
|
|
|
266
307
|
# ripgrep engine
|
|
267
308
|
# ------------------------------------------------------------------
|
|
268
309
|
|
|
269
|
-
def _rg_args(
|
|
310
|
+
def _rg_args(
|
|
311
|
+
self, pattern: str, file_pattern: str, case_sensitive: bool, literal: bool, search_target: str = "."
|
|
312
|
+
) -> List[str]:
|
|
270
313
|
args = [
|
|
271
314
|
"--json",
|
|
272
315
|
"--no-config",
|
|
@@ -297,17 +340,25 @@ class SearchCodebaseTool(BaseTool):
|
|
|
297
340
|
if file_pattern != "*":
|
|
298
341
|
glob = file_pattern if "/" not in file_pattern else f"**/{file_pattern}"
|
|
299
342
|
args += ["-g", glob]
|
|
300
|
-
# Pattern as its own argv element (after -e) and an explicit search path
|
|
301
|
-
#
|
|
302
|
-
|
|
343
|
+
# Pattern as its own argv element (after -e) and an explicit search path
|
|
344
|
+
# (the whole tree, or the caller's ``path`` subtree) so ripgrep never reads
|
|
345
|
+
# stdin in a headless context.
|
|
346
|
+
args += ["-e", pattern, search_target]
|
|
303
347
|
return args
|
|
304
348
|
|
|
305
349
|
async def _run_rg_local(
|
|
306
|
-
self,
|
|
350
|
+
self,
|
|
351
|
+
pattern: str,
|
|
352
|
+
file_pattern: str,
|
|
353
|
+
case_sensitive: bool,
|
|
354
|
+
literal: bool,
|
|
355
|
+
regex,
|
|
356
|
+
search_target: str = ".",
|
|
357
|
+
limit: int = _MAX_FILES,
|
|
307
358
|
) -> SearchRun:
|
|
308
359
|
if shutil.which("rg") is None:
|
|
309
360
|
raise _EngineUnavailable()
|
|
310
|
-
args = self._rg_args(pattern, file_pattern, case_sensitive, literal)
|
|
361
|
+
args = self._rg_args(pattern, file_pattern, case_sensitive, literal, search_target)
|
|
311
362
|
env = {**os.environ, "RIPGREP_CONFIG_FILE": ""}
|
|
312
363
|
try:
|
|
313
364
|
proc = await asyncio.create_subprocess_exec(
|
|
@@ -329,9 +380,16 @@ class SearchCodebaseTool(BaseTool):
|
|
|
329
380
|
return SearchRun(self._parse_rg_json(stdout.decode("utf-8", "replace")))
|
|
330
381
|
|
|
331
382
|
async def _run_rg_sandbox(
|
|
332
|
-
self,
|
|
383
|
+
self,
|
|
384
|
+
pattern: str,
|
|
385
|
+
file_pattern: str,
|
|
386
|
+
case_sensitive: bool,
|
|
387
|
+
literal: bool,
|
|
388
|
+
regex,
|
|
389
|
+
search_target: str = ".",
|
|
390
|
+
limit: int = _MAX_FILES,
|
|
333
391
|
) -> SearchRun:
|
|
334
|
-
args = self._rg_args(pattern, file_pattern, case_sensitive, literal)
|
|
392
|
+
args = self._rg_args(pattern, file_pattern, case_sensitive, literal, search_target)
|
|
335
393
|
cmd = "RIPGREP_CONFIG_FILE= rg " + " ".join(shlex.quote(a) for a in args)
|
|
336
394
|
full_cmd = f"cd {shlex.quote(self._fs_root)} && {cmd} ; echo {_RC_MARKER}=$?"
|
|
337
395
|
try:
|
|
@@ -390,7 +448,9 @@ class SearchCodebaseTool(BaseTool):
|
|
|
390
448
|
# grep engine
|
|
391
449
|
# ------------------------------------------------------------------
|
|
392
450
|
|
|
393
|
-
def _grep_argv(
|
|
451
|
+
def _grep_argv(
|
|
452
|
+
self, pattern: str, file_pattern: str, case_sensitive: bool, literal: bool, search_target: str = "."
|
|
453
|
+
) -> List[str]:
|
|
394
454
|
argv = ["grep", "-r", "-n", "--binary-files=without-match"]
|
|
395
455
|
if not case_sensitive:
|
|
396
456
|
argv.append("-i")
|
|
@@ -403,16 +463,24 @@ class SearchCodebaseTool(BaseTool):
|
|
|
403
463
|
argv.append("--exclude-dir=.*")
|
|
404
464
|
for ext in sorted(self.BINARY_EXTENSIONS):
|
|
405
465
|
argv.append(f"--exclude=*{ext}")
|
|
406
|
-
# -e guards a pattern that starts with '-';
|
|
407
|
-
|
|
466
|
+
# -e guards a pattern that starts with '-'; search_target is the search
|
|
467
|
+
# root (the whole tree, or the caller's ``path`` subtree).
|
|
468
|
+
argv += ["-e", pattern, search_target]
|
|
408
469
|
return argv
|
|
409
470
|
|
|
410
471
|
async def _run_grep_local(
|
|
411
|
-
self,
|
|
472
|
+
self,
|
|
473
|
+
pattern: str,
|
|
474
|
+
file_pattern: str,
|
|
475
|
+
case_sensitive: bool,
|
|
476
|
+
literal: bool,
|
|
477
|
+
regex,
|
|
478
|
+
search_target: str = ".",
|
|
479
|
+
limit: int = _MAX_FILES,
|
|
412
480
|
) -> SearchRun:
|
|
413
481
|
if shutil.which("grep") is None:
|
|
414
482
|
raise _EngineUnavailable()
|
|
415
|
-
argv = self._grep_argv(pattern, file_pattern, case_sensitive, literal)
|
|
483
|
+
argv = self._grep_argv(pattern, file_pattern, case_sensitive, literal, search_target)
|
|
416
484
|
try:
|
|
417
485
|
proc = await asyncio.create_subprocess_exec(
|
|
418
486
|
*argv,
|
|
@@ -431,9 +499,16 @@ class SearchCodebaseTool(BaseTool):
|
|
|
431
499
|
return SearchRun(self._drop_oversize_local(records))
|
|
432
500
|
|
|
433
501
|
async def _run_grep_sandbox(
|
|
434
|
-
self,
|
|
502
|
+
self,
|
|
503
|
+
pattern: str,
|
|
504
|
+
file_pattern: str,
|
|
505
|
+
case_sensitive: bool,
|
|
506
|
+
literal: bool,
|
|
507
|
+
regex,
|
|
508
|
+
search_target: str = ".",
|
|
509
|
+
limit: int = _MAX_FILES,
|
|
435
510
|
) -> SearchRun:
|
|
436
|
-
argv = self._grep_argv(pattern, file_pattern, case_sensitive, literal)
|
|
511
|
+
argv = self._grep_argv(pattern, file_pattern, case_sensitive, literal, search_target)
|
|
437
512
|
cmd = " ".join(shlex.quote(a) for a in argv)
|
|
438
513
|
full_cmd = f"cd {shlex.quote(self._fs_root)} && {cmd} ; echo {_RC_MARKER}=$?"
|
|
439
514
|
try:
|
|
@@ -524,15 +599,23 @@ class SearchCodebaseTool(BaseTool):
|
|
|
524
599
|
# ------------------------------------------------------------------
|
|
525
600
|
|
|
526
601
|
async def _run_python(
|
|
527
|
-
self,
|
|
602
|
+
self,
|
|
603
|
+
pattern: str,
|
|
604
|
+
file_pattern: str,
|
|
605
|
+
case_sensitive: bool,
|
|
606
|
+
literal: bool,
|
|
607
|
+
regex,
|
|
608
|
+
search_target: str = ".",
|
|
609
|
+
limit: int = _MAX_FILES,
|
|
528
610
|
) -> SearchRun:
|
|
529
611
|
if hasattr(self.filesystem, "sandbox"):
|
|
530
|
-
return await self._run_python_sandbox_fallback(file_pattern, regex)
|
|
612
|
+
return await self._run_python_sandbox_fallback(file_pattern, regex, search_target, limit)
|
|
531
613
|
|
|
532
614
|
normalized_pattern = "**/*" if file_pattern == "*" else f"**/{file_pattern}"
|
|
533
615
|
self._load_gitignore_patterns()
|
|
616
|
+
scan_root = Path(self._fs_root) if search_target == "." else Path(self._fs_root) / search_target
|
|
534
617
|
scan = await scan_workspace(
|
|
535
|
-
|
|
618
|
+
scan_root,
|
|
536
619
|
pattern=normalized_pattern,
|
|
537
620
|
include_files=True,
|
|
538
621
|
include_directories=False,
|
|
@@ -543,9 +626,9 @@ class SearchCodebaseTool(BaseTool):
|
|
|
543
626
|
ignore_spec=getattr(self, "_gitignore_spec", None),
|
|
544
627
|
limits=ScanLimits(timeout_seconds=_SCAN_TIMEOUT_SECONDS, max_entries=_SCAN_MAX_ENTRIES),
|
|
545
628
|
)
|
|
546
|
-
return await self._search_scanned_files(scan, regex)
|
|
629
|
+
return await self._search_scanned_files(scan, regex, limit)
|
|
547
630
|
|
|
548
|
-
async def _search_scanned_files(self, scan: ScanOutcome, regex) -> SearchRun:
|
|
631
|
+
async def _search_scanned_files(self, scan: ScanOutcome, regex, limit: int = _MAX_FILES) -> SearchRun:
|
|
549
632
|
cancel_event = threading.Event()
|
|
550
633
|
started = time.monotonic()
|
|
551
634
|
remaining = max(0.01, _SEARCH_TIMEOUT_SECONDS - scan.elapsed_seconds)
|
|
@@ -570,7 +653,7 @@ class SearchCodebaseTool(BaseTool):
|
|
|
570
653
|
if regex.search(line):
|
|
571
654
|
records.append((norm, line_num, line))
|
|
572
655
|
matched_files.add(norm)
|
|
573
|
-
if len(matched_files) >
|
|
656
|
+
if len(matched_files) > limit:
|
|
574
657
|
return SearchRun(
|
|
575
658
|
records,
|
|
576
659
|
False,
|
|
@@ -598,28 +681,37 @@ class SearchCodebaseTool(BaseTool):
|
|
|
598
681
|
task.cancel()
|
|
599
682
|
return SearchRun([], False, "deadline", scan.visited_entries, _SEARCH_TIMEOUT_SECONDS)
|
|
600
683
|
|
|
601
|
-
async def _run_python_sandbox_fallback(
|
|
684
|
+
async def _run_python_sandbox_fallback(
|
|
685
|
+
self, file_pattern: str, regex, search_target: str = ".", limit: int = _MAX_FILES
|
|
686
|
+
) -> SearchRun:
|
|
602
687
|
"""Keep the legacy remote-files fallback off-loop and time bounded."""
|
|
603
688
|
cancel_event = threading.Event()
|
|
604
689
|
started = time.monotonic()
|
|
690
|
+
prefix = "" if search_target == "." else search_target.rstrip("/") + "/"
|
|
605
691
|
|
|
606
692
|
def search() -> SearchRun:
|
|
607
693
|
records: List[Record] = []
|
|
694
|
+
matched_files: set[str] = set()
|
|
608
695
|
for file_path, file_size in self._get_files_batch_sync(file_pattern):
|
|
609
696
|
if cancel_event.is_set() or time.monotonic() - started >= _SEARCH_TIMEOUT_SECONDS:
|
|
610
697
|
return SearchRun(records, False, "deadline", elapsed_seconds=time.monotonic() - started)
|
|
611
698
|
if file_size > _MAX_FILE_SIZE or self._is_likely_binary_by_extension(file_path):
|
|
612
699
|
continue
|
|
700
|
+
norm = self._normalize_path(file_path)
|
|
701
|
+
if prefix and not norm.startswith(prefix):
|
|
702
|
+
continue
|
|
613
703
|
try:
|
|
614
704
|
content = self.filesystem.read_text(file_path)
|
|
615
705
|
if "\x00" in content[:1024]:
|
|
616
706
|
continue
|
|
617
707
|
except Exception:
|
|
618
708
|
continue
|
|
619
|
-
norm = self._normalize_path(file_path)
|
|
620
709
|
for line_num, line in enumerate(content.splitlines(), start=1):
|
|
621
710
|
if regex.search(line):
|
|
622
711
|
records.append((norm, line_num, line))
|
|
712
|
+
matched_files.add(norm)
|
|
713
|
+
if len(matched_files) > limit:
|
|
714
|
+
return SearchRun(records, False, "result_limit", elapsed_seconds=time.monotonic() - started)
|
|
623
715
|
return SearchRun(records, elapsed_seconds=time.monotonic() - started)
|
|
624
716
|
|
|
625
717
|
task = asyncio.create_task(asyncio.to_thread(search))
|
|
@@ -643,6 +735,7 @@ class SearchCodebaseTool(BaseTool):
|
|
|
643
735
|
run: SearchRun,
|
|
644
736
|
original_pattern: str,
|
|
645
737
|
*,
|
|
738
|
+
limit: int = _MAX_FILES,
|
|
646
739
|
line_formatter: Optional[Callable[[int, str], str]] = None,
|
|
647
740
|
) -> str:
|
|
648
741
|
"""Group records by file (first-seen order), apply the display caps, and
|
|
@@ -652,7 +745,7 @@ class SearchCodebaseTool(BaseTool):
|
|
|
652
745
|
for path, line_num, raw in run.records:
|
|
653
746
|
if path in files:
|
|
654
747
|
files[path].append((line_num, raw))
|
|
655
|
-
elif len(files) <
|
|
748
|
+
elif len(files) < limit:
|
|
656
749
|
files[path] = [(line_num, raw)]
|
|
657
750
|
else:
|
|
658
751
|
limit_hit = True
|
|
@@ -690,9 +783,7 @@ class SearchCodebaseTool(BaseTool):
|
|
|
690
783
|
|
|
691
784
|
output = f"# Search Results for '{original_pattern}'\n\n"
|
|
692
785
|
if limit_hit or run.stop_reason == "result_limit":
|
|
693
|
-
output +=
|
|
694
|
-
f"⚠️ **Note:** Showing only the first {_MAX_FILES} results. There are more matches in the codebase.\n\n"
|
|
695
|
-
)
|
|
786
|
+
output += f"⚠️ **Note:** Showing only the first {limit} results. There are more matches in the codebase.\n\n"
|
|
696
787
|
elif not run.complete:
|
|
697
788
|
output += (
|
|
698
789
|
f"⚠️ **Incomplete search:** stopped because of {run.stop_reason or 'a search limit'}. "
|
|
@@ -76,6 +76,7 @@ class TerminalTool(BaseTool):
|
|
|
76
76
|
client = LLMClient(
|
|
77
77
|
provider=provider.value,
|
|
78
78
|
api_key=api_key or "",
|
|
79
|
+
model=self.config.fast_config.model,
|
|
79
80
|
max_retries=rate_limits.max_retries,
|
|
80
81
|
requests_per_minute=rate_limits.requests_per_minute,
|
|
81
82
|
tokens_per_minute=rate_limits.tokens_per_minute,
|
|
@@ -37,6 +37,7 @@ class ThinkHardTool(StreamingTool):
|
|
|
37
37
|
client = InstrumentedLLMClient(
|
|
38
38
|
provider=provider.value,
|
|
39
39
|
api_key=api_key or "",
|
|
40
|
+
model=self.config.thinking_config.model,
|
|
40
41
|
max_retries=rate_limits.max_retries,
|
|
41
42
|
requests_per_minute=rate_limits.requests_per_minute,
|
|
42
43
|
tokens_per_minute=rate_limits.tokens_per_minute,
|
|
@@ -54,6 +55,7 @@ class ThinkHardTool(StreamingTool):
|
|
|
54
55
|
client = LLMClient(
|
|
55
56
|
provider=provider.value,
|
|
56
57
|
api_key=api_key or "",
|
|
58
|
+
model=self.config.thinking_config.model,
|
|
57
59
|
max_retries=rate_limits.max_retries,
|
|
58
60
|
requests_per_minute=rate_limits.requests_per_minute,
|
|
59
61
|
tokens_per_minute=rate_limits.tokens_per_minute,
|
|
@@ -142,6 +142,7 @@ class WebFetchTool(StreamingTool):
|
|
|
142
142
|
client_kwargs = {
|
|
143
143
|
"provider": provider.value,
|
|
144
144
|
"api_key": self.config.get_api_key(provider),
|
|
145
|
+
"model": self.config.fast_config.model,
|
|
145
146
|
"max_retries": rate_limits.max_retries,
|
|
146
147
|
"requests_per_minute": rate_limits.requests_per_minute,
|
|
147
148
|
"tokens_per_minute": rate_limits.tokens_per_minute,
|
|
@@ -2003,8 +2003,8 @@ class ToolCollection(LogMixin):
|
|
|
2003
2003
|
|
|
2004
2004
|
async def eval(
|
|
2005
2005
|
self,
|
|
2006
|
-
language: str,
|
|
2007
2006
|
code: str,
|
|
2007
|
+
language: str = "py",
|
|
2008
2008
|
title: Optional[str] = None,
|
|
2009
2009
|
timeout: Optional[float] = None,
|
|
2010
2010
|
reset: bool = False,
|
|
@@ -2034,8 +2034,8 @@ class ToolCollection(LogMixin):
|
|
|
2034
2034
|
Top-level await works; declarations inside await-wrapped cells do NOT persist — use setGlobal(name, value) for cross-cell state there. Redeclaring an existing top-level name errors: assign without redeclaring, or pass reset=true.
|
|
2035
2035
|
|
|
2036
2036
|
Args:
|
|
2037
|
-
language: "py" for the persistent Python kernel, "js" for the persistent JavaScript kernel (js needs bun or node >= 18 on PATH).
|
|
2038
2037
|
code: code to run in this eval call, verbatim. Top-level await is fine.
|
|
2038
|
+
language: which kernel to run in; defaults to "py" (the persistent Python kernel). Pass "js" for the persistent JavaScript kernel (needs bun or node >= 18 on PATH).
|
|
2039
2039
|
title: short label for this step shown in the transcript (e.g. "load csv", "chart by region").
|
|
2040
2040
|
timeout: timeout for this cell in seconds; 0 disables it. Default 120, max 600.
|
|
2041
2041
|
reset: wipe this language's kernel before running (fresh state). The other language is untouched.
|
|
@@ -2199,7 +2199,13 @@ class ToolCollection(LogMixin):
|
|
|
2199
2199
|
return await self.memory_tool.delete_memory(path)
|
|
2200
2200
|
|
|
2201
2201
|
async def search_codebase(
|
|
2202
|
-
self,
|
|
2202
|
+
self,
|
|
2203
|
+
pattern: str,
|
|
2204
|
+
file_pattern: str = "*",
|
|
2205
|
+
case_sensitive: bool = False,
|
|
2206
|
+
literal: bool = False,
|
|
2207
|
+
path: Optional[str] = None,
|
|
2208
|
+
max_results: int = 128,
|
|
2203
2209
|
) -> str:
|
|
2204
2210
|
"""
|
|
2205
2211
|
Search the codebase for lines matching a regular expression (grep/ripgrep).
|
|
@@ -2210,14 +2216,19 @@ class ToolCollection(LogMixin):
|
|
|
2210
2216
|
`^ $`, quantifiers `* + ? {n,m}`, groups `(...)`). Set `literal=True` to match
|
|
2211
2217
|
the pattern as plain text instead (e.g. to find `arr[0]` or `a||b` verbatim).
|
|
2212
2218
|
|
|
2219
|
+
Narrow a search with `path` (search only within a subdirectory) and
|
|
2220
|
+
`max_results` (cap the number of files returned).
|
|
2221
|
+
|
|
2213
2222
|
Args:
|
|
2214
2223
|
pattern: The regular expression to search for (use `literal=True` to match it as plain text)
|
|
2215
|
-
file_pattern:
|
|
2224
|
+
file_pattern: Glob to filter which files to search by name, e.g. `*.py` (default: all files)
|
|
2216
2225
|
case_sensitive: Whether the search is case-sensitive (default: False)
|
|
2217
2226
|
literal: Treat the pattern as plain text instead of a regular expression (default: False)
|
|
2227
|
+
path: Directory (relative to the project root) to search within; searches the whole project when omitted
|
|
2228
|
+
max_results: Maximum number of matching files to return (default 128, capped at 512)
|
|
2218
2229
|
|
|
2219
2230
|
Returns:
|
|
2220
|
-
Markdown formatted list of files and matches,
|
|
2231
|
+
Markdown formatted list of files and matches, capped at `max_results` files
|
|
2221
2232
|
|
|
2222
2233
|
Raises:
|
|
2223
2234
|
Exception: If any error occurs during the search operation
|
|
@@ -2236,6 +2247,8 @@ class ToolCollection(LogMixin):
|
|
|
2236
2247
|
"file_pattern": file_pattern,
|
|
2237
2248
|
"case_sensitive": case_sensitive,
|
|
2238
2249
|
"literal": literal,
|
|
2250
|
+
"path": path,
|
|
2251
|
+
"max_results": max_results,
|
|
2239
2252
|
}
|
|
2240
2253
|
if formatter is not None:
|
|
2241
2254
|
kwargs["line_formatter"] = formatter
|
|
@@ -2680,6 +2693,17 @@ class ToolCollection(LogMixin):
|
|
|
2680
2693
|
if method_name == "read_image":
|
|
2681
2694
|
return bool(getattr(self.caller, "supports_vision", False))
|
|
2682
2695
|
|
|
2696
|
+
# Vision gate: dispatching the browser agent only works when the model
|
|
2697
|
+
# resolved for the browser-agent role accepts images (it reads page
|
|
2698
|
+
# screenshots). That model may differ from the main one, so gate on it —
|
|
2699
|
+
# not caller.supports_vision — rather than offer a call that can only
|
|
2700
|
+
# fail at dispatch.
|
|
2701
|
+
if method_name == "dispatch_browser_agent":
|
|
2702
|
+
from kolega_code.agent.browseragent import BrowserAgent
|
|
2703
|
+
|
|
2704
|
+
if not BrowserAgent.resolved_model_supports_vision(self.config):
|
|
2705
|
+
return False
|
|
2706
|
+
|
|
2683
2707
|
# Settings gate: eval can be disabled host-wide (AgentConfig.eval_enabled).
|
|
2684
2708
|
# Strict `is False` so Mock configs in tests keep the default (enabled).
|
|
2685
2709
|
if method_name == "eval" and getattr(self.config, "eval_enabled", True) is False:
|