klaude-code 1.2.15__tar.gz → 1.2.17__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.
- {klaude_code-1.2.15 → klaude_code-1.2.17}/PKG-INFO +114 -22
- {klaude_code-1.2.15 → klaude_code-1.2.17}/README.md +112 -21
- {klaude_code-1.2.15 → klaude_code-1.2.17}/pyproject.toml +2 -1
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/cli/main.py +66 -42
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/cli/runtime.py +34 -13
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/__init__.py +3 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/export_cmd.py +2 -2
- klaude_code-1.2.17/src/klaude_code/command/export_online_cmd.py +149 -0
- klaude_code-1.2.17/src/klaude_code/command/prompt-handoff.md +33 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/thinking_cmd.py +5 -1
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/config/config.py +20 -21
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/config/list_model.py +1 -1
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/const/__init__.py +3 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/executor.py +2 -2
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/manager/llm_clients_builder.py +1 -1
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/manager/sub_agent_manager.py +30 -6
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/prompt.py +15 -13
- klaude_code-1.2.15/src/klaude_code/core/prompts/prompt-subagent-explore.md → klaude_code-1.2.17/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -1
- klaude_code-1.2.15/src/klaude_code/core/prompts/prompt-subagent-oracle.md → klaude_code-1.2.17/src/klaude_code/core/prompts/prompt-sub-agent-oracle.md +1 -2
- klaude_code-1.2.17/src/klaude_code/core/prompts/prompt-sub-agent-web.md +48 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/reminders.py +75 -32
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/task.py +18 -22
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/__init__.py +4 -0
- klaude_code-1.2.17/src/klaude_code/core/tool/report_back_tool.py +84 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/sub_agent_tool.py +6 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/tool_runner.py +9 -1
- klaude_code-1.2.17/src/klaude_code/core/tool/web/web_search_tool.md +23 -0
- klaude_code-1.2.17/src/klaude_code/core/tool/web/web_search_tool.py +126 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/turn.py +45 -4
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/anthropic/input.py +14 -5
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/openrouter/input.py +14 -3
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/responses/input.py +19 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/protocol/commands.py +1 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/protocol/events.py +9 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/protocol/model.py +24 -14
- klaude_code-1.2.17/src/klaude_code/protocol/sub_agent/__init__.py +117 -0
- klaude_code-1.2.17/src/klaude_code/protocol/sub_agent/explore.py +63 -0
- klaude_code-1.2.17/src/klaude_code/protocol/sub_agent/oracle.py +91 -0
- klaude_code-1.2.17/src/klaude_code/protocol/sub_agent/task.py +61 -0
- klaude_code-1.2.17/src/klaude_code/protocol/sub_agent/web.py +78 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/protocol/tools.py +2 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/session/export.py +12 -6
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/session/session.py +12 -2
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/session/templates/export_session.html +111 -36
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/completers.py +1 -1
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/event_handler.py +65 -8
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/renderer.py +11 -9
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/developer.py +18 -7
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/metadata.py +24 -12
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/sub_agent.py +63 -3
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/thinking.py +1 -1
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/tools.py +24 -37
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/rich/markdown.py +20 -48
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/rich/status.py +61 -17
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/rich/theme.py +8 -7
- klaude_code-1.2.15/src/klaude_code/core/prompts/prompt-subagent-webfetch.md +0 -46
- klaude_code-1.2.15/src/klaude_code/protocol/sub_agent.py +0 -354
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/auth/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/auth/codex/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/auth/codex/exceptions.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/auth/codex/oauth.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/auth/codex/token_manager.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/cli/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/cli/auth_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/cli/config_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/cli/debug.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/cli/session_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/clear_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/command_abc.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/diff_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/help_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/model_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/prompt-deslop.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/prompt-dev-docs-update.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/prompt-dev-docs.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/prompt-init.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/prompt_command.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/refresh_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/registry.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/release_notes_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/status_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/command/terminal_setup_cmd.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/config/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/config/select_model.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/agent.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/manager/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/manager/agent_manager.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/manager/llm_clients.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
- /klaude_code-1.2.15/src/klaude_code/core/prompts/prompt-subagent.md → /klaude_code-1.2.17/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/_utils.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/multi_edit_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/multi_edit_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/read_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/read_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/write_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/write_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/memory_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/memory_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/skill_loader.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/skill_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/skill_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/shell/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/shell/bash_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/tool_abc.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/tool_context.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/tool_registry.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/truncation.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/web_fetch_tool.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/anthropic/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/anthropic/client.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/client.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/codex/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/codex/client.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/input_common.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/client.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/input.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/stream_processor.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/openrouter/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/openrouter/client.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/openrouter/reasoning_handler.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/registry.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/responses/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/responses/client.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/llm/usage.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/protocol/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/protocol/llm_param.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/protocol/op.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/protocol/op_handler.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/session/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/session/selector.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/trace/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/trace/log.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/core/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/core/display.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/core/input.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/core/stage_manager.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/debug/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/debug/display.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/exec/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/exec/display.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/clipboard.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/display.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/input_prompt_toolkit.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/key_bindings.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/assistant.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/common.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/diffs.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/errors.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/user_input.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/rich/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/rich/live.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/rich/quote.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/rich/searchable_text.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/color.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/control.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/notifier.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/progress_bar.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/utils/__init__.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/utils/common.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/ui/utils/debouncer.py +0 -0
- {klaude_code-1.2.15 → klaude_code-1.2.17}/src/klaude_code/version.py +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: klaude-code
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.17
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Requires-Dist: anthropic>=0.66.0
|
|
6
|
+
Requires-Dist: ddgs>=9.9.3
|
|
6
7
|
Requires-Dist: openai>=1.102.0
|
|
7
8
|
Requires-Dist: pillow>=12.0.0
|
|
8
9
|
Requires-Dist: prompt-toolkit>=3.0.52
|
|
@@ -22,6 +23,7 @@ An minimal and opinionated code agent with multi-model support.
|
|
|
22
23
|
## Key Features
|
|
23
24
|
- **Adaptive Tooling**: Model-aware toolsets (Claude Code tools for Sonnet, Codex `apply_patch` for GPT-5.1/Codex).
|
|
24
25
|
- **Multi-Provider Support**: Compatible with `anthropic-messages-api`,`openai-responses-api`, and `openai-compatible-api`(`openrouter-api`), featuring interleaved thinking, OpenRouter's provider sorting etc.
|
|
26
|
+
- **Structured Sub-Agent Output**: Main agent defines output JSON schema for sub-agents; sub-agents use `report_back` tool with constrained decoding to return schema-compliant structured data.
|
|
25
27
|
- **Skill System**: Extensible support for loading Claude Skills.
|
|
26
28
|
- **Session Management**: Robust context preservation with resumable sessions (`--continue`).
|
|
27
29
|
- **Simple TUI**: Clean interface offering full visibility into model responses, reasoning and actions.
|
|
@@ -70,47 +72,137 @@ Open the configuration file in editor:
|
|
|
70
72
|
klaude config
|
|
71
73
|
```
|
|
72
74
|
|
|
73
|
-
An
|
|
75
|
+
An example config yaml:
|
|
74
76
|
|
|
75
77
|
```yaml
|
|
76
78
|
provider_list:
|
|
77
|
-
- provider_name: openrouter
|
|
79
|
+
- provider_name: openrouter
|
|
78
80
|
protocol: openrouter # support <responses|openrouter|anthropic|openai>
|
|
79
81
|
api_key: <your-openrouter-api-key>
|
|
82
|
+
|
|
83
|
+
- provider_name: openai-responses
|
|
84
|
+
protocol: responses
|
|
85
|
+
api_key: <your-openai-api-key>
|
|
86
|
+
|
|
87
|
+
- provider_name: anthropic
|
|
88
|
+
protocol: anthropic
|
|
89
|
+
api_key: <your-anthropic-api-key>
|
|
90
|
+
|
|
91
|
+
- provider_name: moonshot
|
|
92
|
+
protocol: anthropic
|
|
93
|
+
base_url: https://api.moonshot.cn/anthropic
|
|
94
|
+
api_key: <your-api-key>
|
|
95
|
+
|
|
96
|
+
- provider_name: deepseek
|
|
97
|
+
protocol: anthropic
|
|
98
|
+
base_url: https://api.deepseek.com/anthropic
|
|
99
|
+
api_key: <your-api-key>
|
|
100
|
+
|
|
80
101
|
model_list:
|
|
81
|
-
|
|
82
|
-
|
|
102
|
+
|
|
103
|
+
- model_name: deepseek
|
|
104
|
+
provider: deepseek
|
|
105
|
+
model_params:
|
|
106
|
+
model: deepseek-reasoner
|
|
107
|
+
context_limit: 128000
|
|
108
|
+
thinking:
|
|
109
|
+
type: enabled
|
|
110
|
+
budget_tokens: 8192
|
|
111
|
+
cost:
|
|
112
|
+
currency: CNY
|
|
113
|
+
input: 2
|
|
114
|
+
output: 3
|
|
115
|
+
cache_read: 0.2
|
|
116
|
+
|
|
117
|
+
- model_name: codex-max
|
|
118
|
+
provider: openai-responses
|
|
83
119
|
model_params:
|
|
84
|
-
model:
|
|
85
|
-
context_limit: 368000
|
|
120
|
+
model: gpt-5.1-codex-max
|
|
86
121
|
thinking:
|
|
87
122
|
reasoning_effort: medium
|
|
88
|
-
|
|
123
|
+
context_limit: 400000
|
|
124
|
+
max_tokens: 128000
|
|
125
|
+
cost:
|
|
126
|
+
input: 1.25
|
|
127
|
+
output: 10
|
|
128
|
+
cache_read: 0.13
|
|
129
|
+
|
|
130
|
+
- model_name: gpt-5.1
|
|
89
131
|
provider: openrouter
|
|
90
132
|
model_params:
|
|
91
133
|
model: openai/gpt-5.1
|
|
92
|
-
context_limit:
|
|
134
|
+
context_limit: 400000
|
|
135
|
+
max_tokens: 128000
|
|
136
|
+
verbosity: high
|
|
93
137
|
thinking:
|
|
94
138
|
reasoning_effort: high
|
|
95
|
-
|
|
139
|
+
cost:
|
|
140
|
+
input: 1.25
|
|
141
|
+
output: 10
|
|
142
|
+
cache_read: 0.13
|
|
143
|
+
|
|
144
|
+
- model_name: kimi@moonshot
|
|
145
|
+
provider: moonshot
|
|
146
|
+
model_params:
|
|
147
|
+
model: kimi-k2-thinking
|
|
148
|
+
context_limit: 262144
|
|
149
|
+
thinking:
|
|
150
|
+
type: enabled
|
|
151
|
+
budget_tokens: 8192
|
|
152
|
+
cost:
|
|
153
|
+
currency: CNY
|
|
154
|
+
input: 4
|
|
155
|
+
output: 16
|
|
156
|
+
cache_read: 1
|
|
157
|
+
|
|
158
|
+
- model_name: opus
|
|
96
159
|
provider: openrouter
|
|
97
160
|
model_params:
|
|
98
|
-
model: anthropic/claude-4.5-
|
|
99
|
-
context_limit:
|
|
161
|
+
model: anthropic/claude-4.5-opus
|
|
162
|
+
context_limit: 200000
|
|
100
163
|
provider_routing:
|
|
101
|
-
|
|
102
|
-
|
|
164
|
+
only: [ google-vertex ]
|
|
165
|
+
verbosity: high
|
|
166
|
+
thinking:
|
|
167
|
+
type: enabled
|
|
168
|
+
budget_tokens: 31999
|
|
169
|
+
cost:
|
|
170
|
+
input: 5
|
|
171
|
+
output: 25
|
|
172
|
+
cache_read: 0.5
|
|
173
|
+
cache_write: 6.25
|
|
174
|
+
|
|
175
|
+
- model_name: gemini
|
|
103
176
|
provider: openrouter
|
|
104
177
|
model_params:
|
|
105
|
-
model:
|
|
106
|
-
context_limit:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
178
|
+
model: google/gemini-3-pro-preview
|
|
179
|
+
context_limit: 1048576
|
|
180
|
+
thinking:
|
|
181
|
+
reasoning_effort: medium
|
|
182
|
+
cost:
|
|
183
|
+
input: 2
|
|
184
|
+
output: 12
|
|
185
|
+
cache_read: 0.2
|
|
186
|
+
|
|
187
|
+
- model_name: haiku
|
|
188
|
+
provider: anthropic
|
|
189
|
+
model_params:
|
|
190
|
+
model: claude-haiku-4-5-20251001
|
|
191
|
+
context_limit: 200000
|
|
192
|
+
cost:
|
|
193
|
+
input: 1
|
|
194
|
+
output: 5
|
|
195
|
+
cache_read: 0.1
|
|
196
|
+
cache_write: 1.25
|
|
197
|
+
|
|
198
|
+
main_model: opus
|
|
199
|
+
|
|
200
|
+
sub_agent_models:
|
|
201
|
+
oracle: gpt-5.1
|
|
112
202
|
explore: haiku
|
|
113
|
-
task:
|
|
203
|
+
task: opus
|
|
204
|
+
webfetchagent: haiku
|
|
205
|
+
|
|
114
206
|
```
|
|
115
207
|
|
|
116
208
|
List configured providers and models:
|
|
@@ -5,6 +5,7 @@ An minimal and opinionated code agent with multi-model support.
|
|
|
5
5
|
## Key Features
|
|
6
6
|
- **Adaptive Tooling**: Model-aware toolsets (Claude Code tools for Sonnet, Codex `apply_patch` for GPT-5.1/Codex).
|
|
7
7
|
- **Multi-Provider Support**: Compatible with `anthropic-messages-api`,`openai-responses-api`, and `openai-compatible-api`(`openrouter-api`), featuring interleaved thinking, OpenRouter's provider sorting etc.
|
|
8
|
+
- **Structured Sub-Agent Output**: Main agent defines output JSON schema for sub-agents; sub-agents use `report_back` tool with constrained decoding to return schema-compliant structured data.
|
|
8
9
|
- **Skill System**: Extensible support for loading Claude Skills.
|
|
9
10
|
- **Session Management**: Robust context preservation with resumable sessions (`--continue`).
|
|
10
11
|
- **Simple TUI**: Clean interface offering full visibility into model responses, reasoning and actions.
|
|
@@ -53,47 +54,137 @@ Open the configuration file in editor:
|
|
|
53
54
|
klaude config
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
An
|
|
57
|
+
An example config yaml:
|
|
57
58
|
|
|
58
59
|
```yaml
|
|
59
60
|
provider_list:
|
|
60
|
-
- provider_name: openrouter
|
|
61
|
+
- provider_name: openrouter
|
|
61
62
|
protocol: openrouter # support <responses|openrouter|anthropic|openai>
|
|
62
63
|
api_key: <your-openrouter-api-key>
|
|
64
|
+
|
|
65
|
+
- provider_name: openai-responses
|
|
66
|
+
protocol: responses
|
|
67
|
+
api_key: <your-openai-api-key>
|
|
68
|
+
|
|
69
|
+
- provider_name: anthropic
|
|
70
|
+
protocol: anthropic
|
|
71
|
+
api_key: <your-anthropic-api-key>
|
|
72
|
+
|
|
73
|
+
- provider_name: moonshot
|
|
74
|
+
protocol: anthropic
|
|
75
|
+
base_url: https://api.moonshot.cn/anthropic
|
|
76
|
+
api_key: <your-api-key>
|
|
77
|
+
|
|
78
|
+
- provider_name: deepseek
|
|
79
|
+
protocol: anthropic
|
|
80
|
+
base_url: https://api.deepseek.com/anthropic
|
|
81
|
+
api_key: <your-api-key>
|
|
82
|
+
|
|
63
83
|
model_list:
|
|
64
|
-
|
|
65
|
-
|
|
84
|
+
|
|
85
|
+
- model_name: deepseek
|
|
86
|
+
provider: deepseek
|
|
87
|
+
model_params:
|
|
88
|
+
model: deepseek-reasoner
|
|
89
|
+
context_limit: 128000
|
|
90
|
+
thinking:
|
|
91
|
+
type: enabled
|
|
92
|
+
budget_tokens: 8192
|
|
93
|
+
cost:
|
|
94
|
+
currency: CNY
|
|
95
|
+
input: 2
|
|
96
|
+
output: 3
|
|
97
|
+
cache_read: 0.2
|
|
98
|
+
|
|
99
|
+
- model_name: codex-max
|
|
100
|
+
provider: openai-responses
|
|
66
101
|
model_params:
|
|
67
|
-
model:
|
|
68
|
-
context_limit: 368000
|
|
102
|
+
model: gpt-5.1-codex-max
|
|
69
103
|
thinking:
|
|
70
104
|
reasoning_effort: medium
|
|
71
|
-
|
|
105
|
+
context_limit: 400000
|
|
106
|
+
max_tokens: 128000
|
|
107
|
+
cost:
|
|
108
|
+
input: 1.25
|
|
109
|
+
output: 10
|
|
110
|
+
cache_read: 0.13
|
|
111
|
+
|
|
112
|
+
- model_name: gpt-5.1
|
|
72
113
|
provider: openrouter
|
|
73
114
|
model_params:
|
|
74
115
|
model: openai/gpt-5.1
|
|
75
|
-
context_limit:
|
|
116
|
+
context_limit: 400000
|
|
117
|
+
max_tokens: 128000
|
|
118
|
+
verbosity: high
|
|
76
119
|
thinking:
|
|
77
120
|
reasoning_effort: high
|
|
78
|
-
|
|
121
|
+
cost:
|
|
122
|
+
input: 1.25
|
|
123
|
+
output: 10
|
|
124
|
+
cache_read: 0.13
|
|
125
|
+
|
|
126
|
+
- model_name: kimi@moonshot
|
|
127
|
+
provider: moonshot
|
|
128
|
+
model_params:
|
|
129
|
+
model: kimi-k2-thinking
|
|
130
|
+
context_limit: 262144
|
|
131
|
+
thinking:
|
|
132
|
+
type: enabled
|
|
133
|
+
budget_tokens: 8192
|
|
134
|
+
cost:
|
|
135
|
+
currency: CNY
|
|
136
|
+
input: 4
|
|
137
|
+
output: 16
|
|
138
|
+
cache_read: 1
|
|
139
|
+
|
|
140
|
+
- model_name: opus
|
|
79
141
|
provider: openrouter
|
|
80
142
|
model_params:
|
|
81
|
-
model: anthropic/claude-4.5-
|
|
82
|
-
context_limit:
|
|
143
|
+
model: anthropic/claude-4.5-opus
|
|
144
|
+
context_limit: 200000
|
|
83
145
|
provider_routing:
|
|
84
|
-
|
|
85
|
-
|
|
146
|
+
only: [ google-vertex ]
|
|
147
|
+
verbosity: high
|
|
148
|
+
thinking:
|
|
149
|
+
type: enabled
|
|
150
|
+
budget_tokens: 31999
|
|
151
|
+
cost:
|
|
152
|
+
input: 5
|
|
153
|
+
output: 25
|
|
154
|
+
cache_read: 0.5
|
|
155
|
+
cache_write: 6.25
|
|
156
|
+
|
|
157
|
+
- model_name: gemini
|
|
86
158
|
provider: openrouter
|
|
87
159
|
model_params:
|
|
88
|
-
model:
|
|
89
|
-
context_limit:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
160
|
+
model: google/gemini-3-pro-preview
|
|
161
|
+
context_limit: 1048576
|
|
162
|
+
thinking:
|
|
163
|
+
reasoning_effort: medium
|
|
164
|
+
cost:
|
|
165
|
+
input: 2
|
|
166
|
+
output: 12
|
|
167
|
+
cache_read: 0.2
|
|
168
|
+
|
|
169
|
+
- model_name: haiku
|
|
170
|
+
provider: anthropic
|
|
171
|
+
model_params:
|
|
172
|
+
model: claude-haiku-4-5-20251001
|
|
173
|
+
context_limit: 200000
|
|
174
|
+
cost:
|
|
175
|
+
input: 1
|
|
176
|
+
output: 5
|
|
177
|
+
cache_read: 0.1
|
|
178
|
+
cache_write: 1.25
|
|
179
|
+
|
|
180
|
+
main_model: opus
|
|
181
|
+
|
|
182
|
+
sub_agent_models:
|
|
183
|
+
oracle: gpt-5.1
|
|
95
184
|
explore: haiku
|
|
96
|
-
task:
|
|
185
|
+
task: opus
|
|
186
|
+
webfetchagent: haiku
|
|
187
|
+
|
|
97
188
|
```
|
|
98
189
|
|
|
99
190
|
List configured providers and models:
|
|
@@ -4,12 +4,13 @@ build-backend = "uv_build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "klaude-code"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.17"
|
|
8
8
|
description = "Add your description here"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13"
|
|
11
11
|
dependencies = [
|
|
12
12
|
"anthropic>=0.66.0",
|
|
13
|
+
"ddgs>=9.9.3",
|
|
13
14
|
"openai>=1.102.0",
|
|
14
15
|
"pillow>=12.0.0",
|
|
15
16
|
"prompt-toolkit>=3.0.52",
|
|
@@ -13,7 +13,7 @@ from klaude_code.cli.debug import DEBUG_FILTER_HELP, open_log_file_in_editor, re
|
|
|
13
13
|
from klaude_code.cli.session_cmd import register_session_commands
|
|
14
14
|
from klaude_code.config import load_config
|
|
15
15
|
from klaude_code.session import Session, resume_select_session
|
|
16
|
-
from klaude_code.trace import prepare_debug_log_file
|
|
16
|
+
from klaude_code.trace import DebugType, prepare_debug_log_file
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def set_terminal_title(title: str) -> None:
|
|
@@ -22,6 +22,63 @@ def set_terminal_title(title: str) -> None:
|
|
|
22
22
|
sys.stdout.flush()
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
def setup_terminal_title() -> None:
|
|
26
|
+
"""Set terminal title to current folder name."""
|
|
27
|
+
folder_name = os.path.basename(os.getcwd())
|
|
28
|
+
set_terminal_title(f"{folder_name}: klaude")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def prepare_debug_logging(debug: bool, debug_filter: str | None) -> tuple[bool, set[DebugType] | None, Path | None]:
|
|
32
|
+
"""Resolve debug settings and prepare log file if debugging is enabled.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
A tuple of (debug_enabled, debug_filters, log_path).
|
|
36
|
+
log_path is None if debugging is disabled.
|
|
37
|
+
"""
|
|
38
|
+
debug_enabled, debug_filters = resolve_debug_settings(debug, debug_filter)
|
|
39
|
+
log_path: Path | None = None
|
|
40
|
+
if debug_enabled:
|
|
41
|
+
log_path = prepare_debug_log_file()
|
|
42
|
+
return debug_enabled, debug_filters, log_path
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def read_input_content(cli_argument: str) -> str | None:
|
|
46
|
+
"""Read and merge input from stdin and CLI argument.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
cli_argument: The input content passed as CLI argument.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
The merged input content, or None if no input was provided.
|
|
53
|
+
"""
|
|
54
|
+
from klaude_code.trace import log
|
|
55
|
+
|
|
56
|
+
parts: list[str] = []
|
|
57
|
+
|
|
58
|
+
# Handle stdin input
|
|
59
|
+
if not sys.stdin.isatty():
|
|
60
|
+
try:
|
|
61
|
+
stdin = sys.stdin.read().rstrip("\n")
|
|
62
|
+
if stdin:
|
|
63
|
+
parts.append(stdin)
|
|
64
|
+
except (OSError, ValueError) as e:
|
|
65
|
+
# Expected I/O-related errors when reading from stdin (e.g. broken pipe, closed stream).
|
|
66
|
+
log((f"Error reading from stdin: {e}", "red"))
|
|
67
|
+
except Exception as e:
|
|
68
|
+
# Unexpected errors are still reported but kept from crashing the CLI.
|
|
69
|
+
log((f"Unexpected error reading from stdin: {e}", "red"))
|
|
70
|
+
|
|
71
|
+
if cli_argument:
|
|
72
|
+
parts.append(cli_argument)
|
|
73
|
+
|
|
74
|
+
content = "\n".join(parts)
|
|
75
|
+
if len(content) == 0:
|
|
76
|
+
log(("Error: No input content provided", "red"))
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
return content
|
|
80
|
+
|
|
81
|
+
|
|
25
82
|
def _version_callback(value: bool) -> None:
|
|
26
83
|
"""Show version and exit."""
|
|
27
84
|
if value:
|
|
@@ -90,33 +147,10 @@ def exec_command(
|
|
|
90
147
|
),
|
|
91
148
|
) -> None:
|
|
92
149
|
"""Execute non-interactively with provided input."""
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
# Set terminal title with current folder name
|
|
96
|
-
folder_name = os.path.basename(os.getcwd())
|
|
97
|
-
set_terminal_title(f"{folder_name}: klaude")
|
|
98
|
-
|
|
99
|
-
parts: list[str] = []
|
|
150
|
+
setup_terminal_title()
|
|
100
151
|
|
|
101
|
-
|
|
102
|
-
if
|
|
103
|
-
try:
|
|
104
|
-
stdin = sys.stdin.read().rstrip("\n")
|
|
105
|
-
if stdin:
|
|
106
|
-
parts.append(stdin)
|
|
107
|
-
except (OSError, ValueError) as e:
|
|
108
|
-
# Expected I/O-related errors when reading from stdin (e.g. broken pipe, closed stream).
|
|
109
|
-
log((f"Error reading from stdin: {e}", "red"))
|
|
110
|
-
except Exception as e:
|
|
111
|
-
# Unexpected errors are still reported but kept from crashing the CLI.
|
|
112
|
-
log((f"Unexpected error reading from stdin: {e}", "red"))
|
|
113
|
-
|
|
114
|
-
if input_content:
|
|
115
|
-
parts.append(input_content)
|
|
116
|
-
|
|
117
|
-
input_content = "\n".join(parts)
|
|
118
|
-
if len(input_content) == 0:
|
|
119
|
-
log(("Error: No input content provided", "red"))
|
|
152
|
+
merged_input = read_input_content(input_content)
|
|
153
|
+
if merged_input is None:
|
|
120
154
|
raise typer.Exit(1)
|
|
121
155
|
|
|
122
156
|
from klaude_code.cli.runtime import AppInitConfig, run_exec
|
|
@@ -133,11 +167,7 @@ def exec_command(
|
|
|
133
167
|
if chosen_model is None:
|
|
134
168
|
return
|
|
135
169
|
|
|
136
|
-
debug_enabled, debug_filters =
|
|
137
|
-
|
|
138
|
-
log_path: Path | None = None
|
|
139
|
-
if debug_enabled:
|
|
140
|
-
log_path = prepare_debug_log_file()
|
|
170
|
+
debug_enabled, debug_filters, log_path = prepare_debug_logging(debug, debug_filter)
|
|
141
171
|
|
|
142
172
|
init_config = AppInitConfig(
|
|
143
173
|
model=chosen_model,
|
|
@@ -154,7 +184,7 @@ def exec_command(
|
|
|
154
184
|
asyncio.run(
|
|
155
185
|
run_exec(
|
|
156
186
|
init_config=init_config,
|
|
157
|
-
input_content=
|
|
187
|
+
input_content=merged_input,
|
|
158
188
|
)
|
|
159
189
|
)
|
|
160
190
|
|
|
@@ -210,10 +240,8 @@ def main_callback(
|
|
|
210
240
|
from klaude_code.cli.runtime import AppInitConfig, run_interactive
|
|
211
241
|
from klaude_code.config.select_model import select_model_from_config
|
|
212
242
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
set_terminal_title(f"{folder_name}: klaude")
|
|
216
|
-
# Interactive mode
|
|
243
|
+
setup_terminal_title()
|
|
244
|
+
|
|
217
245
|
chosen_model = model
|
|
218
246
|
if select_model:
|
|
219
247
|
chosen_model = select_model_from_config(preferred=model)
|
|
@@ -232,11 +260,7 @@ def main_callback(
|
|
|
232
260
|
session_id = Session.most_recent_session_id()
|
|
233
261
|
# If still no session_id, leave as None to create a new session
|
|
234
262
|
|
|
235
|
-
debug_enabled, debug_filters =
|
|
236
|
-
|
|
237
|
-
log_path: Path | None = None
|
|
238
|
-
if debug_enabled:
|
|
239
|
-
log_path = prepare_debug_log_file()
|
|
263
|
+
debug_enabled, debug_filters, log_path = prepare_debug_logging(debug, debug_filter)
|
|
240
264
|
|
|
241
265
|
init_config = AppInitConfig(
|
|
242
266
|
model=chosen_model,
|
|
@@ -127,6 +127,28 @@ async def initialize_app_components(init_config: AppInitConfig) -> AppComponents
|
|
|
127
127
|
)
|
|
128
128
|
|
|
129
129
|
|
|
130
|
+
async def initialize_session(
|
|
131
|
+
executor: Executor,
|
|
132
|
+
event_queue: asyncio.Queue[events.Event],
|
|
133
|
+
session_id: str | None = None,
|
|
134
|
+
) -> str | None:
|
|
135
|
+
"""Initialize a session and return the active session ID.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
executor: The executor to submit operations to.
|
|
139
|
+
event_queue: The event queue for synchronization.
|
|
140
|
+
session_id: Optional session ID to resume. If None, creates a new session.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
The active session ID, or None if no session is active.
|
|
144
|
+
"""
|
|
145
|
+
await executor.submit_and_wait(op.InitAgentOperation(session_id=session_id))
|
|
146
|
+
await event_queue.join()
|
|
147
|
+
|
|
148
|
+
active_session_ids = executor.context.agent_manager.active_session_ids()
|
|
149
|
+
return active_session_ids[0] if active_session_ids else session_id
|
|
150
|
+
|
|
151
|
+
|
|
130
152
|
async def cleanup_app_components(components: AppComponents) -> None:
|
|
131
153
|
"""Clean up all application components."""
|
|
132
154
|
try:
|
|
@@ -167,13 +189,7 @@ async def run_exec(init_config: AppInitConfig, input_content: str) -> None:
|
|
|
167
189
|
components = await initialize_app_components(init_config)
|
|
168
190
|
|
|
169
191
|
try:
|
|
170
|
-
|
|
171
|
-
await components.executor.submit_and_wait(op.InitAgentOperation())
|
|
172
|
-
await components.event_queue.join()
|
|
173
|
-
|
|
174
|
-
# Get the session_id from the newly created agent
|
|
175
|
-
session_ids = components.executor.context.agent_manager.active_session_ids()
|
|
176
|
-
session_id = session_ids[0] if session_ids else None
|
|
192
|
+
session_id = await initialize_session(components.executor, components.event_queue)
|
|
177
193
|
|
|
178
194
|
# Submit the input content directly
|
|
179
195
|
await components.executor.submit_and_wait(
|
|
@@ -245,12 +261,15 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
|
|
|
245
261
|
restore_sigint = install_sigint_double_press_exit(_show_toast_once, _hide_progress)
|
|
246
262
|
|
|
247
263
|
try:
|
|
248
|
-
await components.executor.
|
|
249
|
-
|
|
264
|
+
await initialize_session(components.executor, components.event_queue, session_id=session_id)
|
|
265
|
+
|
|
266
|
+
def _get_active_session_id() -> str | None:
|
|
267
|
+
"""Get the current active session ID dynamically.
|
|
250
268
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
269
|
+
This is necessary because /clear command creates a new session with a different ID.
|
|
270
|
+
"""
|
|
271
|
+
active_ids = components.executor.context.agent_manager.active_session_ids()
|
|
272
|
+
return active_ids[0] if active_ids else None
|
|
254
273
|
|
|
255
274
|
# Input
|
|
256
275
|
await input_provider.start()
|
|
@@ -261,6 +280,8 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
|
|
|
261
280
|
elif user_input.text.strip() == "":
|
|
262
281
|
continue
|
|
263
282
|
# Submit user input operation - directly use the payload from iter_inputs
|
|
283
|
+
# Use dynamic session_id lookup to handle /clear creating new sessions
|
|
284
|
+
active_session_id = _get_active_session_id()
|
|
264
285
|
submission_id = await components.executor.submit(
|
|
265
286
|
op.UserInputOperation(input=user_input, session_id=active_session_id)
|
|
266
287
|
)
|
|
@@ -271,7 +292,7 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
|
|
|
271
292
|
else:
|
|
272
293
|
# Esc monitor for long-running, interruptible operations
|
|
273
294
|
async def _on_esc_interrupt() -> None:
|
|
274
|
-
await components.executor.submit(op.InterruptOperation(target_session_id=
|
|
295
|
+
await components.executor.submit(op.InterruptOperation(target_session_id=_get_active_session_id()))
|
|
275
296
|
|
|
276
297
|
stop_event, esc_task = start_esc_interrupt_monitor(_on_esc_interrupt)
|
|
277
298
|
# Wait for this specific task to complete before accepting next input
|
|
@@ -30,6 +30,7 @@ def ensure_commands_loaded() -> None:
|
|
|
30
30
|
from .clear_cmd import ClearCommand
|
|
31
31
|
from .diff_cmd import DiffCommand
|
|
32
32
|
from .export_cmd import ExportCommand
|
|
33
|
+
from .export_online_cmd import ExportOnlineCommand
|
|
33
34
|
from .help_cmd import HelpCommand
|
|
34
35
|
from .model_cmd import ModelCommand
|
|
35
36
|
from .refresh_cmd import RefreshTerminalCommand
|
|
@@ -40,6 +41,7 @@ def ensure_commands_loaded() -> None:
|
|
|
40
41
|
|
|
41
42
|
# Register in desired display order
|
|
42
43
|
register(ExportCommand())
|
|
44
|
+
register(ExportOnlineCommand())
|
|
43
45
|
register(RefreshTerminalCommand())
|
|
44
46
|
register(ThinkingCommand())
|
|
45
47
|
register(ModelCommand())
|
|
@@ -60,6 +62,7 @@ def __getattr__(name: str) -> object:
|
|
|
60
62
|
"ClearCommand": "clear_cmd",
|
|
61
63
|
"DiffCommand": "diff_cmd",
|
|
62
64
|
"ExportCommand": "export_cmd",
|
|
65
|
+
"ExportOnlineCommand": "export_online_cmd",
|
|
63
66
|
"HelpCommand": "help_cmd",
|
|
64
67
|
"ModelCommand": "model_cmd",
|
|
65
68
|
"RefreshTerminalCommand": "refresh_cmd",
|
|
@@ -25,7 +25,7 @@ class ExportCommand(CommandABC):
|
|
|
25
25
|
|
|
26
26
|
@property
|
|
27
27
|
def support_addition_params(self) -> bool:
|
|
28
|
-
return
|
|
28
|
+
return False
|
|
29
29
|
|
|
30
30
|
@property
|
|
31
31
|
def is_interactive(self) -> bool:
|
|
@@ -33,7 +33,7 @@ class ExportCommand(CommandABC):
|
|
|
33
33
|
|
|
34
34
|
async def run(self, raw: str, agent: Agent) -> CommandResult:
|
|
35
35
|
try:
|
|
36
|
-
output_path = self._resolve_output_path(
|
|
36
|
+
output_path = self._resolve_output_path("", agent)
|
|
37
37
|
html_doc = self._build_html(agent)
|
|
38
38
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
39
39
|
output_path.write_text(html_doc, encoding="utf-8")
|