kolega-code 0.27.0__tar.gz → 0.27.1__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.27.0 → kolega_code-0.27.1}/CHANGELOG.md +30 -0
  2. {kolega_code-0.27.0 → kolega_code-0.27.1}/PKG-INFO +4 -1
  3. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/__init__.py +1 -1
  4. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/__init__.py +1 -1
  5. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/baseagent.py +6 -0
  6. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/compression.py +6 -3
  7. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tools.py +23 -0
  8. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/config.py +100 -7
  9. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/main.py +28 -4
  10. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/model_catalog.py +76 -35
  11. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/model_connection.py +4 -0
  12. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/provider_registry.py +24 -1
  13. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/settings.py +32 -0
  14. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/custom_model.py +9 -6
  15. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/settings_panel.py +103 -0
  16. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/settings_screen.py +29 -0
  17. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/config.py +21 -0
  18. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/client.py +16 -2
  19. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/exceptions.py +31 -1
  20. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/instrumented_client.py +1 -1
  21. kolega_code-0.27.1/kolega_code/llm/providers/tinker.py +609 -0
  22. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/__init__.py +5 -0
  23. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/accessors.py +42 -6
  24. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/__init__.py +12 -0
  25. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/openrouter.py +914 -886
  26. kolega_code-0.27.1/kolega_code/llm/specs/catalog/thinking_machines.py +34 -0
  27. kolega_code-0.27.1/kolega_code/llm/specs/catalog/tinker.py +221 -0
  28. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/thinking.py +18 -0
  29. kolega_code-0.27.1/kolega_code/llm/specs/tinker_catalog.py +229 -0
  30. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/usage.py +1 -1
  31. {kolega_code-0.27.0 → kolega_code-0.27.1}/pyproject.toml +13 -2
  32. {kolega_code-0.27.0 → kolega_code-0.27.1}/.gitignore +0 -0
  33. {kolega_code-0.27.0 → kolega_code-0.27.1}/CONTRIBUTING.md +0 -0
  34. {kolega_code-0.27.0 → kolega_code-0.27.1}/LICENSE +0 -0
  35. {kolega_code-0.27.0 → kolega_code-0.27.1}/MIGRATION.md +0 -0
  36. {kolega_code-0.27.0 → kolega_code-0.27.1}/README.md +0 -0
  37. {kolega_code-0.27.0 → kolega_code-0.27.1}/RELEASING.md +0 -0
  38. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/LICENSE +0 -0
  39. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/manifest.json +0 -0
  40. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/deep-research/SKILL.md +0 -0
  41. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/deep-research/references/evidence-and-reporting.md +0 -0
  42. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/deep-research/references/gigacode-workflow.md +0 -0
  43. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/deep-research/scripts/deep-research.workflow +0 -0
  44. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/deep-research/scripts/materialize_report.py +0 -0
  45. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/docx/LICENSE +0 -0
  46. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/docx/SKILL.md +0 -0
  47. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/docx/references/examples.md +0 -0
  48. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/docx/references/limitations.md +0 -0
  49. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/docx/references/operations.md +0 -0
  50. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/docx/references/quality.md +0 -0
  51. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/docx/requirements.txt +0 -0
  52. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/docx/scripts/docx_tool.py +0 -0
  53. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/docx/scripts/smoke_test.py +0 -0
  54. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/humanizer/LICENSE +0 -0
  55. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/humanizer/SKILL.md +0 -0
  56. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/LICENSE +0 -0
  57. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/SKILL.md +0 -0
  58. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/references/examples.md +0 -0
  59. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/references/limitations.md +0 -0
  60. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/references/ocr.md +0 -0
  61. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/references/operations.md +0 -0
  62. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/references/quality.md +0 -0
  63. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/references/redaction.md +0 -0
  64. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-paddle.txt +0 -0
  65. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-surya.txt +0 -0
  66. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/requirements.txt +0 -0
  67. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/scripts/pdf_tool.py +0 -0
  68. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pdf/scripts/smoke_test.py +0 -0
  69. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pptx/LICENSE +0 -0
  70. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pptx/SKILL.md +0 -0
  71. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pptx/references/examples.md +0 -0
  72. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pptx/references/limitations.md +0 -0
  73. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pptx/references/operations.md +0 -0
  74. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pptx/requirements.txt +0 -0
  75. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pptx/scripts/pptx_tool.py +0 -0
  76. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/pptx/scripts/smoke_test.py +0 -0
  77. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/review/SKILL.md +0 -0
  78. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/review/references/github-publishing.md +0 -0
  79. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/skill-authoring/SKILL.md +0 -0
  80. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/skill-authoring/references/review-checklist.md +0 -0
  81. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/xlsx/LICENSE +0 -0
  82. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/xlsx/SKILL.md +0 -0
  83. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/xlsx/references/examples.md +0 -0
  84. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/xlsx/references/limitations.md +0 -0
  85. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/xlsx/references/operations.md +0 -0
  86. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/xlsx/references/quality.md +0 -0
  87. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/xlsx/requirements.txt +0 -0
  88. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/xlsx/scripts/smoke_test.py +0 -0
  89. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/_bundled_skills/skills/xlsx/scripts/xlsx_tool.py +0 -0
  90. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/browseragent.py +0 -0
  91. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/coder.py +0 -0
  92. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/common.py +0 -0
  93. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/context.py +0 -0
  94. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/conversation.py +0 -0
  95. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/custom_agents.py +0 -0
  96. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/edit_protocols.py +0 -0
  97. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/errors.py +0 -0
  98. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/__init__.py +0 -0
  99. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/bridge.py +0 -0
  100. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/bundle-requirements.in +0 -0
  101. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/bundle-requirements.txt +0 -0
  102. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/env.py +0 -0
  103. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/js_kernel.py +0 -0
  104. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/kernel.py +0 -0
  105. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/prelude.js +0 -0
  106. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/prelude.py +0 -0
  107. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/protocol.py +0 -0
  108. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/py_kernel.py +0 -0
  109. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/runner.js +0 -0
  110. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/eval/runner.py +0 -0
  111. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/generalagent.py +0 -0
  112. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/goal.py +0 -0
  113. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/investigationagent.py +0 -0
  114. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/model_routing.py +0 -0
  115. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/__init__.py +0 -0
  116. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/accounting.py +0 -0
  117. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/budget.py +0 -0
  118. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/context.py +0 -0
  119. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/errors.py +0 -0
  120. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/executor.py +0 -0
  121. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/guide.py +0 -0
  122. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/journal.py +0 -0
  123. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/runtime.py +0 -0
  124. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/orchestration/types.py +0 -0
  125. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/planningagent.py +0 -0
  126. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_dump.py +0 -0
  127. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_overrides.py +0 -0
  128. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_provider.py +0 -0
  129. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_exhausted.user.md +0 -0
  130. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_nudge.user.md.j2 +0 -0
  131. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/truncated_turn_nudge.user.md.j2 +0 -0
  132. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
  133. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
  134. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
  135. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
  136. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/extensions/cli/build_questions.md +0 -0
  137. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/extensions/cli/current_plan_artifact.md.j2 +0 -0
  138. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/extensions/cli/mode_switch_notice.md.j2 +0 -0
  139. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
  140. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/extensions/cli/scratchpad.md.j2 +0 -0
  141. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
  142. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list_readonly.md +0 -0
  143. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/extensions/cli/worktree_control.md.j2 +0 -0
  144. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
  145. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
  146. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/agents/coder_ask.md.j2 +0 -0
  147. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/agents/coder_base.md.j2 +0 -0
  148. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +0 -0
  149. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
  150. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
  151. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
  152. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
  153. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/includes/context_updates.md +0 -0
  154. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
  155. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
  156. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
  157. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
  158. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
  159. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
  160. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/system/includes/terminal_tools.md +0 -0
  161. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
  162. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
  163. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/prompts.py +0 -0
  164. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/agent_tool.py +0 -0
  165. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/base_tool.py +0 -0
  166. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
  167. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/build_tool.py +0 -0
  168. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/codex_patch.py +0 -0
  169. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
  170. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/edit_tool.py +0 -0
  171. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/eval_tool.py +0 -0
  172. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/hashline_v2.py +0 -0
  173. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/lsp_tool.py +0 -0
  174. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
  175. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/network_status.py +0 -0
  176. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
  177. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
  178. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
  179. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
  180. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
  181. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
  182. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
  183. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
  184. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
  185. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
  186. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/snapshot_tool.py +0 -0
  187. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
  188. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
  189. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/web_fetch/__init__.py +0 -0
  190. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/web_fetch/answering.py +0 -0
  191. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/web_fetch/documents.py +0 -0
  192. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/web_fetch/extractors.py +0 -0
  193. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/web_fetch/pipeline.py +0 -0
  194. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/web_fetch/retrieval.py +0 -0
  195. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
  196. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
  197. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/tool_backend/workflow_tool.py +0 -0
  198. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/utils/commands.py +0 -0
  199. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/agent/volatile_context.py +0 -0
  200. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/auth/__init__.py +0 -0
  201. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/auth/_jwt.py +0 -0
  202. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/auth/chatgpt_oauth.py +0 -0
  203. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/auth/constants.py +0 -0
  204. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/auth/tokens.py +0 -0
  205. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/browser_extension/__init__.py +0 -0
  206. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/browser_extension/framing.py +0 -0
  207. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/browser_extension/installer.py +0 -0
  208. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/browser_extension/manager.py +0 -0
  209. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/browser_extension/multiplex.py +0 -0
  210. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/browser_extension/native_host.py +0 -0
  211. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/browser_extension/protocol.py +0 -0
  212. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/browser_extension/registry.py +0 -0
  213. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/browser_extension/runtime.py +0 -0
  214. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/__init__.py +0 -0
  215. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/app.py +0 -0
  216. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/ask_output.py +0 -0
  217. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/browser_backend.py +0 -0
  218. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/clipboard_image.py +0 -0
  219. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/connection.py +0 -0
  220. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/cron.py +0 -0
  221. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/diagnostics.py +0 -0
  222. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/file_index.py +0 -0
  223. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/goal.py +0 -0
  224. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/loop.py +0 -0
  225. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/mentions.py +0 -0
  226. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/messages.py +0 -0
  227. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/plan_artifacts.py +0 -0
  228. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/session_event_store.py +0 -0
  229. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/session_journal.py +0 -0
  230. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/session_store.py +0 -0
  231. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/session_usage.py +0 -0
  232. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/skills.py +0 -0
  233. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/slash_commands.py +0 -0
  234. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/theme.py +0 -0
  235. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/__init__.py +0 -0
  236. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/agent_runtime.py +0 -0
  237. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/app_base.py +0 -0
  238. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/changes_screen.py +0 -0
  239. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/command_handlers.py +0 -0
  240. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/constants.py +0 -0
  241. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/loop_runtime.py +0 -0
  242. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/memory_screen.py +0 -0
  243. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/onboarding_screen.py +0 -0
  244. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/prompt_flows.py +0 -0
  245. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/session_diff.py +0 -0
  246. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/state.py +0 -0
  247. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/status_dashboard.py +0 -0
  248. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/styles.tcss +0 -0
  249. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/sub_agent_screen.py +0 -0
  250. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/terminal_display.py +0 -0
  251. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/transcript.py +0 -0
  252. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/tui/widgets.py +0 -0
  253. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/cli/updater.py +0 -0
  254. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/events.py +0 -0
  255. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/git_env.py +0 -0
  256. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/hooks/__init__.py +0 -0
  257. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/hooks/backends.py +0 -0
  258. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/hooks/config.py +0 -0
  259. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/hooks/dispatcher.py +0 -0
  260. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/hooks/events.py +0 -0
  261. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/hooks/matcher.py +0 -0
  262. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/hooks/outcome.py +0 -0
  263. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/ledger.py +0 -0
  264. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/models.py +0 -0
  265. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/__init__.py +0 -0
  266. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/_token_encoding.py +0 -0
  267. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/anthropic.py +0 -0
  268. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/base.py +0 -0
  269. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
  270. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/deepseek_responses.py +0 -0
  271. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/google.py +0 -0
  272. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/models.py +0 -0
  273. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/openai.py +0 -0
  274. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/openai_responses.py +0 -0
  275. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/providers/responses_common.py +0 -0
  276. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/ratelimit.py +0 -0
  277. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/anthropic.py +0 -0
  278. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/dashscope.py +0 -0
  279. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/deepseek.py +0 -0
  280. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/fireworks.py +0 -0
  281. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/google.py +0 -0
  282. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/kimi_coding.py +0 -0
  283. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/moonshot.py +0 -0
  284. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/ollama_cloud.py +0 -0
  285. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/openai.py +0 -0
  286. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/openai_chatgpt.py +0 -0
  287. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/together.py +0 -0
  288. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/xai.py +0 -0
  289. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/catalog/zai.py +0 -0
  290. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/openrouter_catalog.py +0 -0
  291. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/specs/types.py +0 -0
  292. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/timeouts.py +0 -0
  293. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/llm/tool_execution_ids.py +0 -0
  294. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/local_state.py +0 -0
  295. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/mcp/__init__.py +0 -0
  296. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/mcp/config.py +0 -0
  297. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/mcp/oauth.py +0 -0
  298. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/mcp/service.py +0 -0
  299. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/mcp/state.py +0 -0
  300. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/mcp/tools.py +0 -0
  301. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/mcp/transport.py +0 -0
  302. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/memory/__init__.py +0 -0
  303. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/memory/identity.py +0 -0
  304. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/memory/manager.py +0 -0
  305. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/memory/manifest.py +0 -0
  306. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/memory/markdown.py +0 -0
  307. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/memory/models.py +0 -0
  308. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/memory/protocol.py +0 -0
  309. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/memory/registry.py +0 -0
  310. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/models/__init__.py +0 -0
  311. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/models/sandbox_terminal_state.py +0 -0
  312. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/permissions.py +0 -0
  313. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/runtime.py +0 -0
  314. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/README.md +0 -0
  315. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/__init__.py +0 -0
  316. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/async_filesystem.py +0 -0
  317. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/base.py +0 -0
  318. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/browser.py +0 -0
  319. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/event_loop.py +0 -0
  320. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/filesystem.py +0 -0
  321. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/local.py +0 -0
  322. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/serializer.py +0 -0
  323. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/terminal.py +0 -0
  324. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/sandbox/utils.py +0 -0
  325. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/scratchpad.py +0 -0
  326. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/security/__init__.py +0 -0
  327. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/security/secrets.py +0 -0
  328. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/base.py +0 -0
  329. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/browser.py +0 -0
  330. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/file_system.py +0 -0
  331. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/html.py +0 -0
  332. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/lsp/__init__.py +0 -0
  333. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/lsp/client.py +0 -0
  334. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/lsp/config.py +0 -0
  335. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/lsp/detector.py +0 -0
  336. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/lsp/diagnostics.py +0 -0
  337. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/lsp/edits.py +0 -0
  338. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/lsp/manager.py +0 -0
  339. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/lsp/registry.py +0 -0
  340. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/lsp/registry.yaml +0 -0
  341. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/snapshots.py +0 -0
  342. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/terminal.py +0 -0
  343. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/terminal_buffer.py +0 -0
  344. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/services/workspace_scan.py +0 -0
  345. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/session/__init__.py +0 -0
  346. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/session/control.py +0 -0
  347. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/session/inmemory.py +0 -0
  348. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/session/projection.py +0 -0
  349. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/session/recording.py +0 -0
  350. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/session/runtime.py +0 -0
  351. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/session/store.py +0 -0
  352. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/testing/__init__.py +0 -0
  353. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/testing/store_conformance.py +0 -0
  354. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/tools/__init__.py +0 -0
  355. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/tools/core.py +0 -0
  356. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/tools/definitions.py +0 -0
  357. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/tools/param_aliases.py +0 -0
  358. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/tools/registry.py +0 -0
  359. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/utils/__init__.py +0 -0
  360. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/utils/images.py +0 -0
  361. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/__init__.py +0 -0
  362. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/assets/fold.js +0 -0
  363. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/assets/player.css +0 -0
  364. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/assets/player.html +0 -0
  365. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/assets/player.js +0 -0
  366. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/bundle.py +0 -0
  367. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/hosting.py +0 -0
  368. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/redaction.py +0 -0
  369. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/server.py +0 -0
  370. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/singlefile.py +0 -0
  371. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/web/theme_css.py +0 -0
  372. {kolega_code-0.27.0 → kolega_code-0.27.1}/kolega_code/worktrees.py +0 -0
@@ -6,6 +6,36 @@ This project uses GitHub Releases for detailed generated release notes. This fil
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.27.1 - 2026-08-10
10
+
11
+ ### Added
12
+
13
+ - Thinking Machines models can now be used through either the hosted API or
14
+ the native Tinker `SamplingClient`, with model discovery, settings, usage
15
+ tracking, and connection testing integrated across the CLI and TUI.
16
+ - History compression thresholds can now be configured from Settings,
17
+ `settings.json`, `KOLEGA_CODE_COMPRESSION_THRESHOLD`, or
18
+ `--compression-threshold`.
19
+ - Sub-agent dispatch can now be enabled or disabled for a session from
20
+ Settings, `settings.json`, `KOLEGA_CODE_SUBAGENTS`, or `--subagents on|off`.
21
+
22
+ ### Changed
23
+
24
+ - Compression summaries can use up to 8,192 tokens, reducing the risk that
25
+ important context is lost in longer sessions.
26
+ - The bundled OpenRouter catalogue was refreshed from the 2026-08-10 model
27
+ list and weekly rankings. It now includes 260 tool-capable models, including
28
+ featured `deepseek/deepseek-v4-flash-0731`.
29
+
30
+ ### Fixed
31
+
32
+ - Provider connection tests now send a system message, improving compatibility
33
+ with models that reject probes containing only a user message.
34
+
35
+ ### Security
36
+
37
+ - Updated `h2` to `4.4.1` to address `GHSA-6hr6-w5qg-qmwg`.
38
+
9
39
  ## 0.27.0 - 2026-08-06
10
40
 
11
41
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kolega-code
3
- Version: 0.27.0
3
+ Version: 0.27.1
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/
@@ -276,6 +276,9 @@ Requires-Dist: pytest-xdist==3.8.0; extra == 'dev'
276
276
  Requires-Dist: pytest==9.0.3; extra == 'dev'
277
277
  Requires-Dist: ruff==0.15.12; extra == 'dev'
278
278
  Requires-Dist: twine==6.2.0; extra == 'dev'
279
+ Provides-Extra: tinker
280
+ Requires-Dist: tinker-cookbook==0.5.3; extra == 'tinker'
281
+ Requires-Dist: tml-renderers==0.1.0; extra == 'tinker'
279
282
  Description-Content-Type: text/markdown
280
283
 
281
284
  # Kolega Code
@@ -151,4 +151,4 @@ __all__ = [
151
151
  "parse_git_status_output",
152
152
  ]
153
153
 
154
- __version__ = "0.27.0"
154
+ __version__ = "0.27.1"
@@ -51,4 +51,4 @@ __all__ = [
51
51
  "ToolExtension",
52
52
  ]
53
53
 
54
- __version__ = "0.27.0"
54
+ __version__ = "0.27.1"
@@ -439,6 +439,12 @@ class BaseAgent(LogMixin):
439
439
  # Counts consecutive transient LLM failures (rate-limit / overload) so the turn loop
440
440
  # backs off and eventually gives up instead of retrying forever; reset on any good turn.
441
441
  self._consecutive_llm_retries = 0
442
+ # Host-configured compression threshold (fraction of the context window) shadows
443
+ # the class default when the config carries one; every read below and in
444
+ # _send_context_update goes through the instance attribute.
445
+ config_threshold = getattr(self.config, "history_compression_threshold", None)
446
+ if config_threshold is not None:
447
+ self.history_compression_threshold = config_threshold
442
448
  self.compressor = HistoryCompressor(threshold=self.history_compression_threshold)
443
449
  self.emitter = AgentEventEmitter(
444
450
  connection_manager=self.connection_manager,
@@ -39,9 +39,12 @@ class HistoryCompressor:
39
39
  KEEP_RECENT_MESSAGES = 6
40
40
  # Don't bother summarizing a trivially short prefix.
41
41
  MIN_PREFIX_TO_SUMMARIZE = 3
42
- # Cap the summary length: the prompt targets ~600 words (~900 tokens), so a
43
- # small ceiling keeps it tight and avoids the model's full completion budget.
44
- SUMMARY_MAX_TOKENS = 2048
42
+ # Cap the summary length. The prompt targets ~600 words, but reasoning
43
+ # models (deepseek-v4-flash Responses, etc.) can consume the entire budget
44
+ # on chain-of-thought and leave no room for text output, producing an empty
45
+ # summary. A generous ceiling gives reasoning headroom while still staying
46
+ # well under the model's full completion budget.
47
+ SUMMARY_MAX_TOKENS = 8192
45
48
 
46
49
  def __init__(self, threshold: float = 0.8) -> None:
47
50
  # Fraction of the model context window above which compression kicks in
@@ -2312,6 +2312,21 @@ class ToolCollection(LogMixin):
2312
2312
  Returns:
2313
2313
  True if the tool should be included, False otherwise
2314
2314
  """
2315
+ # Settings gate: sub-agent dispatch can be disabled host-wide
2316
+ # (AgentConfig.subagents_enabled, from settings.json or the --subagents
2317
+ # flag). Placed first so it also beats the custom_tool_groups whitelist
2318
+ # below (planning/investigation agents) and covers host extension
2319
+ # dispatch tools appended to this instance's agent_dispatch_tools.
2320
+ # Gigacode workflow workers are exempt: their dispatch chain is lent by
2321
+ # run_workflow (a separate opt-in) and depth-narrowed below.
2322
+ # Strict `is False` so Mock configs in tests keep the default (enabled).
2323
+ if (
2324
+ method_name in self.agent_dispatch_tools
2325
+ and getattr(self.config, "subagents_enabled", True) is False
2326
+ and not has_workflow_context_marker(getattr(self.caller, "sub_agent_context", None))
2327
+ ):
2328
+ return False
2329
+
2315
2330
  # Gigacode delegation depth is scoped through sub_agent_context. It only
2316
2331
  # narrows a workflow worker's existing dispatch inventory; callers with no
2317
2332
  # workflow context retain their normal behavior.
@@ -2472,6 +2487,14 @@ class ToolCollection(LogMixin):
2472
2487
  dispatch_candidates.intersection_update(self.tool_config.allowed_tools)
2473
2488
  if "dispatch_agent" in dispatch_candidates and not self._available_agent_types():
2474
2489
  dispatch_candidates.discard("dispatch_agent")
2490
+ # Sub-agent dispatch disabled host-wide (AgentConfig.subagents_enabled):
2491
+ # no dispatch candidates remain, so the informational
2492
+ # list_subagent_models tool drops out as well. Gigacode paths are
2493
+ # unaffected: the top-level workflow-authoring branch above already
2494
+ # qualified, and a workflow worker with delegation depth left keeps the
2495
+ # dispatch chain lent by run_workflow.
2496
+ if getattr(self.config, "subagents_enabled", True) is False and not has_workflow_context_marker(context):
2497
+ dispatch_candidates.clear()
2475
2498
  return bool(dispatch_candidates)
2476
2499
 
2477
2500
  async def initialize(self) -> list[str]:
@@ -11,12 +11,17 @@ from pydantic import ValidationError
11
11
 
12
12
  from kolega_code.auth.tokens import ChatGPTTokenManager, OAuthTokens
13
13
  from kolega_code.config import AgentConfig, AgentRole, EditProtocol, ModelConfig, ModelProvider, RateLimitConfig
14
- from kolega_code.llm.specs import MODEL_SPECS, get_model_specs, normalize_thinking_effort
14
+ from kolega_code.llm.specs import MODEL_SPECS, get_model_specs, model_is_known, normalize_thinking_effort
15
15
  from kolega_code.mcp.config import load_mcp_config
16
16
  from kolega_code.services.lsp.config import LspConfig
17
17
 
18
18
  from .provider_registry import default_model_for_provider
19
- from .settings import CliSettings, SettingsStore
19
+ from .settings import (
20
+ COMPRESSION_THRESHOLD_MAX_PERCENT,
21
+ COMPRESSION_THRESHOLD_MIN_PERCENT,
22
+ CliSettings,
23
+ SettingsStore,
24
+ )
20
25
 
21
26
  # Providers authenticated by an OAuth sign-in instead of a static API key.
22
27
  OAUTH_PROVIDERS = frozenset({ModelProvider.OPENAI_CHATGPT})
@@ -48,6 +53,9 @@ API_KEY_ENV = {
48
53
  ModelProvider.KIMI_CODING: "KIMI_CODING_API_KEY",
49
54
  ModelProvider.OLLAMA_CLOUD: "OLLAMA_API_KEY",
50
55
  ModelProvider.OPENROUTER: "OPENROUTER_API_KEY",
56
+ ModelProvider.THINKING_MACHINES: "TINKER_API_KEY",
57
+ # Native Tinker sampling authenticates with the same key.
58
+ ModelProvider.TINKER: "TINKER_API_KEY",
51
59
  }
52
60
 
53
61
  DEFAULT_WEB_SEARCH_BACKEND = "duckduckgo"
@@ -61,6 +69,13 @@ SEARXNG_BASE_URL_ENV = "SEARXNG_BASE_URL"
61
69
  # LSP master switch: on or off. Absent means defer to settings.lsp_enabled.
62
70
  LSP_MODES = ("on", "off")
63
71
  LSP_MODE_ENV = "KOLEGA_CODE_LSP"
72
+ # Sub-agent dispatch (dispatch_agent) master switch: on or off. Absent means
73
+ # defer to settings.subagents_enabled, then the default (enabled).
74
+ SUBAGENT_MODES = ("on", "off")
75
+ SUBAGENTS_MODE_ENV = "KOLEGA_CODE_SUBAGENTS"
76
+ # Compression threshold override, in percent (10-100). Absent means defer to
77
+ # settings.compression_threshold, then the agent's built-in default (80%).
78
+ COMPRESSION_THRESHOLD_ENV = "KOLEGA_CODE_COMPRESSION_THRESHOLD"
64
79
  # Env vars that supply a cloud web-search backend's key, keyed by backend name.
65
80
  SEARCH_BACKEND_KEY_ENV = {
66
81
  "firecrawl": "FIRECRAWL_API_KEY",
@@ -85,6 +100,12 @@ class CliConfigOverrides:
85
100
  edit_protocol: Optional[str] = None
86
101
  web_search_mode: Optional[str] = None
87
102
  lsp_mode: Optional[str] = None
103
+ # Sub-agent dispatch override from the --subagents flag ("on"/"off"); None
104
+ # defers to KOLEGA_CODE_SUBAGENTS, then settings.subagents_enabled.
105
+ subagents_mode: Optional[str] = None
106
+ # Compression threshold in percent, as typed on the command line; parsed and
107
+ # validated in _compression_threshold.
108
+ compression_threshold: Optional[str] = None
88
109
 
89
110
 
90
111
  def load_cli_env(project_path: Path, env: Optional[Mapping[str, str]] = None) -> dict[str, str]:
@@ -161,11 +182,19 @@ def _ensure_explicit_model_supported(
161
182
  provider_source: Optional[str],
162
183
  ) -> None:
163
184
  """Raise a targeted error when an explicit model is paired with the wrong provider."""
164
- if (provider.value, model) in MODEL_SPECS:
185
+ if model_is_known(provider, model):
165
186
  return
166
187
 
167
188
  model_label = f"{model_source}={model}" if model_source else f"Model '{model}'"
168
189
  provider_label = f"{provider_source}={provider.value}" if provider_source else f"provider {provider.value}"
190
+ if provider == ModelProvider.TINKER:
191
+ # Checkpoint paths (tinker://...) always resolve via the wildcard; an
192
+ # unknown base model id needs a catalog refresh.
193
+ raise CliConfigError(
194
+ f"{model_label} is not a known Tinker base model. "
195
+ "Run `kolega-code models refresh --provider tinker` to pick up newer bases, "
196
+ "or use a saved checkpoint path (tinker://<run-id>/sampler_weights/<step>)."
197
+ )
169
198
  sources = _model_sources(model)
170
199
  if sources:
171
200
  preferred = sources[0]
@@ -274,14 +303,74 @@ def _lsp_enabled(
274
303
  return True
275
304
 
276
305
 
306
+ def _subagents_enabled(
307
+ env: Mapping[str, str],
308
+ settings: Optional[CliSettings],
309
+ override: Optional[str],
310
+ ) -> bool:
311
+ """Resolve the sub-agent dispatch master switch with flag-over-env-over-settings precedence."""
312
+ mode = (override or env.get(SUBAGENTS_MODE_ENV) or "").strip().lower()
313
+ if mode:
314
+ if mode not in SUBAGENT_MODES:
315
+ valid = ", ".join(SUBAGENT_MODES)
316
+ raise CliConfigError(f"Unsupported subagents mode '{mode}'. Valid modes: {valid}")
317
+ return mode == "on"
318
+ if settings is not None and settings.subagents_enabled is not None:
319
+ return bool(settings.subagents_enabled)
320
+ return True
321
+
322
+
323
+ def _compression_threshold(
324
+ env: Mapping[str, str],
325
+ settings: Optional[CliSettings],
326
+ override: Optional[str],
327
+ ) -> Optional[float]:
328
+ """Resolve the compression threshold with flag-over-env-over-settings precedence.
329
+
330
+ User-facing surfaces carry a percent (10-100); the returned value is the
331
+ fraction the agent compares against, or None for the built-in default (80%).
332
+ Explicit flag/env values are validated strictly (a typo must fail loudly);
333
+ settings values were already range-coerced at load."""
334
+ # Resolve presence per layer instead of via _explicit_value, whose truthiness
335
+ # check treats an explicit empty value as absent; here it is invalid input to
336
+ # reject, not a missing layer to fall through.
337
+ explicit: Optional[str] = None
338
+ source: Optional[str] = None
339
+ if override is not None:
340
+ explicit, source = override, "--compression-threshold"
341
+ elif COMPRESSION_THRESHOLD_ENV in env:
342
+ explicit, source = env[COMPRESSION_THRESHOLD_ENV], COMPRESSION_THRESHOLD_ENV
343
+ percent: Optional[float] = None
344
+ if explicit is not None:
345
+ try:
346
+ percent = float(explicit)
347
+ except ValueError:
348
+ percent = None
349
+ if (
350
+ percent is None
351
+ or percent < COMPRESSION_THRESHOLD_MIN_PERCENT
352
+ or percent > COMPRESSION_THRESHOLD_MAX_PERCENT
353
+ ):
354
+ raise CliConfigError(
355
+ f"Unsupported compression threshold '{explicit}' from {source}. "
356
+ f"Valid range: {COMPRESSION_THRESHOLD_MIN_PERCENT}-{COMPRESSION_THRESHOLD_MAX_PERCENT} (percent)."
357
+ )
358
+ elif settings is not None and settings.compression_threshold is not None:
359
+ percent = settings.compression_threshold
360
+ if percent is None:
361
+ return None
362
+ return percent / 100.0
363
+
364
+
277
365
  def _coerce_known_model(provider: ModelProvider, model: Optional[str]) -> str:
278
366
  """Return ``model`` if it's a known spec for ``provider``, else the default.
279
367
 
280
368
  Guards against a settings.json that points at a model which has since been
281
369
  renamed or removed (e.g. an old ChatGPT slug): without this, config building
282
- raises and the TUI disables the composer, locking the user out.
370
+ raises and the TUI disables the composer, locking the user out. Wildcard-
371
+ addressed models (Tinker checkpoint paths) count as known and are kept.
283
372
  """
284
- if model and (provider.value, model) in MODEL_SPECS:
373
+ if model and model_is_known(provider, model):
285
374
  return model
286
375
  return default_model_for_provider(provider)
287
376
 
@@ -370,7 +459,7 @@ def _slot_provider_model(
370
459
  saved_provider, saved_model = saved.get("provider"), saved.get("model")
371
460
  if saved_provider and saved_model:
372
461
  provider = _provider(saved_provider)
373
- if (provider.value, saved_model) not in MODEL_SPECS:
462
+ if not model_is_known(provider, saved_model):
374
463
  saved_model = default_model_for_provider(provider)
375
464
  return provider, saved_model
376
465
 
@@ -461,7 +550,7 @@ def _agent_model_overrides(
461
550
  model_source=model_key,
462
551
  provider_source=provider_key if provider_env_value else None,
463
552
  )
464
- elif (provider.value, model_value) not in MODEL_SPECS:
553
+ elif not model_is_known(provider, model_value):
465
554
  model_value = default_model_for_provider(provider)
466
555
  overrides[role.value] = _model_config(provider, model_value, thinking_effort=effort_value)
467
556
  return overrides
@@ -519,6 +608,7 @@ def build_agent_config(
519
608
  agent_model_overrides = _agent_model_overrides(loaded_env, settings)
520
609
  web_search_backend, web_search_api_key, web_search_base_url = _search_config(loaded_env, settings)
521
610
  web_search_mode = _web_search_mode(loaded_env, settings, overrides.web_search_mode)
611
+ compression_threshold = _compression_threshold(loaded_env, settings, overrides.compression_threshold)
522
612
  state_dir = settings_store.root if settings_store is not None else SettingsStore().root
523
613
  mcp_config = load_mcp_config(
524
614
  project_path,
@@ -569,6 +659,7 @@ def build_agent_config(
569
659
  kimi_coding_api_key=_api_key_for_provider(ModelProvider.KIMI_CODING, loaded_env, settings),
570
660
  ollama_cloud_api_key=_api_key_for_provider(ModelProvider.OLLAMA_CLOUD, loaded_env, settings),
571
661
  openrouter_api_key=_api_key_for_provider(ModelProvider.OPENROUTER, loaded_env, settings),
662
+ thinking_machines_api_key=_api_key_for_provider(ModelProvider.THINKING_MACHINES, loaded_env, settings),
572
663
  environment=overrides.environment or loaded_env.get("KOLEGA_CODE_ENVIRONMENT", "development"),
573
664
  edit_protocol=edit_protocol,
574
665
  long_context_config=_model_config(long_provider, long_model, thinking_effort=active_thinking_effort),
@@ -583,6 +674,8 @@ def build_agent_config(
583
674
  lsp=LspConfig(enabled=_lsp_enabled(loaded_env, settings, overrides.lsp_mode)),
584
675
  lsp_project_trusted=lsp_project_trusted,
585
676
  eval_enabled=(True if settings is None or settings.eval_enabled is None else bool(settings.eval_enabled)),
677
+ subagents_enabled=_subagents_enabled(loaded_env, settings, overrides.subagents_mode),
678
+ history_compression_threshold=compression_threshold,
586
679
  )
587
680
  except ValueError as exc:
588
681
  raise CliConfigError(str(exc)) from exc
@@ -73,6 +73,7 @@ from .diagnostics import write_crash_log
73
73
  from .config import (
74
74
  DEPRECATED_THINKING_TOKENS_MESSAGE,
75
75
  LSP_MODES,
76
+ SUBAGENT_MODES,
76
77
  WEB_SEARCH_MODES,
77
78
  CliConfigError,
78
79
  CliConfigOverrides,
@@ -82,7 +83,7 @@ from .config import (
82
83
  )
83
84
  from .connection import CliConnectionManager
84
85
  from .mentions import build_file_attachments
85
- from .model_catalog import SORT_CHOICES, apply_catalog_overlay, run_models_list, run_models_refresh
86
+ from .model_catalog import SORT_CHOICES, apply_all_catalog_overlays, run_models_list, run_models_refresh
86
87
  from .session_store import SessionRecord, SessionStore, SessionStoreError, resolve_active_project
87
88
  from .settings import CliSettings, SettingsStore, SettingsStoreError
88
89
  from .goal import (
@@ -155,9 +156,9 @@ def main(argv: Optional[Iterable[str]] = None) -> int:
155
156
  except (OSError, ValueError, RuntimeError):
156
157
  pass
157
158
  args = parse_args(list(argv) if argv is not None else sys.argv[1:])
158
- # Merge any cached provider catalog before a command resolves a model. This
159
- # only reads a local file; refreshing it is an explicit `models refresh`.
160
- apply_catalog_overlay(getattr(args, "state_dir", None))
159
+ # Merge any cached provider catalogs before a command resolves a model.
160
+ # This only reads local files; refreshing them is an explicit `models refresh`.
161
+ apply_all_catalog_overlays(getattr(args, "state_dir", None))
161
162
  try:
162
163
  if getattr(args, "version", False):
163
164
  return _run_version()
@@ -241,6 +242,13 @@ def _add_common_model_args(parser: argparse.ArgumentParser) -> None:
241
242
  parser.add_argument("--thinking-effort", help="Model-specific thinking effort for the active model.")
242
243
  parser.add_argument("--thinking-tokens", dest="deprecated_thinking_tokens", type=int, help=argparse.SUPPRESS)
243
244
  parser.add_argument("--environment", help="Environment label for tracing/metadata.")
245
+ parser.add_argument(
246
+ "--compression-threshold",
247
+ metavar="PERCENT",
248
+ help="Context-window usage percentage that triggers automatic history compression "
249
+ "(10-100; default 80). Overrides settings.json for this session; not persisted. "
250
+ "100 effectively disables automatic compression.",
251
+ )
244
252
  parser.add_argument(
245
253
  "--edit-protocol",
246
254
  choices=[protocol.value for protocol in EditProtocol],
@@ -332,6 +340,13 @@ def _add_tui_args(parser: argparse.ArgumentParser) -> None:
332
340
  default=None,
333
341
  help="Force LSP tools on or off for this session (overrides settings.json; not persisted).",
334
342
  )
343
+ parser.add_argument(
344
+ "--subagents",
345
+ choices=list(SUBAGENT_MODES),
346
+ default=None,
347
+ help="Force sub-agent dispatch (dispatch_agent) on or off for this session "
348
+ "(overrides settings.json; not persisted).",
349
+ )
335
350
  _add_session_args(parser, session_help="Legacy alias for --resume SESSION_ID.")
336
351
  _add_worktree_args(parser)
337
352
  _add_common_model_args(parser)
@@ -427,6 +442,13 @@ def _build_subcommand_parser() -> argparse.ArgumentParser:
427
442
  default=None,
428
443
  help="Force LSP tools on or off for this session (overrides settings.json; not persisted).",
429
444
  )
445
+ ask.add_argument(
446
+ "--subagents",
447
+ choices=list(SUBAGENT_MODES),
448
+ default=None,
449
+ help="Force sub-agent dispatch (dispatch_agent) on or off for this session "
450
+ "(overrides settings.json; not persisted).",
451
+ )
430
452
  ask.add_argument("--save", action="store_true", help="Persist the session after the prompt completes.")
431
453
  ask.add_argument("--json", action="store_true", help="Emit complete messages and events as JSON.")
432
454
  ask.add_argument("--browser-visible", action="store_true", help="Launch visible Playwright browser windows.")
@@ -640,6 +662,8 @@ def _overrides_from_args(args: argparse.Namespace) -> CliConfigOverrides:
640
662
  edit_protocol=getattr(args, "edit_protocol", None),
641
663
  web_search_mode=getattr(args, "web_search", None),
642
664
  lsp_mode=getattr(args, "lsp", None),
665
+ subagents_mode=getattr(args, "subagents", None),
666
+ compression_threshold=getattr(args, "compression_threshold", None),
643
667
  )
644
668
 
645
669
 
@@ -1,14 +1,13 @@
1
- """Model-catalog inspection and the optional OpenRouter catalog overlay.
1
+ """Model-catalog inspection and optional runtime catalog overlays.
2
2
 
3
3
  Backs ``kolega-code models list`` and ``kolega-code models refresh``.
4
4
 
5
- The bundled OpenRouter catalog is a snapshot taken when a Kolega Code release is
6
- cut, so a model published after that release is unknown to it. ``models refresh``
7
- fetches the documented ``/api/v1/models`` endpoint once, on request, and caches
8
- the result in the state directory; the cache is merged into ``MODEL_SPECS`` at
9
- CLI startup. Startup itself never touches the network, and cached entries are
10
- never marked ``featured`` — Settings pickers lead with the release's curated-by-
11
- usage set (and admit any catalogued id through their "Other…" entry), while
5
+ Bundled catalogs are snapshots taken when a Kolega Code release is cut, so a
6
+ model published after that release is unknown to them. ``models refresh``
7
+ fetches a provider's live catalog once, on request, and caches the result in
8
+ the state directory; the cache is merged into ``MODEL_SPECS`` at CLI startup.
9
+ Startup itself never touches the network, and cached entries are never marked
10
+ ``featured`` — Settings pickers lead with the release's curated set, while
12
11
  sub-agent prompts keep showing the featured set alone.
13
12
  """
14
13
 
@@ -23,55 +22,87 @@ from typing import Any, Iterable, Optional, Sequence
23
22
  from kolega_code.config import ModelProvider
24
23
  from kolega_code.llm.specs import MODEL_SPECS, is_featured_model
25
24
  from kolega_code.llm.specs import openrouter_catalog as openrouter
25
+ from kolega_code.llm.specs import tinker_catalog as tinker
26
26
 
27
27
  from .provider_registry import PROVIDER_LABELS, get_ui_model, rebuild_ui_model_options
28
28
  from .session_store import default_state_dir
29
29
 
30
- # Point the overlay at an explicit file (useful for pinning a catalog in CI).
31
- CATALOG_PATH_ENV = "KOLEGA_CODE_OPENROUTER_CATALOG"
32
- # Ignore any cached overlay and use the bundled snapshot alone.
33
- CATALOG_DISABLE_ENV = "KOLEGA_CODE_DISABLE_OPENROUTER_CATALOG"
30
+ # Overlay sources keyed by provider value. Each module exposes PROVIDER,
31
+ # MODELS_URL, CACHE_FILENAME, fetch_models(), catalog_entries(), load_cache()
32
+ # and save_cache().
33
+ OVERLAY_SOURCES = {
34
+ openrouter.PROVIDER: openrouter,
35
+ tinker.PROVIDER: tinker,
36
+ }
37
+
38
+
39
+ def _overlay_module(catalog: str) -> Any:
40
+ module = OVERLAY_SOURCES.get(catalog)
41
+ if module is None:
42
+ raise ValueError(
43
+ f"No refreshable catalog for provider '{catalog}'. Valid: {', '.join(sorted(OVERLAY_SOURCES))}"
44
+ )
45
+ return module
46
+
47
+
48
+ def _catalog_env_names(catalog: str) -> tuple[str, str]:
49
+ upper = catalog.upper()
50
+ return f"KOLEGA_CODE_{upper}_CATALOG", f"KOLEGA_CODE_DISABLE_{upper}_CATALOG"
51
+
52
+
53
+ # OpenRouter's pin/disable env vars, kept as module constants for back-compat
54
+ # (tests and docs reference them by name).
55
+ CATALOG_PATH_ENV, CATALOG_DISABLE_ENV = _catalog_env_names(openrouter.PROVIDER)
34
56
 
35
57
  SORT_CHOICES = ("popularity", "id")
36
58
 
37
59
 
38
- def overlay_path(state_dir: Optional[Path] = None, env: Optional[dict[str, str]] = None) -> Path:
39
- """Resolve the OpenRouter overlay cache path."""
60
+ def overlay_path(
61
+ state_dir: Optional[Path] = None,
62
+ env: Optional[dict[str, str]] = None,
63
+ catalog: str = openrouter.PROVIDER,
64
+ ) -> Path:
65
+ """Resolve an overlay cache path for ``catalog``."""
66
+ module = _overlay_module(catalog)
40
67
  environ = env if env is not None else dict(os.environ)
41
- override = environ.get(CATALOG_PATH_ENV)
68
+ path_env, _ = _catalog_env_names(catalog)
69
+ override = environ.get(path_env)
42
70
  if override:
43
71
  return Path(override).expanduser()
44
72
  root = state_dir or default_state_dir(environ)
45
- return Path(root).expanduser() / openrouter.CACHE_FILENAME
73
+ return Path(root).expanduser() / module.CACHE_FILENAME
46
74
 
47
75
 
48
- def overlay_disabled(env: Optional[dict[str, str]] = None) -> bool:
76
+ def overlay_disabled(env: Optional[dict[str, str]] = None, catalog: str = openrouter.PROVIDER) -> bool:
49
77
  environ = env if env is not None else dict(os.environ)
50
- value = (environ.get(CATALOG_DISABLE_ENV) or "").strip().lower()
78
+ _, disable_env = _catalog_env_names(catalog)
79
+ value = (environ.get(disable_env) or "").strip().lower()
51
80
  return value not in ("", "0", "false", "no")
52
81
 
53
82
 
54
83
  def apply_catalog_overlay(
55
84
  state_dir: Optional[Path] = None,
56
85
  env: Optional[dict[str, str]] = None,
86
+ catalog: str = openrouter.PROVIDER,
57
87
  ) -> int:
58
- """Merge a cached OpenRouter catalog into ``MODEL_SPECS``; return entries added.
88
+ """Merge a cached ``catalog`` overlay into ``MODEL_SPECS``; return entries added.
59
89
 
60
90
  Bundled entries always win: a refresh may add models, never redefine the
61
91
  reviewed specs (or the featured set) that shipped with the release. Any
62
92
  failure is silent by design — the bundled snapshot is a complete catalog on
63
93
  its own, and no CLI command should fail because a cache file is unreadable.
64
94
  """
65
- if overlay_disabled(env):
95
+ module = _overlay_module(catalog)
96
+ if overlay_disabled(env, catalog=catalog):
66
97
  return 0
67
- path = overlay_path(state_dir, env)
68
- entries = openrouter.load_cache(path)
98
+ path = overlay_path(state_dir, env, catalog=catalog)
99
+ entries = module.load_cache(path)
69
100
  if not entries:
70
101
  return 0
71
102
 
72
103
  added = 0
73
104
  for identifier, spec in entries:
74
- key = (openrouter.PROVIDER, identifier)
105
+ key = (module.PROVIDER, identifier)
75
106
  if key in MODEL_SPECS:
76
107
  continue
77
108
  # Overlay models are never featured: the picker keeps showing the
@@ -84,6 +115,14 @@ def apply_catalog_overlay(
84
115
  return added
85
116
 
86
117
 
118
+ def apply_all_catalog_overlays(state_dir: Optional[Path] = None) -> int:
119
+ """Merge every configured catalog overlay; return total entries added."""
120
+ total = 0
121
+ for catalog in OVERLAY_SOURCES:
122
+ total += apply_catalog_overlay(state_dir, catalog=catalog)
123
+ return total
124
+
125
+
87
126
  def catalog_rows(
88
127
  *,
89
128
  provider: Optional[str] = None,
@@ -186,24 +225,25 @@ def run_models_list(args: Any, printer) -> int:
186
225
  def run_models_refresh(args: Any, printer, error_printer) -> int:
187
226
  """Handle ``kolega-code models refresh``."""
188
227
  provider = _resolve_provider(getattr(args, "provider", None)) or openrouter.PROVIDER
189
- if provider != openrouter.PROVIDER:
190
- error_printer(f"Only '{openrouter.PROVIDER}' has a refreshable catalog.")
228
+ module = OVERLAY_SOURCES.get(provider)
229
+ if module is None:
230
+ error_printer(f"No refreshable catalog for provider '{provider}'. Valid: {', '.join(sorted(OVERLAY_SOURCES))}.")
191
231
  return 2
192
232
 
193
- printer(f"Fetching {openrouter.MODELS_URL} ...")
233
+ printer(f"Fetching {module.MODELS_URL} ...")
194
234
  try:
195
- payload = openrouter.fetch_models()
196
- entries = openrouter.catalog_entries(payload)
235
+ payload = module.fetch_models()
236
+ entries = module.catalog_entries(payload)
197
237
  except Exception as exc: # noqa: BLE001 - surface the cause, whatever the transport raised
198
- error_printer(f"Could not refresh the OpenRouter catalog: {exc}")
238
+ error_printer(f"Could not refresh the {provider} catalog: {exc}")
199
239
  return 1
200
240
 
201
- bundled = {model for (provider_value, model) in MODEL_SPECS if provider_value == openrouter.PROVIDER}
202
- path = overlay_path(getattr(args, "state_dir", None))
203
- previously_cached = {identifier for identifier, _ in openrouter.load_cache(path)}
241
+ bundled = {model for (provider_value, model) in MODEL_SPECS if provider_value == provider}
242
+ path = overlay_path(getattr(args, "state_dir", None), catalog=provider)
243
+ previously_cached = {identifier for identifier, _ in module.load_cache(path)}
204
244
  new_models = [identifier for identifier, _ in entries if identifier not in bundled]
205
245
 
206
- openrouter.save_cache(path, entries, fetched_at=dt.datetime.now(dt.timezone.utc).isoformat())
246
+ module.save_cache(path, entries, fetched_at=dt.datetime.now(dt.timezone.utc).isoformat())
207
247
 
208
248
  added = [identifier for identifier in new_models if identifier not in previously_cached]
209
249
  printer(
@@ -212,8 +252,9 @@ def run_models_refresh(args: Any, printer, error_printer) -> int:
212
252
  )
213
253
  if added:
214
254
  printer("Newly available: " + ", ".join(sorted(added)[:20]) + ("..." if len(added) > 20 else ""))
215
- if overlay_disabled():
216
- printer(f"NOTE: {CATALOG_DISABLE_ENV} is set, so the cache is ignored at startup.")
255
+ if overlay_disabled(catalog=provider):
256
+ _, disable_env = _catalog_env_names(provider)
257
+ printer(f"NOTE: {disable_env} is set, so the cache is ignored at startup.")
217
258
  return 0
218
259
 
219
260
 
@@ -27,6 +27,10 @@ async def _probe_generate(client: Any, model: str, messages: MessageHistory) ->
27
27
  with llm_call_origin(helper_origin("model_connection")):
28
28
  return await client.generate(
29
29
  messages=messages,
30
+ # The Anthropic provider family (anthropic, moonshot, zai,
31
+ # kimi_coding, thinking_machines) requires a system message, so the
32
+ # probe must carry one even though it is not the point of the test.
33
+ system=Message(role="system", content=[TextBlock(text="Reply with OK.")]),
30
34
  model=model,
31
35
  max_completion_tokens=CONNECTION_TEST_MAX_COMPLETION_TOKENS,
32
36
  tools=[],