kolega-code 0.26.8__tar.gz → 0.26.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. {kolega_code-0.26.8 → kolega_code-0.26.9}/CHANGELOG.md +50 -0
  2. {kolega_code-0.26.8 → kolega_code-0.26.9}/PKG-INFO +12 -1
  3. {kolega_code-0.26.8 → kolega_code-0.26.9}/README.md +11 -0
  4. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/__init__.py +1 -1
  5. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/__init__.py +1 -1
  6. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/app.py +4 -4
  7. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/config.py +136 -81
  8. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/messages.py +18 -0
  9. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/model_connection.py +21 -16
  10. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/provider_registry.py +18 -1
  11. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/settings.py +30 -6
  12. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/onboarding_screen.py +10 -1
  13. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/settings_panel.py +443 -116
  14. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/settings_screen.py +105 -48
  15. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/styles.tcss +11 -1
  16. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/accessors.py +14 -8
  17. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/deepseek.py +9 -5
  18. {kolega_code-0.26.8 → kolega_code-0.26.9}/pyproject.toml +1 -1
  19. {kolega_code-0.26.8 → kolega_code-0.26.9}/.gitignore +0 -0
  20. {kolega_code-0.26.8 → kolega_code-0.26.9}/CONTRIBUTING.md +0 -0
  21. {kolega_code-0.26.8 → kolega_code-0.26.9}/LICENSE +0 -0
  22. {kolega_code-0.26.8 → kolega_code-0.26.9}/MIGRATION.md +0 -0
  23. {kolega_code-0.26.8 → kolega_code-0.26.9}/RELEASING.md +0 -0
  24. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/LICENSE +0 -0
  25. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/manifest.json +0 -0
  26. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/deep-research/SKILL.md +0 -0
  27. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/deep-research/references/evidence-and-reporting.md +0 -0
  28. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/deep-research/references/gigacode-workflow.md +0 -0
  29. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/deep-research/scripts/deep-research.workflow +0 -0
  30. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/deep-research/scripts/materialize_report.py +0 -0
  31. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/docx/LICENSE +0 -0
  32. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/docx/SKILL.md +0 -0
  33. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/docx/references/examples.md +0 -0
  34. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/docx/references/limitations.md +0 -0
  35. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/docx/references/operations.md +0 -0
  36. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/docx/references/quality.md +0 -0
  37. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/docx/requirements.txt +0 -0
  38. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/docx/scripts/docx_tool.py +0 -0
  39. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/docx/scripts/smoke_test.py +0 -0
  40. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/humanizer/LICENSE +0 -0
  41. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/humanizer/SKILL.md +0 -0
  42. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/LICENSE +0 -0
  43. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/SKILL.md +0 -0
  44. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/references/examples.md +0 -0
  45. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/references/limitations.md +0 -0
  46. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/references/ocr.md +0 -0
  47. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/references/operations.md +0 -0
  48. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/references/quality.md +0 -0
  49. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/references/redaction.md +0 -0
  50. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-paddle.txt +0 -0
  51. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-surya.txt +0 -0
  52. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/requirements.txt +0 -0
  53. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/scripts/pdf_tool.py +0 -0
  54. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pdf/scripts/smoke_test.py +0 -0
  55. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pptx/LICENSE +0 -0
  56. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pptx/SKILL.md +0 -0
  57. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pptx/references/examples.md +0 -0
  58. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pptx/references/limitations.md +0 -0
  59. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pptx/references/operations.md +0 -0
  60. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pptx/requirements.txt +0 -0
  61. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pptx/scripts/pptx_tool.py +0 -0
  62. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/pptx/scripts/smoke_test.py +0 -0
  63. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/review/SKILL.md +0 -0
  64. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/review/references/github-publishing.md +0 -0
  65. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/skill-authoring/SKILL.md +0 -0
  66. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/skill-authoring/references/review-checklist.md +0 -0
  67. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/xlsx/LICENSE +0 -0
  68. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/xlsx/SKILL.md +0 -0
  69. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/xlsx/references/examples.md +0 -0
  70. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/xlsx/references/limitations.md +0 -0
  71. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/xlsx/references/operations.md +0 -0
  72. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/xlsx/references/quality.md +0 -0
  73. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/xlsx/requirements.txt +0 -0
  74. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/xlsx/scripts/smoke_test.py +0 -0
  75. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/_bundled_skills/skills/xlsx/scripts/xlsx_tool.py +0 -0
  76. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/baseagent.py +0 -0
  77. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/browseragent.py +0 -0
  78. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/coder.py +0 -0
  79. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/common.py +0 -0
  80. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/compression.py +0 -0
  81. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/context.py +0 -0
  82. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/conversation.py +0 -0
  83. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/custom_agents.py +0 -0
  84. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/edit_protocols.py +0 -0
  85. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/errors.py +0 -0
  86. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/__init__.py +0 -0
  87. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/bridge.py +0 -0
  88. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/bundle-requirements.in +0 -0
  89. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/bundle-requirements.txt +0 -0
  90. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/env.py +0 -0
  91. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/js_kernel.py +0 -0
  92. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/kernel.py +0 -0
  93. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/prelude.js +0 -0
  94. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/prelude.py +0 -0
  95. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/protocol.py +0 -0
  96. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/py_kernel.py +0 -0
  97. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/runner.js +0 -0
  98. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/eval/runner.py +0 -0
  99. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/generalagent.py +0 -0
  100. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/goal.py +0 -0
  101. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/investigationagent.py +0 -0
  102. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/model_routing.py +0 -0
  103. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/__init__.py +0 -0
  104. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/accounting.py +0 -0
  105. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/budget.py +0 -0
  106. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/context.py +0 -0
  107. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/errors.py +0 -0
  108. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/executor.py +0 -0
  109. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/guide.py +0 -0
  110. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/journal.py +0 -0
  111. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/runtime.py +0 -0
  112. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/orchestration/types.py +0 -0
  113. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/planningagent.py +0 -0
  114. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_dump.py +0 -0
  115. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_overrides.py +0 -0
  116. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_provider.py +0 -0
  117. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_exhausted.user.md +0 -0
  118. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_nudge.user.md.j2 +0 -0
  119. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/truncated_turn_nudge.user.md.j2 +0 -0
  120. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
  121. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
  122. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
  123. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
  124. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +0 -0
  125. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/extensions/cli/build_questions.md +0 -0
  126. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/extensions/cli/current_plan_artifact.md.j2 +0 -0
  127. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/extensions/cli/mode_switch_notice.md.j2 +0 -0
  128. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
  129. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/extensions/cli/scratchpad.md.j2 +0 -0
  130. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
  131. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list_readonly.md +0 -0
  132. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/extensions/cli/worktree_control.md.j2 +0 -0
  133. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
  134. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
  135. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/agents/coder_ask.md.j2 +0 -0
  136. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/agents/coder_base.md.j2 +0 -0
  137. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +0 -0
  138. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
  139. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
  140. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
  141. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
  142. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/includes/context_updates.md +0 -0
  143. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
  144. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
  145. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
  146. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
  147. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
  148. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
  149. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
  150. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
  151. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/prompts.py +0 -0
  152. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/agent_tool.py +0 -0
  153. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/base_tool.py +0 -0
  154. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
  155. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/build_tool.py +0 -0
  156. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/codex_patch.py +0 -0
  157. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
  158. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/edit_tool.py +0 -0
  159. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/eval_tool.py +0 -0
  160. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/glob_tool.py +0 -0
  161. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/hashline_v2.py +0 -0
  162. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/list_directory_tool.py +0 -0
  163. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/lsp_tool.py +0 -0
  164. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
  165. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/network_status.py +0 -0
  166. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
  167. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
  168. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
  169. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
  170. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
  171. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
  172. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
  173. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
  174. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
  175. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
  176. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/search_codebase_tool.py +0 -0
  177. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/snapshot_tool.py +0 -0
  178. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
  179. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
  180. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/think_hard_tool.py +0 -0
  181. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/web_fetch/__init__.py +0 -0
  182. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/web_fetch/answering.py +0 -0
  183. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/web_fetch/documents.py +0 -0
  184. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/web_fetch/extractors.py +0 -0
  185. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/web_fetch/pipeline.py +0 -0
  186. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/web_fetch/retrieval.py +0 -0
  187. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
  188. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
  189. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tool_backend/workflow_tool.py +0 -0
  190. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/tools.py +0 -0
  191. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/utils/commands.py +0 -0
  192. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/agent/volatile_context.py +0 -0
  193. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/auth/__init__.py +0 -0
  194. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/auth/_jwt.py +0 -0
  195. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/auth/chatgpt_oauth.py +0 -0
  196. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/auth/constants.py +0 -0
  197. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/auth/tokens.py +0 -0
  198. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/browser_extension/__init__.py +0 -0
  199. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/browser_extension/framing.py +0 -0
  200. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/browser_extension/installer.py +0 -0
  201. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/browser_extension/manager.py +0 -0
  202. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/browser_extension/multiplex.py +0 -0
  203. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/browser_extension/native_host.py +0 -0
  204. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/browser_extension/protocol.py +0 -0
  205. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/browser_extension/registry.py +0 -0
  206. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/browser_extension/runtime.py +0 -0
  207. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/__init__.py +0 -0
  208. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/ask_output.py +0 -0
  209. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/browser_backend.py +0 -0
  210. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/clipboard_image.py +0 -0
  211. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/connection.py +0 -0
  212. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/cron.py +0 -0
  213. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/diagnostics.py +0 -0
  214. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/file_index.py +0 -0
  215. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/goal.py +0 -0
  216. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/loop.py +0 -0
  217. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/main.py +0 -0
  218. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/mentions.py +0 -0
  219. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/model_catalog.py +0 -0
  220. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/plan_artifacts.py +0 -0
  221. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/session_event_store.py +0 -0
  222. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/session_journal.py +0 -0
  223. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/session_store.py +0 -0
  224. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/session_usage.py +0 -0
  225. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/skills.py +0 -0
  226. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/slash_commands.py +0 -0
  227. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/theme.py +0 -0
  228. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/__init__.py +0 -0
  229. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/agent_runtime.py +0 -0
  230. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/app_base.py +0 -0
  231. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/changes_screen.py +0 -0
  232. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/command_handlers.py +0 -0
  233. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/constants.py +0 -0
  234. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/custom_model.py +0 -0
  235. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/loop_runtime.py +0 -0
  236. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/memory_screen.py +0 -0
  237. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/prompt_flows.py +0 -0
  238. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/session_diff.py +0 -0
  239. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/state.py +0 -0
  240. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/status_dashboard.py +0 -0
  241. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/sub_agent_screen.py +0 -0
  242. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/terminal_display.py +0 -0
  243. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/transcript.py +0 -0
  244. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/tui/widgets.py +0 -0
  245. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/cli/updater.py +0 -0
  246. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/config.py +0 -0
  247. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/events.py +0 -0
  248. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/git_env.py +0 -0
  249. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/hooks/__init__.py +0 -0
  250. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/hooks/backends.py +0 -0
  251. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/hooks/config.py +0 -0
  252. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/hooks/dispatcher.py +0 -0
  253. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/hooks/events.py +0 -0
  254. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/hooks/matcher.py +0 -0
  255. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/hooks/outcome.py +0 -0
  256. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/client.py +0 -0
  257. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/exceptions.py +0 -0
  258. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/instrumented_client.py +0 -0
  259. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/ledger.py +0 -0
  260. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/models.py +0 -0
  261. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/__init__.py +0 -0
  262. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/_token_encoding.py +0 -0
  263. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/anthropic.py +0 -0
  264. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/base.py +0 -0
  265. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
  266. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/deepseek_responses.py +0 -0
  267. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/google.py +0 -0
  268. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/models.py +0 -0
  269. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/openai.py +0 -0
  270. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/openai_responses.py +0 -0
  271. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/providers/responses_common.py +0 -0
  272. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/ratelimit.py +0 -0
  273. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/__init__.py +0 -0
  274. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/__init__.py +0 -0
  275. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/anthropic.py +0 -0
  276. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/dashscope.py +0 -0
  277. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/fireworks.py +0 -0
  278. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/google.py +0 -0
  279. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/kimi_coding.py +0 -0
  280. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/moonshot.py +0 -0
  281. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/ollama_cloud.py +0 -0
  282. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/openai.py +0 -0
  283. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/openai_chatgpt.py +0 -0
  284. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/openrouter.py +0 -0
  285. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/together.py +0 -0
  286. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/xai.py +0 -0
  287. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/catalog/zai.py +0 -0
  288. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/openrouter_catalog.py +0 -0
  289. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/thinking.py +0 -0
  290. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/specs/types.py +0 -0
  291. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/timeouts.py +0 -0
  292. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/tool_execution_ids.py +0 -0
  293. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/llm/usage.py +0 -0
  294. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/local_state.py +0 -0
  295. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/mcp/__init__.py +0 -0
  296. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/mcp/config.py +0 -0
  297. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/mcp/oauth.py +0 -0
  298. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/mcp/service.py +0 -0
  299. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/mcp/state.py +0 -0
  300. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/mcp/tools.py +0 -0
  301. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/mcp/transport.py +0 -0
  302. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/memory/__init__.py +0 -0
  303. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/memory/identity.py +0 -0
  304. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/memory/manager.py +0 -0
  305. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/memory/manifest.py +0 -0
  306. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/memory/markdown.py +0 -0
  307. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/memory/models.py +0 -0
  308. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/memory/protocol.py +0 -0
  309. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/memory/registry.py +0 -0
  310. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/models/__init__.py +0 -0
  311. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/models/sandbox_terminal_state.py +0 -0
  312. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/permissions.py +0 -0
  313. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/runtime.py +0 -0
  314. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/README.md +0 -0
  315. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/__init__.py +0 -0
  316. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/async_filesystem.py +0 -0
  317. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/base.py +0 -0
  318. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/browser.py +0 -0
  319. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/event_loop.py +0 -0
  320. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/filesystem.py +0 -0
  321. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/local.py +0 -0
  322. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/serializer.py +0 -0
  323. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/terminal.py +0 -0
  324. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/sandbox/utils.py +0 -0
  325. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/scratchpad.py +0 -0
  326. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/security/__init__.py +0 -0
  327. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/security/secrets.py +0 -0
  328. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/base.py +0 -0
  329. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/browser.py +0 -0
  330. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/file_system.py +0 -0
  331. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/html.py +0 -0
  332. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/lsp/__init__.py +0 -0
  333. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/lsp/client.py +0 -0
  334. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/lsp/config.py +0 -0
  335. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/lsp/detector.py +0 -0
  336. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/lsp/diagnostics.py +0 -0
  337. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/lsp/edits.py +0 -0
  338. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/lsp/manager.py +0 -0
  339. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/lsp/registry.py +0 -0
  340. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/lsp/registry.yaml +0 -0
  341. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/snapshots.py +0 -0
  342. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/terminal.py +0 -0
  343. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/terminal_buffer.py +0 -0
  344. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/services/workspace_scan.py +0 -0
  345. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/session/__init__.py +0 -0
  346. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/session/control.py +0 -0
  347. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/session/inmemory.py +0 -0
  348. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/session/projection.py +0 -0
  349. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/session/recording.py +0 -0
  350. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/session/runtime.py +0 -0
  351. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/session/store.py +0 -0
  352. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/testing/__init__.py +0 -0
  353. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/testing/store_conformance.py +0 -0
  354. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/tools/__init__.py +0 -0
  355. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/tools/core.py +0 -0
  356. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/tools/definitions.py +0 -0
  357. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/tools/param_aliases.py +0 -0
  358. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/tools/registry.py +0 -0
  359. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/utils/__init__.py +0 -0
  360. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/utils/images.py +0 -0
  361. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/__init__.py +0 -0
  362. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/assets/fold.js +0 -0
  363. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/assets/player.css +0 -0
  364. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/assets/player.html +0 -0
  365. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/assets/player.js +0 -0
  366. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/bundle.py +0 -0
  367. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/hosting.py +0 -0
  368. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/redaction.py +0 -0
  369. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/server.py +0 -0
  370. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/singlefile.py +0 -0
  371. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/web/theme_css.py +0 -0
  372. {kolega_code-0.26.8 → kolega_code-0.26.9}/kolega_code/worktrees.py +0 -0
@@ -6,6 +6,56 @@ This project uses GitHub Releases for detailed generated release notes. This fil
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.26.9 - 2026-08-03
10
+
11
+ ### Added
12
+
13
+ - Settings → Model & Account gains a **Model Slots** section for pinning the fast
14
+ and thinking models, each with its own provider. Previously these slots were
15
+ reachable only through CLI flags and environment variables, so in the TUI they
16
+ silently inherited the active model — every `web_fetch` answering call ran on
17
+ the main coding model. Slots still inherit by default, and each row now shows
18
+ which model it currently resolves to.
19
+ - The README now includes a direct invitation to the Kolega Code Discord
20
+ community.
21
+
22
+ ### Changed
23
+
24
+ - Settings gains a **Providers** category, first in the rail, holding every model
25
+ provider's API key and the ChatGPT sign-in, each row labelled with its live
26
+ credential status. **Model & Account** is renamed **Models** and keeps only what
27
+ runs. Keys now stage per provider, so credentials for a provider you are not
28
+ currently using — needed by a fast/thinking slot or an agent-role override — can be
29
+ entered without switching your main model and switching back. **Test Connection**
30
+ moves with them and probes the selected provider rather than the active model, so a
31
+ credential can be checked without running on that provider.
32
+ - **Breaking:** provider and model are now always specified together. `--provider`
33
+ without `--model` (and the per-role/per-slot equivalents such as
34
+ `KOLEGA_CODE_FAST_PROVIDER`) is an error instead of silently selecting that
35
+ provider's default model, and a model named without a provider is rejected rather
36
+ than assumed to be Anthropic's. Scripts passing only one of the pair need updating;
37
+ the error names the missing flag. Saved settings are unaffected — the Settings UI
38
+ always writes both — and a saved model that later leaves the catalog still degrades
39
+ to the provider's default rather than blocking startup.
40
+
41
+ ### Fixed
42
+
43
+ - `deepseek-v4-flash` no longer has its reasoning truncated mid-derivation. The
44
+ 64000-token output cap added in 0.26.8 was measured on the chat API for
45
+ `deepseek-v4-pro` and applied to flash by assumption; flash actually runs to
46
+ at least 112990 output tokens in a single Responses call. Hard tasks that
47
+ reason for a long time before acting were cut off at the cap and produced no
48
+ tool call at all. flash now uses its full published output budget, while pro
49
+ and the fireworks/openrouter DeepSeek routes keep the 64000 cap where their
50
+ measured ceilings apply.
51
+
52
+ ### Removed
53
+
54
+ - The unreachable `DEFAULT_LONG_MODEL`, `DEFAULT_FAST_MODEL`, `DEFAULT_THINKING_MODEL`
55
+ and their provider constants. No model was ever resolved through them — an unset
56
+ slot inherits the active model — but they were documented as defaults, which is
57
+ where "what is my fast model?" became unanswerable.
58
+
9
59
  ## 0.26.8 - 2026-08-03
10
60
 
11
61
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kolega-code
3
- Version: 0.26.8
3
+ Version: 0.26.9
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/
@@ -494,6 +494,7 @@ Full documentation lives at **[kolega-ai.github.io/kolega-code](https://kolega-a
494
494
  - [Contributing](CONTRIBUTING.md)
495
495
  - [Security policy](SECURITY.md)
496
496
  - [Issue tracker](https://github.com/kolega-ai/kolega-code/issues)
497
+ - [Discord community](https://discord.gg/kaS8PKKp4)
497
498
 
498
499
  ## Contributing
499
500
 
@@ -504,3 +505,13 @@ privately per [SECURITY.md](SECURITY.md).
504
505
  ## License
505
506
 
506
507
  Released under the [Apache License 2.0](LICENSE).
508
+
509
+ ## Join the community
510
+
511
+ Building something with Kolega Code, hit a rough edge, or want to shape where
512
+ Gigacode goes next? Come talk to us.
513
+
514
+ [![Join our Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/kaS8PKKp4)
515
+
516
+ **→ [Join the Kolega Code Discord](https://discord.gg/kaS8PKKp4)** — share workflows,
517
+ get help, and hear about releases first.
@@ -215,6 +215,7 @@ Full documentation lives at **[kolega-ai.github.io/kolega-code](https://kolega-a
215
215
  - [Contributing](CONTRIBUTING.md)
216
216
  - [Security policy](SECURITY.md)
217
217
  - [Issue tracker](https://github.com/kolega-ai/kolega-code/issues)
218
+ - [Discord community](https://discord.gg/kaS8PKKp4)
218
219
 
219
220
  ## Contributing
220
221
 
@@ -225,3 +226,13 @@ privately per [SECURITY.md](SECURITY.md).
225
226
  ## License
226
227
 
227
228
  Released under the [Apache License 2.0](LICENSE).
229
+
230
+ ## Join the community
231
+
232
+ Building something with Kolega Code, hit a rough edge, or want to shape where
233
+ Gigacode goes next? Come talk to us.
234
+
235
+ [![Join our Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/kaS8PKKp4)
236
+
237
+ **→ [Join the Kolega Code Discord](https://discord.gg/kaS8PKKp4)** — share workflows,
238
+ get help, and hear about releases first.
@@ -151,4 +151,4 @@ __all__ = [
151
151
  "parse_git_status_output",
152
152
  ]
153
153
 
154
- __version__ = "0.26.8"
154
+ __version__ = "0.26.9"
@@ -51,4 +51,4 @@ __all__ = [
51
51
  "ToolExtension",
52
52
  ]
53
53
 
54
- __version__ = "0.26.8"
54
+ __version__ = "0.26.9"
@@ -1101,16 +1101,16 @@ class KolegaCodeApp(
1101
1101
  if event.button.id == "save_settings":
1102
1102
  await self._save_settings_from_ui()
1103
1103
  return
1104
- if event.button.id == "settings_chatgpt_login":
1104
+ if event.button.id == "provider_chatgpt_login":
1105
1105
  await self._settings_login_chatgpt()
1106
1106
  return
1107
- if event.button.id == "settings_chatgpt_logout":
1107
+ if event.button.id == "provider_chatgpt_logout":
1108
1108
  self._settings_logout_chatgpt()
1109
1109
  return
1110
- if event.button.id == "settings_remove_api_key":
1110
+ if event.button.id == "provider_remove_api_key":
1111
1111
  self._settings_remove_api_key()
1112
1112
  return
1113
- if event.button.id == "settings_test_connection":
1113
+ if event.button.id == "provider_test_connection":
1114
1114
  await self._test_settings_connection()
1115
1115
  return
1116
1116
  if event.button.id and event.button.id.startswith("mcp_"):
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import os
6
6
  from dataclasses import dataclass
7
7
  from pathlib import Path
8
- from typing import Mapping, Optional
8
+ from typing import Mapping, NoReturn, Optional
9
9
 
10
10
  from pydantic import ValidationError
11
11
 
@@ -21,12 +21,9 @@ from .settings import CliSettings, SettingsStore
21
21
  # Providers authenticated by an OAuth sign-in instead of a static API key.
22
22
  OAUTH_PROVIDERS = frozenset({ModelProvider.OPENAI_CHATGPT})
23
23
 
24
- DEFAULT_LONG_PROVIDER = ModelProvider.ANTHROPIC
25
- DEFAULT_LONG_MODEL = "claude-opus-5"
26
- DEFAULT_FAST_PROVIDER = ModelProvider.ANTHROPIC
27
- DEFAULT_FAST_MODEL = "claude-haiku-4-5-20251001"
28
- DEFAULT_THINKING_PROVIDER = ModelProvider.ANTHROPIC
29
- DEFAULT_THINKING_MODEL = "claude-opus-5"
24
+ # No built-in provider or model defaults by design. A model must be named together with
25
+ # its provider (see _require_provider_for_model), and an unset operational slot inherits
26
+ # the active model rather than pinning itself to any particular model.
30
27
  DEPRECATED_THINKING_TOKENS_MESSAGE = (
31
28
  "Thinking token budgets have been replaced by model-specific named effort. "
32
29
  "Use --thinking-effort or KOLEGA_CODE_THINKING_EFFORT."
@@ -120,6 +117,34 @@ def _model_sources(model: str) -> list[str]:
120
117
  return sorted(provider for provider, candidate in MODEL_SPECS if candidate == model)
121
118
 
122
119
 
120
+ def _require_provider_for_model(model: str, model_source: Optional[str], provider_names: str) -> NoReturn:
121
+ """Reject a model named without a provider.
122
+
123
+ Nothing is guessed here. The same model id can be served by several providers on
124
+ different credentials (e.g. an OpenAI id reachable both by API key and by ChatGPT
125
+ subscription), so picking one for the user would silently choose an account.
126
+ """
127
+ label = f"{model_source}={model}" if model_source else f"Model '{model}'"
128
+ sources = _model_sources(model)
129
+ hint = (
130
+ f" It is offered by: {', '.join(sources)}."
131
+ if sources
132
+ else f" Valid providers: {', '.join(provider.value for provider in ModelProvider)}."
133
+ )
134
+ raise CliConfigError(f"{label} also needs a provider; set {provider_names}.{hint}")
135
+
136
+
137
+ def _require_model_for_provider(provider: str, provider_source: Optional[str], model_names: str) -> NoReturn:
138
+ """Reject a provider named without a model.
139
+
140
+ Provider and model are always specified together: there is no house default model
141
+ to fall back on, and picking one from the catalog would pin a choice the user did
142
+ not make.
143
+ """
144
+ label = f"{provider_source}={provider}" if provider_source else f"Provider '{provider}'"
145
+ raise CliConfigError(f"{label} also needs a model; set {model_names}.")
146
+
147
+
123
148
  def _ensure_explicit_model_supported(
124
149
  provider: ModelProvider,
125
150
  model: str,
@@ -227,16 +252,19 @@ def _active_provider_model(
227
252
  model_value, model_source = _explicit_value(overrides.model, env, "KOLEGA_CODE_MODEL", "--model")
228
253
 
229
254
  if provider_value or model_value:
230
- provider = _provider(provider_value or DEFAULT_LONG_PROVIDER.value)
231
- if model_value:
232
- _ensure_explicit_model_supported(
233
- provider,
234
- model_value,
235
- model_source=model_source,
236
- provider_source=provider_source,
237
- )
238
- return provider, model_value
239
- return provider, default_model_for_provider(provider)
255
+ if not provider_value:
256
+ assert model_value is not None
257
+ _require_provider_for_model(model_value, model_source, "--provider or KOLEGA_CODE_PROVIDER")
258
+ if not model_value:
259
+ _require_model_for_provider(provider_value, provider_source, "--model or KOLEGA_CODE_MODEL")
260
+ provider = _provider(provider_value)
261
+ _ensure_explicit_model_supported(
262
+ provider,
263
+ model_value,
264
+ model_source=model_source,
265
+ provider_source=provider_source,
266
+ )
267
+ return provider, model_value
240
268
 
241
269
  if settings and settings.active_provider and settings.active_model:
242
270
  try:
@@ -254,42 +282,56 @@ def _slot_provider_model(
254
282
  model_env_key: str,
255
283
  provider_override: Optional[str],
256
284
  model_override: Optional[str],
257
- default_provider: ModelProvider,
258
- default_model: str,
259
- active_provider: Optional[ModelProvider],
260
- active_model: Optional[str],
285
+ active_provider: ModelProvider,
286
+ active_model: str,
287
+ saved: Optional[Mapping[str, str]] = None,
261
288
  ) -> tuple[ModelProvider, str]:
262
- provider_value, provider_source = _explicit_value(
263
- provider_override,
264
- env,
265
- provider_env_key,
266
- f"--{provider_env_key.removeprefix('KOLEGA_CODE_').lower().replace('_', '-')}",
267
- )
268
- model_value, model_source = _explicit_value(
269
- model_override,
270
- env,
271
- model_env_key,
272
- f"--{model_env_key.removeprefix('KOLEGA_CODE_').lower().replace('_', '-')}",
273
- )
289
+ """Resolve one operational slot: CLI flag > env var > saved slot > active model.
274
290
 
275
- if provider_value or model_value:
276
- provider = _provider(provider_value or (active_provider.value if active_provider else default_provider.value))
277
- if model_value:
278
- _ensure_explicit_model_supported(
279
- provider,
280
- model_value,
281
- model_source=model_source,
282
- provider_source=provider_source,
283
- )
284
- return provider, model_value
285
- return provider, active_model if active_provider == provider and active_model else default_model_for_provider(
286
- provider
291
+ ``saved`` is a persisted ``{provider, model}`` override from Settings, always
292
+ carrying both fields (``CliSettings`` drops half-written entries). Provider and
293
+ model must be given together here too, so a flag/env that names only one of them
294
+ is an error rather than a silent pick.
295
+
296
+ Only explicit values are validated against the catalog: a *saved* model that has
297
+ since left the catalog degrades to the provider's default rather than locking the
298
+ user out of Settings.
299
+
300
+ There is no built-in per-slot default: an unset slot inherits the active model, and
301
+ ``build_agent_config`` raises ``MISSING_MODEL_SELECTION_MESSAGE`` before calling this
302
+ when no active model is configured, so ``active_provider``/``active_model`` are always
303
+ present here.
304
+ """
305
+ provider_flag = f"--{provider_env_key.removeprefix('KOLEGA_CODE_').lower().replace('_', '-')}"
306
+ model_flag = f"--{model_env_key.removeprefix('KOLEGA_CODE_').lower().replace('_', '-')}"
307
+ provider_value, provider_source = _explicit_value(provider_override, env, provider_env_key, provider_flag)
308
+ model_value, model_source = _explicit_value(model_override, env, model_env_key, model_flag)
309
+
310
+ if provider_value and not model_value:
311
+ _require_model_for_provider(provider_value, provider_source, f"{model_flag} or {model_env_key}")
312
+ if model_value and not provider_value:
313
+ _require_provider_for_model(model_value, model_source, f"{provider_flag} or {provider_env_key}")
314
+
315
+ if provider_value:
316
+ assert model_value is not None
317
+ provider = _provider(provider_value)
318
+ _ensure_explicit_model_supported(
319
+ provider,
320
+ model_value,
321
+ model_source=model_source,
322
+ provider_source=provider_source,
287
323
  )
324
+ return provider, model_value
288
325
 
289
- if active_provider and active_model:
290
- return active_provider, active_model
326
+ saved = saved or {}
327
+ saved_provider, saved_model = saved.get("provider"), saved.get("model")
328
+ if saved_provider and saved_model:
329
+ provider = _provider(saved_provider)
330
+ if (provider.value, saved_model) not in MODEL_SPECS:
331
+ saved_model = default_model_for_provider(provider)
332
+ return provider, saved_model
291
333
 
292
- return default_provider, default_model
334
+ return active_provider, active_model
293
335
 
294
336
 
295
337
  def _model_config(provider: ModelProvider, model: str, thinking_effort: Optional[str] = None) -> ModelConfig:
@@ -339,14 +381,15 @@ def _agent_role_env_keys(role: AgentRole) -> tuple[str, str, str]:
339
381
  def _agent_model_overrides(
340
382
  env: Mapping[str, str],
341
383
  settings: Optional[CliSettings],
342
- active_provider: ModelProvider,
343
- active_model: str,
344
384
  ) -> dict[str, ModelConfig]:
345
385
  """Resolve per-agent-role model overrides from env vars over saved settings.
346
386
 
347
- A role with neither an env nor a settings provider/model is omitted, so it
348
- inherits the active model. Field-level precedence is env > settings, mirroring
349
- the per-slot resolution used for long/fast/thinking.
387
+ A role with neither an env nor a settings provider/model is omitted, so it inherits
388
+ the active model. Provider and model are specified together, exactly as for the
389
+ operational slots: an env var naming only one of them is an error rather than a
390
+ silent pick. Saved entries always carry both (``CliSettings`` drops half-written
391
+ ones), and a saved model that has left the catalog degrades to the provider default
392
+ instead of locking the user out of Settings.
350
393
  """
351
394
  saved = settings.agent_models if settings else {}
352
395
  overrides: dict[str, ModelConfig] = {}
@@ -355,31 +398,29 @@ def _agent_model_overrides(
355
398
  entry = saved.get(role.value) or {}
356
399
  provider_env_value = env.get(provider_key)
357
400
  model_env_value = env.get(model_key)
358
- effort_env_value = env.get(effort_key)
401
+ effort_value = env.get(effort_key) or entry.get("thinking_effort")
402
+
403
+ if provider_env_value and not model_env_value and not entry.get("model"):
404
+ _require_model_for_provider(provider_env_value, provider_key, model_key)
405
+ if model_env_value and not provider_env_value and not entry.get("provider"):
406
+ _require_provider_for_model(model_env_value, model_key, provider_key)
407
+
359
408
  provider_value = provider_env_value or entry.get("provider")
360
409
  model_value = model_env_value or entry.get("model")
361
- effort_value = effort_env_value or entry.get("thinking_effort")
362
-
363
- if not provider_value and not model_value:
410
+ if not provider_value or not model_value:
364
411
  continue
365
412
 
366
- provider = _provider(provider_value or active_provider.value)
367
- if model_value:
368
- if model_env_value:
369
- _ensure_explicit_model_supported(
370
- provider,
371
- model_value,
372
- model_source=model_key,
373
- provider_source=provider_key if provider_env_value else None,
374
- )
375
- elif (provider.value, model_value) not in MODEL_SPECS:
376
- model_value = default_model_for_provider(provider)
377
- model = model_value
378
- elif active_provider == provider and active_model:
379
- model = active_model
380
- else:
381
- model = default_model_for_provider(provider)
382
- overrides[role.value] = _model_config(provider, model, thinking_effort=effort_value)
413
+ provider = _provider(provider_value)
414
+ if model_env_value:
415
+ _ensure_explicit_model_supported(
416
+ provider,
417
+ model_value,
418
+ model_source=model_key,
419
+ provider_source=provider_key if provider_env_value else None,
420
+ )
421
+ elif (provider.value, model_value) not in MODEL_SPECS:
422
+ model_value = default_model_for_provider(provider)
423
+ overrides[role.value] = _model_config(provider, model_value, thinking_effort=effort_value)
383
424
  return overrides
384
425
 
385
426
 
@@ -411,8 +452,6 @@ def build_agent_config(
411
452
  "KOLEGA_CODE_MODEL",
412
453
  overrides.provider,
413
454
  overrides.model,
414
- DEFAULT_LONG_PROVIDER,
415
- DEFAULT_LONG_MODEL,
416
455
  active_provider,
417
456
  active_model,
418
457
  )
@@ -422,10 +461,9 @@ def build_agent_config(
422
461
  "KOLEGA_CODE_FAST_MODEL",
423
462
  overrides.fast_provider,
424
463
  overrides.fast_model,
425
- DEFAULT_FAST_PROVIDER,
426
- DEFAULT_FAST_MODEL,
427
464
  active_provider,
428
465
  active_model,
466
+ settings.model_slots.get("fast") if settings else None,
429
467
  )
430
468
  thinking_provider, thinking_model = _slot_provider_model(
431
469
  loaded_env,
@@ -433,10 +471,9 @@ def build_agent_config(
433
471
  "KOLEGA_CODE_THINKING_MODEL",
434
472
  overrides.thinking_provider,
435
473
  overrides.thinking_model,
436
- DEFAULT_THINKING_PROVIDER,
437
- DEFAULT_THINKING_MODEL,
438
474
  active_provider,
439
475
  active_model,
476
+ settings.model_slots.get("thinking") if settings else None,
440
477
  )
441
478
  active_thinking_effort = _resolve_active_thinking_effort(
442
479
  long_provider,
@@ -449,7 +486,7 @@ def build_agent_config(
449
486
  active_thinking_effort if thinking_provider == long_provider and thinking_model == long_model else None
450
487
  )
451
488
 
452
- agent_model_overrides = _agent_model_overrides(loaded_env, settings, active_provider, active_model)
489
+ agent_model_overrides = _agent_model_overrides(loaded_env, settings)
453
490
  web_search_backend, web_search_api_key, web_search_base_url = _search_config(loaded_env, settings)
454
491
  state_dir = settings_store.root if settings_store is not None else SettingsStore().root
455
492
  mcp_config = load_mcp_config(
@@ -547,6 +584,24 @@ def key_status(provider: str, project_path: Path, settings: Optional[CliSettings
547
584
  return "missing"
548
585
 
549
586
 
587
+ def resolved_api_key(provider: str, project_path: Path, settings: Optional[CliSettings] = None) -> Optional[str]:
588
+ """The API key a provider would actually use: env var first, then stored settings.
589
+
590
+ The value counterpart to ``key_status``, which reports the same precedence in words.
591
+ """
592
+ return _api_key_for_provider(_provider(provider), load_cli_env(project_path), settings)
593
+
594
+
595
+ def probe_token_manager(settings: Optional[CliSettings]) -> Optional[ChatGPTTokenManager]:
596
+ """A ChatGPT token manager for credential probes, deliberately non-persisting.
597
+
598
+ A probe runs against an unapplied Settings draft, so a token refresh triggered by it
599
+ must not write back to settings.json the way the session's own manager does.
600
+ """
601
+ tokens = _resolve_chatgpt_tokens(settings)
602
+ return ChatGPTTokenManager(tokens) if tokens is not None else None
603
+
604
+
550
605
  def active_model_override_message(
551
606
  config: AgentConfig,
552
607
  project_path: Path,
@@ -249,6 +249,24 @@ BROWSER_MODEL_EXPLICIT_NO_VISION = (
249
249
  BROWSER_MODEL_PROVIDER_NO_VISION = (
250
250
  "Provider {provider} has no vision-capable Browser models. Choose another provider or Default (inherit)."
251
251
  )
252
+ PROVIDERS_HINT = (
253
+ "Credentials for model providers. Select one to add, replace, or remove its key. "
254
+ "What actually runs is chosen under Models."
255
+ )
256
+ MODEL_CREDENTIAL_POINTER = "API keys and ChatGPT sign-in live under Providers."
257
+ PROVIDER_CREDENTIAL_STATUS = "Credential status: {status}"
258
+ PROVIDER_KEY_STAGED = "Key will be saved for {provider} when you Apply."
259
+ PROVIDER_KEY_NOT_STORED = (
260
+ "There is no locally stored key for this provider. Environment credentials are not changed here."
261
+ )
262
+ PROVIDER_KEY_REMOVAL_STAGED = "The locally stored API key will be removed when you Apply."
263
+ PROVIDER_TEST_RUNNING = "Testing {provider}/{model}…"
264
+ MODEL_SLOT_INHERITED = "Using {provider}/{model} (inherited from the active model)."
265
+ MODEL_SLOT_PINNED = "Using {provider}/{model}."
266
+ MODEL_SLOT_HINT = (
267
+ "Utility slots used outside the main conversation. Default inherits the active model; "
268
+ "a slot may use a different provider, which needs that provider's API key."
269
+ )
252
270
 
253
271
  # Status dashboard
254
272
  STATUS_TOKENS_UNKNOWN = "Token counts unavailable."
@@ -4,9 +4,9 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  from dataclasses import dataclass
7
- from typing import Any, Callable
7
+ from typing import Any, Callable, Optional
8
8
 
9
- from kolega_code.config import AgentConfig
9
+ from kolega_code.config import ModelProvider, RateLimitConfig
10
10
  from kolega_code.llm.client import LLMClient
11
11
  from kolega_code.llm.exceptions import LLMError, llm_error_message
12
12
  from kolega_code.llm.ledger import helper_origin, llm_call_origin
@@ -34,27 +34,35 @@ async def _probe_generate(client: Any, model: str, messages: MessageHistory) ->
34
34
 
35
35
 
36
36
  async def test_model_connection(
37
- config: AgentConfig,
37
+ provider: ModelProvider,
38
+ model: str,
38
39
  *,
40
+ api_key: str = "",
41
+ token_manager: Any = None,
42
+ rate_limits: Optional[RateLimitConfig] = None,
39
43
  client_factory: Callable[..., Any] = LLMClient,
40
44
  timeout: float = CONNECTION_TEST_TIMEOUT_SECONDS,
41
45
  usage_ledger: Any = None,
42
46
  ) -> ModelConnectionResult:
43
- """Send a tiny no-tool prompt through the selected model.
47
+ """Send a tiny no-tool prompt through one provider/model pair.
44
48
 
45
49
  This is intentionally opt-in: providers do not expose one uniform, free auth
46
50
  endpoint, so a real generation is the only dependable cross-provider probe.
51
+
52
+ The target is passed in rather than read off an ``AgentConfig`` so a credential can
53
+ be probed on its own — the Providers screen tests a key for a provider that may not
54
+ be in use, and must keep working when the rest of the model configuration is broken.
47
55
  """
48
56
 
49
- model_config = config.long_context_config
57
+ limits = rate_limits or RateLimitConfig()
50
58
  try:
51
59
  factory_kwargs: dict[str, Any] = {
52
- "provider": model_config.provider,
53
- "api_key": config.get_api_key(model_config.provider) or "",
60
+ "provider": provider,
61
+ "api_key": api_key,
54
62
  "max_retries": 0,
55
- "requests_per_minute": model_config.rate_limits.requests_per_minute,
56
- "tokens_per_minute": model_config.rate_limits.tokens_per_minute,
57
- "token_manager": config.get_chatgpt_token_manager(),
63
+ "requests_per_minute": limits.requests_per_minute,
64
+ "tokens_per_minute": limits.tokens_per_minute,
65
+ "token_manager": token_manager,
58
66
  }
59
67
  # The probe is a real paid request; account for it when the host has a
60
68
  # ledger. Omitted when None so injected fake factories keep their shape.
@@ -63,18 +71,15 @@ async def test_model_connection(
63
71
  client = client_factory(**factory_kwargs)
64
72
  messages = MessageHistory([Message(role="user", content=[TextBlock(text="Reply with OK.")])])
65
73
  await asyncio.wait_for(
66
- _probe_generate(client, model_config.model, messages),
74
+ _probe_generate(client, model, messages),
67
75
  timeout=timeout,
68
76
  )
69
77
  except asyncio.TimeoutError:
70
78
  return ModelConnectionResult(False, f"Connection test timed out after {timeout:g} seconds.")
71
79
  except LLMError as exc:
72
- return ModelConnectionResult(False, llm_error_message(exc, model=model_config.model))
80
+ return ModelConnectionResult(False, llm_error_message(exc, model=model))
73
81
  except Exception:
74
82
  return ModelConnectionResult(
75
83
  False, "The connection test failed unexpectedly. Check the provider and try again."
76
84
  )
77
- return ModelConnectionResult(
78
- True,
79
- f"Connected to {model_config.provider.value}/{model_config.model}.",
80
- )
85
+ return ModelConnectionResult(True, f"Connected to {provider.value}/{model}.")
@@ -319,13 +319,30 @@ AGENT_ROLE_LABELS: dict[AgentRole, str] = {
319
319
  }
320
320
 
321
321
 
322
+ # Display labels and render order for the operational model slots the UI exposes.
323
+ # The long-context slot is the active model itself, so it is not listed here.
324
+ MODEL_SLOT_LABELS: dict[str, str] = {
325
+ "fast": "Fast",
326
+ "thinking": "Thinking",
327
+ }
328
+
329
+
322
330
  def agent_role_options() -> list[tuple[str, str]]:
323
331
  """Return (label, role-value) pairs for the configurable agent roles, in order."""
324
332
  return [(label, role.value) for role, label in AGENT_ROLE_LABELS.items()]
325
333
 
326
334
 
335
+ def model_slot_options() -> list[tuple[str, str]]:
336
+ """Return (label, slot-value) pairs for the configurable model slots, in order."""
337
+ return [(label, slot) for slot, label in MODEL_SLOT_LABELS.items()]
338
+
339
+
327
340
  def agent_role_provider_options() -> list[tuple[str, str]]:
328
- """Provider Select options for a per-agent row, with an inherit option first."""
341
+ """Provider Select options for an override row, with an inherit option first.
342
+
343
+ Shared by the per-agent rows and the model-slot rows: both mean "no override —
344
+ inherit the active model" when the sentinel is selected.
345
+ """
329
346
  return [("Default (inherit)", INHERIT_SENTINEL), *ui_provider_options()]
330
347
 
331
348