@brandon_9527/tcode 1.0.3 → 1.0.6
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.
- package/dist/python-src/entry.py +59 -17
- package/dist/python-src/main.py +69 -11
- package/dist/python-src/pyproject.toml +2 -1
- package/dist/python-src/src/core/deepagents.py +1 -1
- package/dist/python-src/src/managers/manager_agent.py +13 -13
- package/dist/python-src/src/managers/manager_context.py +1 -1
- package/dist/python-src/src/managers/manager_instruction.py +9 -9
- package/dist/python-src/src/managers/sandbox.py +3 -3
- package/dist/python-src/src/middlewares/dynamic_content.py +13 -10
- package/dist/python-src/src/middlewares/inject_content.py +0 -0
- package/dist/python-src/src/middlewares/subagents.py +4 -4
- package/dist/python-src/src/middlewares/summary.py +36 -36
- package/dist/python-src/src/prompts/prompts.py +1 -1
- package/dist/python-src/src/stream/formatter.py +19 -19
- package/dist/python-src/src/stream/handler.py +44 -45
- package/dist/python-src/src/stream/handler_with_tracker.py +7 -7
- package/dist/python-src/src/tools/tools.py +2 -2
- package/dist/python-src/src/tui/chatui.py +32 -36
- package/dist/python-src/src/tui/components/tlist.py +7 -7
- package/dist/python-src/src/tui/components/tscroll_panel.py +8 -8
- package/dist/python-src/src/tui/demo.py +22 -0
- package/dist/python-src/src/tui/utils/trender.py +20 -20
- package/dist/python-src/uv.lock +1974 -1939
- package/package.json +1 -1
|
@@ -19,20 +19,20 @@ from prompt_toolkit.layout import Layout,HSplit
|
|
|
19
19
|
from prompt_toolkit.styles import Style
|
|
20
20
|
from prompt_toolkit import Application
|
|
21
21
|
class InterruptSelector:
|
|
22
|
-
def __init__(A,description,options,callback):B=description;A.options=options;A.description=B;A.selected_index=0;A.callback=callback;A.rows=A.
|
|
23
|
-
def
|
|
24
|
-
def
|
|
22
|
+
def __init__(A,description,options,callback):B=description;A.options=options;A.description=B;A.selected_index=0;A.callback=callback;A.rows=A.p();A.list_container=HSplit(A.rows,padding=0);A.markdown=A.r(B);C=Window(content=A.markdown.content,height=A.markdown.height,dont_extend_height=_B,style='class:desc');D=Frame(body=C);A.container=HSplit([C,A.list_container]);A.kb=KeyBindings();A.q()
|
|
23
|
+
def r(C,content):A=StringIO();B=Console(file=A,width=80,force_terminal=_B,color_system='truecolor');B.print(Align.left(Markdown(content)),justify='left');return Window(content=FormattedTextControl(ANSI(A.getvalue())),height=D(min=1))
|
|
24
|
+
def p(A):
|
|
25
25
|
E='class:suggestion.selected';B=[]
|
|
26
26
|
for(F,C)in enumerate(A.options):D=F==A.selected_index;G='> 'if D else' ';H=E if D else'class:suggestion.label';I='class:suggestion.desc';J=VSplit([Window(FormattedTextControl([(E,G)]),width=2),Window(FormattedTextControl([(H,C[_A])]),width=60),Window(FormattedTextControl([(I,C[_C])]),wrap_lines=_B,dont_extend_width=False,always_hide_cursor=_B)],height=1);B.append(J)
|
|
27
27
|
return B
|
|
28
|
-
def
|
|
29
|
-
def
|
|
28
|
+
def t(A):A.rows=A.p();A.list_container.children=A.rows;get_app().invalidate()
|
|
29
|
+
def q(A):
|
|
30
30
|
@A.kb.add('up')
|
|
31
31
|
def B(event):
|
|
32
|
-
if A.selected_index>0:A.selected_index-=1;A.
|
|
32
|
+
if A.selected_index>0:A.selected_index-=1;A.t()
|
|
33
33
|
@A.kb.add('down')
|
|
34
34
|
def C(event):
|
|
35
|
-
if A.selected_index<len(A.options)-1:A.selected_index+=1;A.
|
|
35
|
+
if A.selected_index<len(A.options)-1:A.selected_index+=1;A.t()
|
|
36
36
|
@A.kb.add('enter')
|
|
37
37
|
def D(event):A.callback(A.selected_index)
|
|
38
38
|
async def demo():
|
|
@@ -6,22 +6,22 @@ from prompt_toolkit.layout.controls import UIControl,UIContent
|
|
|
6
6
|
from prompt_toolkit.data_structures import Point
|
|
7
7
|
from prompt_toolkit.formatted_text import ANSI
|
|
8
8
|
class ScrollableFormattedLogControl(FormattedTextControl):
|
|
9
|
-
def __init__(A):A.lines=[];A.scroll_offset=0;A._height=0;A.last_count=0;super().__init__(A.
|
|
9
|
+
def __init__(A):A.lines=[];A.scroll_offset=0;A._height=0;A.last_count=0;super().__init__(A.y,focusable=True,show_cursor=False)
|
|
10
10
|
def clear(A):A.lines=[];A.scroll_offset=0;A.last_count=0;A._height=0
|
|
11
|
-
def append_text(A,ansi_text):B=ansi_text.splitlines();A.lines.extend(B);A.last_count=len(B);A.
|
|
11
|
+
def append_text(A,ansi_text):B=ansi_text.splitlines();A.lines.extend(B);A.last_count=len(B);A.z()
|
|
12
12
|
def update_last(A,ansi_text):
|
|
13
13
|
B=ansi_text.splitlines()
|
|
14
14
|
if A.lines:A.lines=A.lines[:-A.last_count]+B
|
|
15
15
|
else:A.lines=B
|
|
16
|
-
A.last_count=len(B);A.
|
|
16
|
+
A.last_count=len(B);A.z()
|
|
17
17
|
def refresh_scroll(A):
|
|
18
18
|
if A._height:A.scroll_offset=max(0,len(A.lines)-A._height)
|
|
19
|
-
def
|
|
19
|
+
def z(A):
|
|
20
20
|
if A._height:A.scroll_offset=max(0,len(A.lines)-A._height)
|
|
21
21
|
def x(A,amount):
|
|
22
22
|
if A._height:B=max(0,len(A.lines)-A._height);A.scroll_offset=max(0,min(A.scroll_offset+amount,B))
|
|
23
23
|
def is_focusable(A):return True
|
|
24
|
-
def
|
|
24
|
+
def y(A):
|
|
25
25
|
C=A._height or 100;D=A.lines[A.scroll_offset:A.scroll_offset+C];B=[]
|
|
26
26
|
for E in D:F=sanitize_ansi_text(E);B.extend(ANSI(F).__pt_formatted_text__());B.append(('','\n'))
|
|
27
27
|
return B
|
|
@@ -34,15 +34,15 @@ class ScrollableFormattedLogControl(FormattedTextControl):
|
|
|
34
34
|
class ScrollableLogControl(UIControl):
|
|
35
35
|
def __init__(A):A.lines=[];A.scroll_offset=0;A.visible_lines=[];A._height=0;A.last_count=0
|
|
36
36
|
def clear(A):A.visible_lines=[];A.lines=[];A.scroll_offset=0;A.last_count=0;A._height=0
|
|
37
|
-
def append_text(A,ansi_text):B=ansi_text.splitlines();A.lines.extend(B);A.last_count=len(B);A.
|
|
37
|
+
def append_text(A,ansi_text):B=ansi_text.splitlines();A.lines.extend(B);A.last_count=len(B);A.z()
|
|
38
38
|
def update_last(A,ansi_text):
|
|
39
39
|
B=ansi_text.splitlines()
|
|
40
40
|
if A.lines:A.lines=A.lines[:-A.last_count]+B
|
|
41
41
|
else:A.lines=B
|
|
42
|
-
A.last_count=len(B);A.
|
|
42
|
+
A.last_count=len(B);A.z()
|
|
43
43
|
def refresh_scroll(A):
|
|
44
44
|
if A._height:A.scroll_offset=max(0,len(A.lines)-A._height)
|
|
45
|
-
def
|
|
45
|
+
def z(A):A.scroll_offset=max(0,len(A.lines)-A._height)
|
|
46
46
|
def x(A,amount):A.scroll_offset=max(0,min(A.scroll_offset+amount,max(0,len(A.lines)-A._height)))
|
|
47
47
|
def is_focusable(A):return True
|
|
48
48
|
def create_content(A,width,height):B=height;A._height=B;A.visible_lines=A.lines[A.scroll_offset:A.scroll_offset+B];return UIContent(get_line=A.get_line,line_count=len(A.visible_lines),cursor_position=Point(0,len(A.visible_lines)-1))
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
_E='agentTypes'
|
|
2
|
+
_D='skills'
|
|
3
|
+
_C='workdir'
|
|
4
|
+
_B='providerDisplayName'
|
|
5
|
+
_A='model'
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from rich.panel import Panel
|
|
8
|
+
from rich.layout import Layout
|
|
9
|
+
from rich.text import Text
|
|
10
|
+
from rich.align import Align
|
|
11
|
+
from rich.box import ROUNDED
|
|
12
|
+
import os
|
|
13
|
+
PRODUCT_NAME='MyAgent'
|
|
14
|
+
PRODUCT_VERSION='1.0.0'
|
|
15
|
+
ASCII_LOGO=[' _____ _ ',' |_ _| __ _ ___| |_ ___ _ __ '," | || '__| |/ _ \\ __/ _ \\| '__|",' | || | | | __/ || (_) | | ',' |_||_| |_|\\___|\\__\\___/|_| ']
|
|
16
|
+
def banner_view(config):
|
|
17
|
+
J='bold';I='right';G='bold yellow';F='left';B='dim';A=config;D=Console();K=os.get_terminal_size().columns or 80
|
|
18
|
+
if K<20:D.print(f"[bold]{PRODUCT_NAME} v{PRODUCT_VERSION}[/bold]");D.print(f"[dim]{A[_B]} · {A[_A]}[/dim]");return
|
|
19
|
+
C=Layout();C.split_row(Layout(name=F,ratio=1),Layout(name=I,ratio=1));L=A[_C].split('/')[-1]or'workspace';H=A[_D];M=', '.join(H[:3])if H else'none';E=[Text('Welcome back!',style=J),'']
|
|
20
|
+
for N in ASCII_LOGO:E.append(Text(N,style='bright_cyan'))
|
|
21
|
+
E.extend(['',Text(f"{A[_A]}",style=B),Text(f"~/{L}",style=B)]);C[F].update(Align.left('\n'.join(map(str,E))));O=[Text('Tips for getting started',style=G),Text('输入消息开始对话',style=B),Text("使用 'exit' 退出,Ctrl+C 中断",style=B),'',Text('Configuration',style=G),Text(f"Provider: {A[_B]}",style=B),Text(f"Model: {A[_A][:30]}",style=B),Text(f"Skills: {M}",style=B),'',Text('Agent Types',style=G),Text(' · '.join(A[_E]),style=B)];C[I].update(Align.left('\n'.join(map(str,O))));P=Text(f" {PRODUCT_NAME} v{PRODUCT_VERSION}",style=J);Q=Panel(C,title=P,title_align=F,border_style='blue',box=ROUNDED,padding=(0,1));D.print(Q)
|
|
22
|
+
if __name__=='__main__':test_config={_C:'/user/projects/ai-agent',_D:['code','chat','search','debug'],_B:'OpenAI',_A:'gpt-4o-mini',_E:['chat','code','tool']};banner_view(test_config)
|
|
@@ -27,7 +27,7 @@ from src.tui.components.tdiff import render_diff_as_markdown
|
|
|
27
27
|
from src.tui.components.tdisplay import render_content_with_line_limit
|
|
28
28
|
from src.tui.utils.render import markdown_to_wrapped_text
|
|
29
29
|
def display_tool_call(tool_name,args,events=[]):
|
|
30
|
-
C=tool_name;A=events;E=format_tool_compact(C,args);D=
|
|
30
|
+
C=tool_name;A=events;E=format_tool_compact(C,args);D=h(C,args);B=Tree(Text(_I,style=_J)+Text(f"{E}",style=_C),guide_style=_D)
|
|
31
31
|
if A and len(A)>0:F=display_sub_panel(D,sub_events=A);B.add(F)
|
|
32
32
|
else:B.add(D)
|
|
33
33
|
return B
|
|
@@ -36,14 +36,14 @@ def display_tool_result(tool_name,args=_E,result=_E,events=[]):
|
|
|
36
36
|
if A is _E:A={}
|
|
37
37
|
H=format_tool_compact(G,A);C=G.lower()
|
|
38
38
|
try:
|
|
39
|
-
if C==_K and isinstance(A,dict):B=
|
|
40
|
-
elif C==_L and isinstance(A,dict):B=
|
|
41
|
-
elif C in[_M]and isinstance(A,dict):B=
|
|
42
|
-
elif C==_H and isinstance(A,dict):B=
|
|
43
|
-
elif C==_N and isinstance(A,dict):B=
|
|
44
|
-
elif C==_O and isinstance(A,dict):B=
|
|
45
|
-
elif C==_P and isinstance(A,dict):B=
|
|
46
|
-
else:B=
|
|
39
|
+
if C==_K and isinstance(A,dict):B=f(A)
|
|
40
|
+
elif C==_L and isinstance(A,dict):B=f(A)
|
|
41
|
+
elif C in[_M]and isinstance(A,dict):B=f(A)
|
|
42
|
+
elif C==_H and isinstance(A,dict):B=o(A,D)
|
|
43
|
+
elif C==_N and isinstance(A,dict):B=m(A,D)
|
|
44
|
+
elif C==_O and isinstance(A,dict):B=n(A,D)
|
|
45
|
+
elif C==_P and isinstance(A,dict):B=l(A,D)
|
|
46
|
+
else:B=k(A,D)
|
|
47
47
|
except Exception as I:import traceback as J;B=Text(f"Error: {str(I)}\n{J.format_exc()}",style='red')
|
|
48
48
|
F=Tree(Text(_I,style=_J)+Text(f"{H}",style=_C),guide_style=_D)
|
|
49
49
|
if E and len(E)>0:K=display_sub_panel(B,sub_events=E);F.add(K)
|
|
@@ -101,19 +101,19 @@ def format_tool_compact(name,args):
|
|
|
101
101
|
I=', '.join(M)
|
|
102
102
|
if len(I)>50:I=I[:47]+_B
|
|
103
103
|
return f"{J}({I})"
|
|
104
|
-
def
|
|
104
|
+
def h(tool_name,arguments):
|
|
105
105
|
D=' Will search for pattern';C=arguments;B='bold grey';A=tool_name.lower()
|
|
106
106
|
if A==_H:return Text(f"running ...",style=B)
|
|
107
107
|
if A==_M:return Text(f" Executing ...",style=B)
|
|
108
108
|
elif A==_L:return g(C)
|
|
109
|
-
elif A==_K:return
|
|
109
|
+
elif A==_K:return j(C)
|
|
110
110
|
elif A in[_N,_O]:return Text(D,style=B)
|
|
111
111
|
elif A==_P:return Text(D,stype=B)
|
|
112
112
|
else:return Text(' Executing ...',style=B)
|
|
113
113
|
def display_sub_panel(result=_E,sub_events=[]):
|
|
114
114
|
I='calling';H='success';C=result;A=[]
|
|
115
115
|
for(M,D)in enumerate(sub_events):
|
|
116
|
-
E=D[3]['name'];F=json.dumps(D[3]['args'])[:
|
|
116
|
+
E=D[3]['name'];F=json.dumps(D[3]['args'])[:100];G=D[3].get(H,I);N=D[3].get(_R,'')
|
|
117
117
|
if G==H:B=Tree(Text('● ',style=_Q)+Text(f" {E}({F})",style=_C),guide_style=_D);A.append(B)
|
|
118
118
|
elif G=='error':B=Tree(Text('● ',style='bold red')+Text(f" {E}({F})",style=_C),guide_style=_D);A.append(B)
|
|
119
119
|
elif G==I:B=Tree(Text('○ ',style=_Q)+Text(f" {E}({F})",style=_C),guide_style=_D);A.append(B)
|
|
@@ -122,7 +122,7 @@ def display_sub_panel(result=_E,sub_events=[]):
|
|
|
122
122
|
else:A.append(C)
|
|
123
123
|
else:A.append(markdown_to_wrapped_text(f"calling ...",prefix=_E))
|
|
124
124
|
J=Columns(A,column_first=True,expand=True);K=Box(' \n \n \n \n \n \n \n ');L=Panel(J,title_align='left',box=K);return L
|
|
125
|
-
def
|
|
125
|
+
def j(arguments):
|
|
126
126
|
A=arguments;B=A.get(_F,'');C=A.get('old_string','');D=A.get('new_string','');E=''
|
|
127
127
|
if os.path.exists(B):
|
|
128
128
|
with open(B,'r',encoding='utf-8')as F:G=F.read()
|
|
@@ -136,7 +136,7 @@ def g(arguments):
|
|
|
136
136
|
E=recognize_language(A)
|
|
137
137
|
if E:G=f"```\n{E}\n{B}\n```";return render_content_with_line_limit(G,'',100)
|
|
138
138
|
else:return render_content_with_line_limit(B,'',100)
|
|
139
|
-
def
|
|
139
|
+
def f(arguments):
|
|
140
140
|
B=arguments.get(_F,'');C=''
|
|
141
141
|
if os.path.exists(B):C=open(B,'r').read()
|
|
142
142
|
E=C.split(_A);F=len(E);A=50
|
|
@@ -145,7 +145,7 @@ def k(arguments):
|
|
|
145
145
|
H=recognize_language(B)
|
|
146
146
|
if H:J=f"```{H}\n{D}\n```";return render_content_with_line_limit(J,'',-1)
|
|
147
147
|
else:return render_content_with_line_limit(D,'',-1)
|
|
148
|
-
def
|
|
148
|
+
def i(arguments,result):
|
|
149
149
|
C=result.strip().split(_A);F=len(C);B=[];D=10;G=C[:D]
|
|
150
150
|
for(H,A)in enumerate(G):
|
|
151
151
|
I=''if H==0 else''
|
|
@@ -154,7 +154,7 @@ def l(arguments,result):
|
|
|
154
154
|
E=F-D
|
|
155
155
|
if E>0:B.append(f" ... and {E} more lines")
|
|
156
156
|
return Text(_A.join(B),style=_G)
|
|
157
|
-
def
|
|
157
|
+
def o(arguments,result):
|
|
158
158
|
C=result.strip().split(_A);F=len(C);B=[];D=10;G=C[:D]
|
|
159
159
|
for(H,A)in enumerate(G):
|
|
160
160
|
I=''if H==0 else''
|
|
@@ -163,7 +163,7 @@ def h(arguments,result):
|
|
|
163
163
|
E=F-D
|
|
164
164
|
if E>0:B.append(f" ... and {E} more lines")
|
|
165
165
|
return Text(_A.join(B),style=_G)
|
|
166
|
-
def
|
|
166
|
+
def m(arguments,result):
|
|
167
167
|
C=result.strip().split(_A);F=len(C);B=[];D=10;G=C[:D]
|
|
168
168
|
for(H,A)in enumerate(G):
|
|
169
169
|
I=''if H==0 else''
|
|
@@ -172,7 +172,7 @@ def i(arguments,result):
|
|
|
172
172
|
E=F-D
|
|
173
173
|
if E>0:B.append(f" ... and {E} more lines")
|
|
174
174
|
return Text(_A.join(B),style=_G)
|
|
175
|
-
def
|
|
175
|
+
def n(arguments,result):
|
|
176
176
|
C=result.strip().split(_A);F=len(C);B=[];D=10;G=C[:D]
|
|
177
177
|
for(H,A)in enumerate(G):
|
|
178
178
|
I=''if H==0 else''
|
|
@@ -181,7 +181,7 @@ def m(arguments,result):
|
|
|
181
181
|
E=F-D
|
|
182
182
|
if E>0:B.append(f" ... and {E} more lines")
|
|
183
183
|
return Text(_A.join(B),style=_G)
|
|
184
|
-
def
|
|
184
|
+
def l(arguments,result):
|
|
185
185
|
C=result.strip().split(_A);F=len(C);B=[];D=10;G=C[:D]
|
|
186
186
|
for(H,A)in enumerate(G):
|
|
187
187
|
I=''if H==0 else''
|
|
@@ -190,7 +190,7 @@ def f(arguments,result):
|
|
|
190
190
|
E=F-D
|
|
191
191
|
if E>0:B.append(f" ... and {E} more lines")
|
|
192
192
|
return Text(_A.join(B),style=_G)
|
|
193
|
-
def
|
|
193
|
+
def k(arguments,result):
|
|
194
194
|
B=result;A=str(B)if B else'tool completed successfully'
|
|
195
195
|
if len(A)>500:C=A[:500]+'\n ... (truncated)'
|
|
196
196
|
else:C=A
|