kolega-code 0.8.1__tar.gz → 0.8.3__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.1 → kolega_code-0.8.3}/.github/workflows/ci.yml +1 -1
- {kolega_code-0.8.1 → kolega_code-0.8.3}/CONTRIBUTING.md +1 -1
- {kolega_code-0.8.1 → kolega_code-0.8.3}/PKG-INFO +1 -1
- {kolega_code-0.8.1 → kolega_code-0.8.3}/RELEASING.md +1 -1
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/cli/overview.md +1 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/gigacode.mdx +14 -3
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/tui/interface.md +4 -3
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/__init__.py +1 -1
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/__init__.py +1 -1
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/orchestration/guide.py +20 -4
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/orchestration/journal.py +77 -7
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/orchestration/runtime.py +41 -3
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/orchestration/types.py +2 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +4 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/agent_tool.py +164 -12
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/workflow_tool.py +193 -22
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tools.py +8 -4
- kolega_code-0.8.3/kolega_code/cli/app.py +1384 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/main.py +38 -7
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/settings.py +18 -0
- kolega_code-0.8.3/kolega_code/cli/tui/__init__.py +1 -0
- kolega_code-0.8.3/kolega_code/cli/tui/agent_runtime.py +306 -0
- kolega_code-0.8.3/kolega_code/cli/tui/command_handlers.py +810 -0
- kolega_code-0.8.3/kolega_code/cli/tui/constants.py +24 -0
- kolega_code-0.8.3/kolega_code/cli/tui/prompt_flows.py +430 -0
- kolega_code-0.8.3/kolega_code/cli/tui/settings_panel.py +408 -0
- kolega_code-0.8.3/kolega_code/cli/tui/state.py +199 -0
- kolega_code-0.8.3/kolega_code/cli/tui/status_dashboard.py +267 -0
- kolega_code-0.8.3/kolega_code/cli/tui/styles.tcss +335 -0
- kolega_code-0.8.3/kolega_code/cli/tui/sub_agent_screen.py +367 -0
- kolega_code-0.8.3/kolega_code/cli/tui/transcript.py +1397 -0
- kolega_code-0.8.3/kolega_code/cli/tui/widgets.py +658 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/pyproject.toml +2 -1
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_anthropic_token_counting.py +4 -6
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_chatgpt_live.py +1 -1
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_client.py +8 -17
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_instrumented_client_integration.py +5 -6
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_live_providers.py +1 -1
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_openai_token_counting.py +5 -6
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_commands.py +1 -1
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_compaction_tui_events.py +4 -2
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_prompt_provider.py +1 -1
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_prompts.py +8 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_workflow_tool.py +143 -5
- {kolega_code-0.8.1/kolega_code/auth/tests → kolega_code-0.8.3/tests/auth}/test_chatgpt_oauth.py +1 -1
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_app.py +1388 -363
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_app_compaction_restore.py +4 -4
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_app_image_vision_warning.py +7 -6
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_app_model_switch_vision.py +5 -6
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_clipboard_image.py +1 -1
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_main.py +67 -2
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_settings.py +29 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_slash_commands.py +2 -2
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_themes.py +4 -3
- kolega_code-0.8.3/tests/cli/test_tui_stylesheet.py +87 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3/tests}/conftest.py +1 -1
- kolega_code-0.8.3/tests/utils/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/uv.lock +5 -5
- kolega_code-0.8.1/kolega_code/cli/app.py +0 -6071
- {kolega_code-0.8.1 → kolega_code-0.8.3}/.env.example +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/.github/workflows/docs.yml +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/.github/workflows/release.yml +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/.gitignore +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/LICENSE +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/README.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/SECURITY.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/.gitignore +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/README.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/astro.config.mjs +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/package-lock.json +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/package.json +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/public/favicon.svg +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/assets/demo.gif +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/assets/kolega-dark.svg +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/assets/kolega-light.svg +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/cli/ask.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/cli/doctor.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/cli/sessions.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/concepts/agents.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/concepts/how-it-works.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/concepts/tools.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/configuration/environment-variables.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/configuration/providers-and-models.mdx +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/configuration/settings-and-api-keys.mdx +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/configuration/sign-in-with-chatgpt.mdx +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/getting-started/installation.mdx +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/getting-started/quick-start.mdx +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/hooks.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/index.mdx +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/skills.mdx +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/tui/composer.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/tui/modes.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/tui/sessions-and-resume.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content/docs/tui/slash-commands.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/content.config.ts +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/src/styles/brand.css +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/docs/tsconfig.json +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/baseagent.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/browseragent.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/coder.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/common.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/compression.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/context.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/conversation.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/errors.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/generalagent.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/investigationagent.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/orchestration/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/orchestration/budget.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/orchestration/errors.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/orchestration/executor.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/planningagent.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_provider.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/prompts.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/base_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/build_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/create_file_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/glob_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/list_directory_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/replace_entire_file_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/replace_lines_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_and_replace_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/search_codebase_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/think_hard_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/agent/utils/commands.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/auth/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/auth/_jwt.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/auth/chatgpt_oauth.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/auth/constants.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/auth/tokens.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/clipboard_image.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/config.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/connection.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/file_index.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/mentions.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/messages.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/provider_registry.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/session_store.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/skills.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/slash_commands.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/theme.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/cli/updater.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/config.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/events.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/hooks/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/hooks/backends.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/hooks/config.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/hooks/dispatcher.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/hooks/events.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/hooks/matcher.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/hooks/outcome.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/client.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/exceptions.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/instrumented_client.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/models.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/orchestration/tests → kolega_code-0.8.3/kolega_code/llm/providers}/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/providers/anthropic.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/providers/base.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/providers/google.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/providers/models.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/providers/openai.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/providers/openai_responses.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/providers/responses_common.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/ratelimit.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/specs.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/llm/tool_execution_ids.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/models/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/models/sandbox_terminal_state.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/permissions.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/runtime.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/README.md +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/async_filesystem.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/base.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/browser.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/event_loop.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/filesystem.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/local.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/serializer.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/terminal.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/sandbox/utils.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/services/base.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/services/browser.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/services/file_system.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/services/html.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/services/terminal.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/services/terminal_buffer.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/tools/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/tools/core.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/tools/definitions.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/tools/registry.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/utils/__init__.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/kolega_code/utils/images.py +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/run_tests.sh +0 -0
- {kolega_code-0.8.1 → kolega_code-0.8.3}/scripts/install-kolega-code.sh +0 -0
- {kolega_code-0.8.1/kolega_code/agent → kolega_code-0.8.3}/tests/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests/llm → kolega_code-0.8.3/tests/agent}/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/compaction_helpers.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests/tool_backend → kolega_code-0.8.3/tests/agent/llm}/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_billing_openai_cache.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_chatgpt_oauth_provider.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_dashscope_mapping.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_error_boundary.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_exceptions.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_google_thought_signature.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_google_tool_signature_live.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_instrumented_client.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_langfuse_normalization.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_model_specs.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_openai_cached_tokens.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_openai_cached_tokens_stream.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_openai_message_conversion.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_openai_responses_provider.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_supports_vision.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_thinking_effort.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/llm/test_tool_execution_ids.py +0 -0
- {kolega_code-0.8.1/kolega_code/auth/tests → kolega_code-0.8.3/tests/agent/orchestration}/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/orchestration/tests → kolega_code-0.8.3/tests/agent/orchestration}/test_orchestration.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/services/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/services/test_browser.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/services/test_browser_parity.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/services/test_file_system.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/services/test_sandbox_terminal_input.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/services/test_terminal.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/services/test_terminal_buffer.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/services/test_terminal_state_serializer.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_agent_tools_inventory.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_base_agent.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_coder_attachments.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_coder_prompt_extensions.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_compaction_integration.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_compaction_persistence.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_compaction_subagent.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_compress_command.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_compression.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_conversation_compaction.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_duplicate_tool_results.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_empty_message_handling.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_event_emitter.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_general_agent.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_gigacode_gating.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_hooks_integration.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_html.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_image_compat.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_parallel_tool_calls.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_permissions.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_planning_agent.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_read_image_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_tool_registry.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/test_tools.py +0 -0
- {kolega_code-0.8.1/kolega_code/hooks/tests → kolega_code-0.8.3/tests/agent/tool_backend}/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_agent_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_base_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_browser_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_build_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_create_file_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_edit_preview.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_glob_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_glob_tool_sandbox_parity.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_list_directory_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_read_file_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_replace_entire_file_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_replace_lines_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_search_and_replace_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_search_codebase_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_terminal_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_think_hard_integration.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_think_hard_streaming.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_web_fetch_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/agent/tests → kolega_code-0.8.3/tests/agent}/tool_backend/test_web_search_tool.py +0 -0
- {kolega_code-0.8.1/kolega_code/llm/providers → kolega_code-0.8.3/tests/auth}/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/auth/tests → kolega_code-0.8.3/tests/auth}/test_tokens.py +0 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_cli_config.py +0 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_connection.py +0 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_file_index.py +0 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_mentions.py +0 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_provider_registry.py +0 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_session_store.py +0 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_skills.py +0 -0
- {kolega_code-0.8.1/kolega_code/cli/tests → kolega_code-0.8.3/tests/cli}/test_updater.py +0 -0
- {kolega_code-0.8.1/kolega_code/tools/tests → kolega_code-0.8.3/tests/hooks}/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/hooks/tests → kolega_code-0.8.3/tests/hooks}/test_hooks.py +0 -0
- {kolega_code-0.8.1/kolega_code/utils/tests → kolega_code-0.8.3/tests/tools}/__init__.py +0 -0
- {kolega_code-0.8.1/kolega_code/tools/tests → kolega_code-0.8.3/tests/tools}/test_definitions.py +0 -0
- {kolega_code-0.8.1/kolega_code/utils/tests → kolega_code-0.8.3/tests/utils}/test_images.py +0 -0
- {kolega_code-0.8.1/kolega_code/utils/tests → kolega_code-0.8.3/tests/utils}/test_images_ascii.py +0 -0
|
@@ -46,7 +46,7 @@ Run slow and integration tests only when you have the required credentials:
|
|
|
46
46
|
You can pass additional pytest arguments through the wrapper:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
./run_tests.sh
|
|
49
|
+
./run_tests.sh tests/agent/llm/test_client.py -ra
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
## Documentation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kolega-code
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.3
|
|
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/). |
|
|
@@ -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:
|
|
@@ -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.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
import inspect
|
|
3
|
+
import json
|
|
3
4
|
from pathlib import Path
|
|
4
|
-
from typing import Union, Optional
|
|
5
|
+
from typing import Any, Union, Optional
|
|
5
6
|
from datetime import datetime, timezone
|
|
6
7
|
import time
|
|
7
8
|
|
|
@@ -561,6 +562,105 @@ class AgentTool(BaseTool):
|
|
|
561
562
|
max_iterations=getattr(self.caller, "max_iterations", None),
|
|
562
563
|
)
|
|
563
564
|
|
|
565
|
+
@staticmethod
|
|
566
|
+
def _write_jsonl_message(path: Optional[Path], message: dict) -> None:
|
|
567
|
+
if path is None:
|
|
568
|
+
return
|
|
569
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
570
|
+
with path.open("a", encoding="utf-8") as handle:
|
|
571
|
+
handle.write(json.dumps(message, default=str) + "\n")
|
|
572
|
+
|
|
573
|
+
@staticmethod
|
|
574
|
+
def _render_workflow_message(message: dict) -> str:
|
|
575
|
+
role = str(message.get("role") or "message")
|
|
576
|
+
content = message.get("content", "")
|
|
577
|
+
lines = [f"### {role}", ""]
|
|
578
|
+
if isinstance(content, str):
|
|
579
|
+
lines.append(content)
|
|
580
|
+
elif isinstance(content, list):
|
|
581
|
+
for item in content:
|
|
582
|
+
if isinstance(item, dict):
|
|
583
|
+
item_type = item.get("type", "content")
|
|
584
|
+
if item_type == "text":
|
|
585
|
+
lines.append(str(item.get("text", "")))
|
|
586
|
+
elif item_type == "tool_use":
|
|
587
|
+
lines.append(f"**Tool use:** `{item.get('name', '')}`")
|
|
588
|
+
lines.append("```json")
|
|
589
|
+
lines.append(json.dumps(item.get("input", {}), indent=2, default=str))
|
|
590
|
+
lines.append("```")
|
|
591
|
+
elif item_type == "tool_result":
|
|
592
|
+
status = "Error" if item.get("is_error") else "Result"
|
|
593
|
+
lines.append(f"**Tool {status}:** `{item.get('name', '')}`")
|
|
594
|
+
lines.append("```")
|
|
595
|
+
lines.append(str(item.get("content", "")))
|
|
596
|
+
lines.append("```")
|
|
597
|
+
else:
|
|
598
|
+
lines.append("```json")
|
|
599
|
+
lines.append(json.dumps(item, indent=2, default=str))
|
|
600
|
+
lines.append("```")
|
|
601
|
+
else:
|
|
602
|
+
rendered = item.to_markdown() if hasattr(item, "to_markdown") else str(item)
|
|
603
|
+
lines.append(rendered)
|
|
604
|
+
else:
|
|
605
|
+
lines.append(str(content))
|
|
606
|
+
return "\n".join(lines).rstrip() + "\n"
|
|
607
|
+
|
|
608
|
+
@staticmethod
|
|
609
|
+
def _render_value_markdown(value: Any) -> str:
|
|
610
|
+
if value is None:
|
|
611
|
+
return "None"
|
|
612
|
+
if isinstance(value, str):
|
|
613
|
+
return value
|
|
614
|
+
try:
|
|
615
|
+
return "```json\n" + json.dumps(value, indent=2, default=str) + "\n```"
|
|
616
|
+
except (TypeError, ValueError):
|
|
617
|
+
return str(value)
|
|
618
|
+
|
|
619
|
+
def _write_workflow_agent_markdown(
|
|
620
|
+
self,
|
|
621
|
+
artifact_paths: Optional[dict],
|
|
622
|
+
*,
|
|
623
|
+
metadata: dict,
|
|
624
|
+
prompt: str,
|
|
625
|
+
status: str,
|
|
626
|
+
result: Optional[str] = None,
|
|
627
|
+
structured: Any = None,
|
|
628
|
+
tokens: int = 0,
|
|
629
|
+
error: Optional[str] = None,
|
|
630
|
+
history: Optional[list[dict]] = None,
|
|
631
|
+
) -> None:
|
|
632
|
+
if not artifact_paths or not artifact_paths.get("markdown"):
|
|
633
|
+
return
|
|
634
|
+
path = Path(artifact_paths["markdown"])
|
|
635
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
636
|
+
lines = [
|
|
637
|
+
f"# Workflow agent {metadata.get('call_index', '')}: {metadata.get('label') or metadata.get('agent_name') or 'agent'}",
|
|
638
|
+
"",
|
|
639
|
+
"## Metadata",
|
|
640
|
+
"",
|
|
641
|
+
f"- Call index: {metadata.get('call_index', '')}",
|
|
642
|
+
f"- Label: {metadata.get('label') or ''}",
|
|
643
|
+
f"- Phase: {metadata.get('phase') or ''}",
|
|
644
|
+
f"- Agent type: {metadata.get('agent_type') or metadata.get('agent_name') or ''}",
|
|
645
|
+
f"- Status: {status}",
|
|
646
|
+
f"- Tokens: {tokens}",
|
|
647
|
+
]
|
|
648
|
+
if error:
|
|
649
|
+
lines.append(f"- Error: {error}")
|
|
650
|
+
jsonl_path = artifact_paths.get("jsonl")
|
|
651
|
+
if jsonl_path:
|
|
652
|
+
lines.append(f"- Raw transcript: `{jsonl_path}`")
|
|
653
|
+
lines.extend(["", "## Task prompt", "", prompt.strip() or "(empty)"])
|
|
654
|
+
if structured is not None:
|
|
655
|
+
lines.extend(["", "## Structured result", "", self._render_value_markdown(structured)])
|
|
656
|
+
if result is not None:
|
|
657
|
+
lines.extend(["", "## Final recap", "", result])
|
|
658
|
+
if history:
|
|
659
|
+
lines.extend(["", "## Message history", ""])
|
|
660
|
+
for message in history:
|
|
661
|
+
lines.append(self._render_workflow_message(message))
|
|
662
|
+
path.write_text("\n".join(lines).rstrip() + "\n", encoding="utf-8")
|
|
663
|
+
|
|
564
664
|
async def dispatch_workflow_agent(
|
|
565
665
|
self,
|
|
566
666
|
agent_class,
|
|
@@ -569,6 +669,8 @@ class AgentTool(BaseTool):
|
|
|
569
669
|
config=None,
|
|
570
670
|
schema: Optional[dict] = None,
|
|
571
671
|
sub_agent_info_extra: Optional[dict] = None,
|
|
672
|
+
artifact_paths: Optional[dict] = None,
|
|
673
|
+
artifact_metadata: Optional[dict] = None,
|
|
572
674
|
):
|
|
573
675
|
"""Dispatch one sub-agent for a gigacode workflow.
|
|
574
676
|
|
|
@@ -609,6 +711,16 @@ class AgentTool(BaseTool):
|
|
|
609
711
|
if sub_agent_info_extra:
|
|
610
712
|
sub_agent_info.update({k: v for k, v in sub_agent_info_extra.items() if v is not None})
|
|
611
713
|
|
|
714
|
+
artifact_metadata = dict(artifact_metadata or {})
|
|
715
|
+
artifact_metadata.setdefault("agent_name", agent_name)
|
|
716
|
+
if artifact_paths:
|
|
717
|
+
for key in ("markdown", "jsonl"):
|
|
718
|
+
if artifact_paths.get(key):
|
|
719
|
+
artifact_paths[key] = Path(artifact_paths[key])
|
|
720
|
+
if artifact_paths.get("jsonl"):
|
|
721
|
+
artifact_paths["jsonl"].parent.mkdir(parents=True, exist_ok=True)
|
|
722
|
+
artifact_paths["jsonl"].write_text("", encoding="utf-8")
|
|
723
|
+
|
|
612
724
|
capture: dict = {}
|
|
613
725
|
extra_extensions = []
|
|
614
726
|
effective_task = task
|
|
@@ -618,6 +730,7 @@ class AgentTool(BaseTool):
|
|
|
618
730
|
|
|
619
731
|
await self._send_status_event("GENERATING", f"Starting {agent_name} task", sub_agent_info=sub_agent_info)
|
|
620
732
|
conversation_finished = False
|
|
733
|
+
agent = None
|
|
621
734
|
|
|
622
735
|
try:
|
|
623
736
|
agent = self._construct_workflow_sub_agent(agent_class, config, extra_extensions)
|
|
@@ -627,7 +740,13 @@ class AgentTool(BaseTool):
|
|
|
627
740
|
agent.sub_agent_context = sub_agent_info
|
|
628
741
|
|
|
629
742
|
last_saved_index = await self._stream_workflow_agent(
|
|
630
|
-
agent,
|
|
743
|
+
agent,
|
|
744
|
+
agent_name,
|
|
745
|
+
sub_agent_info,
|
|
746
|
+
conversation_id,
|
|
747
|
+
last_saved_index=-1,
|
|
748
|
+
task=effective_task,
|
|
749
|
+
artifact_jsonl_path=artifact_paths.get("jsonl") if artifact_paths else None,
|
|
631
750
|
)
|
|
632
751
|
|
|
633
752
|
# Single re-prompt if a schema was requested but submit_result wasn't called.
|
|
@@ -639,6 +758,7 @@ class AgentTool(BaseTool):
|
|
|
639
758
|
conversation_id,
|
|
640
759
|
last_saved_index=last_saved_index,
|
|
641
760
|
task=self._STRUCTURED_OUTPUT_NUDGE,
|
|
761
|
+
artifact_jsonl_path=artifact_paths.get("jsonl") if artifact_paths else None,
|
|
642
762
|
)
|
|
643
763
|
|
|
644
764
|
result = await agent.recap_agent_outcome()
|
|
@@ -664,6 +784,21 @@ class AgentTool(BaseTool):
|
|
|
664
784
|
)
|
|
665
785
|
|
|
666
786
|
structured = capture.get("value") if schema else None
|
|
787
|
+
final_history = agent.dump_message_history() if agent is not None else []
|
|
788
|
+
if artifact_paths and artifact_paths.get("jsonl"):
|
|
789
|
+
# Persist any history messages that completed after the last stream event.
|
|
790
|
+
for i in range(last_saved_index + 1, len(final_history)):
|
|
791
|
+
self._write_jsonl_message(artifact_paths.get("jsonl"), final_history[i])
|
|
792
|
+
self._write_workflow_agent_markdown(
|
|
793
|
+
artifact_paths,
|
|
794
|
+
metadata=artifact_metadata,
|
|
795
|
+
prompt=task,
|
|
796
|
+
status="completed",
|
|
797
|
+
result=result,
|
|
798
|
+
structured=structured,
|
|
799
|
+
tokens=total_tokens if isinstance(total_tokens, int) else 0,
|
|
800
|
+
history=final_history,
|
|
801
|
+
)
|
|
667
802
|
return result, (total_tokens if isinstance(total_tokens, int) else 0), structured
|
|
668
803
|
|
|
669
804
|
except Exception as e:
|
|
@@ -678,6 +813,20 @@ class AgentTool(BaseTool):
|
|
|
678
813
|
},
|
|
679
814
|
)
|
|
680
815
|
conversation_finished = True
|
|
816
|
+
final_history = []
|
|
817
|
+
if agent is not None:
|
|
818
|
+
try:
|
|
819
|
+
final_history = agent.dump_message_history()
|
|
820
|
+
except Exception: # noqa: BLE001 - transcript capture must not mask the real failure
|
|
821
|
+
final_history = []
|
|
822
|
+
self._write_workflow_agent_markdown(
|
|
823
|
+
artifact_paths,
|
|
824
|
+
metadata=artifact_metadata,
|
|
825
|
+
prompt=task,
|
|
826
|
+
status="failed",
|
|
827
|
+
error=str(e),
|
|
828
|
+
history=final_history,
|
|
829
|
+
)
|
|
681
830
|
await self.log_error(f"Error in workflow {agent_name}: {str(e)}", sender="AgentTool")
|
|
682
831
|
await self._send_status_event("ERROR", f"Error in {agent_name}: {str(e)}", sub_agent_info=sub_agent_info)
|
|
683
832
|
raise
|
|
@@ -704,6 +853,7 @@ class AgentTool(BaseTool):
|
|
|
704
853
|
*,
|
|
705
854
|
last_saved_index: int,
|
|
706
855
|
task: str,
|
|
856
|
+
artifact_jsonl_path: Optional[Path] = None,
|
|
707
857
|
) -> int:
|
|
708
858
|
"""Stream one process_message_stream pass, broadcasting events and recording
|
|
709
859
|
newly-completed history messages. Returns the updated last_saved_index.
|
|
@@ -729,19 +879,21 @@ class AgentTool(BaseTool):
|
|
|
729
879
|
)
|
|
730
880
|
await self.connection_manager.broadcast_event(evt, self.workspace_id, self.thread_id)
|
|
731
881
|
|
|
732
|
-
if
|
|
882
|
+
if complete:
|
|
733
883
|
current_history = agent.dump_message_history()
|
|
734
884
|
for i in range(last_saved_index + 1, len(current_history)):
|
|
735
885
|
hist_msg = current_history[i]
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
886
|
+
if conversation_id:
|
|
887
|
+
await self._record_message(
|
|
888
|
+
conversation_id,
|
|
889
|
+
{
|
|
890
|
+
"role": hist_msg.get("role", "assistant"),
|
|
891
|
+
"content": hist_msg.get("content", []),
|
|
892
|
+
"stream_uuid": None,
|
|
893
|
+
},
|
|
894
|
+
i + 1,
|
|
895
|
+
)
|
|
896
|
+
self._write_jsonl_message(artifact_jsonl_path, hist_msg)
|
|
745
897
|
last_saved_index = len(current_history) - 1
|
|
746
898
|
|
|
747
899
|
return last_saved_index
|