klaude-code 1.2.16__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.
Files changed (196) hide show
  1. {klaude_code-1.2.16 → klaude_code-1.2.17}/PKG-INFO +112 -21
  2. {klaude_code-1.2.16 → klaude_code-1.2.17}/README.md +110 -20
  3. {klaude_code-1.2.16 → klaude_code-1.2.17}/pyproject.toml +2 -1
  4. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/cli/runtime.py +12 -2
  5. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/__init__.py +3 -0
  6. klaude_code-1.2.17/src/klaude_code/command/export_online_cmd.py +149 -0
  7. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/config/config.py +16 -17
  8. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/manager/sub_agent_manager.py +1 -1
  9. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-sub-agent-oracle.md +0 -1
  10. klaude_code-1.2.17/src/klaude_code/core/prompts/prompt-sub-agent-web.md +48 -0
  11. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/task.py +8 -0
  12. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/__init__.py +2 -0
  13. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/report_back_tool.py +28 -2
  14. klaude_code-1.2.17/src/klaude_code/core/tool/web/web_search_tool.md +23 -0
  15. klaude_code-1.2.17/src/klaude_code/core/tool/web/web_search_tool.py +126 -0
  16. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/commands.py +1 -0
  17. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/events.py +8 -0
  18. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/sub_agent/__init__.py +1 -1
  19. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/sub_agent/explore.py +1 -1
  20. klaude_code-1.2.17/src/klaude_code/protocol/sub_agent/web.py +78 -0
  21. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/tools.py +1 -0
  22. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/session/templates/export_session.html +99 -24
  23. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/event_handler.py +36 -9
  24. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/renderer.py +3 -3
  25. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/sub_agent.py +14 -10
  26. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/tools.py +4 -10
  27. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/rich/status.py +32 -6
  28. klaude_code-1.2.16/src/klaude_code/core/prompts/prompt-sub-agent-webfetch.md +0 -46
  29. klaude_code-1.2.16/src/klaude_code/protocol/sub_agent/web_fetch.py +0 -74
  30. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/__init__.py +0 -0
  31. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/auth/__init__.py +0 -0
  32. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/auth/codex/__init__.py +0 -0
  33. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/auth/codex/exceptions.py +0 -0
  34. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/auth/codex/jwt_utils.py +0 -0
  35. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/auth/codex/oauth.py +0 -0
  36. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/auth/codex/token_manager.py +0 -0
  37. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/cli/__init__.py +0 -0
  38. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/cli/auth_cmd.py +0 -0
  39. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/cli/config_cmd.py +0 -0
  40. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/cli/debug.py +0 -0
  41. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/cli/main.py +0 -0
  42. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/cli/session_cmd.py +0 -0
  43. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/clear_cmd.py +0 -0
  44. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/command_abc.py +0 -0
  45. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/diff_cmd.py +0 -0
  46. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/export_cmd.py +0 -0
  47. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/help_cmd.py +0 -0
  48. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/model_cmd.py +0 -0
  49. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/prompt-deslop.md +0 -0
  50. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/prompt-dev-docs-update.md +0 -0
  51. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/prompt-dev-docs.md +0 -0
  52. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/prompt-handoff.md +0 -0
  53. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/prompt-init.md +0 -0
  54. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/prompt_command.py +0 -0
  55. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/refresh_cmd.py +0 -0
  56. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/registry.py +0 -0
  57. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/release_notes_cmd.py +0 -0
  58. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/status_cmd.py +0 -0
  59. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/terminal_setup_cmd.py +0 -0
  60. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/command/thinking_cmd.py +0 -0
  61. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/config/__init__.py +0 -0
  62. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/config/list_model.py +0 -0
  63. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/config/select_model.py +0 -0
  64. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/const/__init__.py +0 -0
  65. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/__init__.py +0 -0
  66. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/agent.py +0 -0
  67. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/executor.py +0 -0
  68. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/manager/__init__.py +0 -0
  69. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/manager/agent_manager.py +0 -0
  70. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/manager/llm_clients.py +0 -0
  71. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/manager/llm_clients_builder.py +0 -0
  72. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/prompt.py +0 -0
  73. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-claude-code.md +0 -0
  74. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +0 -0
  75. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-codex-gpt-5-1.md +0 -0
  76. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-gemini.md +0 -0
  77. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-minimal.md +0 -0
  78. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-sub-agent-explore.md +0 -0
  79. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/prompts/prompt-sub-agent.md +0 -0
  80. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/reminders.py +0 -0
  81. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/__init__.py +0 -0
  82. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/_utils.py +0 -0
  83. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/apply_patch.py +0 -0
  84. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/apply_patch_tool.md +0 -0
  85. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/apply_patch_tool.py +0 -0
  86. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/edit_tool.md +0 -0
  87. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/edit_tool.py +0 -0
  88. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/multi_edit_tool.md +0 -0
  89. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/multi_edit_tool.py +0 -0
  90. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/read_tool.md +0 -0
  91. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/read_tool.py +0 -0
  92. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/write_tool.md +0 -0
  93. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/file/write_tool.py +0 -0
  94. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/__init__.py +0 -0
  95. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/memory_tool.md +0 -0
  96. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/memory_tool.py +0 -0
  97. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/skill_loader.py +0 -0
  98. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/skill_tool.md +0 -0
  99. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/memory/skill_tool.py +0 -0
  100. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/shell/__init__.py +0 -0
  101. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/shell/bash_tool.md +0 -0
  102. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/shell/bash_tool.py +0 -0
  103. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/shell/command_safety.py +0 -0
  104. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/sub_agent_tool.py +0 -0
  105. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/__init__.py +0 -0
  106. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/todo_write_tool.md +0 -0
  107. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/todo_write_tool.py +0 -0
  108. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/todo_write_tool_raw.md +0 -0
  109. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/update_plan_tool.md +0 -0
  110. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/todo/update_plan_tool.py +0 -0
  111. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/tool_abc.py +0 -0
  112. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/tool_context.py +0 -0
  113. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/tool_registry.py +0 -0
  114. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/tool_runner.py +0 -0
  115. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/truncation.py +0 -0
  116. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/__init__.py +0 -0
  117. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/mermaid_tool.md +0 -0
  118. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/mermaid_tool.py +0 -0
  119. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/web_fetch_tool.md +0 -0
  120. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/tool/web/web_fetch_tool.py +0 -0
  121. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/core/turn.py +0 -0
  122. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/__init__.py +0 -0
  123. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/anthropic/__init__.py +0 -0
  124. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/anthropic/client.py +0 -0
  125. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/anthropic/input.py +0 -0
  126. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/client.py +0 -0
  127. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/codex/__init__.py +0 -0
  128. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/codex/client.py +0 -0
  129. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/input_common.py +0 -0
  130. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/__init__.py +0 -0
  131. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/client.py +0 -0
  132. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/input.py +0 -0
  133. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/stream_processor.py +0 -0
  134. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -0
  135. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/openrouter/__init__.py +0 -0
  136. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/openrouter/client.py +0 -0
  137. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/openrouter/input.py +0 -0
  138. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/openrouter/reasoning_handler.py +0 -0
  139. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/registry.py +0 -0
  140. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/responses/__init__.py +0 -0
  141. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/responses/client.py +0 -0
  142. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/responses/input.py +0 -0
  143. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/llm/usage.py +0 -0
  144. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/__init__.py +0 -0
  145. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/llm_param.py +0 -0
  146. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/model.py +0 -0
  147. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/op.py +0 -0
  148. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/op_handler.py +0 -0
  149. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/sub_agent/oracle.py +0 -0
  150. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/protocol/sub_agent/task.py +0 -0
  151. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/session/__init__.py +0 -0
  152. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/session/export.py +0 -0
  153. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/session/selector.py +0 -0
  154. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/session/session.py +0 -0
  155. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/trace/__init__.py +0 -0
  156. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/trace/log.py +0 -0
  157. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/__init__.py +0 -0
  158. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/core/__init__.py +0 -0
  159. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/core/display.py +0 -0
  160. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/core/input.py +0 -0
  161. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/core/stage_manager.py +0 -0
  162. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/__init__.py +0 -0
  163. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/debug/__init__.py +0 -0
  164. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/debug/display.py +0 -0
  165. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/exec/__init__.py +0 -0
  166. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/exec/display.py +0 -0
  167. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/__init__.py +0 -0
  168. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/clipboard.py +0 -0
  169. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/completers.py +0 -0
  170. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/display.py +0 -0
  171. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/input_prompt_toolkit.py +0 -0
  172. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/modes/repl/key_bindings.py +0 -0
  173. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/__init__.py +0 -0
  174. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/assistant.py +0 -0
  175. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/common.py +0 -0
  176. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/developer.py +0 -0
  177. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/diffs.py +0 -0
  178. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/errors.py +0 -0
  179. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/metadata.py +0 -0
  180. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/thinking.py +0 -0
  181. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/renderers/user_input.py +0 -0
  182. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/rich/__init__.py +0 -0
  183. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/rich/live.py +0 -0
  184. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/rich/markdown.py +0 -0
  185. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/rich/quote.py +0 -0
  186. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/rich/searchable_text.py +0 -0
  187. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/rich/theme.py +0 -0
  188. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/__init__.py +0 -0
  189. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/color.py +0 -0
  190. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/control.py +0 -0
  191. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/notifier.py +0 -0
  192. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/terminal/progress_bar.py +0 -0
  193. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/utils/__init__.py +0 -0
  194. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/utils/common.py +0 -0
  195. {klaude_code-1.2.16 → klaude_code-1.2.17}/src/klaude_code/ui/utils/debouncer.py +0 -0
  196. {klaude_code-1.2.16 → 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.16
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
@@ -71,47 +72,137 @@ Open the configuration file in editor:
71
72
  klaude config
72
73
  ```
73
74
 
74
- An minimal example config yaml using OpenRouter's API Key:
75
+ An example config yaml:
75
76
 
76
77
  ```yaml
77
78
  provider_list:
78
- - provider_name: openrouter-work
79
+ - provider_name: openrouter
79
80
  protocol: openrouter # support <responses|openrouter|anthropic|openai>
80
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
+
81
101
  model_list:
82
- - model_name: gpt-5.1-codex
83
- provider: openrouter
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
84
119
  model_params:
85
- model: openai/gpt-5.1-codex
86
- context_limit: 368000
120
+ model: gpt-5.1-codex-max
87
121
  thinking:
88
122
  reasoning_effort: medium
89
- - model_name: gpt-5.1-high
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
90
131
  provider: openrouter
91
132
  model_params:
92
133
  model: openai/gpt-5.1
93
- context_limit: 368000
134
+ context_limit: 400000
135
+ max_tokens: 128000
136
+ verbosity: high
94
137
  thinking:
95
138
  reasoning_effort: high
96
- - model_name: sonnet
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
97
159
  provider: openrouter
98
160
  model_params:
99
- model: anthropic/claude-4.5-sonnet
100
- context_limit: 168000
161
+ model: anthropic/claude-4.5-opus
162
+ context_limit: 200000
101
163
  provider_routing:
102
- sort: throughput
103
- - model_name: haiku
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
104
176
  provider: openrouter
105
177
  model_params:
106
- model: anthropic/claude-haiku-4.5
107
- context_limit: 168000
108
- provider_routing:
109
- sort: throughput
110
- main_model: gpt-5.1-codex
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
+
111
200
  sub_agent_models:
112
- oracle: gpt-5.1-high
201
+ oracle: gpt-5.1
113
202
  explore: haiku
114
- task: sonnet
203
+ task: opus
204
+ webfetchagent: haiku
205
+
115
206
  ```
116
207
 
117
208
  List configured providers and models:
@@ -54,47 +54,137 @@ Open the configuration file in editor:
54
54
  klaude config
55
55
  ```
56
56
 
57
- An minimal example config yaml using OpenRouter's API Key:
57
+ An example config yaml:
58
58
 
59
59
  ```yaml
60
60
  provider_list:
61
- - provider_name: openrouter-work
61
+ - provider_name: openrouter
62
62
  protocol: openrouter # support <responses|openrouter|anthropic|openai>
63
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
+
64
83
  model_list:
65
- - model_name: gpt-5.1-codex
66
- provider: openrouter
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
67
101
  model_params:
68
- model: openai/gpt-5.1-codex
69
- context_limit: 368000
102
+ model: gpt-5.1-codex-max
70
103
  thinking:
71
104
  reasoning_effort: medium
72
- - model_name: gpt-5.1-high
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
73
113
  provider: openrouter
74
114
  model_params:
75
115
  model: openai/gpt-5.1
76
- context_limit: 368000
116
+ context_limit: 400000
117
+ max_tokens: 128000
118
+ verbosity: high
77
119
  thinking:
78
120
  reasoning_effort: high
79
- - model_name: sonnet
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
80
141
  provider: openrouter
81
142
  model_params:
82
- model: anthropic/claude-4.5-sonnet
83
- context_limit: 168000
143
+ model: anthropic/claude-4.5-opus
144
+ context_limit: 200000
84
145
  provider_routing:
85
- sort: throughput
86
- - model_name: haiku
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
87
158
  provider: openrouter
88
159
  model_params:
89
- model: anthropic/claude-haiku-4.5
90
- context_limit: 168000
91
- provider_routing:
92
- sort: throughput
93
- main_model: gpt-5.1-codex
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
+
94
182
  sub_agent_models:
95
- oracle: gpt-5.1-high
183
+ oracle: gpt-5.1
96
184
  explore: haiku
97
- task: sonnet
185
+ task: opus
186
+ webfetchagent: haiku
187
+
98
188
  ```
99
189
 
100
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.16"
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",
@@ -261,7 +261,15 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
261
261
  restore_sigint = install_sigint_double_press_exit(_show_toast_once, _hide_progress)
262
262
 
263
263
  try:
264
- active_session_id = await initialize_session(components.executor, components.event_queue, session_id=session_id)
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.
268
+
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
265
273
 
266
274
  # Input
267
275
  await input_provider.start()
@@ -272,6 +280,8 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
272
280
  elif user_input.text.strip() == "":
273
281
  continue
274
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()
275
285
  submission_id = await components.executor.submit(
276
286
  op.UserInputOperation(input=user_input, session_id=active_session_id)
277
287
  )
@@ -282,7 +292,7 @@ async def run_interactive(init_config: AppInitConfig, session_id: str | None = N
282
292
  else:
283
293
  # Esc monitor for long-running, interruptible operations
284
294
  async def _on_esc_interrupt() -> None:
285
- await components.executor.submit(op.InterruptOperation(target_session_id=active_session_id))
295
+ await components.executor.submit(op.InterruptOperation(target_session_id=_get_active_session_id()))
286
296
 
287
297
  stop_event, esc_task = start_esc_interrupt_monitor(_on_esc_interrupt)
288
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",
@@ -0,0 +1,149 @@
1
+ from __future__ import annotations
2
+
3
+ import secrets
4
+ import shutil
5
+ import subprocess
6
+ import tempfile
7
+ from pathlib import Path
8
+ from typing import TYPE_CHECKING
9
+
10
+ from klaude_code.command.command_abc import CommandABC, CommandResult
11
+ from klaude_code.protocol import commands, events, model
12
+ from klaude_code.session.export import build_export_html
13
+
14
+ if TYPE_CHECKING:
15
+ from klaude_code.core.agent import Agent
16
+
17
+
18
+ class ExportOnlineCommand(CommandABC):
19
+ """Export and deploy the current session to surge.sh as a static webpage."""
20
+
21
+ @property
22
+ def name(self) -> commands.CommandName:
23
+ return commands.CommandName.EXPORT_ONLINE
24
+
25
+ @property
26
+ def summary(self) -> str:
27
+ return "Export and deploy session to surge.sh"
28
+
29
+ @property
30
+ def support_addition_params(self) -> bool:
31
+ return False
32
+
33
+ @property
34
+ def is_interactive(self) -> bool:
35
+ return False
36
+
37
+ async def run(self, raw: str, agent: Agent) -> CommandResult:
38
+ # Check if npx or surge is available
39
+ surge_cmd = self._get_surge_command()
40
+ if not surge_cmd:
41
+ event = events.DeveloperMessageEvent(
42
+ session_id=agent.session.id,
43
+ item=model.DeveloperMessageItem(
44
+ content="surge.sh CLI not found. Install with: npm install -g surge",
45
+ command_output=model.CommandOutput(command_name=self.name, is_error=True),
46
+ ),
47
+ )
48
+ return CommandResult(events=[event])
49
+
50
+ # Check if user is logged in to surge
51
+ if not self._is_surge_logged_in(surge_cmd):
52
+ login_cmd = " ".join([*surge_cmd, "login"])
53
+ event = events.DeveloperMessageEvent(
54
+ session_id=agent.session.id,
55
+ item=model.DeveloperMessageItem(
56
+ content=f"Not logged in to surge.sh. Please run: {login_cmd}",
57
+ command_output=model.CommandOutput(command_name=self.name, is_error=True),
58
+ ),
59
+ )
60
+ return CommandResult(events=[event])
61
+
62
+ try:
63
+ html_doc = self._build_html(agent)
64
+ domain = self._generate_domain()
65
+ url = self._deploy_to_surge(surge_cmd, html_doc, domain)
66
+
67
+ event = events.DeveloperMessageEvent(
68
+ session_id=agent.session.id,
69
+ item=model.DeveloperMessageItem(
70
+ content=f"Session deployed to: {url}",
71
+ command_output=model.CommandOutput(command_name=self.name),
72
+ ),
73
+ )
74
+ return CommandResult(events=[event])
75
+ except Exception as exc:
76
+ import traceback
77
+
78
+ event = events.DeveloperMessageEvent(
79
+ session_id=agent.session.id,
80
+ item=model.DeveloperMessageItem(
81
+ content=f"Failed to deploy session: {exc}\n{traceback.format_exc()}",
82
+ command_output=model.CommandOutput(command_name=self.name, is_error=True),
83
+ ),
84
+ )
85
+ return CommandResult(events=[event])
86
+
87
+ def _get_surge_command(self) -> list[str] | None:
88
+ """Check if surge CLI is available, prefer npx if available."""
89
+ # Check for npx first (more common)
90
+ if shutil.which("npx"):
91
+ return ["npx", "surge"]
92
+ # Check for globally installed surge
93
+ if shutil.which("surge"):
94
+ return ["surge"]
95
+ return None
96
+
97
+ def _is_surge_logged_in(self, surge_cmd: list[str]) -> bool:
98
+ """Check if user is logged in to surge.sh via 'surge whoami'."""
99
+ try:
100
+ cmd = [*surge_cmd, "whoami"]
101
+ result = subprocess.run(
102
+ cmd,
103
+ capture_output=True,
104
+ text=True,
105
+ timeout=30,
106
+ )
107
+ # If logged in, whoami returns 0 and prints the email
108
+ # If not logged in, it returns non-zero or prints "Not Authenticated"
109
+ if result.returncode != 0:
110
+ return False
111
+ output = (result.stdout + result.stderr).lower()
112
+ if "not authenticated" in output or "not logged in" in output:
113
+ return False
114
+ return bool(result.stdout.strip())
115
+ except (subprocess.TimeoutExpired, OSError):
116
+ return False
117
+
118
+ def _generate_domain(self) -> str:
119
+ """Generate a random subdomain for surge.sh."""
120
+ random_suffix = secrets.token_hex(4)
121
+ return f"klaude-session-{random_suffix}.surge.sh"
122
+
123
+ def _deploy_to_surge(self, surge_cmd: list[str], html_content: str, domain: str) -> str:
124
+ """Deploy HTML content to surge.sh and return the URL."""
125
+ with tempfile.TemporaryDirectory() as tmpdir:
126
+ html_path = Path(tmpdir) / "index.html"
127
+ html_path.write_text(html_content, encoding="utf-8")
128
+
129
+ # Run surge with --domain flag
130
+ cmd = [*surge_cmd, tmpdir, "--domain", domain]
131
+ result = subprocess.run(
132
+ cmd,
133
+ capture_output=True,
134
+ text=True,
135
+ timeout=60,
136
+ )
137
+
138
+ if result.returncode != 0:
139
+ error_msg = result.stderr or result.stdout or "Unknown error"
140
+ raise RuntimeError(f"Surge deployment failed: {error_msg}")
141
+
142
+ return f"https://{domain}"
143
+
144
+ def _build_html(self, agent: Agent) -> str:
145
+ profile = agent.profile
146
+ system_prompt = (profile.system_prompt if profile else "") or ""
147
+ tools = profile.tools if profile else []
148
+ model_name = profile.llm_client.model_name if profile else "unknown"
149
+ return build_export_html(agent.session, system_prompt, tools, model_name)
@@ -79,8 +79,8 @@ class Config(BaseModel):
79
79
 
80
80
  def get_example_config() -> Config:
81
81
  return Config(
82
- main_model="gpt-5.1",
83
- sub_agent_models={"explore": "haiku", "oracle": "gpt-5.1-high"},
82
+ main_model="opus",
83
+ sub_agent_models={"explore": "haiku", "oracle": "gpt-5.1", "webagent": "haiku", "task": "opus"},
84
84
  provider_list=[
85
85
  llm_param.LLMConfigProviderParameter(
86
86
  provider_name="openai",
@@ -93,6 +93,11 @@ def get_example_config() -> Config:
93
93
  protocol=llm_param.LLMClientProtocol.OPENROUTER,
94
94
  api_key="your-openrouter-api-key",
95
95
  ),
96
+ llm_param.LLMConfigProviderParameter(
97
+ provider_name="anthropic",
98
+ protocol=llm_param.LLMClientProtocol.ANTHROPIC,
99
+ api_key="your-anthropic-api-key",
100
+ ),
96
101
  ],
97
102
  model_list=[
98
103
  ModelConfig(
@@ -100,31 +105,25 @@ def get_example_config() -> Config:
100
105
  provider="openai",
101
106
  model_params=llm_param.LLMConfigModelParameter(
102
107
  model="gpt-5.1-2025-11-13",
103
- max_tokens=32000,
104
108
  verbosity="medium",
105
109
  thinking=llm_param.Thinking(
106
- reasoning_effort="medium",
110
+ reasoning_effort="high",
107
111
  reasoning_summary="auto",
108
- type="enabled",
109
- budget_tokens=None,
110
112
  ),
111
- context_limit=368000,
113
+ context_limit=400000,
112
114
  ),
113
115
  ),
114
116
  ModelConfig(
115
- model_name="gpt-5.1-high",
116
- provider="openai",
117
+ model_name="opus",
118
+ provider="anthropic",
117
119
  model_params=llm_param.LLMConfigModelParameter(
118
- model="gpt-5.1-2025-11-13",
119
- max_tokens=32000,
120
- verbosity="medium",
120
+ model="claude-opus-4-5-20251101",
121
+ verbosity="high",
121
122
  thinking=llm_param.Thinking(
122
- reasoning_effort="high",
123
- reasoning_summary="auto",
124
123
  type="enabled",
125
- budget_tokens=None,
124
+ budget_tokens=31999,
126
125
  ),
127
- context_limit=368000,
126
+ context_limit=200000,
128
127
  ),
129
128
  ),
130
129
  ModelConfig(
@@ -136,7 +135,7 @@ def get_example_config() -> Config:
136
135
  provider_routing=llm_param.OpenRouterProviderRouting(
137
136
  sort="throughput",
138
137
  ),
139
- context_limit=168000,
138
+ context_limit=200000,
140
139
  ),
141
140
  ),
142
141
  ],
@@ -57,7 +57,7 @@ class SubAgentManager:
57
57
  # Structured Output
58
58
  You have a `report_back` tool available. When you complete the task,\
59
59
  you MUST call `report_back` with the structured result matching the required schema.\
60
- This will end the task and return the structured data to the caller.
60
+ Only the content passed to `report_back` will be returned to user.\
61
61
  """
62
62
  base_prompt = child_profile.system_prompt or ""
63
63
  child_profile = AgentProfile(
@@ -3,7 +3,6 @@ You are the Oracle - an expert AI advisor with advanced reasoning capabilities
3
3
  Your role is to provide high-quality technical guidance, code reviews, architectural advice, and strategic planning for software engineering tasks.
4
4
  You are running inside an AI coding system in which you act as a sub-agent that's used when the main agent needs a smarter, more capable model to help out.
5
5
 
6
-
7
6
  Key responsibilities:
8
7
  - Analyze code and architecture patterns
9
8
  - Provide detailed technical reviews and recommendations
@@ -0,0 +1,48 @@
1
+ You are a web research agent that searches and fetches web content to provide up-to-date information.
2
+
3
+ ## Available Tools
4
+
5
+ **WebSearch**: Search the web via DuckDuckGo
6
+ - Returns: title, URL, and snippet for each result
7
+ - Parameter `max_results`: control result count (default: 10, max: 20)
8
+ - Snippets are brief summaries - use WebFetch for full content
9
+
10
+ **WebFetch**: Fetch and process web page content
11
+ - HTML pages are automatically converted to Markdown
12
+ - JSON responses are auto-formatted with indentation
13
+ - Other text content returned as-is
14
+
15
+ ## Tool Usage Strategy
16
+
17
+ Scale tool calls to query complexity:
18
+ - Simple facts: 1-2 calls
19
+ - Medium research: 3-5 calls
20
+ - Deep research/comparisons: 5-10 calls
21
+
22
+ Balance efficiency with thoroughness. For open-ended questions (e.g., "recommendations for video games" or "recent developments in RL"), use more calls for comprehensive answers.
23
+
24
+ ## Search Guidelines
25
+
26
+ - Keep queries concise (1-6 words). Start broad, then narrow if needed
27
+ - Avoid repeating similar queries - they won't yield new results
28
+ - NEVER use '-', 'site:', or quotes unless explicitly asked
29
+ - Include year/date for time-sensitive queries (check "Today's date" in <env>)
30
+ - Use WebFetch to get full content - search snippets are often insufficient
31
+ - Follow relevant links on pages with WebFetch
32
+ - If truncated results are saved to local files, use grep/read to explore
33
+
34
+ ## Response Guidelines
35
+
36
+ - Only your last message is returned to the main agent
37
+ - Be succinct - include only relevant information
38
+ - Lead with the most recent info for evolving topics
39
+ - Favor original sources (company blogs, papers, gov sites) over aggregators
40
+ - Note conflicting sources when they exist
41
+
42
+ ## Sources (REQUIRED)
43
+
44
+ You MUST end every response with a "Sources:" section listing all URLs as markdown links:
45
+
46
+ Sources:
47
+ - [Source Title](https://example.com)
48
+ - [Another Source](https://example.com/page) (saved: /path/to/file)