tass 0.1.7__tar.gz → 0.1.8__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.
- {tass-0.1.7 → tass-0.1.8}/PKG-INFO +25 -1
- {tass-0.1.7 → tass-0.1.8}/README.md +24 -0
- {tass-0.1.7 → tass-0.1.8}/pyproject.toml +1 -1
- {tass-0.1.7 → tass-0.1.8}/src/app.py +38 -16
- {tass-0.1.7 → tass-0.1.8}/uv.lock +1 -1
- {tass-0.1.7 → tass-0.1.8}/.gitignore +0 -0
- {tass-0.1.7 → tass-0.1.8}/.python-version +0 -0
- {tass-0.1.7 → tass-0.1.8}/LICENSE +0 -0
- {tass-0.1.7 → tass-0.1.8}/src/__init__.py +0 -0
- {tass-0.1.7 → tass-0.1.8}/src/cli.py +0 -0
- {tass-0.1.7 → tass-0.1.8}/src/constants.py +0 -0
- {tass-0.1.7 → tass-0.1.8}/src/utils.py +0 -0
- {tass-0.1.7 → tass-0.1.8}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tass
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: A terminal assistant that allows you to ask an LLM to run commands.
|
|
5
5
|
Project-URL: Homepage, https://github.com/cetincan0/tass
|
|
6
6
|
Author: Can Cetin
|
|
@@ -21,10 +21,18 @@ This tool can run commands including ones that can modify, move, or delete files
|
|
|
21
21
|
|
|
22
22
|
## Installation
|
|
23
23
|
|
|
24
|
+
### Using uv
|
|
25
|
+
|
|
24
26
|
```
|
|
25
27
|
uv tool install tass
|
|
26
28
|
```
|
|
27
29
|
|
|
30
|
+
### Using pip
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
pip install tass
|
|
34
|
+
```
|
|
35
|
+
|
|
28
36
|
You can run it with
|
|
29
37
|
|
|
30
38
|
```
|
|
@@ -34,3 +42,19 @@ tass
|
|
|
34
42
|
tass has only been tested with gpt-oss-120b using llama.cpp so far, but in theory any LLM with tool calling capabilities should work. By default, it will try connecting to http://localhost:8080. If you want to use another host, set the `TASS_HOST` environment variable.
|
|
35
43
|
|
|
36
44
|
Once it's running, you can ask questions or give commands like "Create an empty file called test.txt" and it will propose a command to run after user confirmation.
|
|
45
|
+
|
|
46
|
+
You can enter multiline input by ending lines with a backslash (\\). The continuation prompt will appear until you enter a line without a trailing backslash.
|
|
47
|
+
|
|
48
|
+
## Upgrade
|
|
49
|
+
|
|
50
|
+
### Using uv
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
uv tool upgrade tass
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Using pip
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
pip install --upgrade tass
|
|
60
|
+
```
|
|
@@ -8,10 +8,18 @@ This tool can run commands including ones that can modify, move, or delete files
|
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
|
+
### Using uv
|
|
12
|
+
|
|
11
13
|
```
|
|
12
14
|
uv tool install tass
|
|
13
15
|
```
|
|
14
16
|
|
|
17
|
+
### Using pip
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
pip install tass
|
|
21
|
+
```
|
|
22
|
+
|
|
15
23
|
You can run it with
|
|
16
24
|
|
|
17
25
|
```
|
|
@@ -21,3 +29,19 @@ tass
|
|
|
21
29
|
tass has only been tested with gpt-oss-120b using llama.cpp so far, but in theory any LLM with tool calling capabilities should work. By default, it will try connecting to http://localhost:8080. If you want to use another host, set the `TASS_HOST` environment variable.
|
|
22
30
|
|
|
23
31
|
Once it's running, you can ask questions or give commands like "Create an empty file called test.txt" and it will propose a command to run after user confirmation.
|
|
32
|
+
|
|
33
|
+
You can enter multiline input by ending lines with a backslash (\\). The continuation prompt will appear until you enter a line without a trailing backslash.
|
|
34
|
+
|
|
35
|
+
## Upgrade
|
|
36
|
+
|
|
37
|
+
### Using uv
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
uv tool upgrade tass
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Using pip
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
pip install --upgrade tass
|
|
47
|
+
```
|
|
@@ -15,9 +15,7 @@ from src.constants import (
|
|
|
15
15
|
SYSTEM_PROMPT,
|
|
16
16
|
TOOLS,
|
|
17
17
|
)
|
|
18
|
-
from src.utils import
|
|
19
|
-
is_read_only_command,
|
|
20
|
-
)
|
|
18
|
+
from src.utils import is_read_only_command
|
|
21
19
|
|
|
22
20
|
console = Console()
|
|
23
21
|
|
|
@@ -102,22 +100,34 @@ class TassApp:
|
|
|
102
100
|
content = ""
|
|
103
101
|
reasoning_content = ""
|
|
104
102
|
tool_calls_map = {}
|
|
103
|
+
timings_str = ""
|
|
105
104
|
|
|
106
|
-
def generate_layout(
|
|
105
|
+
def generate_layout():
|
|
107
106
|
groups = []
|
|
108
107
|
|
|
109
108
|
if reasoning_content:
|
|
109
|
+
last_three_lines = "\n".join(reasoning_content.rstrip().split("\n")[-3:])
|
|
110
110
|
groups.append(Text(""))
|
|
111
|
-
groups.append(
|
|
111
|
+
groups.append(
|
|
112
|
+
Panel(
|
|
113
|
+
Text(
|
|
114
|
+
last_three_lines,
|
|
115
|
+
style="grey50",
|
|
116
|
+
),
|
|
117
|
+
title="Thought process",
|
|
118
|
+
title_align="left",
|
|
119
|
+
subtitle=timings_str,
|
|
120
|
+
style="grey50",
|
|
121
|
+
)
|
|
122
|
+
)
|
|
112
123
|
|
|
113
124
|
if content:
|
|
114
125
|
groups.append(Text(""))
|
|
115
|
-
groups.append(Markdown(content))
|
|
116
|
-
groups.append(Text(""))
|
|
126
|
+
groups.append(Markdown(content.rstrip()))
|
|
117
127
|
|
|
118
128
|
return Group(*groups)
|
|
119
129
|
|
|
120
|
-
with Live(generate_layout(
|
|
130
|
+
with Live(generate_layout(), refresh_per_second=10) as live:
|
|
121
131
|
for line in response.iter_lines():
|
|
122
132
|
line = line.decode("utf-8")
|
|
123
133
|
if not line.strip():
|
|
@@ -130,12 +140,10 @@ class TassApp:
|
|
|
130
140
|
delta = chunk["choices"][0]["delta"]
|
|
131
141
|
if delta.get("content"):
|
|
132
142
|
content += delta["content"]
|
|
133
|
-
|
|
134
|
-
live.update(generate_layout(last_three_lines, content.rstrip()))
|
|
143
|
+
live.update(generate_layout())
|
|
135
144
|
if delta.get("reasoning_content" ):
|
|
136
145
|
reasoning_content += delta["reasoning_content"]
|
|
137
|
-
|
|
138
|
-
live.update(generate_layout(last_three_lines, content.rstrip()))
|
|
146
|
+
live.update(generate_layout())
|
|
139
147
|
|
|
140
148
|
for tool_call_delta in delta.get("tool_calls", []):
|
|
141
149
|
index = tool_call_delta["index"]
|
|
@@ -164,9 +172,15 @@ class TassApp:
|
|
|
164
172
|
if function.get("arguments"):
|
|
165
173
|
tool_call["function"]["arguments"] += function["arguments"]
|
|
166
174
|
|
|
175
|
+
if all(k in chunk.get("timings", {}) for k in ["prompt_n", "prompt_per_second", "predicted_n", "predicted_per_second"]):
|
|
176
|
+
timings = chunk["timings"]
|
|
177
|
+
timings_str = (
|
|
178
|
+
f"Input: {timings['prompt_n']:,} tokens, {timings['prompt_per_second']:,.2f} tok/s | "
|
|
179
|
+
f"Output: {timings['predicted_n']:,} tokens, {timings['predicted_per_second']:,.2f} tok/s"
|
|
180
|
+
)
|
|
181
|
+
|
|
167
182
|
if chunk["choices"][0]["finish_reason"]:
|
|
168
|
-
|
|
169
|
-
live.update(generate_layout(last_three_lines, content.rstrip()))
|
|
183
|
+
live.update(generate_layout())
|
|
170
184
|
|
|
171
185
|
self.messages.append(
|
|
172
186
|
{
|
|
@@ -362,14 +376,22 @@ class TassApp:
|
|
|
362
376
|
def run(self):
|
|
363
377
|
try:
|
|
364
378
|
self._check_llm_host()
|
|
365
|
-
console.print()
|
|
366
379
|
except KeyboardInterrupt:
|
|
367
380
|
console.print("\nBye!")
|
|
368
381
|
return
|
|
369
382
|
|
|
370
383
|
while True:
|
|
384
|
+
console.print()
|
|
371
385
|
try:
|
|
372
|
-
|
|
386
|
+
input_lines = []
|
|
387
|
+
while True:
|
|
388
|
+
input_line = console.input("> ")
|
|
389
|
+
if not input_line or input_line[-1] != "\\":
|
|
390
|
+
input_lines.append(input_line)
|
|
391
|
+
break
|
|
392
|
+
input_lines.append(input_line[:-1])
|
|
393
|
+
|
|
394
|
+
user_input = "\n".join(input_lines)
|
|
373
395
|
except KeyboardInterrupt:
|
|
374
396
|
console.print("\nBye!")
|
|
375
397
|
break
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|