tau-coding-agent 0.5.4__tar.gz → 0.5.6__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 (416) hide show
  1. {tau_coding_agent-0.5.4/tau_coding_agent.egg-info → tau_coding_agent-0.5.6}/PKG-INFO +2 -1
  2. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/settings.md +8 -5
  3. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/tui.md +5 -3
  4. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/pyproject.toml +2 -1
  5. tau_coding_agent-0.5.6/tau/builtins/extensions/ask_user/__init__.py +16 -0
  6. tau_coding_agent-0.5.6/tau/builtins/extensions/ask_user/component.py +346 -0
  7. tau_coding_agent-0.5.6/tau/builtins/extensions/ask_user/manifest.json +18 -0
  8. tau_coding_agent-0.5.6/tau/builtins/extensions/ask_user/schema.py +41 -0
  9. tau_coding_agent-0.5.6/tau/builtins/extensions/ask_user/tool.py +129 -0
  10. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/extensions/watch/__init__.py +1 -0
  11. tau_coding_agent-0.5.6/tau/builtins/extensions/web/__init__.py +56 -0
  12. tau_coding_agent-0.5.6/tau/builtins/extensions/web/engines/__init__.py +107 -0
  13. tau_coding_agent-0.5.6/tau/builtins/extensions/web/engines/base.py +73 -0
  14. tau_coding_agent-0.5.6/tau/builtins/extensions/web/engines/ddgs_engine.py +117 -0
  15. tau_coding_agent-0.5.6/tau/builtins/extensions/web/engines/exa_engine.py +63 -0
  16. tau_coding_agent-0.5.6/tau/builtins/extensions/web/engines/jina_engine.py +65 -0
  17. tau_coding_agent-0.5.6/tau/builtins/extensions/web/engines/tavily_engine.py +61 -0
  18. tau_coding_agent-0.5.6/tau/builtins/extensions/web/manifest.json +115 -0
  19. tau_coding_agent-0.5.6/tau/builtins/extensions/web/tools/fetch.py +200 -0
  20. tau_coding_agent-0.5.6/tau/builtins/extensions/web/tools/search.py +178 -0
  21. tau_coding_agent-0.5.6/tau/builtins/themes/ayu-dark.yaml +46 -0
  22. tau_coding_agent-0.5.6/tau/builtins/themes/catppuccin.yaml +46 -0
  23. tau_coding_agent-0.5.6/tau/builtins/themes/dracula.yaml +46 -0
  24. tau_coding_agent-0.5.6/tau/builtins/themes/everforest.yaml +46 -0
  25. tau_coding_agent-0.5.6/tau/builtins/themes/gruvbox.yaml +46 -0
  26. tau_coding_agent-0.5.6/tau/builtins/themes/horizon.yaml +46 -0
  27. tau_coding_agent-0.5.6/tau/builtins/themes/kanagawa.yaml +46 -0
  28. tau_coding_agent-0.5.6/tau/builtins/themes/material-ocean.yaml +46 -0
  29. tau_coding_agent-0.5.6/tau/builtins/themes/monokai.yaml +46 -0
  30. tau_coding_agent-0.5.6/tau/builtins/themes/night-owl.yaml +46 -0
  31. tau_coding_agent-0.5.6/tau/builtins/themes/nord.yaml +46 -0
  32. tau_coding_agent-0.5.6/tau/builtins/themes/one-dark.yaml +46 -0
  33. tau_coding_agent-0.5.6/tau/builtins/themes/rose-pine.yaml +46 -0
  34. tau_coding_agent-0.5.6/tau/builtins/themes/solarized-dark.yaml +46 -0
  35. tau_coding_agent-0.5.6/tau/builtins/themes/tokyo-night.yaml +46 -0
  36. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/tools/utils.py +1 -0
  37. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/extensions/api.py +1 -0
  38. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/runtime/service.py +3 -1
  39. tau_coding_agent-0.5.6/tau/telemetry/__init__.py +9 -0
  40. tau_coding_agent-0.5.6/tau/telemetry/service.py +120 -0
  41. tau_coding_agent-0.5.6/tau/telemetry/types.py +24 -0
  42. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/tui.py +0 -1
  43. tau_coding_agent-0.5.6/tau/utils/__init__.py +0 -0
  44. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6/tau_coding_agent.egg-info}/PKG-INFO +2 -1
  45. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau_coding_agent.egg-info/SOURCES.txt +34 -1
  46. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau_coding_agent.egg-info/requires.txt +1 -0
  47. tau_coding_agent-0.5.6/tests/test_telemetry.py +73 -0
  48. tau_coding_agent-0.5.4/tau/utils/telemetry.py +0 -42
  49. tau_coding_agent-0.5.4/tests/test_telemetry.py +0 -75
  50. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/LICENSE +0 -0
  51. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/MANIFEST.in +0 -0
  52. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/README.md +0 -0
  53. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/architecture.md +0 -0
  54. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/auth.md +0 -0
  55. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/cli-reference.md +0 -0
  56. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/creating-tools.md +0 -0
  57. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/development.md +0 -0
  58. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/docs.json +0 -0
  59. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/engine.md +0 -0
  60. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/extension-settings.md +0 -0
  61. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/extensions.md +0 -0
  62. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/http-proxy.md +0 -0
  63. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/index.md +0 -0
  64. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/inference-providers.md +0 -0
  65. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/inference.md +0 -0
  66. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/installation.md +0 -0
  67. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/keybindings.md +0 -0
  68. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/messages.md +0 -0
  69. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/project-context.md +0 -0
  70. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/project-structure.md +0 -0
  71. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/prompts.md +0 -0
  72. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/python-api.md +0 -0
  73. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/quickstart.md +0 -0
  74. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/sessions.md +0 -0
  75. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/skills.md +0 -0
  76. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/themes.md +0 -0
  77. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/tools.md +0 -0
  78. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/docs/usage.md +0 -0
  79. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/setup.cfg +0 -0
  80. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/__init__.py +0 -0
  81. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/agent/__init__.py +0 -0
  82. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/agent/prompt/__init__.py +0 -0
  83. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/agent/prompt/builder.py +0 -0
  84. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/agent/prompt/types.py +0 -0
  85. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/agent/service.py +0 -0
  86. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/agent/types.py +0 -0
  87. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/auth/manager.py +0 -0
  88. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/auth/storage.py +0 -0
  89. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/auth/types.py +0 -0
  90. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/__init__.py +0 -0
  91. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/commands/__init__.py +0 -0
  92. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/commands/clear.py +0 -0
  93. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/commands/compact.py +0 -0
  94. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/commands/reload.py +0 -0
  95. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/commands/session.py +0 -0
  96. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/extensions/btw/__init__.py +0 -0
  97. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/extensions/footer/__init__.py +0 -0
  98. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/extensions/footer/git.py +0 -0
  99. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/extensions/footer/model.py +0 -0
  100. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/extensions/footer/utils.py +0 -0
  101. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/extensions/header/__init__.py +0 -0
  102. {tau_coding_agent-0.5.4/tau/builtins/models → tau_coding_agent-0.5.6/tau/builtins/extensions/web/tools}/__init__.py +0 -0
  103. {tau_coding_agent-0.5.4/tau/builtins/providers → tau_coding_agent-0.5.6/tau/builtins/models}/__init__.py +0 -0
  104. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/models/audio.py +0 -0
  105. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/models/image.py +0 -0
  106. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/models/text.py +0 -0
  107. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/models/video.py +0 -0
  108. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/prompts/commit.md +0 -0
  109. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/prompts/docs.md +0 -0
  110. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/prompts/explain.md +0 -0
  111. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/prompts/fix.md +0 -0
  112. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/prompts/refactor.md +0 -0
  113. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/prompts/review.md +0 -0
  114. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/prompts/test.md +0 -0
  115. {tau_coding_agent-0.5.4/tau/console → tau_coding_agent-0.5.6/tau/builtins/providers}/__init__.py +0 -0
  116. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/providers/audio.py +0 -0
  117. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/providers/image.py +0 -0
  118. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/providers/text.py +0 -0
  119. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/providers/video.py +0 -0
  120. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/skills/code-review/SKILL.md +0 -0
  121. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/skills/debug/SKILL.md +0 -0
  122. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/skills/git-commit/SKILL.md +0 -0
  123. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/skills/skill-creator/LICENSE.txt +0 -0
  124. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/skills/skill-creator/SKILL.md +0 -0
  125. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/themes/dark.yaml +0 -0
  126. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/themes/light.yaml +0 -0
  127. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/tools/__init__.py +0 -0
  128. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/tools/edit.py +0 -0
  129. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/tools/glob.py +0 -0
  130. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/tools/grep.py +0 -0
  131. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/tools/ls.py +0 -0
  132. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/tools/read.py +0 -0
  133. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/tools/terminal.py +0 -0
  134. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/builtins/tools/write.py +0 -0
  135. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/commands/__init__.py +0 -0
  136. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/commands/registry.py +0 -0
  137. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/commands/types.py +0 -0
  138. {tau_coding_agent-0.5.4/tau/console/commands → tau_coding_agent-0.5.6/tau/console}/__init__.py +0 -0
  139. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/console/cli.py +0 -0
  140. {tau_coding_agent-0.5.4/tau/core → tau_coding_agent-0.5.6/tau/console/commands}/__init__.py +0 -0
  141. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/console/commands/auth.py +0 -0
  142. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/console/commands/packages.py +0 -0
  143. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/console/commands/update.py +0 -0
  144. {tau_coding_agent-0.5.4/tau/inference/api → tau_coding_agent-0.5.6/tau/core}/__init__.py +0 -0
  145. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/core/registry.py +0 -0
  146. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/engine/__init__.py +0 -0
  147. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/engine/service.py +0 -0
  148. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/engine/types.py +0 -0
  149. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/extensions/__init__.py +0 -0
  150. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/extensions/context.py +0 -0
  151. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/extensions/loader.py +0 -0
  152. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/extensions/runtime.py +0 -0
  153. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/extensions/settings.py +0 -0
  154. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/hooks/__init__.py +0 -0
  155. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/hooks/engine.py +0 -0
  156. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/hooks/inference.py +0 -0
  157. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/hooks/runtime.py +0 -0
  158. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/hooks/service.py +0 -0
  159. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/hooks/session.py +0 -0
  160. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/hooks/tui.py +0 -0
  161. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/hooks/types.py +0 -0
  162. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/__init__.py +0 -0
  163. {tau_coding_agent-0.5.4/tau/inference/api/audio → tau_coding_agent-0.5.6/tau/inference/api}/__init__.py +0 -0
  164. {tau_coding_agent-0.5.4/tau/inference/api/image → tau_coding_agent-0.5.6/tau/inference/api/audio}/__init__.py +0 -0
  165. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/audio/base.py +0 -0
  166. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/audio/builtins.py +0 -0
  167. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/audio/elevenlabs_audio.py +0 -0
  168. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/audio/gemini_audio.py +0 -0
  169. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/audio/openai_audio.py +0 -0
  170. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/audio/registry.py +0 -0
  171. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/audio/sarvam_audio.py +0 -0
  172. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/audio/service.py +0 -0
  173. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/audio/utils.py +0 -0
  174. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/availability.py +0 -0
  175. {tau_coding_agent-0.5.4/tau/inference/api/text → tau_coding_agent-0.5.6/tau/inference/api/image}/__init__.py +0 -0
  176. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/image/base.py +0 -0
  177. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/image/builtins.py +0 -0
  178. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/image/gemini_image.py +0 -0
  179. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/image/openai_image.py +0 -0
  180. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/image/openrouter.py +0 -0
  181. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/image/registry.py +0 -0
  182. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/image/service.py +0 -0
  183. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/registry.py +0 -0
  184. {tau_coding_agent-0.5.4/tau/inference/api/video → tau_coding_agent-0.5.6/tau/inference/api/text}/__init__.py +0 -0
  185. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/anthropic_claude_code.py +0 -0
  186. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/anthropic_messages.py +0 -0
  187. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/anthropic_vertex.py +0 -0
  188. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/base.py +0 -0
  189. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/builtins.py +0 -0
  190. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/dialect.py +0 -0
  191. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/gemini_generate.py +0 -0
  192. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/github_copilot_chat.py +0 -0
  193. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/google_antigravity.py +0 -0
  194. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/google_vertex.py +0 -0
  195. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/mistral_chat.py +0 -0
  196. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/ollama_chat.py +0 -0
  197. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/openai_codex_responses.py +0 -0
  198. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/openai_completions.py +0 -0
  199. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/openai_responses.py +0 -0
  200. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/openai_vertex.py +0 -0
  201. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/registry.py +0 -0
  202. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/service.py +0 -0
  203. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/types.py +0 -0
  204. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/text/utils.py +0 -0
  205. {tau_coding_agent-0.5.4/tau/inference/model → tau_coding_agent-0.5.6/tau/inference/api/video}/__init__.py +0 -0
  206. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/video/base.py +0 -0
  207. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/video/builtins.py +0 -0
  208. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/video/fal_video.py +0 -0
  209. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/video/openrouter_video.py +0 -0
  210. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/video/registry.py +0 -0
  211. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/video/service.py +0 -0
  212. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/api/video/zai_video.py +0 -0
  213. {tau_coding_agent-0.5.4/tau/inference/provider → tau_coding_agent-0.5.6/tau/inference/model}/__init__.py +0 -0
  214. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/model/registry.py +0 -0
  215. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/model/types.py +0 -0
  216. {tau_coding_agent-0.5.4/tau/message → tau_coding_agent-0.5.6/tau/inference/provider}/__init__.py +0 -0
  217. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/oauth/__init__.py +0 -0
  218. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/oauth/anthropic_claude_code.py +0 -0
  219. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/oauth/github_copilot.py +0 -0
  220. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/oauth/google_antigravity.py +0 -0
  221. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/oauth/openai_codex.py +0 -0
  222. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/oauth/pkce.py +0 -0
  223. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/oauth/types.py +0 -0
  224. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/oauth/utils.py +0 -0
  225. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/registry.py +0 -0
  226. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/provider/types.py +0 -0
  227. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/types.py +0 -0
  228. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/inference/utils.py +0 -0
  229. {tau_coding_agent-0.5.4/tau/modes → tau_coding_agent-0.5.6/tau/message}/__init__.py +0 -0
  230. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/message/types.py +0 -0
  231. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/message/utils.py +0 -0
  232. {tau_coding_agent-0.5.4/tau/modes/interactive → tau_coding_agent-0.5.6/tau/modes}/__init__.py +0 -0
  233. {tau_coding_agent-0.5.4/tau/modes/interactive/components → tau_coding_agent-0.5.6/tau/modes/interactive}/__init__.py +0 -0
  234. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/agent_hooks.py +0 -0
  235. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/app.py +0 -0
  236. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/commands/__init__.py +0 -0
  237. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/commands/appearance.py +0 -0
  238. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/commands/auth.py +0 -0
  239. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/commands/context.py +0 -0
  240. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/commands/extensions.py +0 -0
  241. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/commands/misc.py +0 -0
  242. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/commands/model.py +0 -0
  243. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/commands/session.py +0 -0
  244. {tau_coding_agent-0.5.4/tau/modes/print → tau_coding_agent-0.5.6/tau/modes/interactive/components}/__init__.py +0 -0
  245. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/command_palette.py +0 -0
  246. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/config_selector.py +0 -0
  247. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/extension_selector.py +0 -0
  248. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/file_picker.py +0 -0
  249. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/layout.py +0 -0
  250. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/message_list.py +0 -0
  251. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/model_selector.py +0 -0
  252. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/oauth_selector.py +0 -0
  253. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/overlays.py +0 -0
  254. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/selector_controller.py +0 -0
  255. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/session_selector.py +0 -0
  256. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/settings_selector.py +0 -0
  257. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/theme_selector.py +0 -0
  258. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/thinking_selector.py +0 -0
  259. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/tree_selector.py +0 -0
  260. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/trust_screen.py +0 -0
  261. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/components/voice_selector.py +0 -0
  262. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/input_handler.py +0 -0
  263. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/interactive/ui_context.py +0 -0
  264. {tau_coding_agent-0.5.4/tau/tui/components → tau_coding_agent-0.5.6/tau/modes/print}/__init__.py +0 -0
  265. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/rpc/__init__.py +0 -0
  266. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/rpc/mode.py +0 -0
  267. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/modes/rpc/types.py +0 -0
  268. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/packages/__init__.py +0 -0
  269. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/packages/manager.py +0 -0
  270. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/packages/types.py +0 -0
  271. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/packages/utils.py +0 -0
  272. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/prompts/expand.py +0 -0
  273. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/prompts/loader.py +0 -0
  274. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/prompts/registry.py +0 -0
  275. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/prompts/types.py +0 -0
  276. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/resources/__init__.py +0 -0
  277. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/resources/loader.py +0 -0
  278. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/resources/types.py +0 -0
  279. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/runtime/dependencies.py +0 -0
  280. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/runtime/types.py +0 -0
  281. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/session/branch_summarization.py +0 -0
  282. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/session/compaction.py +0 -0
  283. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/session/manager.py +0 -0
  284. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/session/types.py +0 -0
  285. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/session/utils.py +0 -0
  286. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/settings/manager.py +0 -0
  287. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/settings/paths.py +0 -0
  288. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/settings/storage.py +0 -0
  289. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/settings/types.py +0 -0
  290. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/settings/utils.py +0 -0
  291. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/skills/loader.py +0 -0
  292. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/skills/registry.py +0 -0
  293. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/skills/types.py +0 -0
  294. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/themes/loader.py +0 -0
  295. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/themes/registry.py +0 -0
  296. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/themes/types.py +0 -0
  297. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tool/__init__.py +0 -0
  298. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tool/registry.py +0 -0
  299. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tool/render.py +0 -0
  300. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tool/types.py +0 -0
  301. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/trust/__init__.py +0 -0
  302. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/trust/manager.py +0 -0
  303. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/trust/types.py +0 -0
  304. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/trust/utils.py +0 -0
  305. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/__init__.py +0 -0
  306. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/autocomplete.py +0 -0
  307. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/component.py +0 -0
  308. {tau_coding_agent-0.5.4/tau/utils → tau_coding_agent-0.5.6/tau/tui/components}/__init__.py +0 -0
  309. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/components/box.py +0 -0
  310. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/components/editor.py +0 -0
  311. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/components/image.py +0 -0
  312. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/components/select_list.py +0 -0
  313. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/components/spinner.py +0 -0
  314. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/components/text_input.py +0 -0
  315. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/input.py +0 -0
  316. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/keybinding_hints.py +0 -0
  317. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/markdown.py +0 -0
  318. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/terminal.py +0 -0
  319. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/theme.py +0 -0
  320. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/tui/utils.py +0 -0
  321. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/utils/http_proxy.py +0 -0
  322. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/utils/image_processing.py +0 -0
  323. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/utils/secrets.py +0 -0
  324. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau/utils/version_check.py +0 -0
  325. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau_coding_agent.egg-info/dependency_links.txt +0 -0
  326. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau_coding_agent.egg-info/entry_points.txt +0 -0
  327. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tau_coding_agent.egg-info/top_level.txt +0 -0
  328. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_agent_compaction.py +0 -0
  329. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_agent_prompt.py +0 -0
  330. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_agent_types.py +0 -0
  331. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_ansi.py +0 -0
  332. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_ask_user_extension.py +0 -0
  333. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_auth_command.py +0 -0
  334. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_auth_manager.py +0 -0
  335. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_auth_storage.py +0 -0
  336. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_autocomplete_modifiers.py +0 -0
  337. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_branch_navigation.py +0 -0
  338. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_branch_summarization.py +0 -0
  339. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_builtin_tools.py +0 -0
  340. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_builtin_watch.py +0 -0
  341. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_cli_inputs.py +0 -0
  342. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_command_execution_policy.py +0 -0
  343. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_command_registry.py +0 -0
  344. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_compaction.py +0 -0
  345. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_diff.py +0 -0
  346. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_editor_protocol.py +0 -0
  347. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_engine_execution.py +0 -0
  348. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_engine_steering.py +0 -0
  349. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_engine_types.py +0 -0
  350. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_escape_behavior.py +0 -0
  351. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_extension_api.py +0 -0
  352. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_extension_lifecycle.py +0 -0
  353. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_footer_model.py +0 -0
  354. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_footer_utils.py +0 -0
  355. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_fuzzy.py +0 -0
  356. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_http_proxy.py +0 -0
  357. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_image_processing.py +0 -0
  358. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_inference_api_text_utils.py +0 -0
  359. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_inference_dialect.py +0 -0
  360. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_inference_error_utils.py +0 -0
  361. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_inference_types.py +0 -0
  362. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_inference_utils.py +0 -0
  363. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_keybindings.py +0 -0
  364. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_markdown.py +0 -0
  365. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_message_types.py +0 -0
  366. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_message_utils.py +0 -0
  367. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_model_availability.py +0 -0
  368. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_model_command.py +0 -0
  369. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_model_registry.py +0 -0
  370. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_model_selector_modal.py +0 -0
  371. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_model_types.py +0 -0
  372. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_oauth_utils.py +0 -0
  373. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_package_resources.py +0 -0
  374. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_packages_utils.py +0 -0
  375. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_peer_extension.py +0 -0
  376. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_pkce.py +0 -0
  377. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_prompts_expand.py +0 -0
  378. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_prompts_loader.py +0 -0
  379. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_prompts_registry.py +0 -0
  380. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_provider_registry.py +0 -0
  381. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_resource_loader.py +0 -0
  382. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_rpc_mode.py +0 -0
  383. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_runtime_sdk.py +0 -0
  384. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_secrets.py +0 -0
  385. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_selector_controller.py +0 -0
  386. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_session_manager.py +0 -0
  387. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_session_trust_persist.py +0 -0
  388. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_session_types.py +0 -0
  389. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_session_utils.py +0 -0
  390. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_settings_manager.py +0 -0
  391. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_settings_paths.py +0 -0
  392. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_settings_storage.py +0 -0
  393. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_settings_utils.py +0 -0
  394. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_skills_loader.py +0 -0
  395. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_skills_registry.py +0 -0
  396. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_subagents_extension.py +0 -0
  397. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_text_input.py +0 -0
  398. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_text_llm_invoke.py +0 -0
  399. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_theme_loader.py +0 -0
  400. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_themes_registry.py +0 -0
  401. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_thinking_render.py +0 -0
  402. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tool_registry.py +0 -0
  403. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tool_render.py +0 -0
  404. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_trust_manager.py +0 -0
  405. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_trust_utils.py +0 -0
  406. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tui_capabilities.py +0 -0
  407. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tui_input.py +0 -0
  408. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tui_layout_sizing.py +0 -0
  409. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tui_public_api.py +0 -0
  410. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tui_renderer.py +0 -0
  411. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tui_select_list.py +0 -0
  412. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tui_theme.py +0 -0
  413. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_tui_utils.py +0 -0
  414. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_ui_context.py +0 -0
  415. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_version_check.py +0 -0
  416. {tau_coding_agent-0.5.4 → tau_coding_agent-0.5.6}/tests/test_voice_selector.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tau-coding-agent
3
- Version: 0.5.4
3
+ Version: 0.5.6
4
4
  Summary: A self-extensible agent CLI with terminal UI, multi-provider LLM support, session management with branching, and a plugin system for tools and commands
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
@@ -24,6 +24,7 @@ Requires-Dist: mistletoe==1.5.1
24
24
  Requires-Dist: pyyaml==6.0.2
25
25
  Requires-Dist: pygments==2.20.0
26
26
  Requires-Dist: pathspec==1.1.1
27
+ Requires-Dist: posthog==7.21.3
27
28
  Requires-Dist: gitpython==3.1.50
28
29
  Requires-Dist: grapheme==0.6.0
29
30
  Requires-Dist: arrow==1.4.0
@@ -149,11 +149,14 @@ Toggle during a session with `/effort` or the effort picker.
149
149
  |-------|------|---------|-------------|
150
150
  | `telemetry` | boolean | `true` | Send one anonymous version-only install/update count |
151
151
 
152
- Telemetry sends only the installed Tau version to Tau's Cloudflare Worker once
153
- per version. Tau does not persist identifiers or IP addresses and does not send
154
- prompts, paths, models, authentication state, session data, or tool activity.
155
- As with any HTTP request, Cloudflare necessarily processes the source IP under
156
- its own privacy policy. Failed requests are ignored and never block startup.
152
+ Telemetry sends only the installed Tau version to Tau's PostHog project once
153
+ per version, as a single `tau` event on a shared anonymous distinct ID. When
154
+ enabled, Tau also reports uncaught exceptions (type, message, and traceback)
155
+ to the same PostHog project so crashes can be diagnosed. Tau does not persist
156
+ per-user identifiers and does not send prompts, paths, models, authentication
157
+ state, session data, or tool activity. As with any HTTP request, PostHog
158
+ necessarily processes the source IP under its own privacy policy. Failed
159
+ requests are ignored and never block startup or shutdown.
157
160
 
158
161
  This is a global preference: project settings cannot enable telemetry after it
159
162
  has been disabled globally. Disable it in `/settings` or in
@@ -122,9 +122,11 @@ Input is normalized into typed events:
122
122
  - `BgColorEvent`
123
123
 
124
124
  Use `KeyEvent.matches()` instead of comparing raw escape sequences.
125
- Mouse reporting is enabled while the TUI runs. The stock interactive
126
- `TextInput` moves its caret to the clicked text position, including across
127
- hard newlines and soft-wrapped rows.
125
+ Mouse reporting is not enabled by the TUI terminals only offer clicks and
126
+ wheel-scroll as a single reporting mode, so requesting it would take over the
127
+ terminal's native wheel-scroll and click-drag copy for the whole session.
128
+ `MouseEvent` remains available for embedders that want to opt into that
129
+ trade-off themselves via `Terminal.enable_mouse_tracking()`.
128
130
 
129
131
  ## Overlays
130
132
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tau-coding-agent"
7
- version = "0.5.4"
7
+ version = "0.5.6"
8
8
  description = "A self-extensible agent CLI with terminal UI, multi-provider LLM support, session management with branching, and a plugin system for tools and commands"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -28,6 +28,7 @@ dependencies = [
28
28
  "pyyaml==6.0.2",
29
29
  "pygments==2.20.0",
30
30
  "pathspec==1.1.1",
31
+ "posthog==7.21.3",
31
32
  "gitpython==3.1.50",
32
33
  "grapheme==0.6.0",
33
34
  "arrow==1.4.0",
@@ -0,0 +1,16 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from pathlib import Path
5
+
6
+ # Add this directory to sys.path to allow easy resolution of schema, component, and tool.
7
+ sys.path.insert(0, str(Path(__file__).parent))
8
+
9
+ from tool import AskUserTool
10
+
11
+
12
+ def register(tau) -> None:
13
+ config = tau.config or {}
14
+ if not config.get("enabled", True):
15
+ return
16
+ tau.register_tool(AskUserTool(tau._runtime_ref))
@@ -0,0 +1,346 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ from schema import AskUserOption
6
+
7
+ from tau.tui.component import Component
8
+ from tau.tui.input import InputEvent, KeyEvent
9
+
10
+ FREEFORM_LABEL = "Type something…"
11
+
12
+
13
+ def _typed_char(event: KeyEvent) -> str | None:
14
+ """Return the printable character a key event represents, or None.
15
+
16
+ ``event.key`` is always lowercased by the parser (the original case lives
17
+ in ``event.char``), so text entry must read ``char`` to avoid silently
18
+ lowercasing everything the user types.
19
+ """
20
+ if event.char is not None and len(event.char) >= 1 and event.char.isprintable():
21
+ return event.char
22
+ if len(event.key) == 1 and event.key.isprintable():
23
+ return event.key
24
+ return None
25
+
26
+
27
+ class _AskUserComponent(Component):
28
+ """Floating dialog: option list (single/multi-select) + optional freeform entry."""
29
+
30
+ ML_VISIBLE_ROWS = 8
31
+ ML_MIN_VISIBLE_ROWS = 4 # pad short buffers so the box visibly reads as multi-line
32
+
33
+ def __init__(
34
+ self,
35
+ question: str,
36
+ context: str | None,
37
+ options: list[AskUserOption],
38
+ allow_multiple: bool,
39
+ allow_freeform: bool,
40
+ multiline: bool,
41
+ on_done: Any,
42
+ ) -> None:
43
+ self._question = question
44
+ self._context = context
45
+ self._options = options
46
+ self._allow_multiple = allow_multiple
47
+ self._allow_freeform = allow_freeform
48
+ self._multiline = multiline
49
+ self._on_done = on_done
50
+
51
+ self._cursor = 0
52
+ self._checked: set[int] = set()
53
+ self._mode = "list" # "list" | "freeform"
54
+ self._freeform_value = "" # single-line freeform buffer
55
+
56
+ # Multi-line freeform buffer (used only when self._multiline).
57
+ self._ml_lines: list[str] = [""]
58
+ self._ml_cursor_row = 0
59
+ self._ml_cursor_col = 0
60
+ self._ml_scroll_top = 0
61
+
62
+ # Index of the synthetic "Type something…" row, if present.
63
+ self._freeform_index = len(options) if allow_freeform else -1
64
+ self._row_count = len(options) + (1 if allow_freeform else 0)
65
+
66
+ # No real choices — freeform is the only path, so open straight into the
67
+ # editor with a live cursor instead of forcing an Enter on a single
68
+ # "Type something…" row first. Applies to both single- and multi-line.
69
+ if not self._options and self._allow_freeform:
70
+ self._enter_freeform()
71
+
72
+ def _enter_freeform(self, seed: str = "") -> None:
73
+ self._mode = "freeform"
74
+ if self._multiline:
75
+ self._ml_lines = [seed]
76
+ self._ml_cursor_row = 0
77
+ self._ml_cursor_col = len(seed)
78
+ self._ml_scroll_top = 0
79
+ else:
80
+ self._freeform_value = seed
81
+
82
+ # ── Render ────────────────────────────────────────────────────────────
83
+
84
+ def render(self, width: int) -> list[str]:
85
+ from tau.modes.interactive.components.overlays import _box
86
+
87
+ inner: list[str] = []
88
+ if self._context:
89
+ for line in self._context.splitlines():
90
+ inner.append(f" \x1b[2m{line}\x1b[0m")
91
+ inner.append("")
92
+ inner.append(f" \x1b[1m{self._question}\x1b[0m")
93
+ inner.append("")
94
+
95
+ if self._mode == "freeform" and self._multiline:
96
+ self._clamp_ml_scroll()
97
+ limit = self._ml_scroll_top + self.ML_VISIBLE_ROWS
98
+ visible = self._ml_lines[self._ml_scroll_top : limit]
99
+ for ri, line in enumerate(visible):
100
+ abs_row = self._ml_scroll_top + ri
101
+ if abs_row == self._ml_cursor_row:
102
+ before = line[: self._ml_cursor_col]
103
+ after = line[self._ml_cursor_col :]
104
+ inner.append(f" {before}█{after}")
105
+ else:
106
+ inner.append(f" {line}")
107
+ # Pad with blank rows (display-only, not part of the buffer) so an
108
+ # empty/short answer still shows several rows — a visible cue that
109
+ # this is a multi-line editor, not a single-line box.
110
+ for _ in range(self.ML_MIN_VISIBLE_ROWS - len(visible)):
111
+ inner.append("")
112
+ total = len(self._ml_lines)
113
+ if total > self.ML_VISIBLE_ROWS:
114
+ pct = int(self._ml_scroll_top / max(1, total - self.ML_VISIBLE_ROWS) * 100)
115
+ inner.append(f" \x1b[2m↕ {pct}%\x1b[0m")
116
+ else:
117
+ inner.append("")
118
+ back = "Esc to cancel" if not self._options else "Esc to go back"
119
+ inner.append(
120
+ " \x1b[2mEnter to submit · \\+Enter or Shift+Enter for newline · "
121
+ f"{back}\x1b[0m"
122
+ )
123
+ return _box(inner, "", width, bg="")
124
+
125
+ if self._mode == "freeform":
126
+ inner.append(f" {self._freeform_value}█")
127
+ inner.append("")
128
+ back = "Esc to cancel" if not self._options else "Esc to go back"
129
+ inner.append(f" \x1b[2mEnter to submit · {back}\x1b[0m")
130
+ return _box(inner, "", width, bg="")
131
+
132
+ for i in range(self._row_count):
133
+ is_freeform_row = i == self._freeform_index
134
+ title = FREEFORM_LABEL if is_freeform_row else self._options[i].title
135
+ desc = "" if is_freeform_row else (self._options[i].description or "")
136
+ is_cursor = i == self._cursor
137
+ cursor_mark = "›" if is_cursor else " "
138
+
139
+ if self._allow_multiple and not is_freeform_row:
140
+ # Same tick glyphs as the /extensions config panel. Cursor rows
141
+ # get wrapped in reverse-video below, so leave them uncolored
142
+ # there — an embedded reset would cut the highlight short.
143
+ if i in self._checked:
144
+ box = "✔" if is_cursor else "\x1b[32m✔\x1b[0m"
145
+ else:
146
+ box = "✖" if is_cursor else "\x1b[2m✖\x1b[0m"
147
+ elif not is_freeform_row:
148
+ # Radio-style circles: filled at the cursor position, hollow
149
+ # elsewhere. Same reverse-video caveat as the checkbox ticks
150
+ # above — leave the cursor row's glyph uncolored.
151
+ box = "●" if is_cursor else "\x1b[2m○\x1b[0m"
152
+ else:
153
+ box = " > "
154
+
155
+ row = f" {cursor_mark} {box} {title}"
156
+ if is_cursor:
157
+ row = f"\x1b[7m{row}\x1b[0m"
158
+ if desc:
159
+ row += f" \x1b[2m{desc}\x1b[0m"
160
+ inner.append(row)
161
+
162
+ inner.append("")
163
+ hints = ["↑/↓ move", "Enter confirm", "Esc cancel"]
164
+ if self._allow_multiple:
165
+ hints.insert(1, "Space toggle")
166
+ inner.append(" \x1b[2m" + " · ".join(hints) + "\x1b[0m")
167
+ return _box(inner, "", width)
168
+
169
+ # ── Input ─────────────────────────────────────────────────────────────
170
+
171
+ def handle_input(self, event: InputEvent) -> bool:
172
+ if not isinstance(event, KeyEvent):
173
+ return False
174
+
175
+ if self._mode == "freeform":
176
+ return self._handle_freeform_input(event)
177
+ return self._handle_list_input(event)
178
+
179
+ def _handle_list_input(self, event: KeyEvent) -> bool:
180
+ match event.key:
181
+ case "up":
182
+ self._cursor = (self._cursor - 1) % max(1, self._row_count)
183
+ case "down":
184
+ self._cursor = (self._cursor + 1) % max(1, self._row_count)
185
+ case " " | "space" if self._allow_multiple and self._cursor != self._freeform_index:
186
+ if self._cursor in self._checked:
187
+ self._checked.discard(self._cursor)
188
+ else:
189
+ self._checked.add(self._cursor)
190
+ case "enter":
191
+ if self._cursor == self._freeform_index:
192
+ self._enter_freeform()
193
+ elif self._allow_multiple:
194
+ chosen = self._checked or {self._cursor}
195
+ self._on_done(
196
+ {
197
+ "kind": "selection",
198
+ "selections": [self._options[i].title for i in sorted(chosen)],
199
+ }
200
+ )
201
+ else:
202
+ self._on_done(
203
+ {"kind": "selection", "selections": [self._options[self._cursor].title]}
204
+ )
205
+ case "escape":
206
+ self._on_done(None)
207
+ case _ if self._allow_freeform and _typed_char(event) is not None:
208
+ # Typing directly on the list view jumps straight into freeform
209
+ # entry instead of requiring the user to navigate to and Enter
210
+ # the "Type something…" row first.
211
+ self._enter_freeform(seed=_typed_char(event) or "")
212
+ case _:
213
+ return False
214
+ return True
215
+
216
+ def _handle_freeform_input(self, event: KeyEvent) -> bool:
217
+ if self._multiline:
218
+ return self._handle_multiline_input(event)
219
+
220
+ match event.key:
221
+ case "enter":
222
+ self._on_done({"kind": "freeform", "text": self._freeform_value})
223
+ case "escape":
224
+ # With no real choices there's no list to fall back to — Esc
225
+ # cancels the whole prompt (mirrors the multi-line editor).
226
+ if not self._options:
227
+ self._on_done(None)
228
+ else:
229
+ self._mode = "list"
230
+ self._freeform_value = ""
231
+ case "backspace":
232
+ self._freeform_value = self._freeform_value[:-1]
233
+ case _ if _typed_char(event) is not None:
234
+ self._freeform_value += _typed_char(event) or ""
235
+ case _:
236
+ return False
237
+ return True
238
+
239
+ def _ml_insert_newline(self) -> None:
240
+ line = self._ml_lines[self._ml_cursor_row]
241
+ before, after = line[: self._ml_cursor_col], line[self._ml_cursor_col :]
242
+ self._ml_lines[self._ml_cursor_row] = before
243
+ self._ml_lines.insert(self._ml_cursor_row + 1, after)
244
+ self._ml_cursor_row += 1
245
+ self._ml_cursor_col = 0
246
+
247
+ def _handle_multiline_input(self, event: KeyEvent) -> bool:
248
+ k = event.key
249
+
250
+ if k == "escape":
251
+ if not self._options:
252
+ self._on_done(None)
253
+ else:
254
+ self._mode = "list"
255
+ return True
256
+ if k == "enter":
257
+ # Shift+Enter always inserts a newline. Ctrl+S/Ctrl+Enter aren't
258
+ # reliable across terminals (Ctrl+S is XOFF flow control in many),
259
+ # so plain Enter submits — unless the line ends with a trailing
260
+ # "\", a shell-style continuation marker meaning "newline, please".
261
+ if event.shift:
262
+ self._ml_insert_newline()
263
+ return True
264
+ line = self._ml_lines[self._ml_cursor_row]
265
+ if self._ml_cursor_col > 0 and line[self._ml_cursor_col - 1] == "\\":
266
+ self._ml_lines[self._ml_cursor_row] = (
267
+ line[: self._ml_cursor_col - 1] + line[self._ml_cursor_col :]
268
+ )
269
+ self._ml_cursor_col -= 1
270
+ self._ml_insert_newline()
271
+ return True
272
+ self._on_done({"kind": "freeform", "text": "\n".join(self._ml_lines)})
273
+ return True
274
+ if k == "backspace":
275
+ if self._ml_cursor_col > 0:
276
+ line = self._ml_lines[self._ml_cursor_row]
277
+ self._ml_lines[self._ml_cursor_row] = (
278
+ line[: self._ml_cursor_col - 1] + line[self._ml_cursor_col :]
279
+ )
280
+ self._ml_cursor_col -= 1
281
+ elif self._ml_cursor_row > 0:
282
+ prev = self._ml_lines[self._ml_cursor_row - 1]
283
+ merged = prev + self._ml_lines.pop(self._ml_cursor_row)
284
+ self._ml_cursor_row -= 1
285
+ self._ml_cursor_col = len(prev)
286
+ self._ml_lines[self._ml_cursor_row] = merged
287
+ return True
288
+ if k == "up":
289
+ if self._ml_cursor_row > 0:
290
+ self._ml_cursor_row -= 1
291
+ row_len = len(self._ml_lines[self._ml_cursor_row])
292
+ self._ml_cursor_col = min(self._ml_cursor_col, row_len)
293
+ return True
294
+ if k == "down":
295
+ if self._ml_cursor_row < len(self._ml_lines) - 1:
296
+ self._ml_cursor_row += 1
297
+ row_len = len(self._ml_lines[self._ml_cursor_row])
298
+ self._ml_cursor_col = min(self._ml_cursor_col, row_len)
299
+ return True
300
+ if k == "left":
301
+ if self._ml_cursor_col > 0:
302
+ self._ml_cursor_col -= 1
303
+ elif self._ml_cursor_row > 0:
304
+ self._ml_cursor_row -= 1
305
+ self._ml_cursor_col = len(self._ml_lines[self._ml_cursor_row])
306
+ return True
307
+ if k == "right":
308
+ line = self._ml_lines[self._ml_cursor_row]
309
+ if self._ml_cursor_col < len(line):
310
+ self._ml_cursor_col += 1
311
+ elif self._ml_cursor_row < len(self._ml_lines) - 1:
312
+ self._ml_cursor_row += 1
313
+ self._ml_cursor_col = 0
314
+ return True
315
+ if k == "home":
316
+ self._ml_cursor_col = 0
317
+ return True
318
+ if k == "end":
319
+ self._ml_cursor_col = len(self._ml_lines[self._ml_cursor_row])
320
+ return True
321
+ ch = _typed_char(event)
322
+ if ch is not None:
323
+ line = self._ml_lines[self._ml_cursor_row]
324
+ self._ml_lines[self._ml_cursor_row] = (
325
+ line[: self._ml_cursor_col] + ch + line[self._ml_cursor_col :]
326
+ )
327
+ self._ml_cursor_col += len(ch)
328
+ return True
329
+ return False
330
+
331
+ def _clamp_ml_scroll(self) -> None:
332
+ if self._ml_cursor_row < self._ml_scroll_top:
333
+ self._ml_scroll_top = self._ml_cursor_row
334
+ elif self._ml_cursor_row >= self._ml_scroll_top + self.ML_VISIBLE_ROWS:
335
+ self._ml_scroll_top = self._ml_cursor_row - self.ML_VISIBLE_ROWS + 1
336
+ # Pull the window back down when lines below it are deleted (e.g. via
337
+ # backspace-merge) — otherwise the visible slice shrinks below
338
+ # ML_VISIBLE_ROWS even while there's still enough content to fill it.
339
+ max_scroll_top = max(0, len(self._ml_lines) - self.ML_VISIBLE_ROWS)
340
+ self._ml_scroll_top = max(0, min(self._ml_scroll_top, max_scroll_top))
341
+
342
+ def invalidate(self) -> None:
343
+ pass
344
+
345
+ def set_theme(self, theme: Any) -> None:
346
+ pass
@@ -0,0 +1,18 @@
1
+ {
2
+ "tau": {
3
+ "name": "Ask User",
4
+ "author": "jeomon",
5
+ "settings": {
6
+ "title": "Ask User",
7
+ "fields": [
8
+ {
9
+ "key": "enabled",
10
+ "label": "Enabled",
11
+ "type": "bool",
12
+ "default": true,
13
+ "description": "Register the ask_user tool."
14
+ }
15
+ ]
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,41 @@
1
+ from __future__ import annotations
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class AskUserOption(BaseModel):
7
+ title: str
8
+ description: str | None = None
9
+
10
+
11
+ class AskUserParams(BaseModel):
12
+ question: str = Field(..., description="The question to ask the user")
13
+ context: str | None = Field(
14
+ default=None, description="Relevant context summary shown before the question"
15
+ )
16
+ options: list[str | AskUserOption] | None = Field(
17
+ default=None, description="Multiple-choice options"
18
+ )
19
+ allow_multiple: bool = Field(default=False, description="Allow selecting more than one option")
20
+ allow_freeform: bool = Field(
21
+ default=True, description="Offer a 'Type something' freeform option"
22
+ )
23
+ multiline: bool = Field(
24
+ default=False,
25
+ description=(
26
+ "Use a multi-line text editor for the freeform answer instead of a single "
27
+ "line — set this for open-ended, long-form answers (e.g. 'write your bio', "
28
+ "'describe the requirements'). Supports arrow-key navigation between lines, "
29
+ "Enter for a newline, Ctrl+S/Ctrl+Enter to submit."
30
+ ),
31
+ )
32
+ timeout: int | None = Field(
33
+ default=None, description="Auto-dismiss after N ms and cancel if the prompt times out"
34
+ )
35
+
36
+
37
+ AskUserParams.model_rebuild()
38
+
39
+
40
+ def normalize_options(raw: list[str | AskUserOption] | None) -> list[AskUserOption]:
41
+ return [AskUserOption(title=o) if isinstance(o, str) else o for o in (raw or [])]
@@ -0,0 +1,129 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ from typing import Any
5
+
6
+ from component import _AskUserComponent
7
+ from schema import AskUserParams, normalize_options
8
+
9
+ from tau.tool.render import call_line
10
+ from tau.tool.types import (
11
+ Tool,
12
+ ToolContext,
13
+ ToolExecutionMode,
14
+ ToolInvocation,
15
+ ToolKind,
16
+ ToolResult,
17
+ )
18
+
19
+
20
+ def _render_call(args: dict, _streaming: bool = False) -> list[str]:
21
+ return call_line("ask_user", args.get("question", ""))
22
+
23
+
24
+ def _render_result(content: str, opts: Any) -> list[str]:
25
+ return content.splitlines() or [content]
26
+
27
+
28
+ class AskUserTool(Tool):
29
+ def __init__(self, runtime_ref: Any) -> None:
30
+ self._runtime_ref = runtime_ref
31
+ super().__init__(
32
+ name="ask_user",
33
+ description=(
34
+ "Ask the human a focused question and wait for their decision before "
35
+ "proceeding. Use for high-impact architectural trade-offs, ambiguous or "
36
+ "conflicting requirements, or assumptions that would materially change "
37
+ "the implementation. Supports single-select, multi-select, and freeform "
38
+ "text answers. Only available in an interactive TUI session."
39
+ ),
40
+ schema=AskUserParams,
41
+ kind=ToolKind.Read,
42
+ execution_mode=ToolExecutionMode.Sequential,
43
+ render_call=_render_call,
44
+ render_result=_render_result,
45
+ render_shell="default",
46
+ )
47
+
48
+ async def execute(
49
+ self,
50
+ invocation: ToolInvocation,
51
+ tool_execution_update_callback=None,
52
+ signal=None,
53
+ context: ToolContext | None = None,
54
+ ) -> ToolResult:
55
+ params = AskUserParams.model_validate(invocation.params)
56
+ options = normalize_options(params.options)
57
+
58
+ runtime = self._runtime_ref.runtime if self._runtime_ref is not None else None
59
+ if runtime is None:
60
+ return ToolResult.error(invocation.id, "ask_user unavailable: runtime not ready")
61
+
62
+ from tau.extensions.context import ExtensionContext
63
+
64
+ ext_ctx = ExtensionContext.from_runtime(runtime)
65
+ ui = ext_ctx.ui
66
+ if ui is None:
67
+ return ToolResult.error(
68
+ invocation.id,
69
+ "ask_user requires an interactive TUI session and is "
70
+ "unavailable in headless/RPC mode",
71
+ )
72
+
73
+ from tau.tui.tui import CustomOptions, OverlayOptions
74
+
75
+ loop = asyncio.get_running_loop()
76
+ fut: asyncio.Future[dict | None] = loop.create_future()
77
+ timeout_task_ref: list[asyncio.Task | None] = [None]
78
+
79
+ def _on_done(value: dict | None) -> None:
80
+ t = timeout_task_ref[0]
81
+ if t is not None and not t.done():
82
+ t.cancel()
83
+ if not fut.done():
84
+ fut.set_result(value)
85
+
86
+ def _factory(_tui, _theme, _kb, done):
87
+ component = _AskUserComponent(
88
+ question=params.question,
89
+ context=params.context,
90
+ options=options,
91
+ allow_multiple=params.allow_multiple,
92
+ allow_freeform=params.allow_freeform,
93
+ multiline=params.multiline,
94
+ on_done=lambda v: (_on_done(v), done(v)),
95
+ )
96
+ timeout_ms = params.timeout
97
+ if timeout_ms:
98
+
99
+ async def _auto_dismiss() -> None:
100
+ await asyncio.sleep(timeout_ms / 1000)
101
+ _on_done(None)
102
+ done(None)
103
+
104
+ timeout_task_ref[0] = asyncio.ensure_future(_auto_dismiss())
105
+ return component
106
+
107
+ await ui.custom(
108
+ _factory,
109
+ CustomOptions(overlay_options=OverlayOptions(width="70%", anchor="center", margin=1)),
110
+ )
111
+ response = await fut
112
+
113
+ if response is None:
114
+ return ToolResult.ok(
115
+ invocation.id,
116
+ "The user cancelled the question without answering.",
117
+ metadata={"cancelled": True, "question": params.question},
118
+ )
119
+
120
+ if response["kind"] == "freeform":
121
+ content = response["text"]
122
+ else:
123
+ content = ", ".join(response["selections"])
124
+
125
+ return ToolResult.ok(
126
+ invocation.id,
127
+ content,
128
+ metadata={"cancelled": False, "question": params.question, "response": response},
129
+ )
@@ -100,6 +100,7 @@ async def _fetch(url: str) -> dict[str, str]:
100
100
  "-o",
101
101
  out_tmpl,
102
102
  url,
103
+ stdin=asyncio.subprocess.DEVNULL,
103
104
  stdout=asyncio.subprocess.PIPE,
104
105
  stderr=asyncio.subprocess.PIPE,
105
106
  )