kolega-code 0.26.9__tar.gz → 0.27.0__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.9 → kolega_code-0.27.0}/CHANGELOG.md +255 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/PKG-INFO +2 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/__init__.py +1 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/__init__.py +1 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/baseagent.py +190 -5
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/coder.py +5 -6
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/conversation.py +4 -3
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/kernel.py +31 -4
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/extensions/cli/current_plan_artifact.md.j2 +1 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/extensions/cli/scratchpad.md.j2 +2 -0
- kolega_code-0.27.0/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +6 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +1 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/agents/coder_base.md.j2 +31 -43
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +1 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +3 -3
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +3 -1
- kolega_code-0.27.0/kolega_code/agent/prompt_templates/system/includes/terminal_tools.md +11 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +1 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompts.py +0 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/edit_tool.py +22 -24
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/eval_tool.py +1 -0
- kolega_code-0.27.0/kolega_code/agent/tool_backend/read_file_tool.py +155 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/terminal_tool.py +18 -4
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tools.py +265 -614
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/app.py +4 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/ask_output.py +13 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/config.py +49 -20
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/file_index.py +67 -3
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/main.py +44 -9
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/messages.py +2 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/provider_registry.py +0 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/session_store.py +5 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/settings.py +14 -4
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/skills.py +58 -171
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/agent_runtime.py +8 -3
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/app_base.py +1 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/command_handlers.py +38 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/settings_panel.py +15 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/settings_screen.py +14 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/state.py +8 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/styles.tcss +5 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/transcript.py +75 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/widgets.py +25 -2
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/config.py +7 -9
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/client.py +8 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/ledger.py +1 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/models.py +172 -20
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/deepseek_responses.py +24 -6
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/models.py +3 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/openai.py +25 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/responses_common.py +128 -42
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/__init__.py +2 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/accessors.py +13 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/deepseek.py +15 -2
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/openai.py +12 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/openai_chatgpt.py +13 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/usage.py +14 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/permissions.py +1 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/terminal.py +21 -2
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/tools/__init__.py +2 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/tools/core.py +15 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/tools/definitions.py +54 -1
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/tools/param_aliases.py +52 -12
- {kolega_code-0.26.9 → kolega_code-0.27.0}/pyproject.toml +16 -4
- kolega_code-0.26.9/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +0 -13
- kolega_code-0.26.9/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -7
- kolega_code-0.26.9/kolega_code/agent/tool_backend/glob_tool.py +0 -533
- kolega_code-0.26.9/kolega_code/agent/tool_backend/list_directory_tool.py +0 -304
- kolega_code-0.26.9/kolega_code/agent/tool_backend/read_file_tool.py +0 -160
- kolega_code-0.26.9/kolega_code/agent/tool_backend/search_codebase_tool.py +0 -870
- kolega_code-0.26.9/kolega_code/agent/tool_backend/think_hard_tool.py +0 -220
- {kolega_code-0.26.9 → kolega_code-0.27.0}/.gitignore +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/CONTRIBUTING.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/LICENSE +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/MIGRATION.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/README.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/RELEASING.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/LICENSE +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/manifest.json +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/deep-research/SKILL.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/deep-research/references/evidence-and-reporting.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/deep-research/references/gigacode-workflow.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/deep-research/scripts/deep-research.workflow +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/deep-research/scripts/materialize_report.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/docx/LICENSE +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/docx/SKILL.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/docx/references/examples.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/docx/references/limitations.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/docx/references/operations.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/docx/references/quality.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/docx/requirements.txt +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/docx/scripts/docx_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/docx/scripts/smoke_test.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/humanizer/LICENSE +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/humanizer/SKILL.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/LICENSE +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/SKILL.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/references/examples.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/references/limitations.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/references/ocr.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/references/operations.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/references/quality.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/references/redaction.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-paddle.txt +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-surya.txt +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/requirements.txt +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/scripts/pdf_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pdf/scripts/smoke_test.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pptx/LICENSE +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pptx/SKILL.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pptx/references/examples.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pptx/references/limitations.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pptx/references/operations.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pptx/requirements.txt +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pptx/scripts/pptx_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/pptx/scripts/smoke_test.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/review/SKILL.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/review/references/github-publishing.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/skill-authoring/SKILL.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/skill-authoring/references/review-checklist.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/xlsx/LICENSE +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/xlsx/SKILL.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/xlsx/references/examples.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/xlsx/references/limitations.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/xlsx/references/operations.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/xlsx/references/quality.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/xlsx/requirements.txt +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/xlsx/scripts/smoke_test.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/_bundled_skills/skills/xlsx/scripts/xlsx_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/browseragent.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/common.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/compression.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/context.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/custom_agents.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/edit_protocols.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/errors.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/bridge.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/bundle-requirements.in +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/bundle-requirements.txt +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/env.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/js_kernel.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/prelude.js +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/prelude.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/protocol.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/py_kernel.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/runner.js +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/eval/runner.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/generalagent.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/goal.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/investigationagent.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/model_routing.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/accounting.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/budget.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/context.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/errors.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/executor.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/guide.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/journal.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/runtime.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/orchestration/types.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/planningagent.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_dump.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_overrides.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_provider.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_exhausted.user.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_nudge.user.md.j2 +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/truncated_turn_nudge.user.md.j2 +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/extensions/cli/build_questions.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/extensions/cli/mode_switch_notice.md.j2 +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list_readonly.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/extensions/cli/worktree_control.md.j2 +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/agents/coder_ask.md.j2 +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/includes/context_updates.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/agent_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/base_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/build_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/codex_patch.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/hashline_v2.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/lsp_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/network_status.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/snapshot_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/web_fetch/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/web_fetch/answering.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/web_fetch/documents.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/web_fetch/extractors.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/web_fetch/pipeline.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/web_fetch/retrieval.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/tool_backend/workflow_tool.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/utils/commands.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/agent/volatile_context.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/auth/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/auth/_jwt.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/auth/chatgpt_oauth.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/auth/constants.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/auth/tokens.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/browser_extension/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/browser_extension/framing.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/browser_extension/installer.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/browser_extension/manager.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/browser_extension/multiplex.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/browser_extension/native_host.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/browser_extension/protocol.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/browser_extension/registry.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/browser_extension/runtime.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/browser_backend.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/clipboard_image.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/connection.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/cron.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/diagnostics.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/goal.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/loop.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/mentions.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/model_catalog.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/model_connection.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/plan_artifacts.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/session_event_store.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/session_journal.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/session_usage.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/slash_commands.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/theme.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/changes_screen.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/constants.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/custom_model.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/loop_runtime.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/memory_screen.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/onboarding_screen.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/prompt_flows.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/session_diff.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/status_dashboard.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/sub_agent_screen.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/tui/terminal_display.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/cli/updater.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/events.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/git_env.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/hooks/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/hooks/backends.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/hooks/config.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/hooks/dispatcher.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/hooks/events.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/hooks/matcher.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/hooks/outcome.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/exceptions.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/instrumented_client.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/_token_encoding.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/anthropic.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/base.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/google.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/providers/openai_responses.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/ratelimit.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/anthropic.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/dashscope.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/fireworks.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/google.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/kimi_coding.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/moonshot.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/ollama_cloud.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/openrouter.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/together.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/xai.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/catalog/zai.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/openrouter_catalog.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/thinking.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/specs/types.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/timeouts.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/llm/tool_execution_ids.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/local_state.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/mcp/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/mcp/config.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/mcp/oauth.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/mcp/service.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/mcp/state.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/mcp/tools.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/mcp/transport.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/memory/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/memory/identity.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/memory/manager.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/memory/manifest.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/memory/markdown.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/memory/models.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/memory/protocol.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/memory/registry.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/models/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/models/sandbox_terminal_state.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/runtime.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/README.md +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/async_filesystem.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/base.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/browser.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/event_loop.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/filesystem.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/local.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/serializer.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/terminal.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/sandbox/utils.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/scratchpad.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/security/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/security/secrets.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/base.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/browser.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/file_system.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/html.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/lsp/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/lsp/client.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/lsp/config.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/lsp/detector.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/lsp/diagnostics.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/lsp/edits.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/lsp/manager.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/lsp/registry.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/lsp/registry.yaml +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/snapshots.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/terminal_buffer.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/services/workspace_scan.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/session/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/session/control.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/session/inmemory.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/session/projection.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/session/recording.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/session/runtime.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/session/store.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/testing/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/testing/store_conformance.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/tools/registry.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/utils/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/utils/images.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/__init__.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/assets/fold.js +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/assets/player.css +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/assets/player.html +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/assets/player.js +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/bundle.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/hosting.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/redaction.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/server.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/singlefile.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/web/theme_css.py +0 -0
- {kolega_code-0.26.9 → kolega_code-0.27.0}/kolega_code/worktrees.py +0 -0
|
@@ -6,6 +6,261 @@ This project uses GitHub Releases for detailed generated release notes. This fil
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.27.0 - 2026-08-06
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- The `eval`, `exec_command`, and `lsp` tool descriptions shipped to model
|
|
14
|
+
providers are slimmer (about 450 cl100k tokens less across the three,
|
|
15
|
+
roughly 8% of the whole tool payload): prose now states decision rules and
|
|
16
|
+
contracts instead of restating parameter schema text, `eval`'s JavaScript
|
|
17
|
+
prelude folds to "same helpers as Python, camelCase" with only the
|
|
18
|
+
JS-specific pitfalls spelled out, `lsp`'s operation list groups the seven
|
|
19
|
+
operations that share the `(path, line, symbol)` arguments onto one line,
|
|
20
|
+
and `exec_command`'s `timeout`-alias note is gone (the alias layer absorbs
|
|
21
|
+
it silently). No parameter names, types, or presence change, and no
|
|
22
|
+
behavior changes ride along.
|
|
23
|
+
|
|
24
|
+
- Tool definitions sent to model providers no longer duplicate parameter
|
|
25
|
+
documentation. Every tool docstring's `Args:` section is still parsed into
|
|
26
|
+
per-parameter schema descriptions, but the wire description no longer also
|
|
27
|
+
carries the whole section verbatim (and the schema descriptions no longer
|
|
28
|
+
include the raw docstring continuation-line indentation). Tools whose
|
|
29
|
+
parameters are not fully documented in their schema — freeform tools and
|
|
30
|
+
tools with enum-only schema properties such as the browser tools' `button`,
|
|
31
|
+
`action`, `level`, `part`, `image_type`, and `scale` — keep their `Args:`
|
|
32
|
+
block, since it is the only place those parameters are documented.
|
|
33
|
+
|
|
34
|
+
- The per-type agent dispatch tools (`dispatch_general_agent`,
|
|
35
|
+
`dispatch_investigation_agent`, `dispatch_browser_agent`,
|
|
36
|
+
`dispatch_coding_agent`, and `dispatch_custom_agent`) are consolidated into a
|
|
37
|
+
single `dispatch_agent(agent_type, task, model_override?, browser_target?)`
|
|
38
|
+
tool. `agent_type` is an enum computed per session from the same conditions
|
|
39
|
+
that previously gated the individual tools: `general` and `investigation`
|
|
40
|
+
whenever dispatch is available, `browser` only when the browser-agent model
|
|
41
|
+
supports vision, `coding` where the coding dispatch was previously offered
|
|
42
|
+
(never for the coder itself), and custom agent names when definitions are
|
|
43
|
+
discovered. The description documents the shared dispatch mechanics once plus
|
|
44
|
+
one line per available agent type, and an unavailable `agent_type` returns an
|
|
45
|
+
error listing the valid values. Old sessions that used the removed tool names
|
|
46
|
+
still restore and display normally.
|
|
47
|
+
|
|
48
|
+
- All terminal-capable agents (coder, planning, investigation, general) now
|
|
49
|
+
share a terminal-tools prompt section with codex-style guidance: prefer
|
|
50
|
+
`rg` / `rg --files` over `grep`/`find` when searching for text or files (it is
|
|
51
|
+
much faster; use alternatives if `rg` is not found), and do not use Python
|
|
52
|
+
scripts (or `eval`) to print chunks of a file — use the file-reading tools
|
|
53
|
+
instead.
|
|
54
|
+
- The `resolve` tool — which applies or discards a pending `lsp_edit(apply: false)`
|
|
55
|
+
preview — is now gated like the other LSP tools. With LSP disabled (via
|
|
56
|
+
settings, `KOLEGA_CODE_LSP`, or `--lsp off`) it is removed from the model's
|
|
57
|
+
toolset entirely, since pending actions can only be created while LSP is on.
|
|
58
|
+
Applying a pending action with `resolve` now also goes through the same
|
|
59
|
+
edit-permission prompt as `edit`, `lsp_edit`, and `write`.
|
|
60
|
+
- The two file-read tools are merged into one `read(file_path, offset?, limit?)`
|
|
61
|
+
tool. `offset` is the 1-indexed first line (default 1) and `limit` bounds the
|
|
62
|
+
number of lines; omitted parameters read from the top. Output is truncated to
|
|
63
|
+
2000 lines or 50KB — whichever binds first — snapped to line boundaries, with
|
|
64
|
+
actionable notices such as "[Showing lines a-b of N (50KB limit). Use
|
|
65
|
+
offset=b+1 to continue.]" instead of the old line-only warning and
|
|
66
|
+
100,000-character backstop. A single line larger than the 50KB budget gets an
|
|
67
|
+
explicit message suggesting `rg` / `exec_command` for targeted extraction.
|
|
68
|
+
`path` is accepted at the dispatch boundary as an alias for the canonical
|
|
69
|
+
`file_path`.
|
|
70
|
+
|
|
71
|
+
- `write(path=…)` now also succeeds under the claude_code edit protocol, where
|
|
72
|
+
`write` binds to `claude_write(file_path, content)`: `path` is accepted at
|
|
73
|
+
the dispatch boundary as an alias for `file_path`, matching every other file
|
|
74
|
+
tool. Under the search/replace protocol `path` stays the canonical
|
|
75
|
+
parameter and passes through untouched — alias resolution is signature-aware
|
|
76
|
+
and never rewrites an argument name the bound tool itself accepts.
|
|
77
|
+
|
|
78
|
+
- A successful whole-file `write` (including `hashline_write` and `apply_patch`'s
|
|
79
|
+
Add File) now records the just-written contents as read, so the read-before-edit
|
|
80
|
+
guard accepts a subsequent edit without a fresh read — exactly as it would
|
|
81
|
+
right after a read. Staleness tracking is unchanged: a file modified after the
|
|
82
|
+
write still requires a fresh read before editing.
|
|
83
|
+
- The three skill host tools (`list_skills`, `activate_skill`, and
|
|
84
|
+
`read_skill_resource`) are consolidated into a single `skill` tool with the
|
|
85
|
+
same contract as the old `activate_skill`: it takes the skill name (without a
|
|
86
|
+
leading slash) and returns the activation envelope with the skill's
|
|
87
|
+
instructions, its absolute directory, and the resource file list. Activating
|
|
88
|
+
an already-active skill short-circuits as before, and an unknown name now
|
|
89
|
+
lists close matches (prefix first, then fuzzy) from the catalog so a
|
|
90
|
+
mistyped activation self-corrects in one turn. The in-prompt skill roster
|
|
91
|
+
always lists every skill by name: description text is shed first when the
|
|
92
|
+
metadata budget binds, and skills are never omitted wholesale.
|
|
93
|
+
|
|
94
|
+
### Removed
|
|
95
|
+
|
|
96
|
+
- The `read_entire_file` and `read_file_section` tools are gone, replaced by the
|
|
97
|
+
merged `read` tool above. Deleted: the `ReadFileTool.read_entire_file` /
|
|
98
|
+
`read_file_section` methods and their `read_only_tools` registrations, the
|
|
99
|
+
truncation notices that named `read_file_section`, and the stale
|
|
100
|
+
`dispatch_investigation_agent` docstring tool list. Existing session
|
|
101
|
+
histories keep the old tool names as recorded data and render as-is (restore
|
|
102
|
+
is name-agnostic).
|
|
103
|
+
|
|
104
|
+
- The file-discovery tools are gone from the agent toolset: `glob` (which had
|
|
105
|
+
replaced `list_directory` and `find_files_by_pattern`), and `search_codebase`.
|
|
106
|
+
File and text discovery is now done through the terminal with `rg` /
|
|
107
|
+
`rg --files` (falling back to `find`/`grep`). Deleted: the `GlobTool` and
|
|
108
|
+
`SearchCodebaseTool` backends (the underlying `workspace_scan` service stays),
|
|
109
|
+
the `ToolCollection.glob` / `ToolCollection.search_codebase` methods and their
|
|
110
|
+
`read_only_tools` registrations, the stale `dispatch_investigation_agent`
|
|
111
|
+
docstring tool list (now naming the real surface, including terminal access),
|
|
112
|
+
and the `search_codebase` name from hashline history adaptation.
|
|
113
|
+
`@`-mention autocomplete (`cli/file_index.py`) keeps its exclusions by
|
|
114
|
+
inlining the constants it borrowed. Permission rules and custom-agent
|
|
115
|
+
allowlists naming the removed tools must be updated to the terminal tools
|
|
116
|
+
(`exec_command`, `write_stdin`, `kill_command`, `list_sessions`). Existing
|
|
117
|
+
session histories keep the old tool names as recorded data and render as-is.
|
|
118
|
+
|
|
119
|
+
- The `sleep` tool is gone from the agent toolset: its blind wall-clock wait is
|
|
120
|
+
strictly dominated by `write_stdin`'s empty-input poll, which waits for more
|
|
121
|
+
output or process exit and returns early when the process finishes. The
|
|
122
|
+
`yield_time_ms` clamp semantics (250–30000 ms when writing, 5000–300000 ms
|
|
123
|
+
when polling) moved from the `write_stdin` docstring body into its parameter
|
|
124
|
+
description so the poll path stays discoverable. Existing session histories
|
|
125
|
+
keep the old tool name as recorded data and render as-is.
|
|
126
|
+
|
|
127
|
+
- The `think_hard` tool is gone from the agent toolset, along with the thinking
|
|
128
|
+
model slot that powered it. Deleted: the `ThinkHardTool` backend and its
|
|
129
|
+
`auxiliary/tools/think_hard.system.md` prompt template, the
|
|
130
|
+
`ToolCollection.think_hard` method and its `read_only_tools` registration, the
|
|
131
|
+
`THINK_HARD_PROMPT` constant, and the `thinking_config` model slot itself.
|
|
132
|
+
`prompt` hooks now select only `"fast"` or `"long"`; the
|
|
133
|
+
`--thinking-provider`/`--thinking-model` flags, the
|
|
134
|
+
`KOLEGA_CODE_THINKING_PROVIDER`/`KOLEGA_CODE_THINKING_MODEL` env vars, and the
|
|
135
|
+
Settings Thinking slot row were removed, and a saved `thinking` slot entry in
|
|
136
|
+
`settings.json` is ignored on load. The active model's own thinking effort
|
|
137
|
+
(`--thinking-effort`, `KOLEGA_CODE_THINKING_EFFORT`) is unaffected.
|
|
138
|
+
|
|
139
|
+
- The `get_host` tool is gone from the local toolset. It needs a sandbox host
|
|
140
|
+
provider, so it is now offered only when a terminal manager carrying a
|
|
141
|
+
`sandbox` attribute is injected (cloud sandbox deployments), and the
|
|
142
|
+
localhost fallback branch in the handler is deleted — a registered
|
|
143
|
+
`get_host` always has a sandbox. The gate duck-types on the attribute rather
|
|
144
|
+
than `isinstance`, so kolega-code-e2b's injected `SandboxTerminalManager`
|
|
145
|
+
(possibly subclassed from a pinned older version) keeps qualifying. Existing
|
|
146
|
+
session histories that recorded `get_host` calls keep them as data and
|
|
147
|
+
render as-is (restore is name-agnostic).
|
|
148
|
+
|
|
149
|
+
- The `list_skills`, `activate_skill`, and `read_skill_resource` host tools are
|
|
150
|
+
gone, replaced by the single `skill` tool above. Deleted:
|
|
151
|
+
`SkillCatalog.read_resource` and its truncation cap and traversal guard
|
|
152
|
+
(skill resources are read with the ordinary `read` tool, whose `file_path`
|
|
153
|
+
is relative to the absolute skill directory in the activation output), the
|
|
154
|
+
model-facing list query surface (`format_model_catalog`), and the
|
|
155
|
+
omitted-skills budget pathway in the prompt roster. Existing session
|
|
156
|
+
histories keep the old tool names as recorded data and render as-is
|
|
157
|
+
(restore is name-agnostic).
|
|
158
|
+
|
|
159
|
+
### Fixed
|
|
160
|
+
|
|
161
|
+
- Kimi-family usage is no longer dropped when a request is served entirely from
|
|
162
|
+
the provider's prompt cache. `kimi-for-coding` / `moonshot` report
|
|
163
|
+
`input_tokens: -1` as a sentinel for "no uncached input tokens" on a full
|
|
164
|
+
cache hit; the strict usage validator previously classified that as malformed
|
|
165
|
+
and nulled the whole record, silently removing both input and output tokens
|
|
166
|
+
from session accounting for those turns. The sentinel is now interpreted as
|
|
167
|
+
zero, and the inclusive input total is reconstructed from the cache fields
|
|
168
|
+
(verified live: `-1` + 33 cached = 33 total, matching the same prompt's
|
|
169
|
+
partial-cache report of 27 uncached + 6 cached).
|
|
170
|
+
|
|
171
|
+
## 0.26.10 - 2026-08-05
|
|
172
|
+
|
|
173
|
+
### Added
|
|
174
|
+
|
|
175
|
+
- Hosted (server-side) web search for Responses-API providers. On DeepSeek
|
|
176
|
+
flash and OpenAI gpt-5.x (API key or ChatGPT subscription), kolega can
|
|
177
|
+
request the provider's own
|
|
178
|
+
`{"type": "web_search"}` tool: searches and page-opens execute on the
|
|
179
|
+
provider's servers and the content is injected directly into the model's
|
|
180
|
+
context (billed as input tokens; the context gauge accounts for it from
|
|
181
|
+
usage, since the content never reaches the client). Calls render in the
|
|
182
|
+
transcript as `web_search (hosted)`. Controlled by a new web tool mode —
|
|
183
|
+
`auto` (default: hosted when the model supports it, else the client tools) /
|
|
184
|
+
`hosted` / `client` / `off` — via Settings, `KOLEGA_CODE_WEB_SEARCH_MODE`,
|
|
185
|
+
`ask --web-search`, or the TUI's `/web-search`. When hosted search is active
|
|
186
|
+
the client-side `web_search`/`web_fetch` tools are not registered; `off`
|
|
187
|
+
removes all web tools (for sandboxed/benchmark runs). Notes: provider
|
|
188
|
+
per-search fees, if any, are not modeled in cost reporting (injected tokens
|
|
189
|
+
are); sessions that used hosted search store a new `web_search_call` history
|
|
190
|
+
block that older kolega builds cannot load.
|
|
191
|
+
- LSP tools can now be forced on or off for a single launch: `--lsp on|off`
|
|
192
|
+
on both the TUI and `kolega-code ask`, plus a `KOLEGA_CODE_LSP` env var,
|
|
193
|
+
resolved flag > env > settings > default-enabled. `--lsp on` overrides a
|
|
194
|
+
persisted `lsp_enabled=false` without writing back to settings. Turning LSP
|
|
195
|
+
off now removes the `lsp`/`lsp_edit` tools from the model entirely —
|
|
196
|
+
previously they stayed registered and could only answer "LSP is not
|
|
197
|
+
available" — and the Settings LSP status notes when the launch flag is
|
|
198
|
+
forcing the mode.
|
|
199
|
+
- The per-session scratchpad directory is now exported as `KOLEGA_SCRATCHPAD`
|
|
200
|
+
to every shell command and eval kernel, so scripts and kernels can reach the
|
|
201
|
+
session's throwaway workspace by environment variable instead of hardcoding
|
|
202
|
+
a temp path.
|
|
203
|
+
|
|
204
|
+
### Changed
|
|
205
|
+
|
|
206
|
+
- Thinking now renders as a collapsed row in the TUI transcript — `● Thinking
|
|
207
|
+
· … · 1.2k words` while streaming (a live word counter, never the text),
|
|
208
|
+
flipping to `● Thought · 12s · 1.2k words` on completion; expand the row to
|
|
209
|
+
read the full reasoning. Long reasoning turns (DeepSeek flash especially) no
|
|
210
|
+
longer dominate the transcript with full-height thinking walls.
|
|
211
|
+
- Resumed sessions now restore reasoning as the same collapsed thinking rows,
|
|
212
|
+
in true interleaved order with tool and hosted web-search rows: Anthropic
|
|
213
|
+
thinking text, DeepSeek flash's raw chain-of-thought, and OpenAI/ChatGPT
|
|
214
|
+
reasoning summaries all render (encrypted-only reasoning items have no
|
|
215
|
+
renderable text and are skipped). Previously reasoning vanished entirely
|
|
216
|
+
from restored transcripts.
|
|
217
|
+
- The coder prompt now follows a Codex-style final-message contract: the
|
|
218
|
+
closing report leads with what was delivered and its verified state, stays
|
|
219
|
+
brief by default with structure scaled to complexity, references files by
|
|
220
|
+
path instead of re-pasting contents, and never restates the plan step by
|
|
221
|
+
step. Preambles before tool calls are tightened to a single short line
|
|
222
|
+
naming the purpose of the next action, and verification effort is bounded —
|
|
223
|
+
tool results are trusted (no re-reading a file to confirm an edit applied)
|
|
224
|
+
and verification stops once no remaining check could realistically fail.
|
|
225
|
+
|
|
226
|
+
### Fixed
|
|
227
|
+
|
|
228
|
+
- Hosted web-search calls now render in their true position in the TUI
|
|
229
|
+
transcript. Previously the rows mounted at the bottom and stayed pinned
|
|
230
|
+
there while post-search reasoning kept streaming into the thinking bubble
|
|
231
|
+
above them; the stream now closes the open thinking/response segment at
|
|
232
|
+
each hosted call, so reasoning after a search opens a new bubble below its
|
|
233
|
+
rows (think → search → think → answer). Resumed sessions now render hosted
|
|
234
|
+
`web_search (hosted)` rows from history too — previously they were dropped
|
|
235
|
+
from the restored transcript.
|
|
236
|
+
- `ask --json` no longer emits spurious synthetic message fragments when
|
|
237
|
+
hosted web search flushes response text mid-stream: the lost-text fallback
|
|
238
|
+
now applies once at end of turn, and only when the turn produced no
|
|
239
|
+
assistant message.
|
|
240
|
+
- The context gauge no longer under-reads on `deepseek-v4-flash`. DeepSeek's
|
|
241
|
+
Responses API silently re-attaches every prior round's reasoning server-side and
|
|
242
|
+
bills it as input, but the client history held none of it, so the gauge (and the
|
|
243
|
+
auto-compaction trigger) could run over 100k tokens behind the real billed
|
|
244
|
+
context on reasoning-heavy sessions. Flash's plain-text reasoning is now retained
|
|
245
|
+
in history and resent each turn — the same shape Codex replays, deduped by the
|
|
246
|
+
server so billing is unchanged — which keeps the gauge on the real number and
|
|
247
|
+
preserves chain-of-thought continuity across session restores. The retained
|
|
248
|
+
reasoning text also now appears in `ask --json` message payloads (parity with
|
|
249
|
+
Anthropic thinking text); encrypted-only reasoning from OpenAI/ChatGPT stays
|
|
250
|
+
stripped as before.
|
|
251
|
+
|
|
252
|
+
### Security
|
|
253
|
+
|
|
254
|
+
- Dependency bumps for advisories published 2026-08-03/04: `cryptography`
|
|
255
|
+
48.0.1 → 50.0.0 (PKCS#7 Bleichenbacher oracle CVE-2026-69247, a name-constraint
|
|
256
|
+
wildcard bypass CVE-2026-69248, and a path-building DoS CVE-2026-69249) and
|
|
257
|
+
`aiohttp` 3.14.1 → 3.14.3 (three parser advisories, including an out-of-bounds
|
|
258
|
+
heap read in the C response parser). Exception: Intel Macs stay on
|
|
259
|
+
`cryptography` 48.0.1 — every fixed release dropped Intel-mac wheels, and
|
|
260
|
+
upgrading would break the curl installer there with a Rust+OpenSSL source
|
|
261
|
+
build — so those three advisories are knowingly accepted on that legacy
|
|
262
|
+
platform only.
|
|
263
|
+
|
|
9
264
|
## 0.26.9 - 2026-08-03
|
|
10
265
|
|
|
11
266
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kolega-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: Multi-agent coding in the terminal
|
|
5
5
|
Project-URL: Homepage, https://kolega-ai.github.io/kolega-code/
|
|
6
6
|
Project-URL: Documentation, https://kolega-ai.github.io/kolega-code/
|
|
@@ -231,6 +231,7 @@ Requires-Python: >=3.11
|
|
|
231
231
|
Requires-Dist: anthropic==0.101.0
|
|
232
232
|
Requires-Dist: beautifulsoup4==4.14.3
|
|
233
233
|
Requires-Dist: cryptography==48.0.1; sys_platform == 'darwin' and platform_machine == 'x86_64'
|
|
234
|
+
Requires-Dist: cryptography==50.0.0; sys_platform != 'darwin' or platform_machine != 'x86_64'
|
|
234
235
|
Requires-Dist: ddgs==9.14.4
|
|
235
236
|
Requires-Dist: fastapi==0.139.2
|
|
236
237
|
Requires-Dist: filelock==3.20.3
|
|
@@ -43,7 +43,15 @@ from kolega_code.llm.exceptions import (
|
|
|
43
43
|
)
|
|
44
44
|
from kolega_code.llm.instrumented_client import get_output_tokens
|
|
45
45
|
from kolega_code.llm.ledger import HISTORY_ORIGIN, LlmCallOrigin, helper_origin, llm_call_origin
|
|
46
|
-
from kolega_code.llm.models import
|
|
46
|
+
from kolega_code.llm.models import (
|
|
47
|
+
ImageBlock,
|
|
48
|
+
Message,
|
|
49
|
+
MessageHistory,
|
|
50
|
+
TextBlock,
|
|
51
|
+
ToolCall,
|
|
52
|
+
ToolResult,
|
|
53
|
+
WebSearchCallBlock,
|
|
54
|
+
)
|
|
47
55
|
from kolega_code.llm.providers.models import TokenCount
|
|
48
56
|
from kolega_code.llm.specs import (
|
|
49
57
|
deepseek_output_token_cap,
|
|
@@ -461,6 +469,15 @@ class BaseAgent(LogMixin):
|
|
|
461
469
|
# tool) and used by _unsupported_attachment_message to reject image
|
|
462
470
|
# attachments for non-vision models with a clear message.
|
|
463
471
|
self.supports_vision = bool(model_specs.get("supports_vision", False))
|
|
472
|
+
# Web tool mode: whether the provider's hosted (server-side) web_search
|
|
473
|
+
# tool is requested and whether the client-side web_search/web_fetch
|
|
474
|
+
# tools are registered. Resolved from config.web_search_mode plus the
|
|
475
|
+
# model's supports_hosted_web_search catalog flag; the ToolCollection
|
|
476
|
+
# gate reads client_web_tools_enabled, the stream call reads
|
|
477
|
+
# hosted_web_search_active.
|
|
478
|
+
self.supports_hosted_web_search = bool(model_specs.get("supports_hosted_web_search", False))
|
|
479
|
+
self.web_search_mode = getattr(self.config, "web_search_mode", "auto") or "auto"
|
|
480
|
+
self._apply_web_search_state()
|
|
464
481
|
|
|
465
482
|
self.llm = context.create_llm_client(agent_name=self.agent_name)
|
|
466
483
|
|
|
@@ -487,6 +504,15 @@ class BaseAgent(LogMixin):
|
|
|
487
504
|
self._workflow_accounting: Optional["WorkflowRunAccounting"] = None
|
|
488
505
|
self._accounting_reservation: Optional["AgentReservation"] = None
|
|
489
506
|
self.total_tokens_used: int = 0
|
|
507
|
+
# Hosted web-search accounting side-channel. Searched/fetched content is
|
|
508
|
+
# injected into the model's context SERVER-side (restored on replay of
|
|
509
|
+
# web_search_call items, billed as input) and never reaches the client,
|
|
510
|
+
# so tiktoken-over-history can't see it. The residual — billed input
|
|
511
|
+
# minus the client-side count of the request actually sent — measures it
|
|
512
|
+
# and is added to the gauge in count_current_context. Updated by
|
|
513
|
+
# _update_hosted_search_residual; zeroed by compress_history.
|
|
514
|
+
self._hosted_injected_tokens: int = 0
|
|
515
|
+
self._last_raw_context_count: Optional[int] = None
|
|
490
516
|
# Set by a blocking PostToolUse hook to end the turn after the current tool batch.
|
|
491
517
|
self._hook_end_turn = False
|
|
492
518
|
self.queued_input_provider: Optional[Callable[[], Awaitable[List[QueuedUserInput]]]] = None
|
|
@@ -652,6 +678,74 @@ class BaseAgent(LogMixin):
|
|
|
652
678
|
if callable(initialize):
|
|
653
679
|
initialize()
|
|
654
680
|
|
|
681
|
+
def _apply_web_search_state(self) -> None:
|
|
682
|
+
"""Resolve web_search_mode + model capability into the two live gates.
|
|
683
|
+
|
|
684
|
+
``hosted_web_search_active`` — request the provider's server-side
|
|
685
|
+
web_search tool on main-loop stream calls. ``client_web_tools_enabled``
|
|
686
|
+
— register the client-side web_search/web_fetch tools (read by the
|
|
687
|
+
ToolCollection gate). Hosted active always excludes the client tools:
|
|
688
|
+
two search paths confuse the model and waste schema tokens.
|
|
689
|
+
"""
|
|
690
|
+
mode = (self.web_search_mode or "auto").lower()
|
|
691
|
+
supported = self.supports_hosted_web_search
|
|
692
|
+
if mode == "off":
|
|
693
|
+
hosted, client = False, False
|
|
694
|
+
elif mode == "client":
|
|
695
|
+
hosted, client = False, True
|
|
696
|
+
elif mode == "hosted":
|
|
697
|
+
if not supported:
|
|
698
|
+
provider = self.primary_model_config.provider
|
|
699
|
+
logger.warning(
|
|
700
|
+
"web_search_mode=hosted, but %s/%s has no hosted web search; falling back to the client tools",
|
|
701
|
+
getattr(provider, "value", provider),
|
|
702
|
+
self.primary_model_config.model,
|
|
703
|
+
)
|
|
704
|
+
hosted, client = supported, not supported
|
|
705
|
+
else: # auto
|
|
706
|
+
hosted, client = supported, not supported
|
|
707
|
+
self.hosted_web_search_active = hosted
|
|
708
|
+
self.client_web_tools_enabled = client
|
|
709
|
+
|
|
710
|
+
def apply_web_search_mode(self, mode: str) -> None:
|
|
711
|
+
"""Change the web tool mode mid-session (TUI ``/web-search``).
|
|
712
|
+
|
|
713
|
+
Mirrors :meth:`apply_gigacode`: the tool registry rebuilds per call and
|
|
714
|
+
the next stream call reads the hosted gate, so no cache invalidation is
|
|
715
|
+
needed. No prompt work — the tools carry their own affordances.
|
|
716
|
+
"""
|
|
717
|
+
self.web_search_mode = (mode or "auto").lower()
|
|
718
|
+
self._apply_web_search_state()
|
|
719
|
+
|
|
720
|
+
async def _emit_hosted_tool_call(self, delta: Dict[str, Any]) -> None:
|
|
721
|
+
"""Render a completed hosted web_search call as a tool_call/tool_result pair.
|
|
722
|
+
|
|
723
|
+
The call executed on the provider's servers; there is no local tool
|
|
724
|
+
invocation and the searched content never reaches the client (it is
|
|
725
|
+
injected into the model's context server-side). The shared item id
|
|
726
|
+
correlates the pair in every transcript consumer.
|
|
727
|
+
"""
|
|
728
|
+
block = WebSearchCallBlock(
|
|
729
|
+
item_id=delta.get("id") or None,
|
|
730
|
+
status=delta.get("status"),
|
|
731
|
+
action=delta.get("action") or {},
|
|
732
|
+
)
|
|
733
|
+
tool_call_id = block.item_id or str(uuid.uuid4())
|
|
734
|
+
await self.send_chat_message(
|
|
735
|
+
message_type="tool_call",
|
|
736
|
+
content=f"Calling {WebSearchCallBlock.TOOL_LABEL}: {block.label()}",
|
|
737
|
+
is_streaming=False,
|
|
738
|
+
tool_description=WebSearchCallBlock.TOOL_LABEL,
|
|
739
|
+
tool_call_id=tool_call_id,
|
|
740
|
+
)
|
|
741
|
+
await self.send_chat_message(
|
|
742
|
+
message_type="tool_result",
|
|
743
|
+
content=block.result_summary(),
|
|
744
|
+
is_streaming=False,
|
|
745
|
+
tool_description=WebSearchCallBlock.TOOL_LABEL,
|
|
746
|
+
tool_call_id=tool_call_id,
|
|
747
|
+
)
|
|
748
|
+
|
|
655
749
|
def apply_goal(self, condition: Optional[str], prompt_extension: Optional["PromptExtension"] = None) -> None:
|
|
656
750
|
"""Set, replace, or clear the active autonomous goal for this session.
|
|
657
751
|
|
|
@@ -944,12 +1038,61 @@ class BaseAgent(LogMixin):
|
|
|
944
1038
|
model=self.primary_model_config.model,
|
|
945
1039
|
tools=self.tool_collection.get_tool_list(),
|
|
946
1040
|
)
|
|
1041
|
+
# Hosted web-search content lives only in the server's copy of the
|
|
1042
|
+
# context (restored on replay of the web_search_call items, billed as
|
|
1043
|
+
# input) — the client history has nothing to count for it. Add the
|
|
1044
|
+
# residual measured from billed usage so the gauge AND the compaction
|
|
1045
|
+
# check both see the true context size. Nonzero only while un-compacted
|
|
1046
|
+
# web_search_call blocks exist (see _update_hosted_search_residual).
|
|
1047
|
+
self._last_raw_context_count = token_count.input_tokens
|
|
1048
|
+
if self._hosted_injected_tokens > 0:
|
|
1049
|
+
token_count.input_tokens += self._hosted_injected_tokens
|
|
947
1050
|
|
|
948
1051
|
# Send context update event
|
|
949
1052
|
await self._send_context_update(token_count)
|
|
950
1053
|
|
|
951
1054
|
return token_count
|
|
952
1055
|
|
|
1056
|
+
# Provisional residual bump per hosted web-search call, applied while the
|
|
1057
|
+
# search-bearing response's own billing is telescoped (a response that
|
|
1058
|
+
# searched is several internal invocations billed cumulatively, so its
|
|
1059
|
+
# billed−counted residual overstates the persistent injected size). The next
|
|
1060
|
+
# clean response replaces the estimate with the measured residual. Probe
|
|
1061
|
+
# calibration 2026-08-04 (findings/probes/hosted_web_search_probe.py):
|
|
1062
|
+
# one-call persistent overhead ≈850 (deepseek) / ≈5000 (openai) tokens —
|
|
1063
|
+
# 6000 overestimates safely, and overestimating only compacts early.
|
|
1064
|
+
HOSTED_SEARCH_PROVISIONAL_TOKENS = 6000
|
|
1065
|
+
|
|
1066
|
+
def _update_hosted_search_residual(self, assistant_message: Message) -> None:
|
|
1067
|
+
"""Track server-injected hosted-search content from billed usage.
|
|
1068
|
+
|
|
1069
|
+
Search-bearing responses bump the estimate by a provisional per-call
|
|
1070
|
+
constant (their own billing telescopes internal rounds, so the direct
|
|
1071
|
+
residual would overshoot and could trip compaction spuriously). Clean
|
|
1072
|
+
responses — single invocation, so ``billed − counted`` is exact —
|
|
1073
|
+
replace it with the measurement. No-ops for sessions that never
|
|
1074
|
+
searched, keeping the known ±tokenizer-drift band out of the gauge.
|
|
1075
|
+
"""
|
|
1076
|
+
content = assistant_message.content if isinstance(assistant_message.content, list) else []
|
|
1077
|
+
new_calls = sum(1 for block in content if isinstance(block, WebSearchCallBlock))
|
|
1078
|
+
if new_calls:
|
|
1079
|
+
self._hosted_injected_tokens += self.HOSTED_SEARCH_PROVISIONAL_TOKENS * new_calls
|
|
1080
|
+
return
|
|
1081
|
+
if self._hosted_injected_tokens <= 0 and not self._history_contains_hosted_search():
|
|
1082
|
+
return
|
|
1083
|
+
billed = (assistant_message.usage_metadata or {}).get("prompt_tokens")
|
|
1084
|
+
counted = self._last_raw_context_count
|
|
1085
|
+
if not isinstance(billed, int) or counted is None:
|
|
1086
|
+
return
|
|
1087
|
+
self._hosted_injected_tokens = max(0, billed - counted)
|
|
1088
|
+
|
|
1089
|
+
def _history_contains_hosted_search(self) -> bool:
|
|
1090
|
+
for message in self.history:
|
|
1091
|
+
content = getattr(message, "content", None)
|
|
1092
|
+
if isinstance(content, list) and any(isinstance(block, WebSearchCallBlock) for block in content):
|
|
1093
|
+
return True
|
|
1094
|
+
return False
|
|
1095
|
+
|
|
953
1096
|
async def _send_context_update(self, token_count: TokenCount) -> None:
|
|
954
1097
|
"""Send an event to update the UI about current context usage."""
|
|
955
1098
|
usage_percentage = (token_count.input_tokens / self.model_context_length) * 100
|
|
@@ -977,6 +1120,11 @@ class BaseAgent(LogMixin):
|
|
|
977
1120
|
show progress, then recounts + emits a context_update so the gauge
|
|
978
1121
|
refreshes. Returns the structured outcome.
|
|
979
1122
|
"""
|
|
1123
|
+
# Compacted-away web_search_call blocks stop being replayed, so the
|
|
1124
|
+
# server stops restoring their content. Reset the hosted-search residual
|
|
1125
|
+
# rather than carrying a stale figure; if search blocks survive in the
|
|
1126
|
+
# verbatim tail, the next clean response re-measures it.
|
|
1127
|
+
self._hosted_injected_tokens = 0
|
|
980
1128
|
|
|
981
1129
|
async def on_info(message: str) -> None:
|
|
982
1130
|
await self.log_info(message, sender=self.agent_name)
|
|
@@ -1455,15 +1603,13 @@ class BaseAgent(LogMixin):
|
|
|
1455
1603
|
async def _run_hook_prompt(self, prompt_text: str, model_hint: Optional[str]) -> str:
|
|
1456
1604
|
"""Run a `prompt` hook: a single completion on a chosen model slot.
|
|
1457
1605
|
|
|
1458
|
-
``model_hint`` selects a configured slot ("fast" (default)
|
|
1459
|
-
|
|
1606
|
+
``model_hint`` selects a configured slot ("fast" (default) or "long");
|
|
1607
|
+
arbitrary model ids are not used here to keep provider/API-key
|
|
1460
1608
|
pairing correct across kolega's multi-provider setup.
|
|
1461
1609
|
"""
|
|
1462
1610
|
slot = (model_hint or "fast").lower()
|
|
1463
1611
|
if slot in ("long", "main", "long_context"):
|
|
1464
1612
|
model_config = self.config.long_context_config
|
|
1465
|
-
elif slot == "thinking":
|
|
1466
|
-
model_config = self.config.thinking_config
|
|
1467
1613
|
else:
|
|
1468
1614
|
model_config = self.config.fast_config
|
|
1469
1615
|
|
|
@@ -2093,6 +2239,7 @@ class BaseAgent(LogMixin):
|
|
|
2093
2239
|
model=self.primary_model_config.model,
|
|
2094
2240
|
tools=self.tool_collection.get_tool_list(),
|
|
2095
2241
|
thinking=self.primary_model_config.thinking_effort,
|
|
2242
|
+
hosted_web_search=self.hosted_web_search_active,
|
|
2096
2243
|
),
|
|
2097
2244
|
)
|
|
2098
2245
|
async with stream_cm as stream:
|
|
@@ -2135,8 +2282,46 @@ class BaseAgent(LogMixin):
|
|
|
2135
2282
|
|
|
2136
2283
|
await self.on_tool_use_start(event.tool_call_delta)
|
|
2137
2284
|
|
|
2285
|
+
elif event.type == "hosted_tool_call" and event.tool_call_delta:
|
|
2286
|
+
# A server-side web_search call completed on the
|
|
2287
|
+
# provider's infrastructure — no local execution.
|
|
2288
|
+
# Surface it as a normal tool_call/tool_result pair
|
|
2289
|
+
# so every transcript view renders it.
|
|
2290
|
+
#
|
|
2291
|
+
# Close the current thinking/response segment first
|
|
2292
|
+
# and rotate both uuids: transcript consumers key
|
|
2293
|
+
# streamed entries by uuid, so without rotation the
|
|
2294
|
+
# post-search reasoning folds into the bubble above
|
|
2295
|
+
# these rows instead of opening a new one below
|
|
2296
|
+
# them. Guards mirror the end-of-stream flushes: an
|
|
2297
|
+
# unopened thinking segment yields nothing, while
|
|
2298
|
+
# the response flush is unconditional (an empty
|
|
2299
|
+
# complete response chunk is a documented no-op for
|
|
2300
|
+
# every consumer) so a partially streamed response
|
|
2301
|
+
# entry is never stranded incomplete by rotation.
|
|
2302
|
+
if thinking_started or current_thinking:
|
|
2303
|
+
yield {
|
|
2304
|
+
"type": "thinking",
|
|
2305
|
+
"content": current_thinking,
|
|
2306
|
+
"complete": True,
|
|
2307
|
+
"uuid": thinking_uuid,
|
|
2308
|
+
}
|
|
2309
|
+
current_thinking = ""
|
|
2310
|
+
thinking_started = False
|
|
2311
|
+
thinking_uuid = str(uuid.uuid4())
|
|
2312
|
+
yield {
|
|
2313
|
+
"type": "response",
|
|
2314
|
+
"content": current_response,
|
|
2315
|
+
"complete": True,
|
|
2316
|
+
"uuid": response_uuid,
|
|
2317
|
+
}
|
|
2318
|
+
current_response = ""
|
|
2319
|
+
response_uuid = str(uuid.uuid4())
|
|
2320
|
+
await self._emit_hosted_tool_call(event.tool_call_delta)
|
|
2321
|
+
|
|
2138
2322
|
assistant_message = await stream.get_final_message()
|
|
2139
2323
|
self._normalize_freeform_tool_calls(assistant_message)
|
|
2324
|
+
self._update_hosted_search_residual(assistant_message)
|
|
2140
2325
|
assistant_message.usage_metadata["edit_protocol"] = self.edit_protocol.value
|
|
2141
2326
|
response_output_tokens = get_output_tokens(
|
|
2142
2327
|
assistant_message.usage_metadata,
|
|
@@ -123,27 +123,26 @@ class CoderAgent(BaseAgent, LogMixin):
|
|
|
123
123
|
memory_enabled=memory_enabled,
|
|
124
124
|
)
|
|
125
125
|
|
|
126
|
-
# Configure tool collection with custom coder agent tools
|
|
126
|
+
# Configure tool collection with custom coder agent tools. The
|
|
127
|
+
# coder_agent_tools dispatch group already omits the "coding"
|
|
128
|
+
# agent_type, so the coder never dispatches itself.
|
|
127
129
|
tool_exclusions = [
|
|
128
130
|
"execute_terminal_command",
|
|
129
131
|
"get_tool_list",
|
|
130
132
|
"log_error",
|
|
131
133
|
"log_info",
|
|
132
|
-
# Exclude task-specific dispatch tools since coder shouldn't call itself or other agents
|
|
133
|
-
"dispatch_coding_agent",
|
|
134
134
|
]
|
|
135
135
|
mode_value = self.agent_mode.value if isinstance(self.agent_mode, AgentMode) else self.agent_mode
|
|
136
136
|
if mode_value in (AgentMode.CLI.value, AgentMode.ASK.value):
|
|
137
137
|
tool_exclusions.extend(["build_backend", "build_frontend"])
|
|
138
|
-
if sub_agent:
|
|
139
|
-
# A dispatched coder must not fan out into further sub-agents
|
|
140
|
-
tool_exclusions.append("dispatch_general_agent")
|
|
141
138
|
|
|
142
139
|
tool_config = ToolCollectionConfig(
|
|
143
140
|
custom_tool_groups=["coder_agent_tools"],
|
|
144
141
|
tool_exclusions=tool_exclusions,
|
|
145
142
|
include_memory_tools=True,
|
|
146
143
|
memory_write_access=True,
|
|
144
|
+
# A dispatched coder must not fan out into further general sub-agents
|
|
145
|
+
excluded_agent_types=["general"] if sub_agent else None,
|
|
147
146
|
)
|
|
148
147
|
|
|
149
148
|
self.tool_collection = ToolCollection(
|
|
@@ -22,6 +22,7 @@ from kolega_code.llm.models import (
|
|
|
22
22
|
ThinkingBlock,
|
|
23
23
|
ToolCall,
|
|
24
24
|
ToolResult,
|
|
25
|
+
WebSearchCallBlock,
|
|
25
26
|
)
|
|
26
27
|
from kolega_code.llm.specs import prior_reasoning_is_replayable
|
|
27
28
|
from kolega_code.utils import images as image_utils
|
|
@@ -336,7 +337,7 @@ def _adapt_content_blocks_for_provider(
|
|
|
336
337
|
)
|
|
337
338
|
adapted.append(adapted_block)
|
|
338
339
|
changed = changed or image_changed
|
|
339
|
-
elif isinstance(block, (ThinkingBlock, RedactedThinkingBlock, ResponsesReasoningBlock)):
|
|
340
|
+
elif isinstance(block, (ThinkingBlock, RedactedThinkingBlock, ResponsesReasoningBlock, WebSearchCallBlock)):
|
|
340
341
|
if _preserve_reasoning_block(
|
|
341
342
|
block,
|
|
342
343
|
source_provider=source_provider,
|
|
@@ -396,7 +397,7 @@ def _adapt_content_blocks_for_provider(
|
|
|
396
397
|
call_protocol = (tool_call_protocols or {}).get(
|
|
397
398
|
block.tool_use_id, _source_edit_protocol(block, source_usage_metadata)
|
|
398
399
|
)
|
|
399
|
-
is_hashline_read = block.name
|
|
400
|
+
is_hashline_read = block.name == "read"
|
|
400
401
|
if (
|
|
401
402
|
is_hashline_read
|
|
402
403
|
and call_protocol == "hashline_v2"
|
|
@@ -406,7 +407,7 @@ def _adapt_content_blocks_for_provider(
|
|
|
406
407
|
adapted.append(
|
|
407
408
|
_tool_result_with_content(
|
|
408
409
|
block,
|
|
409
|
-
strip_hashline_read_output(block.content, search=
|
|
410
|
+
strip_hashline_read_output(block.content, search=False),
|
|
410
411
|
)
|
|
411
412
|
)
|
|
412
413
|
changed = True
|