tau-coding-agent 0.1.0__py3-none-any.whl
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.
- tau/__init__.py +0 -0
- tau/agent/__init__.py +11 -0
- tau/agent/prompt/__init__.py +10 -0
- tau/agent/prompt/builder.py +302 -0
- tau/agent/prompt/types.py +33 -0
- tau/agent/service.py +369 -0
- tau/agent/types.py +61 -0
- tau/auth/manager.py +247 -0
- tau/auth/storage.py +82 -0
- tau/auth/types.py +41 -0
- tau/builtins/__init__.py +4 -0
- tau/builtins/__pycache__/__init__.cpython-313.pyc +0 -0
- tau/builtins/__pycache__/__init__.cpython-314.pyc +0 -0
- tau/builtins/commands/__init__.py +41 -0
- tau/builtins/commands/__pycache__/__init__.cpython-313.pyc +0 -0
- tau/builtins/commands/__pycache__/__init__.cpython-314.pyc +0 -0
- tau/builtins/commands/__pycache__/clear.cpython-313.pyc +0 -0
- tau/builtins/commands/__pycache__/clear.cpython-314.pyc +0 -0
- tau/builtins/commands/__pycache__/compact.cpython-313.pyc +0 -0
- tau/builtins/commands/__pycache__/compact.cpython-314.pyc +0 -0
- tau/builtins/commands/__pycache__/reload.cpython-313.pyc +0 -0
- tau/builtins/commands/__pycache__/reload.cpython-314.pyc +0 -0
- tau/builtins/commands/__pycache__/session.cpython-313.pyc +0 -0
- tau/builtins/commands/__pycache__/session.cpython-314.pyc +0 -0
- tau/builtins/commands/clear.py +16 -0
- tau/builtins/commands/compact.py +28 -0
- tau/builtins/commands/reload.py +27 -0
- tau/builtins/commands/session.py +19 -0
- tau/builtins/extensions/footer/__init__.py +76 -0
- tau/builtins/extensions/footer/__pycache__/__init__.cpython-313.pyc +0 -0
- tau/builtins/extensions/footer/__pycache__/git.cpython-313.pyc +0 -0
- tau/builtins/extensions/footer/__pycache__/model.cpython-313.pyc +0 -0
- tau/builtins/extensions/footer/__pycache__/utils.cpython-313.pyc +0 -0
- tau/builtins/extensions/footer/git.py +26 -0
- tau/builtins/extensions/footer/model.py +69 -0
- tau/builtins/extensions/footer/utils.py +44 -0
- tau/builtins/extensions/header/__init__.py +18 -0
- tau/builtins/extensions/header/__pycache__/__init__.cpython-313.pyc +0 -0
- tau/builtins/models/__init__.py +0 -0
- tau/builtins/models/__pycache__/__init__.cpython-313.pyc +0 -0
- tau/builtins/models/__pycache__/text.cpython-313.pyc +0 -0
- tau/builtins/models/audio.py +43 -0
- tau/builtins/models/image.py +43 -0
- tau/builtins/models/text.py +482 -0
- tau/builtins/models/video.py +40 -0
- tau/builtins/prompts/commit.md +7 -0
- tau/builtins/prompts/docs.md +7 -0
- tau/builtins/prompts/explain.md +7 -0
- tau/builtins/prompts/fix.md +7 -0
- tau/builtins/prompts/refactor.md +7 -0
- tau/builtins/prompts/review.md +7 -0
- tau/builtins/prompts/test.md +7 -0
- tau/builtins/providers/__init__.py +0 -0
- tau/builtins/providers/__pycache__/__init__.cpython-313.pyc +0 -0
- tau/builtins/providers/__pycache__/text.cpython-313.pyc +0 -0
- tau/builtins/providers/audio.py +10 -0
- tau/builtins/providers/image.py +9 -0
- tau/builtins/providers/text.py +33 -0
- tau/builtins/providers/video.py +6 -0
- tau/builtins/skills/code-review/SKILL.md +4 -0
- tau/builtins/skills/debug/SKILL.md +4 -0
- tau/builtins/skills/git-commit/SKILL.md +4 -0
- tau/builtins/themes/dark.yaml +1 -0
- tau/builtins/themes/light.yaml +46 -0
- tau/builtins/tools/__init__.py +73 -0
- tau/builtins/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- tau/builtins/tools/__pycache__/__init__.cpython-314.pyc +0 -0
- tau/builtins/tools/__pycache__/bash.cpython-313.pyc +0 -0
- tau/builtins/tools/__pycache__/bash.cpython-314.pyc +0 -0
- tau/builtins/tools/__pycache__/edit.cpython-313.pyc +0 -0
- tau/builtins/tools/__pycache__/edit.cpython-314.pyc +0 -0
- tau/builtins/tools/__pycache__/glob.cpython-313.pyc +0 -0
- tau/builtins/tools/__pycache__/glob.cpython-314.pyc +0 -0
- tau/builtins/tools/__pycache__/grep.cpython-313.pyc +0 -0
- tau/builtins/tools/__pycache__/grep.cpython-314.pyc +0 -0
- tau/builtins/tools/__pycache__/ls.cpython-313.pyc +0 -0
- tau/builtins/tools/__pycache__/ls.cpython-314.pyc +0 -0
- tau/builtins/tools/__pycache__/read.cpython-313.pyc +0 -0
- tau/builtins/tools/__pycache__/read.cpython-314.pyc +0 -0
- tau/builtins/tools/__pycache__/terminal.cpython-313.pyc +0 -0
- tau/builtins/tools/__pycache__/terminal.cpython-314.pyc +0 -0
- tau/builtins/tools/__pycache__/write.cpython-313.pyc +0 -0
- tau/builtins/tools/__pycache__/write.cpython-314.pyc +0 -0
- tau/builtins/tools/edit.py +215 -0
- tau/builtins/tools/glob.py +112 -0
- tau/builtins/tools/grep.py +146 -0
- tau/builtins/tools/ls.py +135 -0
- tau/builtins/tools/read.py +122 -0
- tau/builtins/tools/terminal.py +150 -0
- tau/builtins/tools/write.py +105 -0
- tau/commands/__init__.py +10 -0
- tau/commands/registry.py +71 -0
- tau/commands/types.py +33 -0
- tau/console/__init__.py +0 -0
- tau/console/cli.py +266 -0
- tau/console/commands/__init__.py +0 -0
- tau/console/commands/auth.py +193 -0
- tau/console/commands/packages.py +104 -0
- tau/console/commands/update.py +76 -0
- tau/core/__init__.py +0 -0
- tau/core/registry.py +102 -0
- tau/engine/__init__.py +47 -0
- tau/engine/service.py +768 -0
- tau/engine/types.py +163 -0
- tau/extensions/__init__.py +28 -0
- tau/extensions/api.py +928 -0
- tau/extensions/context.py +462 -0
- tau/extensions/events.py +70 -0
- tau/extensions/loader.py +386 -0
- tau/extensions/runtime.py +184 -0
- tau/extensions/settings.py +137 -0
- tau/hooks/__init__.py +112 -0
- tau/hooks/engine.py +237 -0
- tau/hooks/inference.py +21 -0
- tau/hooks/runtime.py +126 -0
- tau/hooks/service.py +121 -0
- tau/hooks/session.py +117 -0
- tau/hooks/tui.py +61 -0
- tau/hooks/types.py +72 -0
- tau/inference/__init__.py +180 -0
- tau/inference/api/__init__.py +0 -0
- tau/inference/api/audio/__init__.py +0 -0
- tau/inference/api/audio/base.py +29 -0
- tau/inference/api/audio/builtins.py +15 -0
- tau/inference/api/audio/elevenlabs_audio.py +183 -0
- tau/inference/api/audio/gemini_audio.py +95 -0
- tau/inference/api/audio/openai_audio.py +159 -0
- tau/inference/api/audio/registry.py +15 -0
- tau/inference/api/audio/sarvam_audio.py +163 -0
- tau/inference/api/audio/service.py +103 -0
- tau/inference/api/audio/utils.py +47 -0
- tau/inference/api/image/__init__.py +0 -0
- tau/inference/api/image/base.py +17 -0
- tau/inference/api/image/builtins.py +8 -0
- tau/inference/api/image/gemini_image.py +77 -0
- tau/inference/api/image/openai_image.py +103 -0
- tau/inference/api/image/openrouter.py +144 -0
- tau/inference/api/image/registry.py +15 -0
- tau/inference/api/image/service.py +71 -0
- tau/inference/api/registry.py +82 -0
- tau/inference/api/text/__init__.py +0 -0
- tau/inference/api/text/anthropic_claude_code.py +222 -0
- tau/inference/api/text/anthropic_messages.py +196 -0
- tau/inference/api/text/base.py +40 -0
- tau/inference/api/text/builtins.py +19 -0
- tau/inference/api/text/gemini_generate.py +234 -0
- tau/inference/api/text/github_copilot_chat.py +172 -0
- tau/inference/api/text/google_antigravity.py +522 -0
- tau/inference/api/text/mistral_chat.py +284 -0
- tau/inference/api/text/ollama_chat.py +200 -0
- tau/inference/api/text/openai_codex_responses.py +497 -0
- tau/inference/api/text/openai_completions.py +227 -0
- tau/inference/api/text/openai_responses.py +235 -0
- tau/inference/api/text/registry.py +50 -0
- tau/inference/api/text/service.py +297 -0
- tau/inference/api/text/types.py +7 -0
- tau/inference/api/text/utils.py +228 -0
- tau/inference/api/video/__init__.py +0 -0
- tau/inference/api/video/base.py +26 -0
- tau/inference/api/video/builtins.py +7 -0
- tau/inference/api/video/fal_video.py +119 -0
- tau/inference/api/video/openrouter_video.py +142 -0
- tau/inference/api/video/registry.py +15 -0
- tau/inference/api/video/service.py +72 -0
- tau/inference/model/__init__.py +0 -0
- tau/inference/model/registry.py +102 -0
- tau/inference/model/types.py +65 -0
- tau/inference/provider/__init__.py +0 -0
- tau/inference/provider/oauth/__init__.py +35 -0
- tau/inference/provider/oauth/anthropic_claude_code.py +286 -0
- tau/inference/provider/oauth/github_copilot.py +333 -0
- tau/inference/provider/oauth/google_antigravity.py +258 -0
- tau/inference/provider/oauth/openai_codex.py +309 -0
- tau/inference/provider/oauth/pkce.py +14 -0
- tau/inference/provider/oauth/types.py +46 -0
- tau/inference/provider/oauth/utils.py +154 -0
- tau/inference/provider/registry.py +141 -0
- tau/inference/provider/types.py +114 -0
- tau/inference/types.py +549 -0
- tau/inference/utils.py +219 -0
- tau/message/__init__.py +0 -0
- tau/message/types.py +482 -0
- tau/message/utils.py +178 -0
- tau/packages/__init__.py +11 -0
- tau/packages/manager.py +190 -0
- tau/packages/types.py +20 -0
- tau/packages/utils.py +67 -0
- tau/prompts/expand.py +58 -0
- tau/prompts/loader.py +69 -0
- tau/prompts/registry.py +45 -0
- tau/prompts/types.py +24 -0
- tau/rpc/__init__.py +8 -0
- tau/rpc/mode.py +783 -0
- tau/rpc/types.py +252 -0
- tau/runtime/service.py +759 -0
- tau/runtime/types.py +303 -0
- tau/session/branch_summarization.py +312 -0
- tau/session/compaction.py +646 -0
- tau/session/manager.py +652 -0
- tau/session/types.py +188 -0
- tau/session/utils.py +233 -0
- tau/settings/manager.py +1077 -0
- tau/settings/paths.py +150 -0
- tau/settings/storage.py +63 -0
- tau/settings/types.py +173 -0
- tau/settings/utils.py +25 -0
- tau/skills/loader.py +91 -0
- tau/skills/registry.py +70 -0
- tau/skills/types.py +25 -0
- tau/themes/loader.py +238 -0
- tau/themes/registry.py +108 -0
- tau/themes/types.py +19 -0
- tau/tool/__init__.py +3 -0
- tau/tool/registry.py +117 -0
- tau/tool/render.py +21 -0
- tau/tool/types.py +244 -0
- tau/trust/__init__.py +13 -0
- tau/trust/manager.py +80 -0
- tau/trust/types.py +14 -0
- tau/trust/utils.py +72 -0
- tau/tui/__init__.py +54 -0
- tau/tui/agent_hooks.py +346 -0
- tau/tui/ansi.py +330 -0
- tau/tui/app.py +540 -0
- tau/tui/autocomplete.py +33 -0
- tau/tui/capabilities.py +119 -0
- tau/tui/commands/__init__.py +3 -0
- tau/tui/commands/appearance.py +498 -0
- tau/tui/commands/auth.py +232 -0
- tau/tui/commands/context.py +38 -0
- tau/tui/commands/misc.py +82 -0
- tau/tui/commands/model.py +118 -0
- tau/tui/commands/session.py +464 -0
- tau/tui/component.py +268 -0
- tau/tui/components/__init__.py +0 -0
- tau/tui/components/autocomplete_manager.py +267 -0
- tau/tui/components/autocomplete_picker.py +143 -0
- tau/tui/components/box.py +90 -0
- tau/tui/components/command_palette.py +144 -0
- tau/tui/components/dynamic_border.py +19 -0
- tau/tui/components/file_picker.py +233 -0
- tau/tui/components/image.py +181 -0
- tau/tui/components/inline_selector.py +71 -0
- tau/tui/components/layout.py +1194 -0
- tau/tui/components/message_list.py +692 -0
- tau/tui/components/modal.py +97 -0
- tau/tui/components/model_palette.py +204 -0
- tau/tui/components/picker_overlay.py +174 -0
- tau/tui/components/prompt_overlay.py +236 -0
- tau/tui/components/resume_modal.py +372 -0
- tau/tui/components/select_list.py +222 -0
- tau/tui/components/settings_modal.py +274 -0
- tau/tui/components/settings_schema.py +203 -0
- tau/tui/components/spinner.py +119 -0
- tau/tui/components/text_input.py +396 -0
- tau/tui/components/text_prompt.py +82 -0
- tau/tui/components/tree_select_list.py +580 -0
- tau/tui/components/trust_screen.py +97 -0
- tau/tui/diff.py +114 -0
- tau/tui/fuzzy.py +99 -0
- tau/tui/input.py +496 -0
- tau/tui/input_handler.py +716 -0
- tau/tui/keybindings.py +87 -0
- tau/tui/markdown.py +286 -0
- tau/tui/message_renderers.py +31 -0
- tau/tui/overlay.py +326 -0
- tau/tui/renderer.py +378 -0
- tau/tui/terminal.py +499 -0
- tau/tui/theme.py +148 -0
- tau/tui/tui.py +544 -0
- tau/tui/ui_context.py +768 -0
- tau/tui/utils.py +20 -0
- tau/utils/__init__.py +0 -0
- tau/utils/http_proxy.py +221 -0
- tau/utils/image_processing.py +172 -0
- tau/utils/secrets.py +59 -0
- tau/utils/version_check.py +60 -0
- tau_coding_agent-0.1.0.dist-info/METADATA +177 -0
- tau_coding_agent-0.1.0.dist-info/RECORD +283 -0
- tau_coding_agent-0.1.0.dist-info/WHEEL +5 -0
- tau_coding_agent-0.1.0.dist-info/entry_points.txt +2 -0
- tau_coding_agent-0.1.0.dist-info/licenses/LICENSE +21 -0
- tau_coding_agent-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from tau.inference.model.types import Cost, Model, Modality
|
|
2
|
+
|
|
3
|
+
_TEXT = [Modality.Text]
|
|
4
|
+
_IMAGE = [Modality.Image]
|
|
5
|
+
_VIDEO = [Modality.Video]
|
|
6
|
+
|
|
7
|
+
models = [
|
|
8
|
+
# Google Veo 3 via fal.ai
|
|
9
|
+
Model(id="fal-ai/veo3", name="Veo 3", provider="fal", cost=Cost(), input=_TEXT, output=_VIDEO, api="fal-video"),
|
|
10
|
+
Model(id="fal-ai/veo3-fast", name="Veo 3 Fast", provider="fal", cost=Cost(), input=_TEXT, output=_VIDEO, api="fal-video"),
|
|
11
|
+
# Kling via fal.ai
|
|
12
|
+
Model(id="fal-ai/kling-video/v2.1/standard/text-to-video", name="Kling v2.1 Standard", provider="fal", cost=Cost(), input=_TEXT, output=_VIDEO, api="fal-video"),
|
|
13
|
+
Model(id="fal-ai/kling-video/v2.1/pro/text-to-video", name="Kling v2.1 Pro", provider="fal", cost=Cost(), input=_TEXT, output=_VIDEO, api="fal-video"),
|
|
14
|
+
Model(id="fal-ai/kling-video/v2.1/standard/image-to-video", name="Kling v2.1 Standard I2V", provider="fal", cost=Cost(), input=_IMAGE, output=_VIDEO, api="fal-video"),
|
|
15
|
+
Model(id="fal-ai/kling-video/v2.1/pro/image-to-video", name="Kling v2.1 Pro I2V", provider="fal", cost=Cost(), input=_IMAGE, output=_VIDEO, api="fal-video"),
|
|
16
|
+
# Runway Gen4 via fal.ai
|
|
17
|
+
Model(id="fal-ai/runway-gen4/turbo/text-to-video", name="Runway Gen4 Turbo", provider="fal", cost=Cost(), input=_TEXT, output=_VIDEO, api="fal-video"),
|
|
18
|
+
# Hailuo AI via fal.ai
|
|
19
|
+
Model(id="fal-ai/hailuo-ai/video-01", name="Hailuo Video 01", provider="fal", cost=Cost(), input=_TEXT, output=_VIDEO, api="fal-video"),
|
|
20
|
+
Model(id="fal-ai/hailuo-ai/video-01/image-to-video", name="Hailuo Video 01 I2V", provider="fal", cost=Cost(), input=_IMAGE, output=_VIDEO, api="fal-video"),
|
|
21
|
+
# Seedance via fal.ai
|
|
22
|
+
Model(id="fal-ai/seedance-v1/lite/text-to-video", name="Seedance v1 Lite", provider="fal", cost=Cost(), input=_TEXT, output=_VIDEO, api="fal-video"),
|
|
23
|
+
Model(id="fal-ai/seedance-v1/pro/text-to-video", name="Seedance v1 Pro", provider="fal", cost=Cost(), input=_TEXT, output=_VIDEO, api="fal-video"),
|
|
24
|
+
|
|
25
|
+
# OpenRouter video models
|
|
26
|
+
Model(id="bytedance/seedance-2.0", name="Seedance 2.0", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
27
|
+
Model(id="bytedance/seedance-2.0-fast", name="Seedance 2.0 Fast", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
28
|
+
Model(id="bytedance/seedance-1-5-pro", name="Seedance 1.5 Pro", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
29
|
+
Model(id="google/veo-3.1", name="Veo 3.1", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
30
|
+
Model(id="google/veo-3.1-fast", name="Veo 3.1 Fast", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
31
|
+
Model(id="google/veo-3.1-lite", name="Veo 3.1 Lite", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
32
|
+
Model(id="alibaba/wan-2.7", name="Wan 2.7", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
33
|
+
Model(id="alibaba/wan-2.6", name="Wan 2.6", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
34
|
+
Model(id="openai/sora-2-pro", name="Sora 2 Pro", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
35
|
+
Model(id="x-ai/grok-imagine-video", name="Grok Imagine Video", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
36
|
+
Model(id="minimax/hailuo-2.3", name="Hailuo 2.3", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
37
|
+
Model(id="kwaivgi/kling-video-o1", name="Video O1", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
38
|
+
Model(id="kwaivgi/kling-v3.0-pro", name="Video v3.0 Pro", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
39
|
+
Model(id="kwaivgi/kling-v3.0-std", name="Video v3.0 Standard", provider="openrouter", cost=Cost(), input=[Modality.Text, Modality.Image], output=_VIDEO, api="openrouter-video"),
|
|
40
|
+
]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Write a commit message for staged changes
|
|
3
|
+
argument-hint: [context]
|
|
4
|
+
---
|
|
5
|
+
Write a concise git commit message for the staged changes. Follow conventional commit style (type: short summary). If context is provided, use it to inform the message.
|
|
6
|
+
|
|
7
|
+
${1:-no additional context}
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from tau.inference.provider.types import AudioProvider
|
|
2
|
+
|
|
3
|
+
providers = [
|
|
4
|
+
AudioProvider(name="openai", api="openai-audio"),
|
|
5
|
+
AudioProvider(name="openrouter", api="openai-audio", base_url="https://openrouter.ai/api/v1"),
|
|
6
|
+
AudioProvider(name="groq", api="openai-audio", base_url="https://api.groq.com/openai/v1"),
|
|
7
|
+
AudioProvider(name="google", api="gemini-audio"),
|
|
8
|
+
AudioProvider(name="sarvam", api="sarvam-audio", base_url="https://api.sarvam.ai"),
|
|
9
|
+
AudioProvider(name="elevenlabs", api="elevenlabs-audio", base_url="https://api.elevenlabs.io"),
|
|
10
|
+
]
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from tau.inference.provider.types import ImageProvider
|
|
2
|
+
|
|
3
|
+
providers = [
|
|
4
|
+
ImageProvider(name="openrouter", api="openrouter-image", base_url="https://openrouter.ai/api/v1"),
|
|
5
|
+
ImageProvider(name="openai", api="openai-image", base_url="https://api.openai.com/v1"),
|
|
6
|
+
ImageProvider(name="together", api="openai-image", base_url="https://api.together.xyz/v1"),
|
|
7
|
+
ImageProvider(name="fireworks", api="openai-image", base_url="https://api.fireworks.ai/inference/v1"),
|
|
8
|
+
ImageProvider(name="google", api="gemini-image", base_url="https://generativelanguage.googleapis.com"),
|
|
9
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from tau.inference.provider.oauth.openai_codex import OpenAICodexOAuthProvider
|
|
2
|
+
from tau.inference.provider.oauth.anthropic_claude_code import AnthropicClaudeCodeOAuthProvider
|
|
3
|
+
from tau.inference.provider.oauth.github_copilot import GitHubCopilotOAuthProvider
|
|
4
|
+
from tau.inference.provider.oauth.google_antigravity import GoogleAntigravityOAuthProvider
|
|
5
|
+
from tau.inference.provider.types import APIProvider
|
|
6
|
+
from tau.inference.types import LLMOptions
|
|
7
|
+
|
|
8
|
+
api_providers = [
|
|
9
|
+
APIProvider(id="openai", name="OpenAI", api="openai_responses", options=LLMOptions()),
|
|
10
|
+
APIProvider(id="anthropic", name="Anthropic", api="anthropic_messages", options=LLMOptions()),
|
|
11
|
+
APIProvider(id="google", name="Google", api="gemini_generate", options=LLMOptions()),
|
|
12
|
+
APIProvider(id="nvidia", name="NVIDIA", api="openai_completions", options=LLMOptions(base_url="https://integrate.api.nvidia.com/v1")),
|
|
13
|
+
APIProvider(id="groq", name="Groq", api="openai_completions", options=LLMOptions(base_url="https://api.groq.com/openai/v1")),
|
|
14
|
+
APIProvider(id="openrouter", name="OpenRouter", api="openai_completions", options=LLMOptions(base_url="https://openrouter.ai/api/v1", extra_params={"include_reasoning": True})),
|
|
15
|
+
APIProvider(id="perplexity", name="Perplexity", api="openai_responses", options=LLMOptions(base_url="https://api.perplexity.ai/v1")),
|
|
16
|
+
APIProvider(id="xai", name="xAI", api="openai_responses", options=LLMOptions(base_url="https://api.x.ai/v1")),
|
|
17
|
+
APIProvider(id="bedrock", name="AWS Bedrock", api="openai_responses", options=LLMOptions(base_url="https://bedrock-mantle.us-east-1.api.aws/v1")),
|
|
18
|
+
APIProvider(id="kimi", name="Kimi / Moonshot", api="openai_completions", options=LLMOptions(base_url="https://api.moonshot.ai/v1")),
|
|
19
|
+
APIProvider(id="minimax", name="MiniMax", api="anthropic_messages", options=LLMOptions(base_url="https://api.minimax.io/anthropic")),
|
|
20
|
+
APIProvider(id="deepseek", name="DeepSeek", api="openai_completions", options=LLMOptions(base_url="https://api.deepseek.com")),
|
|
21
|
+
APIProvider(id="kilocode", name="Kilo Code", api="openai_completions", options=LLMOptions(base_url="https://api.kilo.ai/api/gateway")),
|
|
22
|
+
APIProvider(id="mistral", name="Mistral", api="mistral_chat", options=LLMOptions()),
|
|
23
|
+
APIProvider(id="ollama", name="Ollama", api="ollama_chat", options=LLMOptions(base_url="http://localhost:11434")),
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
oauth_providers = [
|
|
27
|
+
OpenAICodexOAuthProvider(),
|
|
28
|
+
AnthropicClaudeCodeOAuthProvider(),
|
|
29
|
+
GitHubCopilotOAuthProvider(),
|
|
30
|
+
GoogleAntigravityOAuthProvider(),
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
providers = api_providers + oauth_providers
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Review code changes for bugs, clarity, and correctness
|
|
3
|
+
---
|
|
4
|
+
Read the relevant files or diff. Look for bugs, security issues, unclear logic, and style problems. Report findings as a concise list grouped by severity (critical / warning / suggestion). Be specific — include file and line references where possible.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Diagnose and fix a bug or unexpected behaviour
|
|
3
|
+
---
|
|
4
|
+
Read the relevant code and any error output. Identify the root cause, not just the symptom. Explain the cause in one sentence, then make a targeted fix. Do not change unrelated code. If reproduction steps are unclear, ask before guessing.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Stage and commit changes with a well-formed commit message
|
|
3
|
+
---
|
|
4
|
+
Stage the relevant files, write a conventional commit message based on the diff, and create the commit. Follow the format `type: short summary` (e.g. `feat:`, `fix:`, `refactor:`). Keep the subject under 72 characters. If there are staged changes already, use them as-is.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
name: dark
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: light
|
|
2
|
+
|
|
3
|
+
colors:
|
|
4
|
+
# UI chrome
|
|
5
|
+
divider: "#c8c8c8"
|
|
6
|
+
spinner_frame: "#0066cc"
|
|
7
|
+
spinner_label: "#999999"
|
|
8
|
+
|
|
9
|
+
# Markdown
|
|
10
|
+
heading: { color: "#6d28d9", bold: true }
|
|
11
|
+
code_inline: "#b45309"
|
|
12
|
+
code_block: "#047857"
|
|
13
|
+
code_block_border: "#c8c8c8"
|
|
14
|
+
quote: { color: "#9ca3af", italic: true }
|
|
15
|
+
quote_border: "#c8c8c8"
|
|
16
|
+
hr: "#c8c8c8"
|
|
17
|
+
list_bullet: "#6d28d9"
|
|
18
|
+
link_text: "#0066cc"
|
|
19
|
+
link_url: "#9ca3af"
|
|
20
|
+
|
|
21
|
+
# Messages
|
|
22
|
+
you_label: { color: "#0066cc", bold: true }
|
|
23
|
+
assistant_label: { color: "#047857", bold: true }
|
|
24
|
+
tool_arrow: "#b45309"
|
|
25
|
+
tool_result_ok: "#9ca3af"
|
|
26
|
+
tool_result_err: "#dc2626"
|
|
27
|
+
thinking: { color: "#9ca3af", italic: true }
|
|
28
|
+
error_label: { color: "#dc2626", bold: true }
|
|
29
|
+
dim: "#9ca3af"
|
|
30
|
+
stream_cursor: "#374151"
|
|
31
|
+
|
|
32
|
+
# Select list
|
|
33
|
+
selected_label: { color: "#6d28d9", bold: true }
|
|
34
|
+
selected_desc: "#0066cc"
|
|
35
|
+
normal_label: "#374151"
|
|
36
|
+
normal_desc: "#9ca3af"
|
|
37
|
+
indicator: "#9ca3af"
|
|
38
|
+
empty: "#9ca3af"
|
|
39
|
+
|
|
40
|
+
input:
|
|
41
|
+
prefix: "❯ "
|
|
42
|
+
placeholder: ""
|
|
43
|
+
|
|
44
|
+
spinner:
|
|
45
|
+
frames: ["▖", "▘", "▝", "▗"]
|
|
46
|
+
interval_ms: 120
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Built-in coding-agent tools."""
|
|
2
|
+
|
|
3
|
+
from tau.builtins.tools.read import ReadTool
|
|
4
|
+
from tau.builtins.tools.write import WriteTool
|
|
5
|
+
from tau.builtins.tools.edit import EditTool
|
|
6
|
+
from tau.builtins.tools.terminal import TerminalTool
|
|
7
|
+
from tau.builtins.tools.glob import GlobTool
|
|
8
|
+
from tau.builtins.tools.grep import GrepTool
|
|
9
|
+
from tau.builtins.tools.ls import LsTool
|
|
10
|
+
|
|
11
|
+
TOOLS = [
|
|
12
|
+
ReadTool(),
|
|
13
|
+
WriteTool(),
|
|
14
|
+
EditTool(),
|
|
15
|
+
TerminalTool(),
|
|
16
|
+
GlobTool(),
|
|
17
|
+
GrepTool(),
|
|
18
|
+
LsTool(),
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def create_read_tool() -> ReadTool:
|
|
23
|
+
"""Return a fresh ReadTool instance for delegation in extension renderers."""
|
|
24
|
+
return ReadTool()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def create_write_tool() -> WriteTool:
|
|
28
|
+
"""Return a fresh WriteTool instance for delegation in extension renderers."""
|
|
29
|
+
return WriteTool()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def create_edit_tool() -> EditTool:
|
|
33
|
+
"""Return a fresh EditTool instance for delegation in extension renderers."""
|
|
34
|
+
return EditTool()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def create_terminal_tool() -> TerminalTool:
|
|
38
|
+
"""Return a fresh TerminalTool instance for delegation in extension renderers."""
|
|
39
|
+
return TerminalTool()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def create_glob_tool() -> GlobTool:
|
|
43
|
+
"""Return a fresh GlobTool instance for delegation in extension renderers."""
|
|
44
|
+
return GlobTool()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def create_grep_tool() -> GrepTool:
|
|
48
|
+
"""Return a fresh GrepTool instance for delegation in extension renderers."""
|
|
49
|
+
return GrepTool()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def create_ls_tool() -> LsTool:
|
|
53
|
+
"""Return a fresh LsTool instance for delegation in extension renderers."""
|
|
54
|
+
return LsTool()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
__all__ = [
|
|
58
|
+
"ReadTool",
|
|
59
|
+
"WriteTool",
|
|
60
|
+
"EditTool",
|
|
61
|
+
"TerminalTool",
|
|
62
|
+
"GlobTool",
|
|
63
|
+
"GrepTool",
|
|
64
|
+
"LsTool",
|
|
65
|
+
"TOOLS",
|
|
66
|
+
"create_read_tool",
|
|
67
|
+
"create_write_tool",
|
|
68
|
+
"create_edit_tool",
|
|
69
|
+
"create_terminal_tool",
|
|
70
|
+
"create_glob_tool",
|
|
71
|
+
"create_grep_tool",
|
|
72
|
+
"create_ls_tool",
|
|
73
|
+
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import difflib
|
|
4
|
+
import re
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Optional
|
|
7
|
+
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
from tau.tool.types import (
|
|
11
|
+
Tool, ToolKind,
|
|
12
|
+
ToolInvocation, ToolResult,
|
|
13
|
+
ToolExecutionUpdateCallback, AbortSignal, ToolContext,
|
|
14
|
+
)
|
|
15
|
+
from tau.tool.render import call_line
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _render_edit_call(args: dict, _streaming: bool) -> list[str]:
|
|
19
|
+
return call_line("edit", args.get("path", ""))
|
|
20
|
+
|
|
21
|
+
_CONTEXT_LINES = 2
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class EditParams(BaseModel):
|
|
25
|
+
"""Parameters for the edit tool."""
|
|
26
|
+
path: str = Field(description="Absolute path to the file to edit.")
|
|
27
|
+
old_string: str = Field(description="Exact string to find and replace.")
|
|
28
|
+
new_string: str = Field(description="Replacement string.")
|
|
29
|
+
replace_all: bool = Field(default=False, description="Replace all occurrences; default replaces only the first.")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _parse_hunks(diff: str) -> list[list[tuple[str, int, int, str]]]:
|
|
33
|
+
"""Parse unified diff into hunks of (char, old_line, new_line, text)."""
|
|
34
|
+
hunks: list[list[tuple[str, int, int, str]]] = []
|
|
35
|
+
current: list[tuple[str, int, int, str]] = []
|
|
36
|
+
old_line = new_line = 0
|
|
37
|
+
for raw in diff.splitlines():
|
|
38
|
+
if raw.startswith("---") or raw.startswith("+++"):
|
|
39
|
+
continue
|
|
40
|
+
if raw.startswith("@@"):
|
|
41
|
+
m = re.match(r"@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@", raw)
|
|
42
|
+
if m:
|
|
43
|
+
if current:
|
|
44
|
+
hunks.append(current)
|
|
45
|
+
current = []
|
|
46
|
+
old_line, new_line = int(m.group(1)), int(m.group(2))
|
|
47
|
+
elif raw.startswith("+"):
|
|
48
|
+
current.append(("+", old_line, new_line, raw[1:]))
|
|
49
|
+
new_line += 1
|
|
50
|
+
elif raw.startswith("-"):
|
|
51
|
+
current.append(("-", old_line, new_line, raw[1:]))
|
|
52
|
+
old_line += 1
|
|
53
|
+
else:
|
|
54
|
+
current.append((" ", old_line, new_line, raw[1:]))
|
|
55
|
+
old_line += 1
|
|
56
|
+
new_line += 1
|
|
57
|
+
if current:
|
|
58
|
+
hunks.append(current)
|
|
59
|
+
return hunks
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _render_edit_result(content: str, opts: Any) -> list[str]:
|
|
63
|
+
from tau.tui.ansi import GREEN, RED, DIM, RESET
|
|
64
|
+
metadata = opts.metadata or {}
|
|
65
|
+
added = metadata.get("lines_added", 0)
|
|
66
|
+
removed = metadata.get("lines_removed", 0)
|
|
67
|
+
diff = metadata.get("diff", "")
|
|
68
|
+
|
|
69
|
+
parts = []
|
|
70
|
+
if added:
|
|
71
|
+
parts.append(f"{GREEN}Added {added} {'line' if added == 1 else 'lines'}{RESET}")
|
|
72
|
+
if removed:
|
|
73
|
+
parts.append(f"{RED}Removed {removed} {'line' if removed == 1 else 'lines'}{RESET}")
|
|
74
|
+
result = [", ".join(parts) if parts else content.strip()]
|
|
75
|
+
|
|
76
|
+
if not diff:
|
|
77
|
+
return result
|
|
78
|
+
|
|
79
|
+
hunks = _parse_hunks(diff)
|
|
80
|
+
if not hunks:
|
|
81
|
+
return result
|
|
82
|
+
|
|
83
|
+
has_gaps = False
|
|
84
|
+
|
|
85
|
+
if opts.expanded:
|
|
86
|
+
for hunk in hunks:
|
|
87
|
+
for char, ol, nl, text in hunk:
|
|
88
|
+
if char == "+":
|
|
89
|
+
result.append(f"{GREEN}{nl} + {text}{RESET}")
|
|
90
|
+
elif char == "-":
|
|
91
|
+
result.append(f"{RED}{ol} - {text}{RESET}")
|
|
92
|
+
else:
|
|
93
|
+
result.append(f"{nl} {text}")
|
|
94
|
+
else:
|
|
95
|
+
prev_new_end: int | None = None
|
|
96
|
+
for hunk in hunks:
|
|
97
|
+
new_start = hunk[0][2]
|
|
98
|
+
if prev_new_end is not None:
|
|
99
|
+
gap = new_start - prev_new_end
|
|
100
|
+
if gap > 0:
|
|
101
|
+
result.append(f"{DIM} ··· {gap} line{'s' if gap != 1 else ''}{RESET}")
|
|
102
|
+
has_gaps = True
|
|
103
|
+
|
|
104
|
+
changed = {i for i, (c, *_) in enumerate(hunk) if c != " "}
|
|
105
|
+
show = {j for ci in changed for j in range(max(0, ci - _CONTEXT_LINES), min(len(hunk), ci + _CONTEXT_LINES + 1))}
|
|
106
|
+
|
|
107
|
+
prev_i: int | None = None
|
|
108
|
+
for i, (char, ol, nl, text) in enumerate(hunk):
|
|
109
|
+
if i not in show:
|
|
110
|
+
continue
|
|
111
|
+
if prev_i is not None and i > prev_i + 1:
|
|
112
|
+
gap = i - prev_i - 1
|
|
113
|
+
result.append(f"{DIM} ··· {gap} line{'s' if gap != 1 else ''}{RESET}")
|
|
114
|
+
has_gaps = True
|
|
115
|
+
if char == "+":
|
|
116
|
+
result.append(f"{GREEN}{nl} + {text}{RESET}")
|
|
117
|
+
elif char == "-":
|
|
118
|
+
result.append(f"{RED}{ol} - {text}{RESET}")
|
|
119
|
+
else:
|
|
120
|
+
result.append(f"{nl} {text}")
|
|
121
|
+
prev_i = i
|
|
122
|
+
|
|
123
|
+
last = hunk[-1]
|
|
124
|
+
prev_new_end = last[2] + (1 if last[0] != "-" else 0)
|
|
125
|
+
|
|
126
|
+
if has_gaps or opts.expanded:
|
|
127
|
+
hint = "(ctrl+o to collapse)" if opts.expanded else "··· (ctrl+o to expand)"
|
|
128
|
+
result.append(f"{DIM} {hint}{RESET}")
|
|
129
|
+
|
|
130
|
+
return result
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class EditTool(Tool):
|
|
134
|
+
"""Tool for replacing exact strings in files."""
|
|
135
|
+
def __init__(self) -> None:
|
|
136
|
+
super().__init__(
|
|
137
|
+
name="edit",
|
|
138
|
+
description=(
|
|
139
|
+
"Replace an exact string in a file. Fails if old_string is not found or (when replace_all=false) "
|
|
140
|
+
"appears more than once. Use replace_all=true to replace every occurrence."
|
|
141
|
+
),
|
|
142
|
+
schema=EditParams,
|
|
143
|
+
kind=ToolKind.Edit,
|
|
144
|
+
render_result=_render_edit_result,
|
|
145
|
+
render_call=_render_edit_call,
|
|
146
|
+
render_shell="default",
|
|
147
|
+
prompt_guidelines="Read the file first so you understand context. Prefer small, targeted edits over rewriting large sections.",
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
def get_display_name(self, args: dict[str, Any]) -> str:
|
|
151
|
+
return args.get("path", "edit")
|
|
152
|
+
|
|
153
|
+
async def execute(
|
|
154
|
+
self,
|
|
155
|
+
invocation: ToolInvocation,
|
|
156
|
+
tool_execution_update_callback: Optional[ToolExecutionUpdateCallback] = None,
|
|
157
|
+
signal: Optional[AbortSignal] = None,
|
|
158
|
+
context: Optional[ToolContext] = None,
|
|
159
|
+
) -> ToolResult:
|
|
160
|
+
params = EditParams.model_validate(invocation.params)
|
|
161
|
+
path = Path(params.path)
|
|
162
|
+
|
|
163
|
+
if not path.exists():
|
|
164
|
+
return ToolResult.error(invocation.id, f"File not found: {params.path}")
|
|
165
|
+
if not path.is_file():
|
|
166
|
+
return ToolResult.error(invocation.id, f"Not a file: {params.path}")
|
|
167
|
+
|
|
168
|
+
try:
|
|
169
|
+
original = path.read_text(encoding="utf-8")
|
|
170
|
+
except OSError as e:
|
|
171
|
+
return ToolResult.error(invocation.id, f"Cannot read file: {e}")
|
|
172
|
+
|
|
173
|
+
count = original.count(params.old_string)
|
|
174
|
+
if count == 0:
|
|
175
|
+
return ToolResult.error(invocation.id, f"old_string not found in {params.path}")
|
|
176
|
+
if not params.replace_all and count > 1:
|
|
177
|
+
return ToolResult.error(
|
|
178
|
+
invocation.id,
|
|
179
|
+
f"old_string matches {count} locations in {params.path}. "
|
|
180
|
+
"Provide more context to make it unique, or set replace_all=true.",
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
if params.replace_all:
|
|
184
|
+
updated = original.replace(params.old_string, params.new_string)
|
|
185
|
+
else:
|
|
186
|
+
updated = original.replace(params.old_string, params.new_string, 1)
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
path.write_text(updated, encoding="utf-8")
|
|
190
|
+
except OSError as e:
|
|
191
|
+
return ToolResult.error(invocation.id, f"Cannot write file: {e}")
|
|
192
|
+
|
|
193
|
+
replacements = count if params.replace_all else 1
|
|
194
|
+
|
|
195
|
+
original_lines = original.splitlines(keepends=True)
|
|
196
|
+
updated_lines = updated.splitlines(keepends=True)
|
|
197
|
+
diff_lines = list(difflib.unified_diff(
|
|
198
|
+
original_lines, updated_lines,
|
|
199
|
+
fromfile=f"a/{path.name}", tofile=f"b/{path.name}",
|
|
200
|
+
n=99999,
|
|
201
|
+
))
|
|
202
|
+
diff = "".join(diff_lines)
|
|
203
|
+
lines_added = sum(1 for l in diff_lines if l.startswith("+") and not l.startswith("+++"))
|
|
204
|
+
lines_removed = sum(1 for l in diff_lines if l.startswith("-") and not l.startswith("---"))
|
|
205
|
+
|
|
206
|
+
metadata = {
|
|
207
|
+
"file_path": str(path),
|
|
208
|
+
"lines_added": lines_added,
|
|
209
|
+
"lines_removed": lines_removed,
|
|
210
|
+
"diff": diff,
|
|
211
|
+
"occurrences_replaced": replacements,
|
|
212
|
+
"replace_all": params.replace_all,
|
|
213
|
+
"total_lines": len(updated_lines),
|
|
214
|
+
}
|
|
215
|
+
return ToolResult.ok(invocation.id, f"Replaced {replacements} occurrence(s) in {params.path}", metadata=metadata)
|