tau-coding-agent 0.3.9__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. {tau_coding_agent-0.3.9/tau_coding_agent.egg-info → tau_coding_agent-0.4.0}/PKG-INFO +3 -3
  2. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/README.md +2 -2
  3. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/extension-settings.md +211 -6
  4. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/pyproject.toml +1 -1
  5. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/agent/service.py +59 -12
  6. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/extensions/footer/git.py +1 -1
  7. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/extensions/footer/model.py +1 -1
  8. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/extensions/header/__init__.py +1 -1
  9. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/models/text.py +29 -0
  10. tau_coding_agent-0.4.0/tau/builtins/providers/audio.py +22 -0
  11. tau_coding_agent-0.4.0/tau/builtins/providers/image.py +31 -0
  12. tau_coding_agent-0.4.0/tau/builtins/providers/video.py +11 -0
  13. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/tools/edit.py +1 -1
  14. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/tools/glob.py +2 -2
  15. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/tools/grep.py +14 -5
  16. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/tools/ls.py +1 -1
  17. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/tools/read.py +1 -1
  18. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/tools/terminal.py +48 -19
  19. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/tools/write.py +1 -1
  20. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/console/cli.py +61 -11
  21. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/engine/service.py +237 -161
  22. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/extensions/api.py +151 -10
  23. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/extensions/context.py +68 -0
  24. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/extensions/loader.py +52 -6
  25. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/service.py +13 -1
  26. tau_coding_agent-0.4.0/tau/inference/api/availability.py +64 -0
  27. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/image/service.py +8 -1
  28. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/anthropic_claude_code.py +5 -1
  29. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/anthropic_messages.py +5 -1
  30. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/anthropic_vertex.py +6 -2
  31. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/google_antigravity.py +4 -1
  32. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/google_vertex.py +3 -1
  33. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/service.py +10 -35
  34. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/video/service.py +8 -1
  35. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/model/types.py +10 -0
  36. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/oauth/__init__.py +11 -0
  37. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/registry.py +3 -3
  38. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/types.py +6 -3
  39. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/agent_hooks.py +2 -2
  40. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/app.py +108 -63
  41. tau_coding_agent-0.4.0/tau/modes/interactive/commands/__init__.py +3 -0
  42. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/commands/appearance.py +47 -12
  43. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/commands/auth.py +79 -43
  44. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/commands/context.py +1 -1
  45. tau_coding_agent-0.4.0/tau/modes/interactive/commands/extensions.py +107 -0
  46. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/commands/misc.py +1 -1
  47. tau_coding_agent-0.4.0/tau/modes/interactive/commands/model.py +198 -0
  48. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/commands/session.py +11 -7
  49. tau_coding_agent-0.4.0/tau/modes/interactive/components/__init__.py +0 -0
  50. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/components/command_palette.py +18 -9
  51. tau_coding_agent-0.4.0/tau/modes/interactive/components/config_selector.py +225 -0
  52. tau_coding_agent-0.4.0/tau/modes/interactive/components/extension_selector.py +116 -0
  53. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/components/file_picker.py +21 -10
  54. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/components/layout.py +361 -124
  55. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/components/message_list.py +7 -6
  56. tau_coding_agent-0.4.0/tau/modes/interactive/components/model_selector.py +283 -0
  57. tau_coding_agent-0.4.0/tau/modes/interactive/components/oauth_selector.py +128 -0
  58. tau_coding_agent-0.3.9/tau/tui/components/prompt_overlay.py → tau_coding_agent-0.4.0/tau/modes/interactive/components/overlays.py +163 -3
  59. tau_coding_agent-0.3.9/tau/tui/components/resume_modal.py → tau_coding_agent-0.4.0/tau/modes/interactive/components/session_selector.py +44 -46
  60. tau_coding_agent-0.4.0/tau/modes/interactive/components/settings_selector.py +619 -0
  61. tau_coding_agent-0.4.0/tau/modes/interactive/components/theme_selector.py +103 -0
  62. tau_coding_agent-0.4.0/tau/modes/interactive/components/thinking_selector.py +94 -0
  63. tau_coding_agent-0.3.9/tau/tui/components/tree_select_list.py → tau_coding_agent-0.4.0/tau/modes/interactive/components/tree_selector.py +2 -2
  64. {tau_coding_agent-0.3.9/tau/tui → tau_coding_agent-0.4.0/tau/modes/interactive}/components/trust_screen.py +16 -15
  65. tau_coding_agent-0.4.0/tau/modes/print/__init__.py +0 -0
  66. tau_coding_agent-0.4.0/tau/modes/rpc/__init__.py +8 -0
  67. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/runtime/service.py +22 -11
  68. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/runtime/types.py +13 -11
  69. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/settings/manager.py +66 -25
  70. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/settings/types.py +27 -3
  71. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/themes/loader.py +77 -3
  72. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/themes/registry.py +15 -0
  73. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tool/render.py +1 -1
  74. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tool/types.py +9 -0
  75. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/__init__.py +16 -1
  76. tau_coding_agent-0.3.9/tau/tui/components/autocomplete_manager.py → tau_coding_agent-0.4.0/tau/tui/autocomplete.py +209 -9
  77. tau_coding_agent-0.4.0/tau/tui/component.py +512 -0
  78. tau_coding_agent-0.4.0/tau/tui/components/__init__.py +0 -0
  79. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/components/box.py +17 -1
  80. tau_coding_agent-0.4.0/tau/tui/components/editor.py +72 -0
  81. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/components/image.py +1 -1
  82. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/components/select_list.py +41 -4
  83. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/components/text_input.py +102 -8
  84. tau_coding_agent-0.3.9/tau/tui/input_handler.py → tau_coding_agent-0.4.0/tau/tui/input.py +933 -1
  85. tau_coding_agent-0.4.0/tau/tui/keybinding_hints.py +40 -0
  86. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/markdown.py +41 -7
  87. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/terminal.py +136 -6
  88. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/theme.py +20 -2
  89. tau_coding_agent-0.4.0/tau/tui/tui.py +1266 -0
  90. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/ui_context.py +90 -6
  91. tau_coding_agent-0.3.9/tau/tui/ansi.py → tau_coding_agent-0.4.0/tau/tui/utils.py +235 -0
  92. tau_coding_agent-0.4.0/tau/utils/__init__.py +0 -0
  93. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0/tau_coding_agent.egg-info}/PKG-INFO +3 -3
  94. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau_coding_agent.egg-info/SOURCES.txt +42 -39
  95. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_ansi.py +11 -11
  96. tau_coding_agent-0.4.0/tests/test_auth_command.py +41 -0
  97. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_diff.py +1 -1
  98. tau_coding_agent-0.4.0/tests/test_editor_protocol.py +67 -0
  99. tau_coding_agent-0.4.0/tests/test_engine_steering.py +274 -0
  100. tau_coding_agent-0.4.0/tests/test_extension_api.py +182 -0
  101. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_fuzzy.py +1 -1
  102. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_keybindings.py +4 -4
  103. tau_coding_agent-0.4.0/tests/test_model_availability.py +118 -0
  104. tau_coding_agent-0.4.0/tests/test_model_selector_modal.py +153 -0
  105. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_provider_registry.py +6 -6
  106. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_rpc_mode.py +1 -1
  107. tau_coding_agent-0.4.0/tests/test_settings_manager.py +253 -0
  108. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_tool_render.py +1 -1
  109. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_tui_capabilities.py +1 -1
  110. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_tui_input.py +70 -1
  111. tau_coding_agent-0.4.0/tests/test_tui_layout_sizing.py +182 -0
  112. tau_coding_agent-0.3.9/tau/builtins/providers/audio.py +0 -10
  113. tau_coding_agent-0.3.9/tau/builtins/providers/image.py +0 -15
  114. tau_coding_agent-0.3.9/tau/builtins/providers/video.py +0 -8
  115. tau_coding_agent-0.3.9/tau/rpc/__init__.py +0 -8
  116. tau_coding_agent-0.3.9/tau/tui/autocomplete.py +0 -36
  117. tau_coding_agent-0.3.9/tau/tui/capabilities.py +0 -124
  118. tau_coding_agent-0.3.9/tau/tui/commands/__init__.py +0 -3
  119. tau_coding_agent-0.3.9/tau/tui/commands/model.py +0 -129
  120. tau_coding_agent-0.3.9/tau/tui/component.py +0 -258
  121. tau_coding_agent-0.3.9/tau/tui/components/autocomplete_picker.py +0 -147
  122. tau_coding_agent-0.3.9/tau/tui/components/dynamic_border.py +0 -19
  123. tau_coding_agent-0.3.9/tau/tui/components/inline_selector.py +0 -73
  124. tau_coding_agent-0.3.9/tau/tui/components/modal.py +0 -97
  125. tau_coding_agent-0.3.9/tau/tui/components/model_palette.py +0 -221
  126. tau_coding_agent-0.3.9/tau/tui/components/picker_overlay.py +0 -178
  127. tau_coding_agent-0.3.9/tau/tui/components/settings_modal.py +0 -279
  128. tau_coding_agent-0.3.9/tau/tui/components/settings_schema.py +0 -223
  129. tau_coding_agent-0.3.9/tau/tui/components/text_prompt.py +0 -83
  130. tau_coding_agent-0.3.9/tau/tui/diff.py +0 -114
  131. tau_coding_agent-0.3.9/tau/tui/fuzzy.py +0 -99
  132. tau_coding_agent-0.3.9/tau/tui/input.py +0 -775
  133. tau_coding_agent-0.3.9/tau/tui/keybindings.py +0 -90
  134. tau_coding_agent-0.3.9/tau/tui/message_renderers.py +0 -32
  135. tau_coding_agent-0.3.9/tau/tui/overlay.py +0 -334
  136. tau_coding_agent-0.3.9/tau/tui/renderer.py +0 -390
  137. tau_coding_agent-0.3.9/tau/tui/tui.py +0 -563
  138. tau_coding_agent-0.3.9/tau/tui/utils.py +0 -20
  139. tau_coding_agent-0.3.9/tests/test_settings_manager.py +0 -150
  140. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/LICENSE +0 -0
  141. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/MANIFEST.in +0 -0
  142. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/IMPLEMENTATION_SUMMARY.md +0 -0
  143. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/architecture.md +0 -0
  144. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/auth.md +0 -0
  145. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/cli-reference.md +0 -0
  146. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/development.md +0 -0
  147. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/docs.json +0 -0
  148. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/extensions.md +0 -0
  149. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/http-proxy.md +0 -0
  150. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/index.md +0 -0
  151. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/inference-providers.md +0 -0
  152. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/installation.md +0 -0
  153. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/keybindings.md +0 -0
  154. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/messages.md +0 -0
  155. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/project-context.md +0 -0
  156. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/project-structure.md +0 -0
  157. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/prompts.md +0 -0
  158. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/python-api.md +0 -0
  159. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/quickstart.md +0 -0
  160. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/sessions.md +0 -0
  161. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/settings.md +0 -0
  162. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/skills.md +0 -0
  163. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/themes.md +0 -0
  164. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/tools.md +0 -0
  165. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/docs/usage.md +0 -0
  166. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/setup.cfg +0 -0
  167. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/__init__.py +0 -0
  168. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/agent/__init__.py +0 -0
  169. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/agent/prompt/__init__.py +0 -0
  170. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/agent/prompt/builder.py +0 -0
  171. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/agent/prompt/types.py +0 -0
  172. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/agent/types.py +0 -0
  173. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/auth/manager.py +0 -0
  174. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/auth/storage.py +0 -0
  175. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/auth/types.py +0 -0
  176. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/__init__.py +0 -0
  177. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/commands/__init__.py +0 -0
  178. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/commands/clear.py +0 -0
  179. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/commands/compact.py +0 -0
  180. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/commands/reload.py +0 -0
  181. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/commands/session.py +0 -0
  182. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/extensions/footer/__init__.py +0 -0
  183. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/extensions/footer/utils.py +0 -0
  184. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/models/__init__.py +0 -0
  185. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/models/audio.py +0 -0
  186. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/models/image.py +0 -0
  187. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/models/video.py +0 -0
  188. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/prompts/commit.md +0 -0
  189. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/prompts/docs.md +0 -0
  190. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/prompts/explain.md +0 -0
  191. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/prompts/fix.md +0 -0
  192. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/prompts/refactor.md +0 -0
  193. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/prompts/review.md +0 -0
  194. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/prompts/test.md +0 -0
  195. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/providers/__init__.py +0 -0
  196. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/providers/text.py +0 -0
  197. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/skills/code-review/SKILL.md +0 -0
  198. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/skills/debug/SKILL.md +0 -0
  199. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/skills/git-commit/SKILL.md +0 -0
  200. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/themes/dark.yaml +0 -0
  201. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/themes/light.yaml +0 -0
  202. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/builtins/tools/__init__.py +0 -0
  203. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/commands/__init__.py +0 -0
  204. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/commands/registry.py +0 -0
  205. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/commands/types.py +0 -0
  206. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/console/__init__.py +0 -0
  207. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/console/commands/__init__.py +0 -0
  208. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/console/commands/auth.py +0 -0
  209. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/console/commands/packages.py +0 -0
  210. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/console/commands/update.py +0 -0
  211. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/core/__init__.py +0 -0
  212. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/core/registry.py +0 -0
  213. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/engine/__init__.py +0 -0
  214. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/engine/types.py +0 -0
  215. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/extensions/__init__.py +0 -0
  216. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/extensions/runtime.py +0 -0
  217. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/extensions/settings.py +0 -0
  218. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/hooks/__init__.py +0 -0
  219. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/hooks/engine.py +0 -0
  220. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/hooks/inference.py +0 -0
  221. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/hooks/runtime.py +0 -0
  222. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/hooks/service.py +0 -0
  223. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/hooks/session.py +0 -0
  224. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/hooks/tui.py +0 -0
  225. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/hooks/types.py +0 -0
  226. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/__init__.py +0 -0
  227. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/__init__.py +0 -0
  228. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/__init__.py +0 -0
  229. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/base.py +0 -0
  230. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/builtins.py +0 -0
  231. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/elevenlabs_audio.py +0 -0
  232. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/gemini_audio.py +0 -0
  233. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/openai_audio.py +0 -0
  234. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/registry.py +0 -0
  235. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/sarvam_audio.py +0 -0
  236. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/audio/utils.py +0 -0
  237. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/image/__init__.py +0 -0
  238. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/image/base.py +0 -0
  239. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/image/builtins.py +0 -0
  240. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/image/gemini_image.py +0 -0
  241. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/image/openai_image.py +0 -0
  242. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/image/openrouter.py +0 -0
  243. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/image/registry.py +0 -0
  244. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/registry.py +0 -0
  245. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/__init__.py +0 -0
  246. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/base.py +0 -0
  247. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/builtins.py +0 -0
  248. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/gemini_generate.py +0 -0
  249. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/github_copilot_chat.py +0 -0
  250. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/mistral_chat.py +0 -0
  251. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/ollama_chat.py +0 -0
  252. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/openai_codex_responses.py +0 -0
  253. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/openai_completions.py +0 -0
  254. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/openai_responses.py +0 -0
  255. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/openai_vertex.py +0 -0
  256. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/registry.py +0 -0
  257. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/types.py +0 -0
  258. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/text/utils.py +0 -0
  259. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/video/__init__.py +0 -0
  260. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/video/base.py +0 -0
  261. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/video/builtins.py +0 -0
  262. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/video/fal_video.py +0 -0
  263. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/video/openrouter_video.py +0 -0
  264. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/api/video/registry.py +0 -0
  265. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/model/__init__.py +0 -0
  266. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/model/registry.py +0 -0
  267. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/__init__.py +0 -0
  268. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/oauth/anthropic_claude_code.py +0 -0
  269. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/oauth/github_copilot.py +0 -0
  270. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/oauth/google_antigravity.py +0 -0
  271. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/oauth/openai_codex.py +0 -0
  272. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/oauth/pkce.py +0 -0
  273. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/oauth/types.py +0 -0
  274. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/provider/oauth/utils.py +0 -0
  275. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/types.py +0 -0
  276. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/inference/utils.py +0 -0
  277. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/message/__init__.py +0 -0
  278. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/message/types.py +0 -0
  279. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/message/utils.py +0 -0
  280. {tau_coding_agent-0.3.9/tau/tui/components → tau_coding_agent-0.4.0/tau/modes}/__init__.py +0 -0
  281. {tau_coding_agent-0.3.9/tau/utils → tau_coding_agent-0.4.0/tau/modes/interactive}/__init__.py +0 -0
  282. {tau_coding_agent-0.3.9/tau → tau_coding_agent-0.4.0/tau/modes}/rpc/mode.py +0 -0
  283. {tau_coding_agent-0.3.9/tau → tau_coding_agent-0.4.0/tau/modes}/rpc/types.py +0 -0
  284. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/packages/__init__.py +0 -0
  285. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/packages/manager.py +0 -0
  286. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/packages/types.py +0 -0
  287. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/packages/utils.py +0 -0
  288. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/prompts/expand.py +0 -0
  289. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/prompts/loader.py +0 -0
  290. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/prompts/registry.py +0 -0
  291. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/prompts/types.py +0 -0
  292. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/session/branch_summarization.py +0 -0
  293. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/session/compaction.py +1 -1
  294. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/session/manager.py +0 -0
  295. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/session/types.py +0 -0
  296. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/session/utils.py +1 -1
  297. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/settings/paths.py +0 -0
  298. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/settings/storage.py +0 -0
  299. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/settings/utils.py +0 -0
  300. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/skills/loader.py +0 -0
  301. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/skills/registry.py +0 -0
  302. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/skills/types.py +0 -0
  303. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/themes/types.py +0 -0
  304. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tool/__init__.py +0 -0
  305. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tool/registry.py +0 -0
  306. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/trust/__init__.py +0 -0
  307. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/trust/manager.py +0 -0
  308. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/trust/types.py +0 -0
  309. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/trust/utils.py +0 -0
  310. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/tui/components/spinner.py +0 -0
  311. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/utils/http_proxy.py +0 -0
  312. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/utils/image_processing.py +0 -0
  313. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/utils/secrets.py +0 -0
  314. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau/utils/version_check.py +0 -0
  315. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau_coding_agent.egg-info/dependency_links.txt +0 -0
  316. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau_coding_agent.egg-info/entry_points.txt +0 -0
  317. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau_coding_agent.egg-info/requires.txt +0 -0
  318. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tau_coding_agent.egg-info/top_level.txt +0 -0
  319. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_agent_prompt.py +0 -0
  320. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_agent_types.py +0 -0
  321. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_auth_manager.py +0 -0
  322. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_auth_storage.py +0 -0
  323. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_branch_summarization.py +0 -0
  324. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_builtin_tools.py +0 -0
  325. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_command_registry.py +0 -0
  326. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_compaction.py +0 -0
  327. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_engine_types.py +0 -0
  328. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_footer_utils.py +0 -0
  329. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_http_proxy.py +0 -0
  330. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_image_processing.py +0 -0
  331. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_inference_api_text_utils.py +0 -0
  332. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_inference_error_utils.py +0 -0
  333. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_inference_types.py +0 -0
  334. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_inference_utils.py +0 -0
  335. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_markdown.py +0 -0
  336. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_message_types.py +0 -0
  337. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_message_utils.py +0 -0
  338. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_model_registry.py +0 -0
  339. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_model_types.py +0 -0
  340. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_oauth_utils.py +0 -0
  341. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_packages_utils.py +0 -0
  342. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_pkce.py +0 -0
  343. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_prompts_expand.py +0 -0
  344. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_prompts_loader.py +0 -0
  345. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_prompts_registry.py +0 -0
  346. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_secrets.py +0 -0
  347. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_session_trust_persist.py +0 -0
  348. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_session_types.py +0 -0
  349. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_session_utils.py +0 -0
  350. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_settings_paths.py +0 -0
  351. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_settings_storage.py +0 -0
  352. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_settings_utils.py +0 -0
  353. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_skills_loader.py +0 -0
  354. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_skills_registry.py +0 -0
  355. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_text_llm_invoke.py +0 -0
  356. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_theme_loader.py +0 -0
  357. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_themes_registry.py +0 -0
  358. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_tool_registry.py +0 -0
  359. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_trust_manager.py +0 -0
  360. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_trust_utils.py +0 -0
  361. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_tui_theme.py +0 -0
  362. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_tui_utils.py +0 -0
  363. {tau_coding_agent-0.3.9 → tau_coding_agent-0.4.0}/tests/test_version_check.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tau-coding-agent
3
- Version: 0.3.9
3
+ Version: 0.4.0
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
@@ -32,7 +32,7 @@ Dynamic: license-file
32
32
 
33
33
  # Tau (τ)
34
34
 
35
- Inspired by [Pi](https://pi.dev), **Tau** brings the same agent framework capabilities to Python developers. A self-extensible agent CLI with a terminal UI, multi-provider LLM support, session management with branching, and a plugin system for tools, commands, and customization.
35
+ A Python reimplementation of [Pi](https://pi.dev), **Tau** brings the same agent framework capabilities to Python developers. A self-extensible agent CLI with a terminal UI, multi-provider LLM support, session management with branching, and a plugin system for tools, commands, and customization.
36
36
 
37
37
  <p align="center">
38
38
  <img src="assets/tui.png" alt="Tau TUI" width="700">
@@ -47,7 +47,7 @@ Start a conversation with the agent in the terminal.
47
47
  ### Installation
48
48
 
49
49
  ```bash
50
- pip install tau-coding-agent
50
+ uv pip install tau-coding-agent
51
51
  ```
52
52
 
53
53
  Or install from source:
@@ -1,6 +1,6 @@
1
1
  # Tau (τ)
2
2
 
3
- Inspired by [Pi](https://pi.dev), **Tau** brings the same agent framework capabilities to Python developers. A self-extensible agent CLI with a terminal UI, multi-provider LLM support, session management with branching, and a plugin system for tools, commands, and customization.
3
+ A Python reimplementation of [Pi](https://pi.dev), **Tau** brings the same agent framework capabilities to Python developers. A self-extensible agent CLI with a terminal UI, multi-provider LLM support, session management with branching, and a plugin system for tools, commands, and customization.
4
4
 
5
5
  <p align="center">
6
6
  <img src="assets/tui.png" alt="Tau TUI" width="700">
@@ -15,7 +15,7 @@ Start a conversation with the agent in the terminal.
15
15
  ### Installation
16
16
 
17
17
  ```bash
18
- pip install tau-coding-agent
18
+ uv pip install tau-coding-agent
19
19
  ```
20
20
 
21
21
  Or install from source:
@@ -21,7 +21,7 @@ def register(tau):
21
21
  timeout = config.get("timeout_ms", 5000)
22
22
  ```
23
23
 
24
- In `~/.tau/settings.json` or `.tau/settings.json`:
24
+ The values are stored in `~/.tau/settings.json` (global) or `.tau/settings.json` (project-local):
25
25
 
26
26
  ```json
27
27
  {
@@ -39,6 +39,71 @@ In `~/.tau/settings.json` or `.tau/settings.json`:
39
39
  }
40
40
  ```
41
41
 
42
+ ### Where settings live
43
+
44
+ Settings for an extension are stored in the `settings` object of its entry inside `extensions.list`. Tau matches entries by path — the path in the list must match the path or directory the extension was loaded from.
45
+
46
+ **Project-local** — `.tau/settings.json` (only applies in this directory):
47
+
48
+ ```json
49
+ {
50
+ "extensions": {
51
+ "list": [
52
+ {
53
+ "path": ".tau/extensions/lsp",
54
+ "settings": {
55
+ "lsp": true,
56
+ "eager": [],
57
+ "servers": {
58
+ "pyright": { "enabled": true },
59
+ "ruff": { "enabled": true },
60
+ "typescript-language-server": { "enabled": false }
61
+ }
62
+ }
63
+ },
64
+ {
65
+ "path": ".tau/extensions/voice",
66
+ "settings": {
67
+ "enabled": true,
68
+ "stt_model": "whisper-1",
69
+ "stt_provider": "openai",
70
+ "hold_seconds": 2,
71
+ "sample_rate": 16000
72
+ }
73
+ }
74
+ ]
75
+ }
76
+ }
77
+ ```
78
+
79
+ **Global** — `~/.tau/settings.json` (applies to every project):
80
+
81
+ ```json
82
+ {
83
+ "extensions": {
84
+ "list": [
85
+ {
86
+ "path": "~/.tau/extensions/web-search",
87
+ "settings": {
88
+ "enabled": true,
89
+ "engine": "ddgs",
90
+ "results": 10
91
+ }
92
+ },
93
+ {
94
+ "path": "~/.tau/extensions/my_ext.py",
95
+ "settings": {
96
+ "api_key": "sk-...",
97
+ "timeout_ms": 5000
98
+ }
99
+ }
100
+ ]
101
+ }
102
+ }
103
+ ```
104
+
105
+ Both files can coexist — project settings are merged on top of global settings at startup. Extensions loaded from `.tau/extensions/` read from the project file; extensions loaded from `~/.tau/extensions/` read from the global file.
106
+
42
107
  ## Nested Structures
43
108
 
44
109
  `ExtensionSettings` handles nested configuration just as naturally:
@@ -237,7 +302,147 @@ def register(tau):
237
302
 
238
303
  Extensions can register settings items that appear as a named sub-panel at the bottom of the interactive `/settings` panel. Users can then edit extension settings from the TUI without touching JSON.
239
304
 
240
- ### Basic example
305
+ There are two ways to do this: declare the schema in `manifest.json` (recommended for directory extensions) or register it imperatively with `tau.register_settings()` (useful for single-file extensions).
306
+
307
+ ---
308
+
309
+ ### Option A — manifest.json schema (recommended)
310
+
311
+ Add a `"settings"` block under the `"tau"` key in `manifest.json`. Tau reads it at load time, builds the `/settings` sub-panel automatically, reads current values from the extension's config, and persists changes back to `settings.json` (reloading just that extension so the change applies live — no restart needed).
312
+
313
+ ```json
314
+ {
315
+ "tau": {
316
+ "extensions": ["__init__.py"],
317
+ "dependencies": ["requests"],
318
+ "settings": {
319
+ "title": "Web search",
320
+ "fields": [
321
+ {
322
+ "key": "enabled",
323
+ "label": "Enabled",
324
+ "type": "bool",
325
+ "default": true,
326
+ "description": "Enable or disable the web search extension."
327
+ },
328
+ {
329
+ "key": "engine",
330
+ "label": "Search engine",
331
+ "type": "enum",
332
+ "values": ["ddgs", "exa", "tavily"],
333
+ "default": "ddgs",
334
+ "description": "Which search backend to use."
335
+ },
336
+ {
337
+ "key": "results",
338
+ "label": "Max results",
339
+ "type": "int",
340
+ "default": 10,
341
+ "min": 1,
342
+ "max": 50,
343
+ "description": "Number of results returned per query."
344
+ },
345
+ {
346
+ "key": "api_key",
347
+ "label": "API key",
348
+ "type": "secret",
349
+ "default": "",
350
+ "description": "Provider API key (stored in settings.json)."
351
+ },
352
+ {
353
+ "key": "exa",
354
+ "label": "Exa settings",
355
+ "type": "group",
356
+ "fields": [
357
+ {
358
+ "key": "base_url",
359
+ "label": "Base URL",
360
+ "type": "string",
361
+ "default": "https://api.exa.ai"
362
+ },
363
+ {
364
+ "key": "highlights",
365
+ "label": "Highlights",
366
+ "type": "bool",
367
+ "default": true
368
+ }
369
+ ]
370
+ }
371
+ ]
372
+ }
373
+ }
374
+ }
375
+ ```
376
+
377
+ The corresponding `.tau/settings.json` entry that stores the current values:
378
+
379
+ ```json
380
+ {
381
+ "extensions": {
382
+ "list": [
383
+ {
384
+ "path": ".tau/extensions/web-search",
385
+ "settings": {
386
+ "enabled": true,
387
+ "engine": "exa",
388
+ "results": 20,
389
+ "api_key": "sk-exa-...",
390
+ "exa": {
391
+ "base_url": "https://api.exa.ai",
392
+ "highlights": false
393
+ }
394
+ }
395
+ }
396
+ ]
397
+ }
398
+ }
399
+ ```
400
+
401
+ #### Field types
402
+
403
+ | Type | UI control | Notes |
404
+ |------|-----------|-------|
405
+ | `bool` | Toggle `off` / `on` | Stored as a JSON boolean in settings |
406
+ | `int` | Text input (numeric) | Optional `min` and `max` clamps |
407
+ | `string` | Text input | Optional `pattern` (regex the value must match) |
408
+ | `secret` | Text input | Same as `string`; signals sensitive content |
409
+ | `text` | Text input | Same as `string`; intended for longer values |
410
+ | `enum` or `select` | Cycle through values on Enter | Requires a non-empty `"values"` list |
411
+ | `group` | Opens a nested sub-panel | Contains a `"fields"` list; keys are prefixed |
412
+
413
+ #### Field properties
414
+
415
+ | Property | Required | Description |
416
+ |----------|----------|-------------|
417
+ | `key` | Yes | Setting key. Supports dot-notation: `"exa.api_key"` is equivalent to nesting under a `"exa"` group |
418
+ | `label` | Yes | Display text shown in the `/settings` panel |
419
+ | `type` | No (defaults to `string`) | One of the types listed above |
420
+ | `default` | No | Fallback value when the key is absent from settings |
421
+ | `description` | No | Dimmed help text shown below the label |
422
+ | `values` | `enum`/`select` only | List of allowed values to cycle through |
423
+ | `min` / `max` | `int` only | Clamp the entered value to this range |
424
+ | `pattern` | `string`/`secret`/`text` | Regex the value must fully match; invalid input is silently ignored |
425
+ | `fields` | `group` only | Nested list of field definitions |
426
+
427
+ #### Summary badge
428
+
429
+ The first top-level `bool` field is automatically used as an on/off summary badge on the extension's parent row in the main `/settings` list. This lets users see at a glance whether an extension is enabled without opening its sub-panel.
430
+
431
+ #### Dot-notation keys
432
+
433
+ `"key": "exa.api_key"` at the top level is exactly equivalent to a field with `"key": "api_key"` nested inside a group with `"key": "exa"`. Both read and write the same path in settings:
434
+
435
+ ```json
436
+ { "exa": { "api_key": "sk-..." } }
437
+ ```
438
+
439
+ Use the explicit `group` type when you want the sub-panel to have a header label. Use dot-notation directly when you just want nested storage without the extra level of UI.
440
+
441
+ ---
442
+
443
+ ### Option B — `tau.register_settings()` (imperative)
444
+
445
+ #### Basic example
241
446
 
242
447
  ```python
243
448
  from tau.tui.components.settings_modal import SettingItem
@@ -254,7 +459,7 @@ def register(tau):
254
459
  ], title="My Extension", on_change=on_change)
255
460
  ```
256
461
 
257
- ### `tau.register_settings(items, title, on_change)`
462
+ #### `tau.register_settings(items, title, on_change)`
258
463
 
259
464
  Registers a sub-panel in `/settings` containing the provided items.
260
465
 
@@ -264,7 +469,7 @@ Registers a sub-panel in `/settings` containing the provided items.
264
469
  | `title` | `str` | The sub-panel title shown in the list |
265
470
  | `on_change` | `callable(key, value)` | Called when the user changes a value |
266
471
 
267
- ### `SettingItem` fields
472
+ #### `SettingItem` fields
268
473
 
269
474
  | Field | Type | Description |
270
475
  |-------|------|-------------|
@@ -278,7 +483,7 @@ Registers a sub-panel in `/settings` containing the provided items.
278
483
  | `submenu_settings` | `list[SettingItem] \| None` | Open a full nested sub-panel with these items (arbitrary depth) |
279
484
  | `submenu_on_change` | `callable \| None` | Overrides the parent `on_change` for a nested sub-panel |
280
485
 
281
- ### Nested sub-panels
486
+ #### Nested sub-panels
282
487
 
283
488
  A `SettingItem` with `submenu_settings` opens another level of the settings panel. Nesting can be arbitrarily deep. Use `submenu_on_change` to override the change callback for that level:
284
489
 
@@ -298,7 +503,7 @@ tau.register_settings([
298
503
  ], title="My Extension", on_change=on_change)
299
504
  ```
300
505
 
301
- ### `tau.settings.set_extension_config_key(ext_path, key, value)`
506
+ #### `tau.settings.set_extension_config_key(ext_path, key, value)`
302
507
 
303
508
  Persists a value back to `extensions.list[].settings` in `settings.json`.
304
509
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tau-coding-agent"
7
- version = "0.3.9"
7
+ version = "0.4.0"
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"
@@ -6,6 +6,7 @@ from pathlib import Path
6
6
  from typing import TYPE_CHECKING
7
7
 
8
8
  from tau.agent.types import AgentConfig, AgentContext, AgentPhase, ContextUsage, PromptOptions
9
+ from tau.hooks.engine import CompactionReason as _CompactionReason
9
10
  from tau.hooks.engine import MessageEndEvent, MessageRollbackEvent, SavePointEvent, SettledEvent
10
11
  from tau.hooks.service import Hooks
11
12
  from tau.message.types import (
@@ -15,6 +16,7 @@ from tau.message.types import (
15
16
  UserMessage,
16
17
  )
17
18
  from tau.message.utils import strip_unusable_trailing_assistant
19
+ from tau.session.compaction import ThresholdCompactionStop as _ThresholdCompactionStop
18
20
  from tau.session.utils import to_llm_messages as _to_llm_messages
19
21
  from tau.tool.types import ToolInvocation, ToolResult
20
22
 
@@ -25,10 +27,6 @@ _TOOL_CAP_LINES = 2000 # DEFAULT_MAX_LINES
25
27
  _TOOL_LINE_CAP_BYTES = 2 * 1024 # 2 KB — max bytes for a single line
26
28
 
27
29
 
28
- from tau.hooks.engine import CompactionReason as _CompactionReason
29
- from tau.session.compaction import ThresholdCompactionStop as _ThresholdCompactionStop
30
-
31
-
32
30
  def _fmt_size(n: int) -> str:
33
31
  if n < 1024:
34
32
  return f"{n}B"
@@ -191,7 +189,8 @@ class Agent:
191
189
  # Walk back to a valid UTF-8 boundary
192
190
  while buf and (buf[-1] & 0xC0) == 0x80:
193
191
  buf = buf[:-1]
194
- capped_lines.append(buf.decode("utf-8", errors="replace") + f" …[line truncated: {_fmt_size(lb)} → {_fmt_size(_TOOL_LINE_CAP_BYTES)}]")
192
+ suffix = f" …[line truncated: {_fmt_size(lb)} → {_fmt_size(_TOOL_LINE_CAP_BYTES)}]"
193
+ capped_lines.append(buf.decode("utf-8", errors="replace") + suffix)
195
194
  else:
196
195
  capped_lines.append(line)
197
196
  lines = capped_lines
@@ -209,8 +208,8 @@ class Agent:
209
208
 
210
209
  omitted = total_bytes - byte_count
211
210
  kept.append(
212
- f"[truncated: {_fmt_size(omitted)} omitted"
213
- f" — {_fmt_size(total_bytes)} total, showing first {len(kept)} lines / {_fmt_size(byte_count)}]"
211
+ f"[truncated: {_fmt_size(omitted)} omitted — {_fmt_size(total_bytes)} total,"
212
+ f" showing first {len(kept)} lines / {_fmt_size(byte_count)}]"
214
213
  )
215
214
  return ToolResult(
216
215
  id=result.id,
@@ -258,6 +257,8 @@ class Agent:
258
257
  self._session_manager.append_message(message)
259
258
  case ToolMessage():
260
259
  self._session_manager.append_message(message)
260
+ case UserMessage():
261
+ self._session_manager.append_message(message)
261
262
  case _:
262
263
  pass
263
264
 
@@ -369,9 +370,8 @@ class Agent:
369
370
  # model change, it came from a different model. Treating its usage/overflow data as
370
371
  # a signal for the new model is unreliable (context windows differ), so skip.
371
372
  model_change_ts = self._latest_model_change_timestamp()
372
- if model_change_ts is not None and last is not None:
373
- if last.timestamp <= model_change_ts:
374
- return False
373
+ if model_change_ts is not None and last is not None and last.timestamp <= model_change_ts:
374
+ return False
375
375
 
376
376
  forced = last is not None and is_silent_overflow(last, self._context_window)
377
377
 
@@ -443,7 +443,9 @@ class Agent:
443
443
  if preparation is None:
444
444
  return False
445
445
  try:
446
- await self._apply_compaction(preparation, entries, manual=False, reason=_CompactionReason.Overflow)
446
+ await self._apply_compaction(
447
+ preparation, entries, manual=False, reason=_CompactionReason.Overflow
448
+ )
447
449
  except Exception:
448
450
  self._compaction_failures += 1
449
451
  _log.exception("Overflow-triggered compaction failed")
@@ -501,7 +503,9 @@ class Agent:
501
503
  if res.compaction is not None:
502
504
  return res.compaction, True
503
505
 
504
- await self.hooks.emit(CompactionStartEvent(manual=manual, reason=reason, will_retry=will_retry))
506
+ await self.hooks.emit(
507
+ CompactionStartEvent(manual=manual, reason=reason, will_retry=will_retry)
508
+ )
505
509
  result = await _compact(
506
510
  preparation, self._engine.llm, custom_instructions=custom_instructions
507
511
  ) # type: ignore[arg-type]
@@ -543,6 +547,16 @@ class Agent:
543
547
  if await self._try_overflow_recovery():
544
548
  continue
545
549
  raise
550
+
551
+ # A steering / follow-up message can land *after* the engine loop has
552
+ # already decided to stop: the submit→steer hop runs as a separate
553
+ # task, so it may enqueue just past the turn's final queue check.
554
+ # Drain any such leftovers with continuation turns so a mid-flight
555
+ # message is never silently stranded in the queue.
556
+ while self._engine.has_pending_messages():
557
+ self._signal = asyncio.Event()
558
+ self._engine.llm.api.options.signal = self._signal
559
+ await self._run_continue()
546
560
  finally:
547
561
  self._phase = AgentPhase.IDLE
548
562
 
@@ -582,3 +596,36 @@ class Agent:
582
596
  error = self._engine.state.error_message
583
597
  if error is not None:
584
598
  raise RuntimeError(f"Agent failed: {error}.")
599
+
600
+ async def _run_continue(self) -> None:
601
+ """Run a continuation turn that drains queued steering/follow-up messages.
602
+
603
+ Mirrors ``_run``'s session-sync wiring so messages injected by the engine
604
+ continuation are persisted and rendered just like a normal turn's.
605
+
606
+ Keeps the continuation within the context window the same way the main turn
607
+ does: auto-compact if needed, then resync the engine's history from the
608
+ (possibly compacted) session — ``run_continue`` runs from ``state.messages``,
609
+ which compaction (which only rewrites the session) would otherwise not touch.
610
+ """
611
+ await self._check_compaction()
612
+ session_ctx = self._session_manager.build_session_context()
613
+ self._engine.state.messages = _to_llm_messages(session_ctx.messages)
614
+
615
+ unsubscribe = self.hooks.register(
616
+ "message_end",
617
+ lambda event: self._on_message_end(event),
618
+ )
619
+ unsubscribe_rollback = self.hooks.register(
620
+ "message_rollback",
621
+ lambda event: self._on_message_rollback(event),
622
+ )
623
+ try:
624
+ await self._engine.run_continue(signal=self._signal)
625
+ finally:
626
+ unsubscribe()
627
+ unsubscribe_rollback()
628
+
629
+ error = self._engine.state.error_message
630
+ if error is not None:
631
+ raise RuntimeError(f"Agent failed: {error}.")
@@ -17,7 +17,7 @@ class GitBadge:
17
17
  self._text = f"{display} ({branch})" if branch else display
18
18
 
19
19
  def render(self, width: int) -> list[str]: # noqa: ARG002
20
- from tau.tui.ansi import DIM, RESET
20
+ from tau.tui.utils import DIM, RESET
21
21
 
22
22
  return [DIM + self._text + RESET]
23
23
 
@@ -49,7 +49,7 @@ class ModelBadge:
49
49
  self.set_context(tokens, window)
50
50
 
51
51
  def render(self, width: int) -> list[str]: # noqa: ARG002
52
- from tau.tui.ansi import DIM, RESET
52
+ from tau.tui.utils import DIM, RESET
53
53
 
54
54
  if not self._provider and not self._model:
55
55
  return []
@@ -10,7 +10,7 @@ if TYPE_CHECKING:
10
10
 
11
11
  def register(tau: ExtensionAPI) -> None:
12
12
  from tau.settings.paths import get_app_name, get_app_version
13
- from tau.tui.ansi import BOLD, CYAN, DIM, RESET
13
+ from tau.tui.utils import BOLD, CYAN, DIM, RESET
14
14
  from tau.tui.component import StaticComponent
15
15
 
16
16
  def _build() -> StaticComponent:
@@ -173,6 +173,35 @@ models = [
173
173
  input=_TEXT_IMAGE_VIDEO,
174
174
  output=_TEXT,
175
175
  ),
176
+ Model(
177
+ id="claude-sonnet-4-20250514",
178
+ name="Claude Sonnet 4.6 (Thinking)",
179
+ provider="google-antigravity",
180
+ cost=Cost(),
181
+ thinking=True,
182
+ context_window=200_000,
183
+ input=_TEXT_IMAGE,
184
+ output=_TEXT,
185
+ ),
186
+ Model(
187
+ id="claude-opus-4-20250514",
188
+ name="Claude Opus 4.6 (Thinking)",
189
+ provider="google-antigravity",
190
+ cost=Cost(),
191
+ thinking=True,
192
+ context_window=200_000,
193
+ input=_TEXT_IMAGE,
194
+ output=_TEXT,
195
+ ),
196
+ Model(
197
+ id="gpt-oss-120",
198
+ name="GPT-OSS 120",
199
+ provider="google-antigravity",
200
+ cost=Cost(),
201
+ context_window=128_000,
202
+ input=_TEXT_IMAGE,
203
+ output=_TEXT,
204
+ ),
176
205
  # Google Vertex AI (GCP — API key or ADC)
177
206
  Model(
178
207
  id="gemini-3.1-pro",
@@ -0,0 +1,22 @@
1
+ from tau.inference.provider.types import AudioProvider
2
+
3
+ providers = [
4
+ AudioProvider(id="openai", name="OpenAI", api="openai-audio"),
5
+ AudioProvider(
6
+ id="openrouter",
7
+ name="OpenRouter",
8
+ api="openai-audio",
9
+ base_url="https://openrouter.ai/api/v1",
10
+ ),
11
+ AudioProvider(
12
+ id="groq", name="Groq", api="openai-audio", base_url="https://api.groq.com/openai/v1"
13
+ ),
14
+ AudioProvider(id="google", name="Google", api="gemini-audio"),
15
+ AudioProvider(id="sarvam", name="Sarvam", api="sarvam-audio", base_url="https://api.sarvam.ai"),
16
+ AudioProvider(
17
+ id="elevenlabs",
18
+ name="ElevenLabs",
19
+ api="elevenlabs-audio",
20
+ base_url="https://api.elevenlabs.io",
21
+ ),
22
+ ]
@@ -0,0 +1,31 @@
1
+ from tau.inference.provider.types import ImageProvider
2
+
3
+ providers = [
4
+ ImageProvider(
5
+ id="openrouter",
6
+ name="OpenRouter",
7
+ api="openrouter-image",
8
+ base_url="https://openrouter.ai/api/v1",
9
+ ),
10
+ ImageProvider(
11
+ id="openai", name="OpenAI", api="openai-image", base_url="https://api.openai.com/v1"
12
+ ),
13
+ ImageProvider(
14
+ id="together",
15
+ name="Together AI",
16
+ api="openai-image",
17
+ base_url="https://api.together.xyz/v1",
18
+ ),
19
+ ImageProvider(
20
+ id="fireworks",
21
+ name="Fireworks AI",
22
+ api="openai-image",
23
+ base_url="https://api.fireworks.ai/inference/v1",
24
+ ),
25
+ ImageProvider(
26
+ id="google",
27
+ name="Google",
28
+ api="gemini-image",
29
+ base_url="https://generativelanguage.googleapis.com",
30
+ ),
31
+ ]
@@ -0,0 +1,11 @@
1
+ from tau.inference.provider.types import VideoProvider
2
+
3
+ providers = [
4
+ VideoProvider(id="fal", name="fal.ai", api="fal-video"),
5
+ VideoProvider(
6
+ id="openrouter",
7
+ name="OpenRouter",
8
+ api="openrouter-video",
9
+ base_url="https://openrouter.ai/api/v1",
10
+ ),
11
+ ]
@@ -79,7 +79,7 @@ def _parse_hunks(diff: str) -> list[list[tuple[str, int, int, str]]]:
79
79
 
80
80
 
81
81
  def _render_edit_result(content: str, opts: Any) -> list[str]:
82
- from tau.tui.ansi import DIM, GREEN, RED, RESET
82
+ from tau.tui.utils import DIM, GREEN, RED, RESET
83
83
 
84
84
  metadata = opts.metadata or {}
85
85
  added = metadata.get("lines_added", 0)
@@ -30,7 +30,7 @@ _PREVIEW_LINES = 5
30
30
 
31
31
 
32
32
  def _render_glob_result(content: str, opts: Any) -> list[str]:
33
- from tau.tui.ansi import DIM, RESET
33
+ from tau.tui.utils import DIM, RESET
34
34
 
35
35
  metadata = opts.metadata or {}
36
36
  match_count = metadata.get("match_count", 0)
@@ -143,7 +143,7 @@ class GlobTool(Tool):
143
143
  return None
144
144
  if proc.returncode not in (0, 1):
145
145
  return None
146
- return [l for l in proc.stdout.splitlines() if l]
146
+ return [line for line in proc.stdout.splitlines() if line]
147
147
 
148
148
  def _python_glob(self, pattern: str, base: Path) -> list[str]:
149
149
  return sorted(_glob.glob(str(base / pattern), recursive=True))
@@ -32,7 +32,7 @@ _PREVIEW_LINES = 5
32
32
 
33
33
 
34
34
  def _render_grep_result(content: str, opts: Any) -> list[str]:
35
- from tau.tui.ansi import DIM, RESET
35
+ from tau.tui.utils import DIM, RESET
36
36
 
37
37
  metadata = opts.metadata or {}
38
38
  match_count = metadata.get("match_count", 0)
@@ -134,7 +134,11 @@ class GrepTool(Tool):
134
134
  return ToolResult.error(invocation.id, result["output"])
135
135
  if result["matches"]:
136
136
  return ToolResult.ok(invocation.id, result["output"], metadata=result["metadata"])
137
- return ToolResult.ok(invocation.id, f"No matches for pattern: {params.pattern}", metadata=result["metadata"])
137
+ return ToolResult.ok(
138
+ invocation.id,
139
+ f"No matches for pattern: {params.pattern}",
140
+ metadata=result["metadata"],
141
+ )
138
142
 
139
143
  async def _rg(self, params: GrepParams, target: Path) -> dict | None:
140
144
  cmd = ["rg", "--line-number", "--no-heading", "--with-filename"]
@@ -151,10 +155,10 @@ class GrepTool(Tool):
151
155
  return None
152
156
  if proc.returncode not in (0, 1):
153
157
  return None
154
- lines = [l for l in proc.stdout.splitlines() if l]
158
+ lines = [ln for ln in proc.stdout.splitlines() if ln]
155
159
  truncated = len(lines) > _MAX_MATCHES
156
160
  lines = lines[:_MAX_MATCHES]
157
- files_with_matches = len({l.split(":")[0] for l in lines})
161
+ files_with_matches = len({ln.split(":")[0] for ln in lines})
158
162
  metadata = {
159
163
  "pattern": params.pattern,
160
164
  "files_searched": files_with_matches,
@@ -171,7 +175,12 @@ class GrepTool(Tool):
171
175
  try:
172
176
  regex = re.compile(params.pattern, flags)
173
177
  except re.error as e:
174
- return {"matches": [], "output": f"Invalid regex pattern: {e}", "metadata": {}, "error": True}
178
+ return {
179
+ "matches": [],
180
+ "output": f"Invalid regex pattern: {e}",
181
+ "metadata": {},
182
+ "error": True,
183
+ }
175
184
 
176
185
  files: list[Path] = []
177
186
  if target.is_file():