kolega-code 0.8.0__tar.gz → 0.8.2__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 (325) hide show
  1. {kolega_code-0.8.0 → kolega_code-0.8.2}/PKG-INFO +1 -1
  2. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/cli/overview.md +1 -0
  3. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/gigacode.mdx +14 -3
  4. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/interface.md +4 -3
  5. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/__init__.py +4 -1
  6. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/__init__.py +6 -1
  7. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/baseagent.py +14 -0
  8. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/browseragent.py +2 -0
  9. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/coder.py +2 -0
  10. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/conversation.py +16 -2
  11. kolega_code-0.8.2/kolega_code/agent/errors.py +9 -0
  12. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/generalagent.py +2 -0
  13. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/investigationagent.py +2 -0
  14. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/guide.py +20 -4
  15. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/journal.py +77 -7
  16. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/runtime.py +41 -3
  17. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/types.py +2 -0
  18. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/planningagent.py +2 -0
  19. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +4 -0
  20. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_chatgpt_oauth_provider.py +136 -0
  21. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_error_boundary.py +3 -2
  22. kolega_code-0.8.2/kolega_code/agent/tests/llm/test_openai_responses_provider.py +163 -0
  23. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_thinking_effort.py +5 -1
  24. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_base_agent.py +68 -0
  25. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_tui_events.py +4 -2
  26. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_image_compat.py +56 -0
  27. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_prompts.py +8 -0
  28. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_agent_tool.py +29 -3
  29. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_workflow_tool.py +143 -5
  30. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/agent_tool.py +166 -12
  31. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/workflow_tool.py +193 -22
  32. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tools.py +8 -4
  33. kolega_code-0.8.2/kolega_code/cli/app.py +1384 -0
  34. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/main.py +2 -0
  35. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app.py +1380 -363
  36. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app_compaction_restore.py +4 -4
  37. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app_image_vision_warning.py +7 -6
  38. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app_model_switch_vision.py +5 -6
  39. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_main.py +8 -0
  40. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_themes.py +4 -3
  41. kolega_code-0.8.2/kolega_code/cli/tui/__init__.py +1 -0
  42. kolega_code-0.8.2/kolega_code/cli/tui/agent_runtime.py +306 -0
  43. kolega_code-0.8.2/kolega_code/cli/tui/command_handlers.py +810 -0
  44. kolega_code-0.8.2/kolega_code/cli/tui/constants.py +24 -0
  45. kolega_code-0.8.2/kolega_code/cli/tui/prompt_flows.py +430 -0
  46. kolega_code-0.8.2/kolega_code/cli/tui/settings_panel.py +408 -0
  47. kolega_code-0.8.2/kolega_code/cli/tui/state.py +199 -0
  48. kolega_code-0.8.2/kolega_code/cli/tui/status_dashboard.py +267 -0
  49. kolega_code-0.8.2/kolega_code/cli/tui/styles.py +339 -0
  50. kolega_code-0.8.2/kolega_code/cli/tui/sub_agent_screen.py +367 -0
  51. kolega_code-0.8.2/kolega_code/cli/tui/transcript.py +1397 -0
  52. kolega_code-0.8.2/kolega_code/cli/tui/widgets.py +658 -0
  53. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/client.py +6 -2
  54. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/instrumented_client.py +3 -3
  55. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/models.py +78 -0
  56. kolega_code-0.8.2/kolega_code/llm/providers/chatgpt_oauth.py +103 -0
  57. kolega_code-0.8.2/kolega_code/llm/providers/openai_responses.py +60 -0
  58. kolega_code-0.8.0/kolega_code/llm/providers/chatgpt_oauth.py → kolega_code-0.8.2/kolega_code/llm/providers/responses_common.py +142 -103
  59. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/specs.py +18 -8
  60. {kolega_code-0.8.0 → kolega_code-0.8.2}/pyproject.toml +1 -1
  61. {kolega_code-0.8.0 → kolega_code-0.8.2}/uv.lock +2 -2
  62. kolega_code-0.8.0/kolega_code/cli/app.py +0 -6071
  63. {kolega_code-0.8.0 → kolega_code-0.8.2}/.env.example +0 -0
  64. {kolega_code-0.8.0 → kolega_code-0.8.2}/.github/workflows/ci.yml +0 -0
  65. {kolega_code-0.8.0 → kolega_code-0.8.2}/.github/workflows/docs.yml +0 -0
  66. {kolega_code-0.8.0 → kolega_code-0.8.2}/.github/workflows/release.yml +0 -0
  67. {kolega_code-0.8.0 → kolega_code-0.8.2}/.gitignore +0 -0
  68. {kolega_code-0.8.0 → kolega_code-0.8.2}/CONTRIBUTING.md +0 -0
  69. {kolega_code-0.8.0 → kolega_code-0.8.2}/LICENSE +0 -0
  70. {kolega_code-0.8.0 → kolega_code-0.8.2}/README.md +0 -0
  71. {kolega_code-0.8.0 → kolega_code-0.8.2}/RELEASING.md +0 -0
  72. {kolega_code-0.8.0 → kolega_code-0.8.2}/SECURITY.md +0 -0
  73. {kolega_code-0.8.0 → kolega_code-0.8.2}/conftest.py +0 -0
  74. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/.gitignore +0 -0
  75. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/README.md +0 -0
  76. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/astro.config.mjs +0 -0
  77. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/package-lock.json +0 -0
  78. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/package.json +0 -0
  79. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/public/favicon.svg +0 -0
  80. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/assets/demo.gif +0 -0
  81. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/assets/kolega-dark.svg +0 -0
  82. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/assets/kolega-light.svg +0 -0
  83. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/cli/ask.md +0 -0
  84. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/cli/doctor.md +0 -0
  85. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/cli/sessions.md +0 -0
  86. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/concepts/agents.md +0 -0
  87. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/concepts/how-it-works.md +0 -0
  88. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/concepts/tools.md +0 -0
  89. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/configuration/environment-variables.md +0 -0
  90. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/configuration/providers-and-models.mdx +0 -0
  91. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/configuration/settings-and-api-keys.mdx +0 -0
  92. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/configuration/sign-in-with-chatgpt.mdx +0 -0
  93. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/getting-started/installation.mdx +0 -0
  94. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/getting-started/quick-start.mdx +0 -0
  95. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/hooks.md +0 -0
  96. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/index.mdx +0 -0
  97. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/skills.mdx +0 -0
  98. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/composer.md +0 -0
  99. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/modes.md +0 -0
  100. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/sessions-and-resume.md +0 -0
  101. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/slash-commands.md +0 -0
  102. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content.config.ts +0 -0
  103. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/styles/brand.css +0 -0
  104. {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/tsconfig.json +0 -0
  105. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/common.py +0 -0
  106. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/compression.py +0 -0
  107. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/context.py +0 -0
  108. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/__init__.py +0 -0
  109. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/budget.py +0 -0
  110. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/errors.py +0 -0
  111. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/executor.py +0 -0
  112. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/tests/__init__.py +0 -0
  113. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/tests/test_orchestration.py +0 -0
  114. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_provider.py +0 -0
  115. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
  116. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
  117. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
  118. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
  119. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +0 -0
  120. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
  121. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
  122. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
  123. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
  124. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
  125. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
  126. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
  127. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
  128. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
  129. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
  130. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
  131. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
  132. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
  133. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
  134. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
  135. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
  136. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompts.py +0 -0
  137. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/__init__.py +0 -0
  138. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/compaction_helpers.py +0 -0
  139. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/__init__.py +0 -0
  140. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_anthropic_token_counting.py +0 -0
  141. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_billing_openai_cache.py +0 -0
  142. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_chatgpt_live.py +0 -0
  143. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_client.py +0 -0
  144. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_dashscope_mapping.py +0 -0
  145. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_exceptions.py +0 -0
  146. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_google_thought_signature.py +0 -0
  147. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_google_tool_signature_live.py +0 -0
  148. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_instrumented_client.py +0 -0
  149. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_instrumented_client_integration.py +0 -0
  150. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_langfuse_normalization.py +0 -0
  151. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_live_providers.py +0 -0
  152. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_model_specs.py +0 -0
  153. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_cached_tokens.py +0 -0
  154. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_cached_tokens_stream.py +0 -0
  155. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_message_conversion.py +0 -0
  156. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_token_counting.py +0 -0
  157. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_supports_vision.py +0 -0
  158. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_tool_execution_ids.py +0 -0
  159. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/__init__.py +0 -0
  160. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_browser.py +0 -0
  161. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_browser_parity.py +0 -0
  162. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_file_system.py +0 -0
  163. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_sandbox_terminal_input.py +0 -0
  164. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_terminal.py +0 -0
  165. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_terminal_buffer.py +0 -0
  166. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_terminal_state_serializer.py +0 -0
  167. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_agent_tools_inventory.py +0 -0
  168. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_coder_attachments.py +0 -0
  169. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_coder_prompt_extensions.py +0 -0
  170. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_commands.py +0 -0
  171. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_integration.py +0 -0
  172. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_persistence.py +0 -0
  173. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_subagent.py +0 -0
  174. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compress_command.py +0 -0
  175. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compression.py +0 -0
  176. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_conversation_compaction.py +0 -0
  177. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_duplicate_tool_results.py +0 -0
  178. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_empty_message_handling.py +0 -0
  179. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_event_emitter.py +0 -0
  180. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_general_agent.py +0 -0
  181. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_gigacode_gating.py +0 -0
  182. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_hooks_integration.py +0 -0
  183. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_html.py +0 -0
  184. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_parallel_tool_calls.py +0 -0
  185. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_permissions.py +0 -0
  186. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_planning_agent.py +0 -0
  187. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_prompt_provider.py +0 -0
  188. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_read_image_tool.py +0 -0
  189. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_tool_registry.py +0 -0
  190. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_tools.py +0 -0
  191. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/__init__.py +0 -0
  192. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_base_tool.py +0 -0
  193. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_browser_tool.py +0 -0
  194. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_build_tool.py +0 -0
  195. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_create_file_tool.py +0 -0
  196. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_edit_preview.py +0 -0
  197. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_glob_tool.py +0 -0
  198. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_glob_tool_sandbox_parity.py +0 -0
  199. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_list_directory_tool.py +0 -0
  200. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_read_file_tool.py +0 -0
  201. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_replace_entire_file_tool.py +0 -0
  202. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_replace_lines_tool.py +0 -0
  203. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_search_and_replace_tool.py +0 -0
  204. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_search_codebase_tool.py +0 -0
  205. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_terminal_tool.py +0 -0
  206. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_think_hard_integration.py +0 -0
  207. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_think_hard_streaming.py +0 -0
  208. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_web_fetch_tool.py +0 -0
  209. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_web_search_tool.py +0 -0
  210. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/base_tool.py +0 -0
  211. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
  212. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/build_tool.py +0 -0
  213. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/create_file_tool.py +0 -0
  214. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
  215. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/glob_tool.py +0 -0
  216. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/list_directory_tool.py +0 -0
  217. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
  218. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
  219. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
  220. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/replace_entire_file_tool.py +0 -0
  221. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/replace_lines_tool.py +0 -0
  222. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_and_replace_tool.py +0 -0
  223. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
  224. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
  225. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
  226. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
  227. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
  228. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
  229. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
  230. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
  231. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_codebase_tool.py +0 -0
  232. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
  233. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
  234. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/think_hard_tool.py +0 -0
  235. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
  236. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
  237. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/utils/commands.py +0 -0
  238. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/__init__.py +0 -0
  239. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/_jwt.py +0 -0
  240. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/chatgpt_oauth.py +0 -0
  241. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/constants.py +0 -0
  242. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/tests/__init__.py +0 -0
  243. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/tests/test_chatgpt_oauth.py +0 -0
  244. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/tests/test_tokens.py +0 -0
  245. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/tokens.py +0 -0
  246. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/__init__.py +0 -0
  247. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/clipboard_image.py +0 -0
  248. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/config.py +0 -0
  249. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/connection.py +0 -0
  250. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/file_index.py +0 -0
  251. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/mentions.py +0 -0
  252. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/messages.py +0 -0
  253. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/provider_registry.py +0 -0
  254. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/session_store.py +0 -0
  255. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/settings.py +0 -0
  256. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/skills.py +0 -0
  257. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/slash_commands.py +0 -0
  258. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/__init__.py +0 -0
  259. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_cli_config.py +0 -0
  260. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_clipboard_image.py +0 -0
  261. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_connection.py +0 -0
  262. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_file_index.py +0 -0
  263. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_mentions.py +0 -0
  264. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_provider_registry.py +0 -0
  265. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_session_store.py +0 -0
  266. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_settings.py +0 -0
  267. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_skills.py +0 -0
  268. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_slash_commands.py +0 -0
  269. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_updater.py +0 -0
  270. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/theme.py +0 -0
  271. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/updater.py +0 -0
  272. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/config.py +0 -0
  273. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/events.py +0 -0
  274. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/__init__.py +0 -0
  275. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/backends.py +0 -0
  276. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/config.py +0 -0
  277. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/dispatcher.py +0 -0
  278. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/events.py +0 -0
  279. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/matcher.py +0 -0
  280. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/outcome.py +0 -0
  281. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/tests/__init__.py +0 -0
  282. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/tests/test_hooks.py +0 -0
  283. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/exceptions.py +0 -0
  284. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/__init__.py +0 -0
  285. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/anthropic.py +0 -0
  286. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/base.py +0 -0
  287. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/google.py +0 -0
  288. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/models.py +0 -0
  289. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/openai.py +0 -0
  290. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/ratelimit.py +0 -0
  291. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/tool_execution_ids.py +0 -0
  292. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/models/__init__.py +0 -0
  293. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/models/sandbox_terminal_state.py +0 -0
  294. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/permissions.py +0 -0
  295. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/runtime.py +0 -0
  296. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/README.md +0 -0
  297. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/__init__.py +0 -0
  298. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/async_filesystem.py +0 -0
  299. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/base.py +0 -0
  300. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/browser.py +0 -0
  301. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/event_loop.py +0 -0
  302. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/filesystem.py +0 -0
  303. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/local.py +0 -0
  304. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/serializer.py +0 -0
  305. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/terminal.py +0 -0
  306. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/utils.py +0 -0
  307. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/base.py +0 -0
  308. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/browser.py +0 -0
  309. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/file_system.py +0 -0
  310. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/html.py +0 -0
  311. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/terminal.py +0 -0
  312. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/terminal_buffer.py +0 -0
  313. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/__init__.py +0 -0
  314. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/core.py +0 -0
  315. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/definitions.py +0 -0
  316. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/registry.py +0 -0
  317. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/tests/__init__.py +0 -0
  318. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/tests/test_definitions.py +0 -0
  319. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/__init__.py +0 -0
  320. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/images.py +0 -0
  321. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/tests/__init__.py +0 -0
  322. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/tests/test_images.py +0 -0
  323. {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/tests/test_images_ascii.py +0 -0
  324. {kolega_code-0.8.0 → kolega_code-0.8.2}/run_tests.sh +0 -0
  325. {kolega_code-0.8.0 → kolega_code-0.8.2}/scripts/install-kolega-code.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kolega-code
3
- Version: 0.8.0
3
+ Version: 0.8.2
4
4
  Summary: Local-first AI coding agent for 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/
@@ -39,6 +39,7 @@ kolega-code [PROJECT_PATH]
39
39
  | `--new` | Start a new session (this is the default) |
40
40
  | `--resume [THREAD_ID]` | Resume the latest saved thread, or a specific thread/session ID |
41
41
  | `--browser-visible` | Launch visible Playwright browser windows instead of headless |
42
+ | `--show-logs` | Show the optional diagnostic Logs side-panel tab. Hidden by default to avoid unnecessary log rendering work |
42
43
  | `--permission-mode <auto\|ask>` | Shell/edit permission mode. TUI sessions default to `ask` |
43
44
  | `--session <ID>` | Legacy alias for `--resume THREAD_ID` |
44
45
 
@@ -43,6 +43,15 @@ When the agent runs a workflow, the transcript shows **phase headers** and short
43
43
  [sub-agent inspector](../tui/interface/#sub-agent-inspector) — press `Ctrl+G` to
44
44
  watch every agent's live trajectory, grouped by phase.
45
45
 
46
+ The `run_workflow` result is a compact artifact manifest. It includes paths like
47
+ `resultPath` and `transcriptPath`; the completed workflow result is written to
48
+ `resultPath` instead of returned inline. For normal workflow output, the agent
49
+ should read those main files and avoid reading individual sub-agent transcripts.
50
+ Raw and per-agent debug artifacts may exist under the run directory for explicit
51
+ workflow debugging.
52
+ The agent should read those paths first — not re-run the workflow just to recover
53
+ output text.
54
+
46
55
  ## How it works
47
56
 
48
57
  Under the hood, the agent authors a short **Python script** and runs it with a
@@ -69,9 +78,11 @@ return findings
69
78
 
70
79
  <Aside type="note">
71
80
  Workflows are deterministic and **resumable**. Each run is saved under Kolega
72
- Code's state directory (`workflows/<run-id>/`) with its script, a journal, and each
73
- sub-agent's transcript, so an interrupted run can pick up where it left off instead
74
- of redoing finished work.
81
+ Code's state directory (`workflows/<run-id>/`) with its script, full result files,
82
+ a readable Markdown transcript, raw JSONL, a resume journal, and debug sub-agent
83
+ transcripts, so an interrupted run can pick up where it left off instead of redoing
84
+ finished work. Use resume when intentionally iterating on the workflow; use the
85
+ artifact paths when you only need to inspect output.
75
86
  </Aside>
76
87
 
77
88
  ## Behavior and safety
@@ -14,8 +14,9 @@ The screen is split into two columns:
14
14
  - **Conversation panel** (left, larger) — your chat with the agent. Responses
15
15
  stream in live, tool calls and sub-agent activity appear inline, and detailed
16
16
  tool results are collapsed by default so you can expand only what you need.
17
- - **Side panel** (right) — a set of tabs for status, logs, the terminal, planning,
18
- and settings. Toggle it with `Ctrl+O` or `/sidebar`.
17
+ - **Side panel** (right) — a set of tabs for status, the terminal, planning,
18
+ and settings. Toggle it with `Ctrl+O` or `/sidebar`. The diagnostic Logs tab is
19
+ opt-in; launch with `--show-logs` when you want it.
19
20
 
20
21
  At the bottom sits the **composer** — the text box where you type prompts. See
21
22
  [Chat Composer](../composer/) for everything it can do.
@@ -25,7 +26,7 @@ At the bottom sits the **composer** — the text box where you type prompts. See
25
26
  | Tab | What it shows |
26
27
  | --- | --- |
27
28
  | **Status** | The active provider/model and thinking effort, the current interaction mode (Build/Plan), permission mode, the agent's turn state (idle, generating, thinking, running a tool, running sub-agents, waiting for input, …), token usage, and context warnings. |
28
- | **Logs** | A timestamped, color-coded activity log: sub-agent lifecycle, tool calls, configuration changes. An indicator flags new entries when you're on another tab. |
29
+ | **Logs** | Optional. Launch with `--show-logs` to show a timestamped, color-coded diagnostic activity log. New entries preserve manual scrollback and an indicator flags unseen entries when you're on another tab. |
29
30
  | **Terminal** | Live output from commands the agent runs. |
30
31
  | **Planning** | The current **Plan** (markdown from the planning agent) and the shared **Task List** that both modes can edit. |
31
32
  | **Settings** | Provider, model, thinking effort, and API-key configuration. See [Settings & API Keys](../../configuration/settings-and-api-keys/). |
@@ -18,6 +18,7 @@ from .agent.planningagent import PlanningAgent
18
18
  from .agent.compression import HistoryCompressor
19
19
  from .agent.context import AgentContext, AgentServices, Telemetry, WorkspaceInfo
20
20
  from .agent.conversation import Conversation
21
+ from .agent.errors import AgentError, MaxAgentIterationsExceeded
21
22
  from .events import AgentEventEmitter
22
23
 
23
24
  # Configuration
@@ -86,6 +87,8 @@ __all__ = [
86
87
  "AgentContext",
87
88
  "AgentServices",
88
89
  "Telemetry",
90
+ "AgentError",
91
+ "MaxAgentIterationsExceeded",
89
92
  "WorkspaceInfo",
90
93
  "Conversation",
91
94
  "HistoryCompressor",
@@ -148,4 +151,4 @@ __all__ = [
148
151
  "parse_git_status_output",
149
152
  ]
150
153
 
151
- __version__ = "0.8.0"
154
+ __version__ = "0.8.2"
@@ -8,6 +8,9 @@ from .browseragent import BrowserAgent
8
8
  from .generalagent import GeneralAgent
9
9
  from .planningagent import PlanningAgent
10
10
 
11
+ # Export agent errors
12
+ from .errors import AgentError, MaxAgentIterationsExceeded
13
+
11
14
  # Export agent models
12
15
  from kolega_code.events import AgentStatus, AgentEvent
13
16
 
@@ -25,6 +28,8 @@ __all__ = [
25
28
  "BrowserAgent",
26
29
  "GeneralAgent",
27
30
  "PlanningAgent",
31
+ "AgentError",
32
+ "MaxAgentIterationsExceeded",
28
33
  "AgentStatus",
29
34
  "AgentEvent",
30
35
  "AgentConfig",
@@ -39,4 +44,4 @@ __all__ = [
39
44
  "ToolExtension",
40
45
  ]
41
46
 
42
- __version__ = "0.8.0"
47
+ __version__ = "0.8.2"
@@ -12,6 +12,7 @@ from typing import Any, AsyncGenerator, Dict, List, Optional
12
12
 
13
13
  from .common import LogMixin
14
14
  from .compression import CompactionResult, HistoryCompressor
15
+ from .errors import MaxAgentIterationsExceeded
15
16
  from kolega_code.config import AgentConfig, ModelProvider
16
17
  from kolega_code.events import AgentConnectionManager
17
18
  from .context import AgentContext, AgentServices, Telemetry, WorkspaceInfo
@@ -119,6 +120,7 @@ class BaseAgent(LogMixin):
119
120
  sub_agent_recorder: Optional[Any] = None,
120
121
  hook_dispatcher: Optional[HookDispatcher] = None,
121
122
  context: Optional[AgentContext] = None,
123
+ max_iterations: Optional[int] = None,
122
124
  ) -> None:
123
125
  """
124
126
  Initialize a new BaseAgent instance.
@@ -203,7 +205,11 @@ class BaseAgent(LogMixin):
203
205
  if hook_dispatcher is not None:
204
206
  context.hook_dispatcher = hook_dispatcher
205
207
 
208
+ if max_iterations is not None and max_iterations < 1:
209
+ raise ValueError("max_iterations must be a positive integer or None")
210
+
206
211
  self.context = context
212
+ self.max_iterations = max_iterations
207
213
 
208
214
  # Flat attributes kept for compatibility with subclasses, tools, and hosts.
209
215
  self.project_path = context.workspace.project_path
@@ -1282,7 +1288,15 @@ class BaseAgent(LogMixin):
1282
1288
 
1283
1289
  stop_reason = None
1284
1290
  stop_overrides = 0
1291
+ iterations = 0
1285
1292
  while stop_reason not in ["end_turn", "max_tokens", "stop_sequence"]:
1293
+ iterations += 1
1294
+ if self.max_iterations is not None and iterations > self.max_iterations:
1295
+ raise MaxAgentIterationsExceeded(
1296
+ f"Agent '{self.agent_name}' exceeded max_iterations={self.max_iterations} "
1297
+ "without reaching a terminal stop reason"
1298
+ )
1299
+
1286
1300
  self.mark_cache_checkpoint()
1287
1301
 
1288
1302
  try:
@@ -45,6 +45,7 @@ class BrowserAgent(BaseAgent):
45
45
  usage_recorder: Optional[Any] = None,
46
46
  sub_agent_recorder: Optional[Any] = None,
47
47
  hook_dispatcher: Optional[Any] = None,
48
+ max_iterations: Optional[int] = None,
48
49
  ) -> None:
49
50
  """
50
51
  Initialize a new BrowserAgent instance.
@@ -97,6 +98,7 @@ class BrowserAgent(BaseAgent):
97
98
  usage_recorder=usage_recorder,
98
99
  sub_agent_recorder=sub_agent_recorder,
99
100
  hook_dispatcher=hook_dispatcher,
101
+ max_iterations=max_iterations,
100
102
  )
101
103
 
102
104
  self.tool_collection = ToolCollection(
@@ -49,6 +49,7 @@ class CoderAgent(BaseAgent, LogMixin):
49
49
  usage_recorder: Optional[Any] = None,
50
50
  sub_agent_recorder: Optional[Any] = None,
51
51
  hook_dispatcher: Optional[Any] = None,
52
+ max_iterations: Optional[int] = None,
52
53
  ) -> None:
53
54
  """
54
55
  Initialize a new CoderAgent instance.
@@ -104,6 +105,7 @@ class CoderAgent(BaseAgent, LogMixin):
104
105
  usage_recorder=usage_recorder,
105
106
  sub_agent_recorder=sub_agent_recorder,
106
107
  hook_dispatcher=hook_dispatcher,
108
+ max_iterations=max_iterations,
107
109
  )
108
110
 
109
111
  # Configure tool collection with custom coder agent tools
@@ -16,6 +16,7 @@ from kolega_code.llm.models import (
16
16
  Message,
17
17
  MessageHistory,
18
18
  RedactedThinkingBlock,
19
+ ResponsesReasoningBlock,
19
20
  TextBlock,
20
21
  ThinkingBlock,
21
22
  ToolCall,
@@ -113,8 +114,21 @@ def replace_image_blocks_with_placeholders(messages: List[Message], model_name:
113
114
  return result
114
115
 
115
116
 
117
+ # Groups of providers whose reasoning is mutually replayable. The api-key
118
+ # `openai` and the ChatGPT-subscription `openai_chatgpt` are both the OpenAI
119
+ # Responses API, so encrypted reasoning produced by one replays cleanly to the
120
+ # other — the one exception to "only replay reasoning to the same provider".
121
+ _REASONING_COMPATIBLE_GROUPS: tuple[frozenset[str], ...] = (frozenset({"openai", "openai_chatgpt"}),)
122
+
123
+
116
124
  def _preserve_reasoning_block(block: Any, *, source_provider: str, target_provider: str) -> bool:
117
- return bool(source_provider) and source_provider == target_provider
125
+ if not source_provider:
126
+ return False
127
+ if source_provider == target_provider:
128
+ return True
129
+ return any(
130
+ source_provider in group and target_provider in group for group in _REASONING_COMPATIBLE_GROUPS
131
+ )
118
132
 
119
133
 
120
134
  def _reasoning_placeholder(block: Any, source_provider: str) -> TextBlock:
@@ -134,7 +148,7 @@ def _adapt_content_blocks_for_provider(
134
148
  if isinstance(block, ImageBlock) and not supports_vision:
135
149
  adapted.append(TextBlock(text=_image_placeholder(block.media_type, target_model)))
136
150
  changed = True
137
- elif isinstance(block, (ThinkingBlock, RedactedThinkingBlock)):
151
+ elif isinstance(block, (ThinkingBlock, RedactedThinkingBlock, ResponsesReasoningBlock)):
138
152
  if _preserve_reasoning_block(block, source_provider=source_provider, target_provider=target_provider):
139
153
  adapted.append(block)
140
154
  else:
@@ -0,0 +1,9 @@
1
+ """Exceptions raised by agent runtime loops."""
2
+
3
+
4
+ class AgentError(RuntimeError):
5
+ """Base class for catchable agent runtime errors."""
6
+
7
+
8
+ class MaxAgentIterationsExceeded(AgentError):
9
+ """Raised when an opt-in agent loop iteration cap is exceeded."""
@@ -47,6 +47,7 @@ class GeneralAgent(BaseAgent):
47
47
  usage_recorder: Optional[Any] = None,
48
48
  sub_agent_recorder: Optional[Any] = None,
49
49
  hook_dispatcher: Optional[Any] = None,
50
+ max_iterations: Optional[int] = None,
50
51
  ) -> None:
51
52
  """
52
53
  Initialize a new GeneralAgent instance.
@@ -99,6 +100,7 @@ class GeneralAgent(BaseAgent):
99
100
  usage_recorder=usage_recorder,
100
101
  sub_agent_recorder=sub_agent_recorder,
101
102
  hook_dispatcher=hook_dispatcher,
103
+ max_iterations=max_iterations,
102
104
  )
103
105
 
104
106
  # Full coder-style toolset, minus sub-agent dispatch (a dispatched agent
@@ -45,6 +45,7 @@ class InvestigationAgent(BaseAgent):
45
45
  usage_recorder: Optional[Any] = None,
46
46
  sub_agent_recorder: Optional[Any] = None,
47
47
  hook_dispatcher: Optional[Any] = None,
48
+ max_iterations: Optional[int] = None,
48
49
  ) -> None:
49
50
  """
50
51
  Initialize a new InvestigationAgent instance.
@@ -97,6 +98,7 @@ class InvestigationAgent(BaseAgent):
97
98
  usage_recorder=usage_recorder,
98
99
  sub_agent_recorder=sub_agent_recorder,
99
100
  hook_dispatcher=hook_dispatcher,
101
+ max_iterations=max_iterations,
100
102
  )
101
103
 
102
104
  self.tool_collection = ToolCollection(
@@ -134,10 +134,26 @@ After the workflow returns, integrate the results, run the full test suite yours
134
134
  report. If the plan is small or its parts are tightly coupled, skip the workflow and just
135
135
  implement it directly — orchestration is for genuinely independent fan-out.
136
136
 
137
+ ### Artifacts and transcripts
138
+
139
+ `run_workflow` returns a concise manifest, not necessarily the full workflow output.
140
+ Every completed run persists full artifacts under the state directory and returns
141
+ paths including `resultPath` and `transcriptPath`. If the inline tool result says output was omitted, looks incomplete,
142
+ or would require a long transcript to understand, READ `resultPath` or `transcriptPath`
143
+ with the file-reading tools before deciding work is missing. For normal workflow
144
+ output, use only those main files; avoid reading individual sub-agent transcripts
145
+ unless you are explicitly debugging workflow execution.
146
+
147
+ Never re-run a completed workflow solely to recover output from an omitted/truncated
148
+ inline result. The workflow already ran; inspect the persisted result/transcript first.
149
+ Use `resume_from_run_id` only when you intentionally want to iterate on or change the
150
+ workflow, not as a transcript-recovery mechanism.
151
+
137
152
  ### Resume
138
153
 
139
- Each run persists its script and a journal under the state directory and returns a
140
- `runId` and `scriptPath`. To iterate, edit the script and re-run with `script_path`,
141
- or pass `resume_from_run_id` to replay cached `agent()` results for the unchanged
142
- prefix and only re-run new/changed calls.
154
+ Each run persists its script, full results, a readable transcript, raw JSONL, and a
155
+ resume journal under the state directory and returns a `runId` plus artifact paths.
156
+ To iterate, edit the script and re-run with `script_path`, or pass `resume_from_run_id`
157
+ to replay cached `agent()` results for the unchanged prefix and only re-run new/changed
158
+ calls.
143
159
  """
@@ -4,9 +4,13 @@ Everything a run needs lives under::
4
4
 
5
5
  <state-dir>/workflows/<run_id>/
6
6
  script.py the authored source (its path is returned for edit + re-run)
7
- run.json meta, args, status, timing, token totals
7
+ run.json meta, args, status, timing, token totals, artifact paths
8
8
  journal.jsonl one line per completed agent() call (drives resume)
9
- agents/ per sub-agent transcripts (wired via sub_agent_recorder)
9
+ result.json full JSON-rendered workflow return value
10
+ result.md readable workflow return value
11
+ transcript.jsonl raw workflow events/call outcomes
12
+ transcript.md readable workflow transcript/index
13
+ agents/ per sub-agent raw/readable transcripts
10
14
 
11
15
  Resume contract: scripts are deterministic (the runtime blocks ``random``/``time``
12
16
  and ``import``), so the same source + args produce ``agent()`` calls in the same
@@ -18,6 +22,7 @@ new call onward.
18
22
  from __future__ import annotations
19
23
 
20
24
  import json
25
+ import re
21
26
  from pathlib import Path
22
27
  from typing import Any, Dict, Optional, Tuple
23
28
 
@@ -32,6 +37,15 @@ def saved_workflows_dir(state_dir: Path) -> Path:
32
37
  return workflows_root(state_dir) / "_saved"
33
38
 
34
39
 
40
+ def _slugify(value: str, *, fallback: str = "agent", max_length: int = 64) -> str:
41
+ """Return a filesystem-friendly slug for workflow artifact filenames."""
42
+ slug = re.sub(r"[^A-Za-z0-9._-]+", "-", str(value or "").strip().lower())
43
+ slug = re.sub(r"-+", "-", slug).strip("-._")
44
+ if not slug:
45
+ slug = fallback
46
+ return slug[:max_length].rstrip("-._") or fallback
47
+
48
+
35
49
  class RunJournal:
36
50
  """Owns the on-disk artifacts for a single workflow run."""
37
51
 
@@ -40,6 +54,10 @@ class RunJournal:
40
54
  self.run_id = run_id
41
55
  self.agents_dir = self.run_dir / "agents"
42
56
  self._journal_path = self.run_dir / "journal.jsonl"
57
+ self._transcript_jsonl_path = self.run_dir / "transcript.jsonl"
58
+ self._transcript_md_path = self.run_dir / "transcript.md"
59
+ self._result_json_path = self.run_dir / "result.json"
60
+ self._result_md_path = self.run_dir / "result.md"
43
61
  self._script_path = self.run_dir / "script.py"
44
62
  self._meta_path = self.run_dir / "run.json"
45
63
 
@@ -55,6 +73,33 @@ class RunJournal:
55
73
  def script_path(self) -> Path:
56
74
  return self._script_path
57
75
 
76
+ @property
77
+ def journal_path(self) -> Path:
78
+ return self._journal_path
79
+
80
+ @property
81
+ def transcript_jsonl_path(self) -> Path:
82
+ return self._transcript_jsonl_path
83
+
84
+ @property
85
+ def transcript_md_path(self) -> Path:
86
+ return self._transcript_md_path
87
+
88
+ @property
89
+ def result_json_path(self) -> Path:
90
+ return self._result_json_path
91
+
92
+ @property
93
+ def result_md_path(self) -> Path:
94
+ return self._result_md_path
95
+
96
+ def agent_artifact_paths(self, call_index: int, label: Optional[str] = None) -> Dict[str, Path]:
97
+ """Return stable per-agent raw/readable artifact paths for a workflow call."""
98
+ self.ensure_dirs()
99
+ suffix = _slugify(label or f"call-{call_index}")
100
+ stem = f"agent-{call_index:03d}-{suffix}"
101
+ return {"markdown": self.agents_dir / f"{stem}.md", "jsonl": self.agents_dir / f"{stem}.jsonl"}
102
+
58
103
  def write_script(self, source: str) -> Path:
59
104
  self.ensure_dirs()
60
105
  self._script_path.write_text(source, encoding="utf-8")
@@ -86,16 +131,41 @@ class RunJournal:
86
131
  label: Optional[str],
87
132
  value: Any,
88
133
  status: str = "completed",
134
+ **metadata: Any,
89
135
  ) -> None:
90
- """Append one completed ``agent()`` result for resume replay."""
136
+ """Append one completed ``agent()`` result for resume replay.
137
+
138
+ ``journal.jsonl`` is the resume contract. Extra fields are allowed and ignored
139
+ by ``load_cache()`` so newer artifact metadata remains backward-compatible.
140
+ """
91
141
  self.ensure_dirs()
92
- line = json.dumps(
93
- {"index": call_index, "key": key, "label": label, "status": status, "value": value},
94
- default=str,
95
- )
142
+ payload = {"index": call_index, "key": key, "label": label, "status": status, "value": value}
143
+ payload.update({k: v for k, v in metadata.items() if v is not None})
144
+ line = json.dumps(payload, default=str)
96
145
  with self._journal_path.open("a", encoding="utf-8") as handle:
97
146
  handle.write(line + "\n")
98
147
 
148
+ def append_transcript_event(self, event: Dict[str, Any]) -> None:
149
+ """Append one raw workflow transcript event as JSONL."""
150
+ self.ensure_dirs()
151
+ with self._transcript_jsonl_path.open("a", encoding="utf-8") as handle:
152
+ handle.write(json.dumps(event, default=str) + "\n")
153
+
154
+ def write_result_artifacts(self, result: Any, markdown: str) -> None:
155
+ """Persist the full workflow return value in JSON and readable Markdown."""
156
+ self.ensure_dirs()
157
+ try:
158
+ rendered_json = json.dumps(result, indent=2, default=str)
159
+ except (TypeError, ValueError):
160
+ rendered_json = json.dumps(str(result), indent=2)
161
+ self._result_json_path.write_text(rendered_json + "\n", encoding="utf-8")
162
+ self._result_md_path.write_text(markdown, encoding="utf-8")
163
+
164
+ def write_transcript_markdown(self, markdown: str) -> None:
165
+ """Persist the readable workflow transcript."""
166
+ self.ensure_dirs()
167
+ self._transcript_md_path.write_text(markdown, encoding="utf-8")
168
+
99
169
  def load_cache(self) -> Dict[int, Tuple[str, Any]]:
100
170
  """Read a prior run's journal into ``{call_index: (key, value)}``.
101
171
 
@@ -150,8 +150,19 @@ class WorkflowRuntime:
150
150
 
151
151
  cached = self._resume_cache.get(index)
152
152
  if cached is not None and cached[0] == key:
153
- self._emit_soon("workflow_agent_cached", {"label": spec.label or prompt[:60], "phase": spec.phase})
154
- return cached[1]
153
+ cached_value = cached[1]
154
+ label = spec.label or prompt[:60]
155
+ self._journal.append_transcript_event(
156
+ {
157
+ "type": "agent_cached",
158
+ "index": index,
159
+ "label": label,
160
+ "phase": spec.phase,
161
+ "value": cached_value,
162
+ }
163
+ )
164
+ self._emit_soon("workflow_agent_cached", {"label": label, "phase": spec.phase})
165
+ return cached_value
155
166
 
156
167
  self._agent_count += 1
157
168
  if self._agent_count > self._agent_cap:
@@ -169,7 +180,34 @@ class WorkflowRuntime:
169
180
 
170
181
  self.budget.add(result.tokens)
171
182
  value = result.value
172
- self._journal.record(index, key, spec.label, value, status=result.status)
183
+ self._journal.record(
184
+ index,
185
+ key,
186
+ spec.label,
187
+ value,
188
+ status=result.status,
189
+ phase=spec.phase,
190
+ agent_type=spec.agent_type,
191
+ tokens=result.tokens,
192
+ error=result.error,
193
+ transcript_path=result.transcript_path,
194
+ transcript_markdown_path=result.transcript_markdown_path,
195
+ )
196
+ self._journal.append_transcript_event(
197
+ {
198
+ "type": "agent_call",
199
+ "index": index,
200
+ "label": spec.label,
201
+ "phase": spec.phase,
202
+ "agent_type": spec.agent_type,
203
+ "status": result.status,
204
+ "tokens": result.tokens,
205
+ "error": result.error,
206
+ "value": value,
207
+ "transcript_path": result.transcript_path,
208
+ "transcript_markdown_path": result.transcript_markdown_path,
209
+ }
210
+ )
173
211
  return value
174
212
 
175
213
  async def parallel(self, thunks: Iterable[Callable[[], Awaitable[Any]]]) -> List[Any]:
@@ -56,6 +56,8 @@ class AgentRunResult:
56
56
  agent_id: Optional[str] = None
57
57
  status: str = "completed" # completed | failed | skipped
58
58
  error: Optional[str] = None
59
+ transcript_path: Optional[str] = None
60
+ transcript_markdown_path: Optional[str] = None
59
61
 
60
62
  @property
61
63
  def value(self) -> Any:
@@ -44,6 +44,7 @@ class PlanningAgent(BaseAgent):
44
44
  usage_recorder: Optional[Any] = None,
45
45
  sub_agent_recorder: Optional[Any] = None,
46
46
  hook_dispatcher: Optional[Any] = None,
47
+ max_iterations: Optional[int] = None,
47
48
  ) -> None:
48
49
  super().__init__(
49
50
  project_path,
@@ -70,6 +71,7 @@ class PlanningAgent(BaseAgent):
70
71
  usage_recorder=usage_recorder,
71
72
  sub_agent_recorder=sub_agent_recorder,
72
73
  hook_dispatcher=hook_dispatcher,
74
+ max_iterations=max_iterations,
73
75
  )
74
76
 
75
77
  self._completed_plan: Optional[str] = None
@@ -46,6 +46,10 @@ Do not run destructive commands automatically. Treat commands that delete files,
46
46
 
47
47
  When running tests or builds, choose the smallest command that gives confidence first, then broaden verification when the change has a wider blast radius.
48
48
 
49
+ ## Git Branches and Pull Requests
50
+
51
+ When creating a branch or opening a pull request, follow repository or user conventions if provided; otherwise use Conventional Commits-style names. Use lowercase kebab-case branch names with a conventional type prefix, such as `feat/add-login-rate-limit` or `fix/navbar-overlap`. Use Conventional Commit PR titles, such as `feat(auth): add session timeout` or `fix: handle empty search results`. Keep names descriptive but not overly long.
52
+
49
53
  ## Development Servers
50
54
 
51
55
  When starting a local development server, use an available port and tell the user the URL. If a server is already running on the default port, use another suitable port. Stop servers you started when they are no longer needed unless the user is actively testing them.