kolega-code 0.35.0__tar.gz → 0.36.0__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.35.0 → kolega_code-0.36.0}/CHANGELOG.md +39 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/PKG-INFO +1 -1
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/__init__.py +1 -1
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/__init__.py +1 -1
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/main.py +19 -1
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/provider_registry.py +1 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/settings_panel.py +128 -2
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/settings_screen.py +20 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/bridge.py +84 -36
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/service.py +40 -3
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/openai.py +15 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/openai_chatgpt.py +17 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/config.py +73 -2
- kolega_code-0.36.0/kolega_code/mcp/oauth.py +403 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/service.py +22 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/state.py +12 -1
- {kolega_code-0.35.0 → kolega_code-0.36.0}/pyproject.toml +1 -1
- kolega_code-0.35.0/kolega_code/mcp/oauth.py +0 -241
- {kolega_code-0.35.0 → kolega_code-0.36.0}/.gitignore +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/CONTRIBUTING.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/LICENSE +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/MIGRATION.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/README.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/RELEASING.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/LICENSE +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/manifest.json +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/SKILL.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/references/evidence-and-reporting.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/references/gigacode-workflow.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/scripts/deep-research.workflow +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/deep-research/scripts/materialize_report.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/LICENSE +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/SKILL.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/references/examples.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/references/limitations.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/references/operations.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/references/quality.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/requirements.txt +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/scripts/docx_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/docx/scripts/smoke_test.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/humanizer/LICENSE +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/humanizer/SKILL.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/LICENSE +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/SKILL.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/examples.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/limitations.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/ocr.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/operations.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/quality.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/references/redaction.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-paddle.txt +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/requirements-ocr-surya.txt +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/requirements.txt +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/scripts/pdf_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pdf/scripts/smoke_test.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/LICENSE +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/SKILL.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/references/examples.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/references/limitations.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/references/operations.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/requirements.txt +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/scripts/pptx_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/pptx/scripts/smoke_test.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/review/SKILL.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/review/references/github-publishing.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/skill-authoring/SKILL.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/skill-authoring/references/review-checklist.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/LICENSE +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/SKILL.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/references/examples.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/references/limitations.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/references/operations.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/references/quality.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/requirements.txt +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/scripts/smoke_test.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/_bundled_skills/skills/xlsx/scripts/xlsx_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/agent_factory.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/bridge.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/diffs.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/permissions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/plans.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/questions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/server.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/session.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/acp/usage.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/baseagent.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/browseragent.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/coder.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/common.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/compression.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/context.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/conversation.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/custom_agents.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/edit_protocols.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/errors.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/bridge.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/bundle-requirements.in +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/bundle-requirements.txt +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/env.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/js_kernel.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/kernel.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/prelude.js +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/prelude.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/protocol.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/py_kernel.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/runner.js +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/eval/runner.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/generalagent.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/goal.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/handoff.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/investigationagent.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/model_routing.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/accounting.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/budget.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/context.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/errors.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/executor.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/guide.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/journal.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/runtime.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/orchestration/types.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/planningagent.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_dump.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_overrides.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_provider.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_exhausted.user.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/silent_turn_nudge.user.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/agent_loop/truncated_turn_nudge.user.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/handoff/document.system.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/handoff/document.user.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/build_questions.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/current_plan_artifact.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/mode_switch_notice.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/scratchpad.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list_readonly.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/cli/worktree_control.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/coder_ask.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/coder_base.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/context_updates.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/system/includes/terminal_tools.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/apply_patch.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/ask_user_choice.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_click.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_close.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_console_messages.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_drag.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_drop.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_evaluate.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_file_upload.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_fill_form.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_find.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_handle_dialog.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_hover.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_navigate.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_navigate_back.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_network_request.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_network_requests.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_press_key.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_resize.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_scroll.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_select_option.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_snapshot.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_tabs.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_take_screenshot.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_type.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/browser_wait_for.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/build_backend.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/build_frontend.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/claude_edit.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/claude_write.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/dispatch_agent.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/edit.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/eval.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/exec_command.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/get_host.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/get_task_list.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/get_task_list_readonly.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/hashline_edit.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/hashline_write.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/kill_command.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/list_agents.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/list_sessions.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/list_subagent_models.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/list_workflow_runs.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/lsp.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/lsp_edit.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/multi_edit.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/read.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/read_image.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/resolve.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/run_workflow.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/send_message.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/set_goal.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/skill.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/snapshot.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/switch_worktree.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/update_task_list.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/web_fetch.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/web_search.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/write.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/write_plan.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/tools/write_stdin.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/prompts.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/session_metadata.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/agent_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/base_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/build_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/codex_patch.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/edit_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/eval_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/hashline_v2.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/lsp_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/network_status.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/snapshot_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/answering.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/documents.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/extractors.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/pipeline.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch/retrieval.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_backend/workflow_tool.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tool_definitions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/tools.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/utils/commands.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/agent/volatile_context.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/_jwt.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/chatgpt_oauth.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/constants.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/auth/tokens.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/framing.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/installer.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/manager.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/multiplex.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/native_host.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/protocol.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/registry.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/browser_extension/runtime.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/acp.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/app.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/ask_output.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/atif_export.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/browser_backend.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/clipboard_image.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/config.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/connection.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/cron.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/diagnostics.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/file_index.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/gateway.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/goal.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/loop.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/mentions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/messages.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/model_catalog.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/model_connection.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/peer_messaging.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/plan_artifacts.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/prompt_history.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_event_protocol.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_event_store.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_journal.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_store.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/session_usage.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/settings.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/skills.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/slash_commands.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/theme.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/agent_runtime.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/app_base.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/changes_screen.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/command_handlers.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/constants.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/custom_model.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/loop_runtime.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/memory_screen.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/onboarding_screen.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/pacing.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/prompt_flows.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/session_diff.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/state.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/status_dashboard.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/styles.tcss +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/sub_agent_screen.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/terminal_display.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/transcript.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/tui/widgets.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/cli/updater.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/config.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/events.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/extensions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/access.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/base.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/echo.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/telegram/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/telegram/adapter.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/adapters/telegram/formatting.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/commands.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/config.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/control_relay.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/daemon.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/event_router.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/questions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/redaction.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/router.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/sessions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/gateway/stt.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/git_env.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/backends.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/config.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/dispatcher.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/events.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/matcher.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/hooks/outcome.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/client.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/exceptions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/instrumented_client.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/ledger.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/models.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/_token_encoding.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/anthropic.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/base.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/deepseek_responses.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/google.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/models.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/openai.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/openai_responses.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/perplexity_responses.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/responses_common.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/tinker.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/providers/tinker_trace.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/ratelimit.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/accessors.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/anthropic.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/dashscope.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/deepseek.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/fireworks.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/google.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/groq.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/kimi_coding.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/moonshot.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/ollama_cloud.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/openrouter.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/perplexity_agent.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/thinking_machines.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/tinker.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/together.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/xai.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/catalog/zai.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/custom_endpoints.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/ollama_cloud_catalog.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/openrouter_catalog.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/perplexity_catalog.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/thinking.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/tinker_catalog.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/types.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/specs/validation.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/timeouts.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/tool_execution_ids.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/llm/usage.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/local_state.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/tools.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/mcp/transport.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/identity.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/manager.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/manifest.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/markdown.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/models.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/protocol.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/memory/registry.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/models/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/models/sandbox_terminal_state.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/permissions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/runtime.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/README.md +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/async_filesystem.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/base.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/browser.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/event_loop.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/filesystem.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/local.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/serializer.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/terminal.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/sandbox/utils.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/scratchpad.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/security/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/security/secrets.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/base.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/browser.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/file_system.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/html.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/client.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/config.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/detector.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/diagnostics.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/edits.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/manager.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/registry.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/lsp/registry.yaml +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/snapshots.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/terminal.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/terminal_buffer.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/services/workspace_scan.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/control.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/inbox.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/inmemory.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/projection.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/recording.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/runtime.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/session/store.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/testing/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/testing/store_conformance.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/ask_user.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/core.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/definitions.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/param_aliases.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/tools/registry.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/utils/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/utils/images.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/__init__.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/assets/fold.js +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/assets/player.css +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/assets/player.html +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/assets/player.js +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/bundle.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/hosting.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/redaction.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/server.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/singlefile.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/web/theme_css.py +0 -0
- {kolega_code-0.35.0 → kolega_code-0.36.0}/kolega_code/worktrees.py +0 -0
|
@@ -6,6 +6,45 @@ This project uses GitHub Releases for detailed generated release notes. This fil
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.36.0 - 2026-09-07
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **GPT-6 Astra.** OpenAI's new flagship model is available on both the API
|
|
14
|
+
and ChatGPT-subscription providers: 1M-token context with 128K output,
|
|
15
|
+
vision, hosted web search, `codex_apply_patch` editing, and
|
|
16
|
+
`low`–`max` reasoning effort levels (default `medium`). The
|
|
17
|
+
ChatGPT-subscription route keeps the conservative 400K input budget until
|
|
18
|
+
Astra's larger window is verified on the Codex backend.
|
|
19
|
+
- **Pre-registered OAuth credentials for remote MCP servers.** Servers that
|
|
20
|
+
don't implement Dynamic Client Registration (HubSpot, Slack, GitHub
|
|
21
|
+
Copilot, enterprise IdPs) can now be connected with a pre-registered
|
|
22
|
+
client: new `--oauth-client-id`, `--oauth-client-secret`,
|
|
23
|
+
`--oauth-client-secret-env`, and `--oauth-auth-method` flags on
|
|
24
|
+
`kolega-code mcp add`, matching OAuth controls on the MCP page in TUI
|
|
25
|
+
settings, preserved explicit redirect ports/hosts, actionable diagnostics
|
|
26
|
+
when registration fails, and PBKDF2-salted OAuth cache fingerprints with
|
|
27
|
+
refresh tokens preserved across reconnects.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **Gateway (Telegram):** the typing indicator now stays alive for the whole
|
|
32
|
+
turn. Telegram expires typing actions after ~5 seconds, so it previously
|
|
33
|
+
vanished during exactly the stretches where feedback matters — model
|
|
34
|
+
thinking before the first chunk and long-running tool calls.
|
|
35
|
+
|
|
36
|
+
## 0.35.1 - 2026-09-03
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- **Gateway (Telegram):** the tool-activity status now re-appears below the
|
|
41
|
+
newest reply bubble. Previously it stayed stranded in an older message once
|
|
42
|
+
a reply opened, so later tool calls looked detached from the conversation.
|
|
43
|
+
Adapters without message-delete support keep the edit-in-place behavior.
|
|
44
|
+
- **Gateway service:** the background daemon now launches through the user's
|
|
45
|
+
login shell, so gateway-driven agent sessions see user-installed tools such
|
|
46
|
+
as Homebrew instead of the minimal `PATH` that launchd and systemd provide.
|
|
47
|
+
|
|
9
48
|
## 0.35.0 - 2026-09-03
|
|
10
49
|
|
|
11
50
|
### Added
|
|
@@ -796,6 +796,14 @@ def _build_subcommand_parser() -> argparse.ArgumentParser:
|
|
|
796
796
|
add.add_argument("--env", action="append", default=[], help="Environment variable as NAME=VALUE (repeatable).")
|
|
797
797
|
add.add_argument("--cwd", help="Working directory for stdio command; relative paths resolve under project.")
|
|
798
798
|
add.add_argument("--oauth", action="store_true", help="Enable OAuth for this HTTP MCP server.")
|
|
799
|
+
add.add_argument("--oauth-client-id", help="Pre-registered OAuth client ID.")
|
|
800
|
+
add.add_argument("--oauth-client-secret", help="Pre-registered OAuth client secret.")
|
|
801
|
+
add.add_argument("--oauth-client-secret-env", help="Environment variable name holding the OAuth client secret.")
|
|
802
|
+
add.add_argument(
|
|
803
|
+
"--oauth-auth-method",
|
|
804
|
+
choices=["client_secret_post", "client_secret_basic", "none"],
|
|
805
|
+
help="Token endpoint authentication method.",
|
|
806
|
+
)
|
|
799
807
|
add.add_argument("--oauth-scope", help="OAuth scopes to request.")
|
|
800
808
|
add.add_argument("--redirect-uri", help="OAuth redirect URI; defaults to an ephemeral localhost callback.")
|
|
801
809
|
add.add_argument("--disabled", action="store_true", help="Add the server disabled.")
|
|
@@ -2697,6 +2705,12 @@ def _mcp_mutation_target(args: argparse.Namespace, project_path: Path, state_dir
|
|
|
2697
2705
|
def _server_config_from_add_args(args: argparse.Namespace) -> MCPServerConfig:
|
|
2698
2706
|
headers = _parse_key_value_options(getattr(args, "header", []) or [], "--header")
|
|
2699
2707
|
env = _parse_key_value_options(getattr(args, "env", []) or [], "--env")
|
|
2708
|
+
oauth_client_id = getattr(args, "oauth_client_id", None)
|
|
2709
|
+
oauth_client_secret = getattr(args, "oauth_client_secret", None)
|
|
2710
|
+
oauth_client_secret_env = getattr(args, "oauth_client_secret_env", None)
|
|
2711
|
+
oauth_auth_method = getattr(args, "oauth_auth_method", None)
|
|
2712
|
+
oauth_enabled = bool(args.oauth) or bool(oauth_client_id or oauth_client_secret or oauth_client_secret_env)
|
|
2713
|
+
|
|
2700
2714
|
payload: dict[str, Any] = {
|
|
2701
2715
|
"id": args.server_id,
|
|
2702
2716
|
"name": args.name,
|
|
@@ -2709,9 +2723,13 @@ def _server_config_from_add_args(args: argparse.Namespace) -> MCPServerConfig:
|
|
|
2709
2723
|
"env": env,
|
|
2710
2724
|
"cwd": args.cwd,
|
|
2711
2725
|
"oauth": {
|
|
2712
|
-
"enabled":
|
|
2726
|
+
"enabled": oauth_enabled,
|
|
2713
2727
|
"scope": args.oauth_scope,
|
|
2714
2728
|
"redirect_uri": args.redirect_uri,
|
|
2729
|
+
"client_id": oauth_client_id,
|
|
2730
|
+
"client_secret": oauth_client_secret,
|
|
2731
|
+
"client_secret_env": oauth_client_secret_env,
|
|
2732
|
+
"token_endpoint_auth_method": oauth_auth_method,
|
|
2715
2733
|
},
|
|
2716
2734
|
}
|
|
2717
2735
|
return MCPServerConfig.model_validate(payload)
|
|
@@ -90,6 +90,7 @@ MODEL_LABELS: dict[str, str] = {
|
|
|
90
90
|
"claude-opus-4-5-20251101": "Claude Opus 4.5",
|
|
91
91
|
"claude-haiku-4-5-20251001": "Claude Haiku 4.5",
|
|
92
92
|
# OpenAI (shared labels across the API and ChatGPT-subscription providers)
|
|
93
|
+
"gpt-6-astra": "GPT-6 Astra",
|
|
93
94
|
"gpt-5.6-sol": "GPT-5.6 Sol",
|
|
94
95
|
"gpt-5.6-terra": "GPT-5.6 Terra",
|
|
95
96
|
"gpt-5.6-luna": "GPT-5.6 Luna",
|
|
@@ -104,6 +104,12 @@ MCP_TRANSPORT_OPTIONS = [
|
|
|
104
104
|
("stdio command", "stdio"),
|
|
105
105
|
]
|
|
106
106
|
MCP_ENABLED_OPTIONS = [("Enabled", "true"), ("Disabled", "false")]
|
|
107
|
+
MCP_OAUTH_AUTH_METHOD_OPTIONS = [
|
|
108
|
+
("Auto (POST if secret, none if public)", "auto"),
|
|
109
|
+
("client_secret_post", "client_secret_post"),
|
|
110
|
+
("client_secret_basic", "client_secret_basic"),
|
|
111
|
+
("none (public client / PKCE)", "none"),
|
|
112
|
+
]
|
|
107
113
|
MCP_STATUS_MESSAGE_MAX = 96
|
|
108
114
|
MCP_STATUS_NAME_MAX = 34
|
|
109
115
|
# Compression threshold select: "default" maps to None (the agent's built-in 95%).
|
|
@@ -417,6 +423,16 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
|
|
|
417
423
|
self._update_mcp_transport_fields(str(event.value))
|
|
418
424
|
return
|
|
419
425
|
|
|
426
|
+
if select_id == "mcp_oauth_select":
|
|
427
|
+
transport = "streamable_http"
|
|
428
|
+
try:
|
|
429
|
+
transport = str(self._settings_query_one("#mcp_transport_select", Select).value)
|
|
430
|
+
except NoMatches:
|
|
431
|
+
pass
|
|
432
|
+
http = transport in {"streamable_http", "sse"}
|
|
433
|
+
self._update_mcp_oauth_fields(http and str(event.value) == "true")
|
|
434
|
+
return
|
|
435
|
+
|
|
420
436
|
row = _row_for_widget(select_id)
|
|
421
437
|
if row is not None and select_id == row.provider_id:
|
|
422
438
|
provider = str(event.value)
|
|
@@ -1477,6 +1493,12 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
|
|
|
1477
1493
|
set_input("mcp_url_input", "")
|
|
1478
1494
|
set_input("mcp_headers_input", "")
|
|
1479
1495
|
set_select("mcp_oauth_select", "false")
|
|
1496
|
+
set_input("mcp_oauth_client_id_input", "")
|
|
1497
|
+
set_input("mcp_oauth_client_secret_input", "")
|
|
1498
|
+
set_input("mcp_oauth_client_secret_env_input", "")
|
|
1499
|
+
set_input("mcp_oauth_redirect_uri_input", "")
|
|
1500
|
+
set_input("mcp_oauth_scope_input", "")
|
|
1501
|
+
set_select("mcp_oauth_auth_method_select", "auto")
|
|
1480
1502
|
set_input("mcp_command_input", "")
|
|
1481
1503
|
set_input("mcp_args_input", "")
|
|
1482
1504
|
set_input("mcp_env_input", "")
|
|
@@ -1491,6 +1513,12 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
|
|
|
1491
1513
|
set_input("mcp_url_input", server.url or "")
|
|
1492
1514
|
set_input("mcp_headers_input", json.dumps(server.headers, sort_keys=True) if server.headers else "")
|
|
1493
1515
|
set_select("mcp_oauth_select", "true" if server.oauth.enabled else "false")
|
|
1516
|
+
set_input("mcp_oauth_client_id_input", server.oauth.client_id or "")
|
|
1517
|
+
set_input("mcp_oauth_client_secret_input", server.oauth.client_secret or "")
|
|
1518
|
+
set_input("mcp_oauth_client_secret_env_input", server.oauth.client_secret_env or "")
|
|
1519
|
+
set_input("mcp_oauth_redirect_uri_input", server.oauth.redirect_uri or "")
|
|
1520
|
+
set_input("mcp_oauth_scope_input", server.oauth.scope or "")
|
|
1521
|
+
set_select("mcp_oauth_auth_method_select", server.oauth.token_endpoint_auth_method or "auto")
|
|
1494
1522
|
set_input("mcp_command_input", server.command or "")
|
|
1495
1523
|
set_input("mcp_args_input", " ".join(shlex.quote(arg) for arg in server.args))
|
|
1496
1524
|
set_input("mcp_env_input", json.dumps(server.env, sort_keys=True) if server.env else "")
|
|
@@ -1503,6 +1531,26 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
|
|
|
1503
1531
|
self._set_mcp_source_hint("This server is stored in your global MCP config.")
|
|
1504
1532
|
self._update_mcp_transport_fields(server.transport)
|
|
1505
1533
|
|
|
1534
|
+
def _update_mcp_oauth_fields(self, visible: bool) -> None:
|
|
1535
|
+
for widget_id in (
|
|
1536
|
+
"mcp_oauth_client_id_label",
|
|
1537
|
+
"mcp_oauth_client_id_input",
|
|
1538
|
+
"mcp_oauth_client_secret_label",
|
|
1539
|
+
"mcp_oauth_client_secret_input",
|
|
1540
|
+
"mcp_oauth_client_secret_env_label",
|
|
1541
|
+
"mcp_oauth_client_secret_env_input",
|
|
1542
|
+
"mcp_oauth_redirect_uri_label",
|
|
1543
|
+
"mcp_oauth_redirect_uri_input",
|
|
1544
|
+
"mcp_oauth_scope_label",
|
|
1545
|
+
"mcp_oauth_scope_input",
|
|
1546
|
+
"mcp_oauth_auth_method_label",
|
|
1547
|
+
"mcp_oauth_auth_method_select",
|
|
1548
|
+
):
|
|
1549
|
+
try:
|
|
1550
|
+
self._settings_query_one(f"#{widget_id}").display = visible
|
|
1551
|
+
except NoMatches:
|
|
1552
|
+
pass
|
|
1553
|
+
|
|
1506
1554
|
def _update_mcp_transport_fields(self, transport: str) -> None:
|
|
1507
1555
|
http = transport in {"streamable_http", "sse"}
|
|
1508
1556
|
for widget_id, visible in (
|
|
@@ -1525,6 +1573,12 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
|
|
|
1525
1573
|
self._settings_query_one(f"#{widget_id}").display = visible
|
|
1526
1574
|
except NoMatches:
|
|
1527
1575
|
pass
|
|
1576
|
+
oauth_enabled = False
|
|
1577
|
+
try:
|
|
1578
|
+
oauth_enabled = http and str(self._settings_query_one("#mcp_oauth_select", Select).value) == "true"
|
|
1579
|
+
except NoMatches:
|
|
1580
|
+
pass
|
|
1581
|
+
self._update_mcp_oauth_fields(oauth_enabled)
|
|
1528
1582
|
try:
|
|
1529
1583
|
url_input = self._settings_query_one("#mcp_url_input", Input)
|
|
1530
1584
|
if transport == "streamable_http":
|
|
@@ -1621,7 +1675,8 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
|
|
|
1621
1675
|
enabled = str(self._settings_query_one("#mcp_enabled_select", Select).value) == "true"
|
|
1622
1676
|
url = self._settings_query_one("#mcp_url_input", Input).value.strip() or None
|
|
1623
1677
|
headers_text = self._settings_query_one("#mcp_headers_input", Input).value.strip()
|
|
1624
|
-
|
|
1678
|
+
http = transport in {"streamable_http", "sse"}
|
|
1679
|
+
oauth_enabled = http and str(self._settings_query_one("#mcp_oauth_select", Select).value) == "true"
|
|
1625
1680
|
command = self._settings_query_one("#mcp_command_input", Input).value.strip() or None
|
|
1626
1681
|
args_text = self._settings_query_one("#mcp_args_input", Input).value.strip()
|
|
1627
1682
|
env_text = self._settings_query_one("#mcp_env_input", Input).value.strip()
|
|
@@ -1640,6 +1695,77 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
|
|
|
1640
1695
|
else selected
|
|
1641
1696
|
)
|
|
1642
1697
|
|
|
1698
|
+
oauth_client_id = None
|
|
1699
|
+
oauth_client_secret = None
|
|
1700
|
+
oauth_client_secret_env = None
|
|
1701
|
+
oauth_redirect_uri = None
|
|
1702
|
+
oauth_scope = None
|
|
1703
|
+
oauth_auth_method: Optional[Literal["client_secret_post", "client_secret_basic", "none"]] = None
|
|
1704
|
+
|
|
1705
|
+
if http:
|
|
1706
|
+
try:
|
|
1707
|
+
oauth_client_id = self._settings_query_one("#mcp_oauth_client_id_input", Input).value.strip() or None
|
|
1708
|
+
except NoMatches:
|
|
1709
|
+
pass
|
|
1710
|
+
try:
|
|
1711
|
+
oauth_client_secret = (
|
|
1712
|
+
self._settings_query_one("#mcp_oauth_client_secret_input", Input).value.strip() or None
|
|
1713
|
+
)
|
|
1714
|
+
except NoMatches:
|
|
1715
|
+
pass
|
|
1716
|
+
try:
|
|
1717
|
+
oauth_client_secret_env = (
|
|
1718
|
+
self._settings_query_one("#mcp_oauth_client_secret_env_input", Input).value.strip() or None
|
|
1719
|
+
)
|
|
1720
|
+
except NoMatches:
|
|
1721
|
+
pass
|
|
1722
|
+
try:
|
|
1723
|
+
oauth_redirect_uri = (
|
|
1724
|
+
self._settings_query_one("#mcp_oauth_redirect_uri_input", Input).value.strip() or None
|
|
1725
|
+
)
|
|
1726
|
+
except NoMatches:
|
|
1727
|
+
pass
|
|
1728
|
+
try:
|
|
1729
|
+
oauth_scope = self._settings_query_one("#mcp_oauth_scope_input", Input).value.strip() or None
|
|
1730
|
+
except NoMatches:
|
|
1731
|
+
pass
|
|
1732
|
+
try:
|
|
1733
|
+
method_val = str(self._settings_query_one("#mcp_oauth_auth_method_select", Select).value)
|
|
1734
|
+
if method_val in {"client_secret_post", "client_secret_basic", "none"}:
|
|
1735
|
+
oauth_auth_method = cast(Literal["client_secret_post", "client_secret_basic", "none"], method_val)
|
|
1736
|
+
except NoMatches:
|
|
1737
|
+
pass
|
|
1738
|
+
|
|
1739
|
+
client_name = "Kolega Code"
|
|
1740
|
+
client_uri = None
|
|
1741
|
+
client_metadata_url = None
|
|
1742
|
+
timeout_seconds = 300.0
|
|
1743
|
+
if selected != MCP_NEW_SERVER_VALUE:
|
|
1744
|
+
try:
|
|
1745
|
+
config = self._load_mcp_config_for_ui()
|
|
1746
|
+
existing = config.servers.get(selected)
|
|
1747
|
+
if existing:
|
|
1748
|
+
client_name = existing.oauth.client_name
|
|
1749
|
+
client_uri = existing.oauth.client_uri
|
|
1750
|
+
client_metadata_url = existing.oauth.client_metadata_url
|
|
1751
|
+
timeout_seconds = existing.oauth.timeout_seconds
|
|
1752
|
+
except Exception:
|
|
1753
|
+
pass
|
|
1754
|
+
|
|
1755
|
+
oauth = MCPOAuthConfig(
|
|
1756
|
+
enabled=oauth_enabled,
|
|
1757
|
+
client_id=oauth_client_id,
|
|
1758
|
+
client_secret=oauth_client_secret,
|
|
1759
|
+
client_secret_env=oauth_client_secret_env,
|
|
1760
|
+
redirect_uri=oauth_redirect_uri,
|
|
1761
|
+
scope=oauth_scope,
|
|
1762
|
+
token_endpoint_auth_method=oauth_auth_method,
|
|
1763
|
+
client_name=client_name,
|
|
1764
|
+
client_uri=client_uri,
|
|
1765
|
+
client_metadata_url=client_metadata_url,
|
|
1766
|
+
timeout_seconds=timeout_seconds,
|
|
1767
|
+
)
|
|
1768
|
+
|
|
1643
1769
|
return MCPServerConfig(
|
|
1644
1770
|
id=server_id,
|
|
1645
1771
|
name=name,
|
|
@@ -1647,7 +1773,7 @@ class SettingsPanelMixin(tui_app_base.KolegaAppBase):
|
|
|
1647
1773
|
enabled=enabled,
|
|
1648
1774
|
url=url,
|
|
1649
1775
|
headers=headers,
|
|
1650
|
-
oauth=
|
|
1776
|
+
oauth=oauth,
|
|
1651
1777
|
command=command,
|
|
1652
1778
|
args=args,
|
|
1653
1779
|
env=env,
|
|
@@ -588,6 +588,26 @@ class SettingsScreen(ModalScreen[None]):
|
|
|
588
588
|
allow_blank=False,
|
|
589
589
|
value="false",
|
|
590
590
|
)
|
|
591
|
+
yield Label("OAuth Client ID", id="mcp_oauth_client_id_label")
|
|
592
|
+
yield Input(id="mcp_oauth_client_id_input", placeholder="e.g. client_abc123")
|
|
593
|
+
yield Label("OAuth Client Secret", id="mcp_oauth_client_secret_label")
|
|
594
|
+
yield Input(id="mcp_oauth_client_secret_input", placeholder="optional direct secret", password=True)
|
|
595
|
+
yield Label("OAuth Client Secret Env Var", id="mcp_oauth_client_secret_env_label")
|
|
596
|
+
yield Input(id="mcp_oauth_client_secret_env_input", placeholder="e.g. HUBSPOT_MCP_CLIENT_SECRET")
|
|
597
|
+
yield Label("OAuth Redirect URI", id="mcp_oauth_redirect_uri_label")
|
|
598
|
+
yield Input(
|
|
599
|
+
id="mcp_oauth_redirect_uri_input",
|
|
600
|
+
placeholder="e.g. http://127.0.0.1:33418/callback (default: ephemeral port)",
|
|
601
|
+
)
|
|
602
|
+
yield Label("OAuth Scopes", id="mcp_oauth_scope_label")
|
|
603
|
+
yield Input(id="mcp_oauth_scope_input", placeholder="e.g. read write")
|
|
604
|
+
yield Label("OAuth Token Auth Method", id="mcp_oauth_auth_method_label")
|
|
605
|
+
yield Select(
|
|
606
|
+
settings_panel.MCP_OAUTH_AUTH_METHOD_OPTIONS,
|
|
607
|
+
id="mcp_oauth_auth_method_select",
|
|
608
|
+
allow_blank=False,
|
|
609
|
+
value="auto",
|
|
610
|
+
)
|
|
591
611
|
yield Label("Command", id="mcp_command_label")
|
|
592
612
|
yield Input(id="mcp_command_input", placeholder="npx")
|
|
593
613
|
yield Label("Arguments", id="mcp_args_label")
|
|
@@ -12,10 +12,16 @@ turns:
|
|
|
12
12
|
- a placeholder reply is created on first content and edited in place on a
|
|
13
13
|
throttle until the turn ends (final-only transports get one message at the
|
|
14
14
|
end);
|
|
15
|
-
- tool activity lands in
|
|
16
|
-
|
|
15
|
+
- each round of tool activity lands in its own "working…" message below the
|
|
16
|
+
newest reply bubble: a round that starts after text was streamed opens a
|
|
17
|
+
fresh message (Telegram cannot move messages, so appending to an older one
|
|
18
|
+
would surface above the latest text), and the messages persist as a trail
|
|
19
|
+
of what the agent did during the turn;
|
|
17
20
|
- text is chunked at the adapter's limit; the first chunk is the edited
|
|
18
|
-
message and overflow chunks are sent as continuations on finalize
|
|
21
|
+
message and overflow chunks are sent as continuations on finalize;
|
|
22
|
+
- a typing action is re-sent every few seconds for the whole turn (chat
|
|
23
|
+
platforms expire it after ~5s), so thinking and long tool runs keep
|
|
24
|
+
showing "typing…" until the reply lands.
|
|
19
25
|
|
|
20
26
|
Chunk content is *incremental*, so the renderer appends and re-renders the
|
|
21
27
|
accumulated text — it never replaces with the last segment.
|
|
@@ -34,10 +40,14 @@ from kolega_code.gateway.adapters.telegram.formatting import chunk_text
|
|
|
34
40
|
|
|
35
41
|
logger = logging.getLogger(__name__)
|
|
36
42
|
|
|
37
|
-
#: Cap on
|
|
43
|
+
#: Cap on a round message's lines so a chatty turn cannot spam an unbounded edit.
|
|
38
44
|
MAX_STATUS_LINES = 8
|
|
39
|
-
#:
|
|
40
|
-
|
|
45
|
+
#: Chat platforms expire a typing action after ~5 seconds (Telegram: "status
|
|
46
|
+
#: is set for 5 seconds or less"); refresh slightly faster so the indicator
|
|
47
|
+
#: never lapses while a turn is in progress.
|
|
48
|
+
TYPING_REFRESH_SECONDS = 4.0
|
|
49
|
+
#: Rendered status line: (icon, tool description, tool call id).
|
|
50
|
+
StatusLine = tuple[str, str, str]
|
|
41
51
|
|
|
42
52
|
|
|
43
53
|
class TurnRenderer:
|
|
@@ -51,6 +61,7 @@ class TurnRenderer:
|
|
|
51
61
|
event_queue: asyncio.Queue[AgentEvent],
|
|
52
62
|
chunk_limit: Optional[int] = None,
|
|
53
63
|
edit_throttle_seconds: float = 1.0,
|
|
64
|
+
typing_refresh_seconds: float = TYPING_REFRESH_SECONDS,
|
|
54
65
|
monotonic: Any = time.monotonic,
|
|
55
66
|
) -> None:
|
|
56
67
|
self._adapter = adapter
|
|
@@ -58,6 +69,7 @@ class TurnRenderer:
|
|
|
58
69
|
self._events = event_queue
|
|
59
70
|
self._chunk_limit = chunk_limit or adapter.capabilities.text_chunk_limit
|
|
60
71
|
self._edit_throttle = edit_throttle_seconds
|
|
72
|
+
self._typing_refresh = typing_refresh_seconds
|
|
61
73
|
self._monotonic = monotonic
|
|
62
74
|
# Per-segment state, mirroring the TUI's stream fold: a segment is one
|
|
63
75
|
# contiguous assistant response identified by its chunk uuid (the
|
|
@@ -69,10 +81,17 @@ class TurnRenderer:
|
|
|
69
81
|
self._reply_id: Optional[str] = None
|
|
70
82
|
self._edited_text = ""
|
|
71
83
|
self._last_flush = 0.0
|
|
84
|
+
#: The current tool round's message, one per burst of tool activity.
|
|
85
|
+
#: Older rounds' messages stay in the chat as a trail of the turn.
|
|
72
86
|
self._status_id: Optional[str] = None
|
|
73
|
-
self._status_lines: list[
|
|
87
|
+
self._status_lines: list[StatusLine] = []
|
|
74
88
|
self._status_sent_text = ""
|
|
75
89
|
self._last_status_flush = 0.0
|
|
90
|
+
#: Set when a reply message was sent after the current round message:
|
|
91
|
+
#: the next tool event then opens a fresh round message below the
|
|
92
|
+
#: newest bubble (Telegram cannot move messages) instead of appending
|
|
93
|
+
#: to the stale one higher up the chat.
|
|
94
|
+
self._status_stale = False
|
|
76
95
|
|
|
77
96
|
async def run(self, chunks: AsyncIterator[dict[str, Any]]) -> str:
|
|
78
97
|
"""Consume the turn generator and mirror it into the chat.
|
|
@@ -82,10 +101,12 @@ class TurnRenderer:
|
|
|
82
101
|
reply stays visible.
|
|
83
102
|
"""
|
|
84
103
|
pump: Optional[asyncio.Task[None]] = None
|
|
104
|
+
typing: Optional[asyncio.Task[None]] = None
|
|
85
105
|
if self._events is not None:
|
|
86
106
|
pump = asyncio.create_task(self._event_pump(), name="gateway-turn-event-pump")
|
|
87
107
|
try:
|
|
88
108
|
await self._adapter.set_typing(self._chat_id, True)
|
|
109
|
+
typing = asyncio.create_task(self._typing_keepalive(), name="gateway-turn-typing")
|
|
89
110
|
async for chunk in chunks:
|
|
90
111
|
if chunk.get("type") != "response":
|
|
91
112
|
# Thinking chunks stay off the wire; they are reasoning, not output.
|
|
@@ -111,14 +132,30 @@ class TurnRenderer:
|
|
|
111
132
|
await self._finalize_segment()
|
|
112
133
|
return self._total_text
|
|
113
134
|
finally:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
135
|
+
for task in (pump, typing):
|
|
136
|
+
if task is not None:
|
|
137
|
+
task.cancel()
|
|
138
|
+
try:
|
|
139
|
+
await task
|
|
140
|
+
except asyncio.CancelledError:
|
|
141
|
+
pass
|
|
120
142
|
await self._adapter.set_typing(self._chat_id, False)
|
|
121
|
-
|
|
143
|
+
|
|
144
|
+
async def _typing_keepalive(self) -> None:
|
|
145
|
+
"""Re-send the typing action so the indicator outlives its ~5s expiry.
|
|
146
|
+
|
|
147
|
+
Covers the silent stretches of a turn — model thinking before the
|
|
148
|
+
first chunk and long-running tool calls, where no message is sent or
|
|
149
|
+
edited. Refresh only (never hides: the ``False`` call is the
|
|
150
|
+
adapter's business); a failing adapter must not end the loop, since
|
|
151
|
+
typing is cosmetic.
|
|
152
|
+
"""
|
|
153
|
+
while True:
|
|
154
|
+
await asyncio.sleep(self._typing_refresh)
|
|
155
|
+
try:
|
|
156
|
+
await self._adapter.set_typing(self._chat_id, True)
|
|
157
|
+
except Exception: # noqa: BLE001 — typing indicators are cosmetic
|
|
158
|
+
logger.debug("gateway: typing refresh failed", exc_info=True)
|
|
122
159
|
|
|
123
160
|
# -- Reply messages (one per response segment) -------------------------
|
|
124
161
|
|
|
@@ -144,6 +181,7 @@ class TurnRenderer:
|
|
|
144
181
|
return # final-only transports send once, at the end
|
|
145
182
|
self._reply_id = await self._adapter.send_text(self._chat_id, chunks[0])
|
|
146
183
|
self._edited_text = chunks[0]
|
|
184
|
+
self._status_stale = True
|
|
147
185
|
return
|
|
148
186
|
if not final:
|
|
149
187
|
if len(chunks) > 1:
|
|
@@ -155,6 +193,7 @@ class TurnRenderer:
|
|
|
155
193
|
await self._edit_reply(chunks[0])
|
|
156
194
|
for extra in chunks[1:]:
|
|
157
195
|
await self._adapter.send_text(self._chat_id, extra)
|
|
196
|
+
self._status_stale = True
|
|
158
197
|
|
|
159
198
|
async def _edit_reply(self, text: str) -> None:
|
|
160
199
|
if text == self._edited_text:
|
|
@@ -163,39 +202,58 @@ class TurnRenderer:
|
|
|
163
202
|
await self._adapter.edit_text(self._chat_id, self._reply_id or "", text)
|
|
164
203
|
self._edited_text = text
|
|
165
204
|
|
|
166
|
-
# -- Tool
|
|
205
|
+
# -- Tool round messages ----------------------------------------------
|
|
167
206
|
|
|
168
207
|
async def _event_pump(self) -> None:
|
|
169
208
|
try:
|
|
170
209
|
while True:
|
|
171
210
|
event = await self._events.get()
|
|
172
|
-
|
|
173
|
-
if
|
|
211
|
+
record = self._line_record_for(event)
|
|
212
|
+
if record is None:
|
|
174
213
|
continue
|
|
175
|
-
self.
|
|
176
|
-
|
|
214
|
+
if self._status_stale:
|
|
215
|
+
# The newest reply bubble was sent after the current round
|
|
216
|
+
# message: open a fresh round message below it instead of
|
|
217
|
+
# appending to the stale one higher up the chat.
|
|
218
|
+
self._status_stale = False
|
|
219
|
+
self._status_id = None
|
|
220
|
+
self._status_lines = []
|
|
221
|
+
self._record_line(record)
|
|
177
222
|
await self._flush_status()
|
|
178
223
|
except asyncio.CancelledError:
|
|
179
224
|
raise
|
|
180
225
|
|
|
181
226
|
@staticmethod
|
|
182
|
-
def
|
|
227
|
+
def _line_record_for(event: AgentEvent) -> Optional[StatusLine]:
|
|
183
228
|
if event.event_type != "chat_message":
|
|
184
229
|
return None
|
|
185
230
|
message_type = event.content.get("message_type")
|
|
231
|
+
description = str(event.content.get("tool_description") or "tool")
|
|
232
|
+
call_id = str(event.content.get("tool_call_id") or "")
|
|
186
233
|
if message_type == "tool_call":
|
|
187
|
-
|
|
188
|
-
return f"⏳ {description}"
|
|
234
|
+
return ("⏳", description, call_id)
|
|
189
235
|
if message_type == "tool_result":
|
|
190
|
-
return "✅
|
|
236
|
+
return ("✅", description, call_id)
|
|
191
237
|
if message_type == "tool_error":
|
|
192
|
-
return "❌
|
|
238
|
+
return ("❌", description, call_id)
|
|
193
239
|
return None
|
|
194
240
|
|
|
241
|
+
def _record_line(self, record: StatusLine) -> None:
|
|
242
|
+
icon, _, call_id = record
|
|
243
|
+
if icon != "⏳" and call_id:
|
|
244
|
+
# A finished call replaces its pending line so the round message
|
|
245
|
+
# reads as a settled trail (⏳ bash -> ✅ bash), not an append log.
|
|
246
|
+
for index, (pending_icon, _, pending_id) in enumerate(self._status_lines):
|
|
247
|
+
if pending_icon == "⏳" and pending_id == call_id:
|
|
248
|
+
self._status_lines[index] = record
|
|
249
|
+
return
|
|
250
|
+
self._status_lines.append(record)
|
|
251
|
+
self._status_lines = self._status_lines[-MAX_STATUS_LINES:]
|
|
252
|
+
|
|
195
253
|
async def _flush_status(self) -> None:
|
|
196
254
|
if not self._status_lines:
|
|
197
255
|
return
|
|
198
|
-
text = "\n".join(self._status_lines)
|
|
256
|
+
text = "\n".join(f"{icon} {description}" for icon, description, _ in self._status_lines)
|
|
199
257
|
if text == self._status_sent_text:
|
|
200
258
|
# Line-cap truncation can make a new event's rendered text
|
|
201
259
|
# identical to the previous one; re-sending the same content is a
|
|
@@ -206,20 +264,10 @@ class TurnRenderer:
|
|
|
206
264
|
return
|
|
207
265
|
self._last_status_flush = now
|
|
208
266
|
if self._status_id is None:
|
|
209
|
-
# No
|
|
267
|
+
# No round message on transports that cannot edit it away.
|
|
210
268
|
if not self._adapter.capabilities.supports_edits:
|
|
211
269
|
return
|
|
212
270
|
self._status_id = await self._adapter.send_text(self._chat_id, text)
|
|
213
271
|
else:
|
|
214
272
|
await self._adapter.edit_text(self._chat_id, self._status_id, text)
|
|
215
273
|
self._status_sent_text = text
|
|
216
|
-
|
|
217
|
-
async def _finalize_status(self) -> None:
|
|
218
|
-
if self._status_id is None:
|
|
219
|
-
return
|
|
220
|
-
message_id, self._status_id = self._status_id, None
|
|
221
|
-
if self._adapter.capabilities.supports_delete:
|
|
222
|
-
try:
|
|
223
|
-
await self._adapter.delete_message(self._chat_id, message_id)
|
|
224
|
-
except Exception: # noqa: BLE001 — a stuck status message is cosmetic
|
|
225
|
-
logger.debug("gateway: status delete failed for chat %s", self._chat_id)
|
|
@@ -50,6 +50,34 @@ class ServiceInstallResult:
|
|
|
50
50
|
unit_path: Optional[Path] = None
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
def login_shell(platform: Optional[str] = None) -> str:
|
|
54
|
+
"""The user's login shell: ``$SHELL`` when set, else the platform default.
|
|
55
|
+
|
|
56
|
+
launchd and systemd start service programs directly, so the daemon would
|
|
57
|
+
inherit the service manager's minimal environment (launchd gives agents
|
|
58
|
+
``PATH=/usr/bin:/bin:/usr/sbin:/sbin``), which starves gateway-driven
|
|
59
|
+
agent sessions of Homebrew and other user-installed tools. The service
|
|
60
|
+
therefore launches through the user's login shell: ``-l`` runs the shell
|
|
61
|
+
profile files, so the daemon's environment matches what an interactive
|
|
62
|
+
terminal sees, and nothing is captured at install time.
|
|
63
|
+
"""
|
|
64
|
+
platform = platform if platform is not None else sys.platform
|
|
65
|
+
from_env = os.environ.get("SHELL")
|
|
66
|
+
if from_env:
|
|
67
|
+
return from_env
|
|
68
|
+
return "/bin/zsh" if platform == "darwin" else "/bin/bash"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def service_launch_command(config: GatewayConfig, executable: str, *, shell: str) -> list[str]:
|
|
72
|
+
"""The service-level argv: the login shell exec-ing the daemon.
|
|
73
|
+
|
|
74
|
+
``exec`` replaces the shell process, so termination signals reach the
|
|
75
|
+
daemon directly and launchd/KeepAlive track the real process.
|
|
76
|
+
"""
|
|
77
|
+
inner = " ".join(shlex.quote(part) for part in service_command(config, executable))
|
|
78
|
+
return [shell, "-l", "-c", f"exec {inner}"]
|
|
79
|
+
|
|
80
|
+
|
|
53
81
|
def service_command(config: GatewayConfig, executable: str) -> list[str]:
|
|
54
82
|
"""The exact argv the service runs."""
|
|
55
83
|
return [
|
|
@@ -69,6 +97,7 @@ def install_service(
|
|
|
69
97
|
config: GatewayConfig,
|
|
70
98
|
*,
|
|
71
99
|
executable: Optional[str] = None,
|
|
100
|
+
shell: Optional[str] = None,
|
|
72
101
|
systemd_dir: Optional[Path] = None,
|
|
73
102
|
launchd_dir: Optional[Path] = None,
|
|
74
103
|
platform: Optional[str] = None,
|
|
@@ -76,12 +105,16 @@ def install_service(
|
|
|
76
105
|
"""Write the service definition.
|
|
77
106
|
|
|
78
107
|
``systemd_dir``/``launchd_dir`` are the unit destination directories;
|
|
79
|
-
callers resolve the platform defaults (tests pass temp dirs).
|
|
108
|
+
callers resolve the platform defaults (tests pass temp dirs). ``shell``
|
|
109
|
+
overrides the login shell the service launches through (tests pass one
|
|
110
|
+
for determinism); by default the user's ``$SHELL`` or the platform
|
|
111
|
+
default is used.
|
|
80
112
|
"""
|
|
81
113
|
platform = platform if platform is not None else sys.platform
|
|
82
114
|
executable = executable or shutil.which("kolega-code") or ""
|
|
83
115
|
if not executable:
|
|
84
116
|
raise RuntimeError("kolega-code executable not found; is it on PATH?")
|
|
117
|
+
launch_shell = shell or login_shell(platform)
|
|
85
118
|
config.state_dir.mkdir(parents=True, exist_ok=True)
|
|
86
119
|
result = ServiceInstallResult()
|
|
87
120
|
if platform == "darwin":
|
|
@@ -90,7 +123,7 @@ def install_service(
|
|
|
90
123
|
plist_path = launchd_dir / LAUNCHD_PLIST_NAME
|
|
91
124
|
plist: dict[str, object] = {
|
|
92
125
|
"Label": LAUNCHD_LABEL,
|
|
93
|
-
"ProgramArguments":
|
|
126
|
+
"ProgramArguments": service_launch_command(config, executable, shell=launch_shell),
|
|
94
127
|
"RunAtLoad": True,
|
|
95
128
|
"KeepAlive": True,
|
|
96
129
|
"StandardOutPath": str(config.state_dir / "gateway.log"),
|
|
@@ -103,10 +136,14 @@ def install_service(
|
|
|
103
136
|
systemd_dir = systemd_dir or (Path.home() / ".config" / "systemd" / "user")
|
|
104
137
|
systemd_dir.mkdir(parents=True, exist_ok=True)
|
|
105
138
|
unit_path = systemd_dir / SYSTEMD_UNIT_NAME
|
|
106
|
-
command = " ".join(shlex.quote(part) for part in
|
|
139
|
+
command = " ".join(shlex.quote(part) for part in service_launch_command(config, executable, shell=launch_shell))
|
|
107
140
|
unit_path.write_text(_SYSTEMD_UNIT_TEMPLATE.format(command=command), encoding="utf-8")
|
|
108
141
|
result.unit_path = unit_path
|
|
109
142
|
result.notes.append(f"systemd user unit written to {unit_path}")
|
|
143
|
+
result.notes.append(
|
|
144
|
+
f"the service launches via your login shell ({launch_shell}), so it inherits your "
|
|
145
|
+
"normal terminal environment; restart it after changing your shell profile"
|
|
146
|
+
)
|
|
110
147
|
result.notes.append(
|
|
111
148
|
"the service reads settings.json from the same state dir — make sure your provider "
|
|
112
149
|
"API keys are saved in Settings (they apply to the gateway too)"
|