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.
- {kolega_code-0.8.0 → kolega_code-0.8.2}/PKG-INFO +1 -1
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/cli/overview.md +1 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/gigacode.mdx +14 -3
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/interface.md +4 -3
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/__init__.py +4 -1
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/__init__.py +6 -1
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/baseagent.py +14 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/browseragent.py +2 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/coder.py +2 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/conversation.py +16 -2
- kolega_code-0.8.2/kolega_code/agent/errors.py +9 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/generalagent.py +2 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/investigationagent.py +2 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/guide.py +20 -4
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/journal.py +77 -7
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/runtime.py +41 -3
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/types.py +2 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/planningagent.py +2 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +4 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_chatgpt_oauth_provider.py +136 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_error_boundary.py +3 -2
- kolega_code-0.8.2/kolega_code/agent/tests/llm/test_openai_responses_provider.py +163 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_thinking_effort.py +5 -1
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_base_agent.py +68 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_tui_events.py +4 -2
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_image_compat.py +56 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_prompts.py +8 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_agent_tool.py +29 -3
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_workflow_tool.py +143 -5
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/agent_tool.py +166 -12
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/workflow_tool.py +193 -22
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tools.py +8 -4
- kolega_code-0.8.2/kolega_code/cli/app.py +1384 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/main.py +2 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app.py +1380 -363
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app_compaction_restore.py +4 -4
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app_image_vision_warning.py +7 -6
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_app_model_switch_vision.py +5 -6
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_main.py +8 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_themes.py +4 -3
- kolega_code-0.8.2/kolega_code/cli/tui/__init__.py +1 -0
- kolega_code-0.8.2/kolega_code/cli/tui/agent_runtime.py +306 -0
- kolega_code-0.8.2/kolega_code/cli/tui/command_handlers.py +810 -0
- kolega_code-0.8.2/kolega_code/cli/tui/constants.py +24 -0
- kolega_code-0.8.2/kolega_code/cli/tui/prompt_flows.py +430 -0
- kolega_code-0.8.2/kolega_code/cli/tui/settings_panel.py +408 -0
- kolega_code-0.8.2/kolega_code/cli/tui/state.py +199 -0
- kolega_code-0.8.2/kolega_code/cli/tui/status_dashboard.py +267 -0
- kolega_code-0.8.2/kolega_code/cli/tui/styles.py +339 -0
- kolega_code-0.8.2/kolega_code/cli/tui/sub_agent_screen.py +367 -0
- kolega_code-0.8.2/kolega_code/cli/tui/transcript.py +1397 -0
- kolega_code-0.8.2/kolega_code/cli/tui/widgets.py +658 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/client.py +6 -2
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/instrumented_client.py +3 -3
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/models.py +78 -0
- kolega_code-0.8.2/kolega_code/llm/providers/chatgpt_oauth.py +103 -0
- kolega_code-0.8.2/kolega_code/llm/providers/openai_responses.py +60 -0
- 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
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/specs.py +18 -8
- {kolega_code-0.8.0 → kolega_code-0.8.2}/pyproject.toml +1 -1
- {kolega_code-0.8.0 → kolega_code-0.8.2}/uv.lock +2 -2
- kolega_code-0.8.0/kolega_code/cli/app.py +0 -6071
- {kolega_code-0.8.0 → kolega_code-0.8.2}/.env.example +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/.github/workflows/ci.yml +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/.github/workflows/docs.yml +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/.github/workflows/release.yml +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/.gitignore +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/CONTRIBUTING.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/LICENSE +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/README.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/RELEASING.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/SECURITY.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/conftest.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/.gitignore +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/README.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/astro.config.mjs +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/package-lock.json +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/package.json +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/public/favicon.svg +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/assets/demo.gif +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/assets/kolega-dark.svg +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/assets/kolega-light.svg +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/cli/ask.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/cli/doctor.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/cli/sessions.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/concepts/agents.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/concepts/how-it-works.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/concepts/tools.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/configuration/environment-variables.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/configuration/providers-and-models.mdx +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/configuration/settings-and-api-keys.mdx +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/configuration/sign-in-with-chatgpt.mdx +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/getting-started/installation.mdx +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/getting-started/quick-start.mdx +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/hooks.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/index.mdx +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/skills.mdx +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/composer.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/modes.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/sessions-and-resume.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content/docs/tui/slash-commands.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/content.config.ts +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/src/styles/brand.css +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/docs/tsconfig.json +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/common.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/compression.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/context.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/budget.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/errors.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/executor.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/tests/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/orchestration/tests/test_orchestration.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_provider.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
- {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
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
- {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
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/prompts.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/compaction_helpers.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_anthropic_token_counting.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_billing_openai_cache.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_chatgpt_live.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_client.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_dashscope_mapping.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_exceptions.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_google_thought_signature.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_google_tool_signature_live.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_instrumented_client.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_instrumented_client_integration.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_langfuse_normalization.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_live_providers.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_model_specs.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_cached_tokens.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_cached_tokens_stream.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_message_conversion.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_openai_token_counting.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_supports_vision.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/llm/test_tool_execution_ids.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_browser.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_browser_parity.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_file_system.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_sandbox_terminal_input.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_terminal.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_terminal_buffer.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/services/test_terminal_state_serializer.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_agent_tools_inventory.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_coder_attachments.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_coder_prompt_extensions.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_commands.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_integration.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_persistence.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compaction_subagent.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compress_command.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_compression.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_conversation_compaction.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_duplicate_tool_results.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_empty_message_handling.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_event_emitter.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_general_agent.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_gigacode_gating.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_hooks_integration.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_html.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_parallel_tool_calls.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_permissions.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_planning_agent.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_prompt_provider.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_read_image_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_tool_registry.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/test_tools.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_base_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_browser_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_build_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_create_file_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_edit_preview.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_glob_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_glob_tool_sandbox_parity.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_list_directory_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_read_file_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_replace_entire_file_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_replace_lines_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_search_and_replace_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_search_codebase_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_terminal_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_think_hard_integration.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_think_hard_streaming.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_web_fetch_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tests/tool_backend/test_web_search_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/base_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/build_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/create_file_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/glob_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/list_directory_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/replace_entire_file_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/replace_lines_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_and_replace_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/search_codebase_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/think_hard_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/agent/utils/commands.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/_jwt.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/chatgpt_oauth.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/constants.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/tests/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/tests/test_chatgpt_oauth.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/tests/test_tokens.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/auth/tokens.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/clipboard_image.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/config.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/connection.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/file_index.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/mentions.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/messages.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/provider_registry.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/session_store.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/settings.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/skills.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/slash_commands.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_cli_config.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_clipboard_image.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_connection.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_file_index.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_mentions.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_provider_registry.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_session_store.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_settings.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_skills.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_slash_commands.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/tests/test_updater.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/theme.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/cli/updater.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/config.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/events.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/backends.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/config.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/dispatcher.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/events.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/matcher.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/outcome.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/tests/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/hooks/tests/test_hooks.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/exceptions.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/anthropic.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/base.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/google.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/models.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/providers/openai.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/ratelimit.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/llm/tool_execution_ids.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/models/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/models/sandbox_terminal_state.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/permissions.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/runtime.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/README.md +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/async_filesystem.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/base.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/browser.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/event_loop.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/filesystem.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/local.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/serializer.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/terminal.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/sandbox/utils.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/base.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/browser.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/file_system.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/html.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/terminal.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/services/terminal_buffer.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/core.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/definitions.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/registry.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/tests/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/tools/tests/test_definitions.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/images.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/tests/__init__.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/tests/test_images.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/kolega_code/utils/tests/test_images_ascii.py +0 -0
- {kolega_code-0.8.0 → kolega_code-0.8.2}/run_tests.sh +0 -0
- {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.
|
|
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,
|
|
73
|
-
|
|
74
|
-
of redoing
|
|
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,
|
|
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** |
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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:
|
|
@@ -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
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
prefix and only re-run new/changed
|
|
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
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
154
|
-
|
|
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(
|
|
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.
|