siada-cli 0.0.1__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.
- agent_config.yaml +34 -0
- siada/__init__.py +13 -0
- siada/agent_hub/__init__.py +10 -0
- siada/agent_hub/coder/bug_fix_agent.py +398 -0
- siada/agent_hub/coder/code_gen_agent.py +235 -0
- siada/agent_hub/coder/fe_gen_agent.py +37 -0
- siada/agent_hub/coder/issue_review_agent.py +68 -0
- siada/agent_hub/coder/prompt/__init__.py +0 -0
- siada/agent_hub/coder/prompt/base/__init__.py +0 -0
- siada/agent_hub/coder/prompt/base/capabilities.py +18 -0
- siada/agent_hub/coder/prompt/base/non_interactive.py +14 -0
- siada/agent_hub/coder/prompt/base/prompt_builder.py +33 -0
- siada/agent_hub/coder/prompt/base/rules.py +40 -0
- siada/agent_hub/coder/prompt/base/tool_use.py +14 -0
- siada/agent_hub/coder/prompt/bug_prompt/bug_fix_prompt.py +51 -0
- siada/agent_hub/coder/prompt/bug_prompt/rules.py +53 -0
- siada/agent_hub/coder/prompt/code_gen_prompt.py +45 -0
- siada/agent_hub/coder/prompt/fe_gen_prompt.py +45 -0
- siada/agent_hub/coder/prompt/issue_review_prompt.py +121 -0
- siada/agent_hub/coder/tracing/__init__.py +22 -0
- siada/agent_hub/coder/tracing/logger_tracing_processor.py +458 -0
- siada/agent_hub/hooks/__init__.py +0 -0
- siada/agent_hub/hooks/io_hooks.py +30 -0
- siada/agent_hub/siada_agent.py +214 -0
- siada/config/__init__.py +0 -0
- siada/config/config_loader.py +67 -0
- siada/entrypoint/__init__.py +3 -0
- siada/entrypoint/args_parser/__init__.py +0 -0
- siada/entrypoint/args_parser/args.py +195 -0
- siada/entrypoint/interaction/__init__.py +0 -0
- siada/entrypoint/interaction/base_turn.py +107 -0
- siada/entrypoint/interaction/config.py +30 -0
- siada/entrypoint/interaction/controller.py +122 -0
- siada/entrypoint/interaction/nointeractive_controller.py +27 -0
- siada/entrypoint/interaction/turn/interface.py +116 -0
- siada/entrypoint/interaction/turn/models.py +34 -0
- siada/entrypoint/interaction/turn/run_turn.py +641 -0
- siada/entrypoint/interaction/turn_factory.py +35 -0
- siada/entrypoint/interaction/turn_models.py +28 -0
- siada/entrypoint/siadahub.py +413 -0
- siada/foundation/__init__.py +0 -0
- siada/foundation/code_agent_context.py +48 -0
- siada/foundation/config.py +59 -0
- siada/foundation/constants.py +2 -0
- siada/foundation/context.py +76 -0
- siada/foundation/logging.py +341 -0
- siada/foundation/tools/__init__.py +0 -0
- siada/foundation/tools/get_git_diff.py +105 -0
- siada/io/__init__.py +0 -0
- siada/io/banner.py +148 -0
- siada/io/color_settings.py +207 -0
- siada/io/color_utils.py +16 -0
- siada/io/components/__init__.py +0 -0
- siada/io/components/mdstream.py +204 -0
- siada/io/console_printer.py +68 -0
- siada/io/io.py +661 -0
- siada/io/key_bindings.py +129 -0
- siada/io/notification_command.py +40 -0
- siada/io/test_banner.py +64 -0
- siada/models/__init__.py +0 -0
- siada/models/agent.py +47 -0
- siada/models/coder/__init__.py +0 -0
- siada/models/converter.py +27 -0
- siada/models/model_base_config.py +121 -0
- siada/models/model_run_config.py +153 -0
- siada/provider/__init__.py +0 -0
- siada/provider/client_factory.py +112 -0
- siada/provider/llm_client.py +11 -0
- siada/provider/openrouter/__init__.py +0 -0
- siada/provider/openrouter/coverter.py +17 -0
- siada/provider/openrouter/openroute_provider.py +33 -0
- siada/provider/provider_factory.py +53 -0
- siada/queries/tree-sitter-language-pack/README.md +7 -0
- siada/queries/tree-sitter-language-pack/arduino-tags.scm +5 -0
- siada/queries/tree-sitter-language-pack/c-tags.scm +9 -0
- siada/queries/tree-sitter-language-pack/chatito-tags.scm +16 -0
- siada/queries/tree-sitter-language-pack/commonlisp-tags.scm +122 -0
- siada/queries/tree-sitter-language-pack/cpp-tags.scm +15 -0
- siada/queries/tree-sitter-language-pack/csharp-tags.scm +26 -0
- siada/queries/tree-sitter-language-pack/d-tags.scm +26 -0
- siada/queries/tree-sitter-language-pack/dart-tags.scm +92 -0
- siada/queries/tree-sitter-language-pack/elisp-tags.scm +5 -0
- siada/queries/tree-sitter-language-pack/elixir-tags.scm +54 -0
- siada/queries/tree-sitter-language-pack/elm-tags.scm +19 -0
- siada/queries/tree-sitter-language-pack/gleam-tags.scm +41 -0
- siada/queries/tree-sitter-language-pack/go-tags.scm +42 -0
- siada/queries/tree-sitter-language-pack/java-tags.scm +20 -0
- siada/queries/tree-sitter-language-pack/javascript-tags.scm +88 -0
- siada/queries/tree-sitter-language-pack/lua-tags.scm +34 -0
- siada/queries/tree-sitter-language-pack/ocaml-tags.scm +115 -0
- siada/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +98 -0
- siada/queries/tree-sitter-language-pack/pony-tags.scm +39 -0
- siada/queries/tree-sitter-language-pack/properties-tags.scm +5 -0
- siada/queries/tree-sitter-language-pack/python-tags.scm +14 -0
- siada/queries/tree-sitter-language-pack/r-tags.scm +21 -0
- siada/queries/tree-sitter-language-pack/racket-tags.scm +12 -0
- siada/queries/tree-sitter-language-pack/ruby-tags.scm +64 -0
- siada/queries/tree-sitter-language-pack/rust-tags.scm +60 -0
- siada/queries/tree-sitter-language-pack/solidity-tags.scm +43 -0
- siada/queries/tree-sitter-language-pack/swift-tags.scm +51 -0
- siada/queries/tree-sitter-language-pack/udev-tags.scm +20 -0
- siada/queries/tree-sitter-languages/README.md +23 -0
- siada/queries/tree-sitter-languages/c-tags.scm +9 -0
- siada/queries/tree-sitter-languages/c_sharp-tags.scm +46 -0
- siada/queries/tree-sitter-languages/cpp-tags.scm +15 -0
- siada/queries/tree-sitter-languages/dart-tags.scm +91 -0
- siada/queries/tree-sitter-languages/elisp-tags.scm +8 -0
- siada/queries/tree-sitter-languages/elixir-tags.scm +54 -0
- siada/queries/tree-sitter-languages/elm-tags.scm +19 -0
- siada/queries/tree-sitter-languages/go-tags.scm +30 -0
- siada/queries/tree-sitter-languages/hcl-tags.scm +77 -0
- siada/queries/tree-sitter-languages/java-tags.scm +20 -0
- siada/queries/tree-sitter-languages/javascript-tags.scm +88 -0
- siada/queries/tree-sitter-languages/kotlin-tags.scm +27 -0
- siada/queries/tree-sitter-languages/ocaml-tags.scm +115 -0
- siada/queries/tree-sitter-languages/ocaml_interface-tags.scm +98 -0
- siada/queries/tree-sitter-languages/php-tags.scm +26 -0
- siada/queries/tree-sitter-languages/python-tags.scm +12 -0
- siada/queries/tree-sitter-languages/ql-tags.scm +26 -0
- siada/queries/tree-sitter-languages/ruby-tags.scm +64 -0
- siada/queries/tree-sitter-languages/rust-tags.scm +60 -0
- siada/queries/tree-sitter-languages/scala-tags.scm +65 -0
- siada/queries/tree-sitter-languages/typescript-tags.scm +41 -0
- siada/services/__init__.py +30 -0
- siada/services/at_file_recommendation_design_document.md +1213 -0
- siada/services/code_context_manager.py +136 -0
- siada/services/enhanced_fix_result_check.py +546 -0
- siada/services/execution_trace_collector.py +207 -0
- siada/services/file_recommendation/__init__.py +136 -0
- siada/services/file_recommendation/core/__init__.py +17 -0
- siada/services/file_recommendation/core/completion_engine.py +351 -0
- siada/services/file_recommendation/core/config.py +62 -0
- siada/services/file_recommendation/core/file_discovery.py +353 -0
- siada/services/file_recommendation/core/suggestion.py +110 -0
- siada/services/file_recommendation/utils/__init__.py +22 -0
- siada/services/file_recommendation/utils/path_utils.py +138 -0
- siada/services/file_recommendation/utils/text_utils.py +253 -0
- siada/services/fix_result_check.py +377 -0
- siada/services/handle_at_command/README.md +247 -0
- siada/services/handle_at_command/__init__.py +115 -0
- siada/services/handle_at_command/exceptions.py +46 -0
- siada/services/handle_at_command/models.py +92 -0
- siada/services/handle_at_command/parser.py +189 -0
- siada/services/handle_at_command/processor.py +321 -0
- siada/services/handle_at_command/resolver.py +318 -0
- siada/services/handle_at_command/utils.py +345 -0
- siada/services/model_info_service.py +103 -0
- siada/services/siada_runner.py +170 -0
- siada/session/__init__.py +29 -0
- siada/session/session_manager.py +66 -0
- siada/session/session_models.py +43 -0
- siada/support/__init__.py +0 -0
- siada/support/completer.py +204 -0
- siada/support/editor.py +146 -0
- siada/support/envprocessor.py +54 -0
- siada/support/repo.py +51 -0
- siada/support/slash_commands.py +410 -0
- siada/support/spinner.py +320 -0
- siada/tools/__init__.py +0 -0
- siada/tools/ast/README.md +345 -0
- siada/tools/ast/ast_tool.py +341 -0
- siada/tools/ast/models.py +11 -0
- siada/tools/coder/__init__.py +0 -0
- siada/tools/coder/ask_followup_question.py +70 -0
- siada/tools/coder/cmd_runner.py +132 -0
- siada/tools/coder/file_operator.py +284 -0
- siada/tools/coder/file_search/README.md +223 -0
- siada/tools/coder/file_search/__init__.py +10 -0
- siada/tools/coder/file_search/bin/rg-linux-arm64 +0 -0
- siada/tools/coder/file_search/bin/rg-linux-x64 +0 -0
- siada/tools/coder/file_search/bin/rg-macos-arm64 +0 -0
- siada/tools/coder/file_search/bin/rg-macos-x64 +0 -0
- siada/tools/coder/file_search/bin/rg.exe +0 -0
- siada/tools/coder/file_search/search.py +437 -0
- siada/tools/coder/file_search/setup_package.py +150 -0
- siada/tools/coder/file_search/test_search.py +142 -0
- siada/tools/coder/files.py +147 -0
- siada/tools/coder/fix_attempt_completion.py +58 -0
- siada/tools/coder/issue_review_completion.py +29 -0
- siada/tools/coder/observation/__init__.py +0 -0
- siada/tools/coder/observation/error.py +22 -0
- siada/tools/coder/observation/file_observation.py +216 -0
- siada/tools/coder/observation/observation.py +71 -0
- siada/tools/coder/repo_map/__init__.py +157 -0
- siada/tools/coder/repo_map/dump.py +29 -0
- siada/tools/coder/repo_map/io.py +226 -0
- siada/tools/coder/repo_map/repo_map.py +881 -0
- siada/tools/coder/repo_map/special.py +203 -0
- siada/tools/coder/repo_map/token_counter.py +154 -0
- siada/tools/coder/repo_map/waiting.py +221 -0
- siada/tools/coder/reproduce_completion.py +39 -0
- siada/tools/coder/run_cmd.py +60 -0
- siada/tools/coder/test_completion.py +25 -0
- siada/tools/coder/tool_docs.py +44 -0
- siada/tools/compression_tool.py +200 -0
- siada/tools/read_many_files/README.md +220 -0
- siada/tools/read_many_files/__init__.py +25 -0
- siada/tools/read_many_files/file_processor.py +486 -0
- siada/tools/read_many_files/filters.py +326 -0
- siada/tools/read_many_files/formatters.py +204 -0
- siada/tools/read_many_files/models.py +189 -0
- siada/tools/read_many_files_tool.py +233 -0
- siada/tools/tool_call_format/__init__.py +55 -0
- siada/tools/tool_call_format/file_to_language.py +231 -0
- siada/tools/tool_call_format/formatter_factory.py +80 -0
- siada/tools/tool_call_format/formatters.py +282 -0
- siada/tools/tool_call_format/tool_call_formatter.py +54 -0
- siada/tools/web/__init__.py +0 -0
- siada/tools/web/web_crawl.py +208 -0
- siada/utils.py +194 -0
- siada_cli-0.0.1.dist-info/LICENSE +201 -0
- siada_cli-0.0.1.dist-info/METADATA +457 -0
- siada_cli-0.0.1.dist-info/RECORD +215 -0
- siada_cli-0.0.1.dist-info/WHEEL +4 -0
- siada_cli-0.0.1.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from siada.services.model_info_service import ModelInfoService
|
|
3
|
+
import siada.session.session_models
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import litellm
|
|
7
|
+
from prompt_toolkit.completion import Completion, PathCompleter
|
|
8
|
+
from prompt_toolkit.document import Document
|
|
9
|
+
|
|
10
|
+
import siada.io.io
|
|
11
|
+
from siada.models.model_run_config import ModelRunConfig
|
|
12
|
+
from siada.support.editor import pipe_editor
|
|
13
|
+
from siada.tools.coder.cmd_runner import run_cmd_impl as run_cmd
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SwitchEvent:
|
|
17
|
+
def __init__(self, **kwargs):
|
|
18
|
+
self.kwargs = kwargs
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SlashCommands:
|
|
22
|
+
|
|
23
|
+
def clone(self):
|
|
24
|
+
return SlashCommands(
|
|
25
|
+
io=self.io,
|
|
26
|
+
verbose=self.verbose,
|
|
27
|
+
editor=self.editor,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
io : siada.io.io.InputOutput,
|
|
33
|
+
verbose=False,
|
|
34
|
+
editor=None,
|
|
35
|
+
):
|
|
36
|
+
self.io = io
|
|
37
|
+
self.verbose = verbose
|
|
38
|
+
self.help = None
|
|
39
|
+
self.editor = editor
|
|
40
|
+
|
|
41
|
+
# def cmd_model(self, args):
|
|
42
|
+
|
|
43
|
+
# model_name = args.strip()
|
|
44
|
+
# if not model_name:
|
|
45
|
+
# self.io.print_info("No model name provided")
|
|
46
|
+
# return
|
|
47
|
+
|
|
48
|
+
# model = ModelRunConfig(model_name)
|
|
49
|
+
# return SwitchEvent(model=model)
|
|
50
|
+
|
|
51
|
+
# def cmd_agent(self, args):
|
|
52
|
+
# "Switch to a different agent type"
|
|
53
|
+
|
|
54
|
+
# agent_name = args.strip()
|
|
55
|
+
|
|
56
|
+
# try:
|
|
57
|
+
# from siada.services.siada_runner import SiadaRunner
|
|
58
|
+
|
|
59
|
+
# # Load agent configurations
|
|
60
|
+
# agent_configs = SiadaRunner._load_agent_config()
|
|
61
|
+
# # Get all available agent types (only enabled ones)
|
|
62
|
+
# available_agents = {name: config for name, config in agent_configs.items()
|
|
63
|
+
# if config.get('class') and config.get('enabled', True)}
|
|
64
|
+
|
|
65
|
+
# if not agent_name:
|
|
66
|
+
# self.io.print_info("Available agents:\n")
|
|
67
|
+
# max_name_length = max(len(name) for name in available_agents.keys()) if available_agents else 0
|
|
68
|
+
# for name, config in available_agents.items():
|
|
69
|
+
# description = config.get('description', f'{name.title()} agent')
|
|
70
|
+
# self.io.print_info(f"- {name:<{max_name_length}} : {description}")
|
|
71
|
+
# self.io.print_info("\nUsage: /agent <agent_name>")
|
|
72
|
+
# return
|
|
73
|
+
|
|
74
|
+
# # Normalize agent name (lowercase, remove underscores/hyphens)
|
|
75
|
+
# normalized_name = agent_name.lower().replace('_', '').replace('-', '')
|
|
76
|
+
|
|
77
|
+
# # Find matching agent config
|
|
78
|
+
# agent_config = available_agents.get(normalized_name)
|
|
79
|
+
|
|
80
|
+
# if agent_config is None:
|
|
81
|
+
# available_names = list(available_agents.keys())
|
|
82
|
+
# self.io.print_error(f"Unknown agent: '{agent_name}'")
|
|
83
|
+
# self.io.print_info(f"Available agents: {', '.join(available_names)}")
|
|
84
|
+
# return
|
|
85
|
+
|
|
86
|
+
# # Check if agent class is implemented
|
|
87
|
+
# if not agent_config.get('class'):
|
|
88
|
+
# self.io.print_error(f"Agent '{agent_name}' is not implemented yet")
|
|
89
|
+
# return
|
|
90
|
+
|
|
91
|
+
# self.io.print_info(f"Switching to {agent_name} agent...")
|
|
92
|
+
|
|
93
|
+
# # Return SwitchEvent to change agent
|
|
94
|
+
# return SwitchEvent(agent=normalized_name)
|
|
95
|
+
|
|
96
|
+
# except Exception as e:
|
|
97
|
+
# self.io.print_error(f"Failed to switch agent: {e}")
|
|
98
|
+
# if self.verbose:
|
|
99
|
+
# import traceback
|
|
100
|
+
# self.io.print_error(traceback.format_exc())
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def cmd_shell(self, args):
|
|
104
|
+
"Open a shell"
|
|
105
|
+
self.io.print_info("Switching to shell mode...")
|
|
106
|
+
return SwitchEvent(shell=True)
|
|
107
|
+
|
|
108
|
+
def completions_model(self):
|
|
109
|
+
return ModelInfoService.get_model_names()
|
|
110
|
+
|
|
111
|
+
def cmd_models(self, args):
|
|
112
|
+
"Search the list of available models"
|
|
113
|
+
|
|
114
|
+
args = args.strip()
|
|
115
|
+
|
|
116
|
+
# models.print_matching_models(self.io, args)
|
|
117
|
+
models = ModelInfoService.get_model_names()
|
|
118
|
+
for model in models:
|
|
119
|
+
self.io.print_info(f"- {model}")
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def is_command(self, inp):
|
|
124
|
+
return inp[0] in "/!"
|
|
125
|
+
|
|
126
|
+
def get_raw_completions(self, cmd):
|
|
127
|
+
assert cmd.startswith("/")
|
|
128
|
+
cmd = cmd[1:]
|
|
129
|
+
cmd = cmd.replace("-", "_")
|
|
130
|
+
|
|
131
|
+
raw_completer = getattr(self, f"completions_raw_{cmd}", None)
|
|
132
|
+
return raw_completer
|
|
133
|
+
|
|
134
|
+
def get_completions(self, cmd):
|
|
135
|
+
assert cmd.startswith("/")
|
|
136
|
+
cmd = cmd[1:]
|
|
137
|
+
|
|
138
|
+
cmd = cmd.replace("-", "_")
|
|
139
|
+
fun = getattr(self, f"completions_{cmd}", None)
|
|
140
|
+
if not fun:
|
|
141
|
+
return
|
|
142
|
+
return sorted(fun())
|
|
143
|
+
|
|
144
|
+
def get_commands(self):
|
|
145
|
+
commands = []
|
|
146
|
+
for attr in dir(self):
|
|
147
|
+
if not attr.startswith("cmd_"):
|
|
148
|
+
continue
|
|
149
|
+
cmd = attr[4:]
|
|
150
|
+
cmd = cmd.replace("_", "-")
|
|
151
|
+
commands.append("/" + cmd)
|
|
152
|
+
|
|
153
|
+
return commands
|
|
154
|
+
|
|
155
|
+
def do_run(self, session, cmd_name, args):
|
|
156
|
+
cmd_name = cmd_name.replace("-", "_")
|
|
157
|
+
cmd_method_name = f"cmd_{cmd_name}"
|
|
158
|
+
cmd_method = getattr(self, cmd_method_name, None)
|
|
159
|
+
if not cmd_method:
|
|
160
|
+
self.io.print_info(f"Error: Command {cmd_name} not found.")
|
|
161
|
+
return
|
|
162
|
+
|
|
163
|
+
try:
|
|
164
|
+
# 检查方法的参数签名
|
|
165
|
+
sig = inspect.signature(cmd_method)
|
|
166
|
+
params = list(sig.parameters.keys())
|
|
167
|
+
|
|
168
|
+
# 如果方法有 session 参数,则传递 session 和 args
|
|
169
|
+
if 'session' in params:
|
|
170
|
+
return cmd_method(session, args)
|
|
171
|
+
else:
|
|
172
|
+
# 否则只传递 args
|
|
173
|
+
return cmd_method(args)
|
|
174
|
+
except Exception as err:
|
|
175
|
+
self.io.print_error(f"Unable to complete {cmd_name}: {err}")
|
|
176
|
+
|
|
177
|
+
def matching_commands(self, inp):
|
|
178
|
+
words = inp.strip().split()
|
|
179
|
+
if not words:
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
first_word = words[0]
|
|
183
|
+
rest_inp = inp[len(words[0]) :].strip()
|
|
184
|
+
|
|
185
|
+
all_commands = self.get_commands()
|
|
186
|
+
matching_commands = [cmd for cmd in all_commands if cmd.startswith(first_word)]
|
|
187
|
+
return matching_commands, first_word, rest_inp
|
|
188
|
+
|
|
189
|
+
def run(self, session, inp):
|
|
190
|
+
"""
|
|
191
|
+
Run a command.
|
|
192
|
+
any method called cmd_xxx becomes a command automatically.
|
|
193
|
+
each one must take an args param.
|
|
194
|
+
"""
|
|
195
|
+
if inp.startswith("!"):
|
|
196
|
+
return self.do_run(session, "run", inp[1:])
|
|
197
|
+
|
|
198
|
+
res = self.matching_commands(inp)
|
|
199
|
+
if res is None:
|
|
200
|
+
return
|
|
201
|
+
matching_commands, first_word, rest_inp = res
|
|
202
|
+
if len(matching_commands) == 1:
|
|
203
|
+
command = matching_commands[0][1:]
|
|
204
|
+
return self.do_run(session, command, rest_inp)
|
|
205
|
+
elif first_word in matching_commands:
|
|
206
|
+
command = first_word[1:]
|
|
207
|
+
return self.do_run(session, command, rest_inp)
|
|
208
|
+
elif len(matching_commands) > 1:
|
|
209
|
+
self.io.print_error(f"Ambiguous command: {', '.join(matching_commands)}")
|
|
210
|
+
else:
|
|
211
|
+
self.io.print_error(f"Invalid command: {first_word}")
|
|
212
|
+
|
|
213
|
+
def completions_raw_read_only(self, document, complete_event):
|
|
214
|
+
# Get the text before the cursor
|
|
215
|
+
text = document.text_before_cursor
|
|
216
|
+
|
|
217
|
+
# Skip the first word and the space after it
|
|
218
|
+
after_command = text.split()[-1]
|
|
219
|
+
|
|
220
|
+
# Create a new Document object with the text after the command
|
|
221
|
+
new_document = Document(after_command, cursor_position=len(after_command))
|
|
222
|
+
|
|
223
|
+
def get_paths():
|
|
224
|
+
return [self.coder.root] if self.coder.root else None
|
|
225
|
+
|
|
226
|
+
path_completer = PathCompleter(
|
|
227
|
+
get_paths=get_paths,
|
|
228
|
+
only_directories=False,
|
|
229
|
+
expanduser=True,
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# Adjust the start_position to replace all of 'after_command'
|
|
233
|
+
adjusted_start_position = -len(after_command)
|
|
234
|
+
|
|
235
|
+
# Collect all completions
|
|
236
|
+
all_completions = []
|
|
237
|
+
|
|
238
|
+
# Iterate over the completions and modify them
|
|
239
|
+
for completion in path_completer.get_completions(new_document, complete_event):
|
|
240
|
+
quoted_text = self.quote_fname(after_command + completion.text)
|
|
241
|
+
all_completions.append(
|
|
242
|
+
Completion(
|
|
243
|
+
text=quoted_text,
|
|
244
|
+
start_position=adjusted_start_position,
|
|
245
|
+
display=completion.display,
|
|
246
|
+
style=completion.style,
|
|
247
|
+
selected_style=completion.selected_style,
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
# Add completions from the 'add' command
|
|
252
|
+
add_completions = self.completions_add()
|
|
253
|
+
for completion in add_completions:
|
|
254
|
+
if after_command in completion:
|
|
255
|
+
all_completions.append(
|
|
256
|
+
Completion(
|
|
257
|
+
text=completion,
|
|
258
|
+
start_position=adjusted_start_position,
|
|
259
|
+
display=completion,
|
|
260
|
+
)
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
# Sort all completions based on their text
|
|
264
|
+
sorted_completions = sorted(all_completions, key=lambda c: c.text)
|
|
265
|
+
|
|
266
|
+
# Yield the sorted completions
|
|
267
|
+
for completion in sorted_completions:
|
|
268
|
+
yield completion
|
|
269
|
+
|
|
270
|
+
def cmd_run(self, session, args, add_on_nonzero_exit=False):
|
|
271
|
+
"Run a shell command (alias: !)"
|
|
272
|
+
exit_status, combined_output = run_cmd(
|
|
273
|
+
args,
|
|
274
|
+
verbose=self.verbose,
|
|
275
|
+
error_print=self.io.print_error,
|
|
276
|
+
cwd=session.siada_config.workspace,
|
|
277
|
+
)
|
|
278
|
+
return combined_output
|
|
279
|
+
|
|
280
|
+
def cmd_exit(self, args):
|
|
281
|
+
"Exit the application"
|
|
282
|
+
sys.exit()
|
|
283
|
+
|
|
284
|
+
def cmd_quit(self, args):
|
|
285
|
+
"Exit the application"
|
|
286
|
+
self.cmd_exit(args)
|
|
287
|
+
|
|
288
|
+
def basic_help(self):
|
|
289
|
+
commands = sorted(self.get_commands())
|
|
290
|
+
pad = max(len(cmd) for cmd in commands)
|
|
291
|
+
pad = "{cmd:" + str(pad) + "}"
|
|
292
|
+
for cmd in commands:
|
|
293
|
+
cmd_method_name = f"cmd_{cmd[1:]}".replace("-", "_")
|
|
294
|
+
cmd_method = getattr(self, cmd_method_name, None)
|
|
295
|
+
cmd = pad.format(cmd=cmd)
|
|
296
|
+
if cmd_method:
|
|
297
|
+
description = cmd_method.__doc__
|
|
298
|
+
self.io.print_info(f"{cmd} {description}")
|
|
299
|
+
else:
|
|
300
|
+
self.io.print_info(f"{cmd} No description available.")
|
|
301
|
+
self.io.print_info()
|
|
302
|
+
self.io.print_info("Use `/help <question>` to ask questions about how to use siadahub.")
|
|
303
|
+
|
|
304
|
+
def get_help_md(self):
|
|
305
|
+
"Show help about all commands in markdown"
|
|
306
|
+
|
|
307
|
+
res = """
|
|
308
|
+
|Command|Description|
|
|
309
|
+
|:------|:----------|
|
|
310
|
+
"""
|
|
311
|
+
commands = sorted(self.get_commands())
|
|
312
|
+
for cmd in commands:
|
|
313
|
+
cmd_method_name = f"cmd_{cmd[1:]}".replace("-", "_")
|
|
314
|
+
cmd_method = getattr(self, cmd_method_name, None)
|
|
315
|
+
if cmd_method:
|
|
316
|
+
description = cmd_method.__doc__
|
|
317
|
+
res += f"| **{cmd}** | {description} |\n"
|
|
318
|
+
else:
|
|
319
|
+
res += f"| **{cmd}** | |\n"
|
|
320
|
+
|
|
321
|
+
res += "\n"
|
|
322
|
+
return res
|
|
323
|
+
|
|
324
|
+
# def cmd_map(self, args):
|
|
325
|
+
# "Print out the current repository map"
|
|
326
|
+
# repo_map = self.coder.get_repo_map()
|
|
327
|
+
# if repo_map:
|
|
328
|
+
# self.io.print_info(repo_map)
|
|
329
|
+
# else:
|
|
330
|
+
# self.io.print_info("No repository map available.")
|
|
331
|
+
|
|
332
|
+
# def cmd_map_refresh(self, args):
|
|
333
|
+
# "Force a refresh of the repository map"
|
|
334
|
+
# repo_map = self.coder.get_repo_map(force_refresh=True)
|
|
335
|
+
# if repo_map:
|
|
336
|
+
# self.io.print_info("The repo map has been refreshed, use /map to view it.")
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def cmd_multiline_mode(self, args):
|
|
340
|
+
"Toggle multiline mode (swaps behavior of Enter and Meta+Enter)"
|
|
341
|
+
self.io.toggle_multiline_mode()
|
|
342
|
+
|
|
343
|
+
def cmd_editor(self, initial_content=""):
|
|
344
|
+
"Open an editor to write a prompt"
|
|
345
|
+
|
|
346
|
+
user_input = pipe_editor(initial_content, suffix="md", editor=self.editor)
|
|
347
|
+
if user_input.strip():
|
|
348
|
+
self.io.set_placeholder(user_input.rstrip())
|
|
349
|
+
|
|
350
|
+
def cmd_edit(self, args=""):
|
|
351
|
+
"Siada for /editor: Open an editor to write a prompt"
|
|
352
|
+
return self.cmd_editor(args)
|
|
353
|
+
|
|
354
|
+
# def cmd_think_tokens(self, session, args):
|
|
355
|
+
# """Set the thinking token budget, eg: 8096, 8k, 10.5k, 0.5M, or 0 to disable."""
|
|
356
|
+
|
|
357
|
+
# model = session.interaction_config.model
|
|
358
|
+
|
|
359
|
+
# if not args.strip():
|
|
360
|
+
# # Display current value if no args are provided
|
|
361
|
+
# formatted_budget = model.get_thinking_tokens()
|
|
362
|
+
# if formatted_budget is None:
|
|
363
|
+
# self.io.print_info("Thinking tokens are not currently set.")
|
|
364
|
+
# else:
|
|
365
|
+
# budget = model.get_raw_thinking_tokens()
|
|
366
|
+
# self.io.print_info(
|
|
367
|
+
# f"Current thinking token budget: {budget:,} tokens ({formatted_budget})."
|
|
368
|
+
# )
|
|
369
|
+
# return
|
|
370
|
+
|
|
371
|
+
# value = args.strip()
|
|
372
|
+
# model.set_thinking_tokens(value)
|
|
373
|
+
|
|
374
|
+
# # Handle the special case of 0 to disable thinking tokens
|
|
375
|
+
# if value == "0":
|
|
376
|
+
# self.io.print_info("Thinking tokens disabled.")
|
|
377
|
+
# else:
|
|
378
|
+
# formatted_budget = model.get_thinking_tokens()
|
|
379
|
+
# budget = model.get_raw_thinking_tokens()
|
|
380
|
+
# self.io.print_info(
|
|
381
|
+
# f"Set thinking token budget to {budget:,} tokens ({formatted_budget})."
|
|
382
|
+
# )
|
|
383
|
+
|
|
384
|
+
# def cmd_reasoning_effort(self, session, args):
|
|
385
|
+
# "Set the reasoning effort level (values: number or low/medium/high depending on model)"
|
|
386
|
+
# model = session.interaction_config.model
|
|
387
|
+
|
|
388
|
+
# if not args.strip():
|
|
389
|
+
# # Display current value if no args are provided
|
|
390
|
+
# reasoning_value = model.get_reasoning_effort()
|
|
391
|
+
# if reasoning_value is None:
|
|
392
|
+
# self.io.print_info("Reasoning effort is not currently set.")
|
|
393
|
+
# else:
|
|
394
|
+
# self.io.print_info(f"Current reasoning effort: {reasoning_value}")
|
|
395
|
+
# return
|
|
396
|
+
|
|
397
|
+
# value = args.strip()
|
|
398
|
+
# model.set_reasoning_effort(value)
|
|
399
|
+
# reasoning_value = model.get_reasoning_effort()
|
|
400
|
+
# self.io.print_info(f"Set reasoning effort to {reasoning_value}")
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def main():
|
|
404
|
+
md = SlashCommands(None, None).get_help_md()
|
|
405
|
+
print(md)
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
if __name__ == "__main__":
|
|
409
|
+
status = main()
|
|
410
|
+
sys.exit(status)
|