zrb 1.21.29__py3-none-any.whl → 2.0.0a4__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.
Potentially problematic release.
This version of zrb might be problematic. Click here for more details.
- zrb/__init__.py +118 -129
- zrb/builtin/__init__.py +54 -2
- zrb/builtin/llm/chat.py +147 -0
- zrb/callback/callback.py +8 -1
- zrb/cmd/cmd_result.py +2 -1
- zrb/config/config.py +491 -280
- zrb/config/helper.py +84 -0
- zrb/config/web_auth_config.py +50 -35
- zrb/context/any_shared_context.py +13 -2
- zrb/context/context.py +31 -3
- zrb/context/print_fn.py +13 -0
- zrb/context/shared_context.py +14 -1
- zrb/input/option_input.py +30 -2
- zrb/llm/agent/__init__.py +9 -0
- zrb/llm/agent/agent.py +215 -0
- zrb/llm/agent/summarizer.py +20 -0
- zrb/llm/app/__init__.py +10 -0
- zrb/llm/app/completion.py +281 -0
- zrb/llm/app/confirmation/allow_tool.py +66 -0
- zrb/llm/app/confirmation/handler.py +178 -0
- zrb/llm/app/confirmation/replace_confirmation.py +77 -0
- zrb/llm/app/keybinding.py +34 -0
- zrb/llm/app/layout.py +117 -0
- zrb/llm/app/lexer.py +155 -0
- zrb/llm/app/redirection.py +28 -0
- zrb/llm/app/style.py +16 -0
- zrb/llm/app/ui.py +733 -0
- zrb/llm/config/__init__.py +4 -0
- zrb/llm/config/config.py +122 -0
- zrb/llm/config/limiter.py +247 -0
- zrb/llm/history_manager/__init__.py +4 -0
- zrb/llm/history_manager/any_history_manager.py +23 -0
- zrb/llm/history_manager/file_history_manager.py +91 -0
- zrb/llm/history_processor/summarizer.py +108 -0
- zrb/llm/note/__init__.py +3 -0
- zrb/llm/note/manager.py +122 -0
- zrb/llm/prompt/__init__.py +29 -0
- zrb/llm/prompt/claude_compatibility.py +92 -0
- zrb/llm/prompt/compose.py +55 -0
- zrb/llm/prompt/default.py +51 -0
- zrb/llm/prompt/markdown/mandate.md +23 -0
- zrb/llm/prompt/markdown/persona.md +3 -0
- zrb/llm/prompt/markdown/summarizer.md +21 -0
- zrb/llm/prompt/note.py +41 -0
- zrb/llm/prompt/system_context.py +46 -0
- zrb/llm/prompt/zrb.py +41 -0
- zrb/llm/skill/__init__.py +3 -0
- zrb/llm/skill/manager.py +86 -0
- zrb/llm/task/__init__.py +4 -0
- zrb/llm/task/llm_chat_task.py +316 -0
- zrb/llm/task/llm_task.py +245 -0
- zrb/llm/tool/__init__.py +39 -0
- zrb/llm/tool/bash.py +75 -0
- zrb/llm/tool/code.py +266 -0
- zrb/llm/tool/file.py +419 -0
- zrb/llm/tool/note.py +70 -0
- zrb/{builtin/llm → llm}/tool/rag.py +8 -5
- zrb/llm/tool/search/brave.py +53 -0
- zrb/llm/tool/search/searxng.py +47 -0
- zrb/llm/tool/search/serpapi.py +47 -0
- zrb/llm/tool/skill.py +19 -0
- zrb/llm/tool/sub_agent.py +70 -0
- zrb/llm/tool/web.py +97 -0
- zrb/llm/tool/zrb_task.py +66 -0
- zrb/llm/util/attachment.py +101 -0
- zrb/llm/util/prompt.py +104 -0
- zrb/llm/util/stream_response.py +178 -0
- zrb/session/any_session.py +0 -3
- zrb/session/session.py +1 -1
- zrb/task/base/context.py +25 -13
- zrb/task/base/execution.py +52 -47
- zrb/task/base/lifecycle.py +7 -4
- zrb/task/base_task.py +48 -49
- zrb/task/base_trigger.py +4 -1
- zrb/task/cmd_task.py +6 -0
- zrb/task/http_check.py +11 -5
- zrb/task/make_task.py +3 -0
- zrb/task/rsync_task.py +5 -0
- zrb/task/scaffolder.py +7 -4
- zrb/task/scheduler.py +3 -0
- zrb/task/tcp_check.py +6 -4
- zrb/util/ascii_art/art/bee.txt +17 -0
- zrb/util/ascii_art/art/cat.txt +9 -0
- zrb/util/ascii_art/art/ghost.txt +16 -0
- zrb/util/ascii_art/art/panda.txt +17 -0
- zrb/util/ascii_art/art/rose.txt +14 -0
- zrb/util/ascii_art/art/unicorn.txt +15 -0
- zrb/util/ascii_art/banner.py +92 -0
- zrb/util/cli/markdown.py +22 -2
- zrb/util/cmd/command.py +33 -10
- zrb/util/file.py +51 -32
- zrb/util/match.py +78 -0
- zrb/util/run.py +3 -3
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/METADATA +9 -15
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/RECORD +100 -128
- zrb/attr/__init__.py +0 -0
- zrb/builtin/llm/attachment.py +0 -40
- zrb/builtin/llm/chat_completion.py +0 -274
- zrb/builtin/llm/chat_session.py +0 -270
- zrb/builtin/llm/chat_session_cmd.py +0 -288
- zrb/builtin/llm/chat_trigger.py +0 -79
- zrb/builtin/llm/history.py +0 -71
- zrb/builtin/llm/input.py +0 -27
- zrb/builtin/llm/llm_ask.py +0 -269
- zrb/builtin/llm/previous-session.js +0 -21
- zrb/builtin/llm/tool/__init__.py +0 -0
- zrb/builtin/llm/tool/api.py +0 -75
- zrb/builtin/llm/tool/cli.py +0 -52
- zrb/builtin/llm/tool/code.py +0 -236
- zrb/builtin/llm/tool/file.py +0 -560
- zrb/builtin/llm/tool/note.py +0 -84
- zrb/builtin/llm/tool/sub_agent.py +0 -150
- zrb/builtin/llm/tool/web.py +0 -171
- zrb/builtin/project/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/module/template/app_template/module/my_module/service/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/__init__.py +0 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/__init__.py +0 -0
- zrb/builtin/project/create/__init__.py +0 -0
- zrb/builtin/shell/__init__.py +0 -0
- zrb/builtin/shell/autocomplete/__init__.py +0 -0
- zrb/callback/__init__.py +0 -0
- zrb/cmd/__init__.py +0 -0
- zrb/config/default_prompt/interactive_system_prompt.md +0 -29
- zrb/config/default_prompt/persona.md +0 -1
- zrb/config/default_prompt/summarization_prompt.md +0 -57
- zrb/config/default_prompt/system_prompt.md +0 -38
- zrb/config/llm_config.py +0 -339
- zrb/config/llm_context/config.py +0 -166
- zrb/config/llm_context/config_parser.py +0 -40
- zrb/config/llm_context/workflow.py +0 -81
- zrb/config/llm_rate_limitter.py +0 -190
- zrb/content_transformer/__init__.py +0 -0
- zrb/context/__init__.py +0 -0
- zrb/dot_dict/__init__.py +0 -0
- zrb/env/__init__.py +0 -0
- zrb/group/__init__.py +0 -0
- zrb/input/__init__.py +0 -0
- zrb/runner/__init__.py +0 -0
- zrb/runner/web_route/__init__.py +0 -0
- zrb/runner/web_route/home_page/__init__.py +0 -0
- zrb/session/__init__.py +0 -0
- zrb/session_state_log/__init__.py +0 -0
- zrb/session_state_logger/__init__.py +0 -0
- zrb/task/__init__.py +0 -0
- zrb/task/base/__init__.py +0 -0
- zrb/task/llm/__init__.py +0 -0
- zrb/task/llm/agent.py +0 -204
- zrb/task/llm/agent_runner.py +0 -152
- zrb/task/llm/config.py +0 -122
- zrb/task/llm/conversation_history.py +0 -209
- zrb/task/llm/conversation_history_model.py +0 -67
- zrb/task/llm/default_workflow/coding/workflow.md +0 -41
- zrb/task/llm/default_workflow/copywriting/workflow.md +0 -68
- zrb/task/llm/default_workflow/git/workflow.md +0 -118
- zrb/task/llm/default_workflow/golang/workflow.md +0 -128
- zrb/task/llm/default_workflow/html-css/workflow.md +0 -135
- zrb/task/llm/default_workflow/java/workflow.md +0 -146
- zrb/task/llm/default_workflow/javascript/workflow.md +0 -158
- zrb/task/llm/default_workflow/python/workflow.md +0 -160
- zrb/task/llm/default_workflow/researching/workflow.md +0 -153
- zrb/task/llm/default_workflow/rust/workflow.md +0 -162
- zrb/task/llm/default_workflow/shell/workflow.md +0 -299
- zrb/task/llm/error.py +0 -95
- zrb/task/llm/file_replacement.py +0 -206
- zrb/task/llm/file_tool_model.py +0 -57
- zrb/task/llm/history_processor.py +0 -206
- zrb/task/llm/history_summarization.py +0 -25
- zrb/task/llm/print_node.py +0 -221
- zrb/task/llm/prompt.py +0 -321
- zrb/task/llm/subagent_conversation_history.py +0 -41
- zrb/task/llm/tool_wrapper.py +0 -361
- zrb/task/llm/typing.py +0 -3
- zrb/task/llm/workflow.py +0 -76
- zrb/task/llm_task.py +0 -379
- zrb/task_status/__init__.py +0 -0
- zrb/util/__init__.py +0 -0
- zrb/util/cli/__init__.py +0 -0
- zrb/util/cmd/__init__.py +0 -0
- zrb/util/codemod/__init__.py +0 -0
- zrb/util/string/__init__.py +0 -0
- zrb/xcom/__init__.py +0 -0
- /zrb/{config/default_prompt/file_extractor_system_prompt.md → llm/prompt/markdown/file_extractor.md} +0 -0
- /zrb/{config/default_prompt/repo_extractor_system_prompt.md → llm/prompt/markdown/repo_extractor.md} +0 -0
- /zrb/{config/default_prompt/repo_summarizer_system_prompt.md → llm/prompt/markdown/repo_summarizer.md} +0 -0
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/WHEEL +0 -0
- {zrb-1.21.29.dist-info → zrb-2.0.0a4.dist-info}/entry_points.txt +0 -0
zrb/llm/app/layout.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
|
|
3
|
+
from prompt_toolkit.formatted_text import HTML, AnyFormattedText
|
|
4
|
+
from prompt_toolkit.layout import HSplit, Layout, Window, WindowAlign
|
|
5
|
+
from prompt_toolkit.layout.containers import Float, FloatContainer
|
|
6
|
+
from prompt_toolkit.layout.controls import FormattedTextControl
|
|
7
|
+
from prompt_toolkit.layout.menus import CompletionsMenu
|
|
8
|
+
from prompt_toolkit.lexers import Lexer
|
|
9
|
+
from prompt_toolkit.widgets import Frame, TextArea
|
|
10
|
+
|
|
11
|
+
from zrb.llm.app.completion import InputCompleter
|
|
12
|
+
from zrb.llm.history_manager.any_history_manager import AnyHistoryManager
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def create_input_field(
|
|
16
|
+
history_manager: AnyHistoryManager,
|
|
17
|
+
attach_commands: list[str],
|
|
18
|
+
exit_commands: list[str],
|
|
19
|
+
info_commands: list[str],
|
|
20
|
+
save_commands: list[str],
|
|
21
|
+
load_commands: list[str],
|
|
22
|
+
redirect_output_commands: list[str],
|
|
23
|
+
summarize_commands: list[str],
|
|
24
|
+
exec_commands: list[str],
|
|
25
|
+
) -> TextArea:
|
|
26
|
+
return TextArea(
|
|
27
|
+
height=4,
|
|
28
|
+
prompt=HTML('<style color="ansibrightblue"><b>>>> </b></style>'),
|
|
29
|
+
multiline=True,
|
|
30
|
+
wrap_lines=True,
|
|
31
|
+
completer=InputCompleter(
|
|
32
|
+
history_manager=history_manager,
|
|
33
|
+
attach_commands=attach_commands,
|
|
34
|
+
exit_commands=exit_commands,
|
|
35
|
+
info_commands=info_commands,
|
|
36
|
+
save_commands=save_commands,
|
|
37
|
+
load_commands=load_commands,
|
|
38
|
+
redirect_output_commands=redirect_output_commands,
|
|
39
|
+
summarize_commands=summarize_commands,
|
|
40
|
+
exec_commands=exec_commands,
|
|
41
|
+
),
|
|
42
|
+
complete_while_typing=True,
|
|
43
|
+
focus_on_click=True,
|
|
44
|
+
style="class:input_field",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def create_output_field(greeting: str, lexer: Lexer) -> TextArea:
|
|
49
|
+
return TextArea(
|
|
50
|
+
text=greeting.rstrip() + "\n\n",
|
|
51
|
+
read_only=True,
|
|
52
|
+
scrollbar=False,
|
|
53
|
+
wrap_lines=True,
|
|
54
|
+
lexer=lexer,
|
|
55
|
+
focus_on_click=True,
|
|
56
|
+
focusable=True,
|
|
57
|
+
style="class:output_field",
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def create_layout(
|
|
62
|
+
title: str,
|
|
63
|
+
jargon: str,
|
|
64
|
+
input_field: TextArea,
|
|
65
|
+
output_field: TextArea,
|
|
66
|
+
info_bar_text: Callable[[], AnyFormattedText],
|
|
67
|
+
status_bar_text: Callable[[], AnyFormattedText],
|
|
68
|
+
) -> Layout:
|
|
69
|
+
title_bar_text = HTML(
|
|
70
|
+
f" <style bg='ansipurple' color='white'><b> {title} </b></style> "
|
|
71
|
+
f"<style color='#888888'>| {jargon}</style>"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return Layout(
|
|
75
|
+
FloatContainer(
|
|
76
|
+
content=HSplit(
|
|
77
|
+
[
|
|
78
|
+
# Title Bar
|
|
79
|
+
Window(
|
|
80
|
+
height=2,
|
|
81
|
+
content=FormattedTextControl(title_bar_text),
|
|
82
|
+
style="class:title-bar",
|
|
83
|
+
align=WindowAlign.CENTER,
|
|
84
|
+
),
|
|
85
|
+
# Info Bar
|
|
86
|
+
Window(
|
|
87
|
+
height=2,
|
|
88
|
+
content=FormattedTextControl(info_bar_text),
|
|
89
|
+
style="class:info-bar",
|
|
90
|
+
align=WindowAlign.CENTER,
|
|
91
|
+
),
|
|
92
|
+
# Chat History
|
|
93
|
+
Frame(output_field, title="Conversation", style="class:frame"),
|
|
94
|
+
# Input Area
|
|
95
|
+
Frame(
|
|
96
|
+
input_field,
|
|
97
|
+
title="(ENTER to send, CTRL+ENTER for newline, ESC to cancel)",
|
|
98
|
+
style="class:input-frame",
|
|
99
|
+
),
|
|
100
|
+
# Status Bar
|
|
101
|
+
Window(
|
|
102
|
+
height=1,
|
|
103
|
+
content=FormattedTextControl(status_bar_text),
|
|
104
|
+
style="class:bottom-toolbar",
|
|
105
|
+
),
|
|
106
|
+
]
|
|
107
|
+
),
|
|
108
|
+
floats=[
|
|
109
|
+
Float(
|
|
110
|
+
xcursor=True,
|
|
111
|
+
ycursor=True,
|
|
112
|
+
content=CompletionsMenu(max_height=16, scroll_offset=1),
|
|
113
|
+
),
|
|
114
|
+
],
|
|
115
|
+
),
|
|
116
|
+
focused_element=input_field,
|
|
117
|
+
)
|
zrb/llm/app/lexer.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from prompt_toolkit.lexers import Lexer
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CLIStyleLexer(Lexer):
|
|
7
|
+
def lex_document(self, document):
|
|
8
|
+
lines = document.lines
|
|
9
|
+
line_tokens = {} # Cache for tokens per line
|
|
10
|
+
|
|
11
|
+
# Global state for the document
|
|
12
|
+
current_attrs = set()
|
|
13
|
+
current_fg = ""
|
|
14
|
+
current_bg = ""
|
|
15
|
+
|
|
16
|
+
# Pre-process all lines to handle state across newlines
|
|
17
|
+
# Regex to find ANSI escape sequences (CSI)
|
|
18
|
+
ansi_escape = re.compile(r"\x1B\[([0-9;]*)m")
|
|
19
|
+
|
|
20
|
+
for lineno, line in enumerate(lines):
|
|
21
|
+
tokens = []
|
|
22
|
+
last_end = 0
|
|
23
|
+
|
|
24
|
+
def build_style():
|
|
25
|
+
parts = list(current_attrs)
|
|
26
|
+
if current_fg:
|
|
27
|
+
parts.append(current_fg)
|
|
28
|
+
if current_bg:
|
|
29
|
+
parts.append(current_bg)
|
|
30
|
+
return " ".join(parts)
|
|
31
|
+
|
|
32
|
+
for match in ansi_escape.finditer(line):
|
|
33
|
+
start, end = match.span()
|
|
34
|
+
|
|
35
|
+
# Add text before the escape sequence with current style
|
|
36
|
+
if start > last_end:
|
|
37
|
+
tokens.append((build_style(), line[last_end:start]))
|
|
38
|
+
|
|
39
|
+
# Parse codes
|
|
40
|
+
codes = match.group(1).split(";")
|
|
41
|
+
if not codes or codes == [""]:
|
|
42
|
+
codes = ["0"]
|
|
43
|
+
|
|
44
|
+
# Convert to integers
|
|
45
|
+
int_codes = []
|
|
46
|
+
for c in codes:
|
|
47
|
+
if c.isdigit():
|
|
48
|
+
int_codes.append(int(c))
|
|
49
|
+
|
|
50
|
+
i = 0
|
|
51
|
+
while i < len(int_codes):
|
|
52
|
+
c = int_codes[i]
|
|
53
|
+
i += 1
|
|
54
|
+
|
|
55
|
+
if c == 0:
|
|
56
|
+
current_attrs.clear()
|
|
57
|
+
current_fg = ""
|
|
58
|
+
current_bg = ""
|
|
59
|
+
elif c == 1:
|
|
60
|
+
current_attrs.add("bold")
|
|
61
|
+
elif c == 2:
|
|
62
|
+
current_attrs.add("class:faint")
|
|
63
|
+
elif c == 3:
|
|
64
|
+
current_attrs.add("italic")
|
|
65
|
+
elif c == 4:
|
|
66
|
+
current_attrs.add("underline")
|
|
67
|
+
elif c == 22:
|
|
68
|
+
current_attrs.discard("bold")
|
|
69
|
+
current_attrs.discard("class:faint")
|
|
70
|
+
elif c == 23:
|
|
71
|
+
current_attrs.discard("italic")
|
|
72
|
+
elif c == 24:
|
|
73
|
+
current_attrs.discard("underline")
|
|
74
|
+
elif 30 <= c <= 37:
|
|
75
|
+
colors = [
|
|
76
|
+
"#000000",
|
|
77
|
+
"#ff0000",
|
|
78
|
+
"#00ff00",
|
|
79
|
+
"#ffff00",
|
|
80
|
+
"#0000ff",
|
|
81
|
+
"#ff00ff",
|
|
82
|
+
"#00ffff",
|
|
83
|
+
"#ffffff",
|
|
84
|
+
]
|
|
85
|
+
current_fg = colors[c - 30]
|
|
86
|
+
elif c == 38:
|
|
87
|
+
if i < len(int_codes):
|
|
88
|
+
mode = int_codes[i]
|
|
89
|
+
i += 1
|
|
90
|
+
if mode == 5 and i < len(int_codes):
|
|
91
|
+
i += 1 # Skip 256 color
|
|
92
|
+
elif mode == 2 and i + 2 < len(int_codes):
|
|
93
|
+
r, g, b = (
|
|
94
|
+
int_codes[i],
|
|
95
|
+
int_codes[i + 1],
|
|
96
|
+
int_codes[i + 2],
|
|
97
|
+
)
|
|
98
|
+
i += 3
|
|
99
|
+
current_fg = f"#{r:02x}{g:02x}{b:02x}"
|
|
100
|
+
elif c == 39:
|
|
101
|
+
current_fg = ""
|
|
102
|
+
elif 40 <= c <= 47:
|
|
103
|
+
colors = [
|
|
104
|
+
"#000000",
|
|
105
|
+
"#ff0000",
|
|
106
|
+
"#00ff00",
|
|
107
|
+
"#ffff00",
|
|
108
|
+
"#0000ff",
|
|
109
|
+
"#ff00ff",
|
|
110
|
+
"#00ffff",
|
|
111
|
+
"#ffffff",
|
|
112
|
+
]
|
|
113
|
+
current_bg = f"bg:{colors[c - 40]}"
|
|
114
|
+
elif c == 48:
|
|
115
|
+
if i < len(int_codes):
|
|
116
|
+
mode = int_codes[i]
|
|
117
|
+
i += 1
|
|
118
|
+
if mode == 5 and i < len(int_codes):
|
|
119
|
+
i += 1
|
|
120
|
+
elif mode == 2 and i + 2 < len(int_codes):
|
|
121
|
+
r, g, b = (
|
|
122
|
+
int_codes[i],
|
|
123
|
+
int_codes[i + 1],
|
|
124
|
+
int_codes[i + 2],
|
|
125
|
+
)
|
|
126
|
+
i += 3
|
|
127
|
+
current_bg = f"bg:#{r:02x}{g:02x}{b:02x}"
|
|
128
|
+
elif c == 49:
|
|
129
|
+
current_bg = ""
|
|
130
|
+
elif 90 <= c <= 97:
|
|
131
|
+
colors = [
|
|
132
|
+
"#555555",
|
|
133
|
+
"#ff5555",
|
|
134
|
+
"#55ff55",
|
|
135
|
+
"#ffff55",
|
|
136
|
+
"#5555ff",
|
|
137
|
+
"#ff55ff",
|
|
138
|
+
"#55ffff",
|
|
139
|
+
"#ffffff",
|
|
140
|
+
]
|
|
141
|
+
current_fg = colors[c - 90]
|
|
142
|
+
|
|
143
|
+
last_end = end
|
|
144
|
+
|
|
145
|
+
# Add remaining text
|
|
146
|
+
if last_end < len(line):
|
|
147
|
+
tokens.append((build_style(), line[last_end:]))
|
|
148
|
+
|
|
149
|
+
# Store tokens for this line
|
|
150
|
+
line_tokens[lineno] = tokens
|
|
151
|
+
|
|
152
|
+
def get_line(lineno):
|
|
153
|
+
return line_tokens.get(lineno, [])
|
|
154
|
+
|
|
155
|
+
return get_line
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class StreamToUI(io.TextIOBase):
|
|
6
|
+
"""Redirect stdout to UI's append_to_output."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, ui_callback):
|
|
9
|
+
self.ui_callback = ui_callback
|
|
10
|
+
self.original_stdout = sys.stdout
|
|
11
|
+
self.original_stderr = sys.stderr
|
|
12
|
+
self._is_first_write = True
|
|
13
|
+
|
|
14
|
+
def write(self, text: str) -> int:
|
|
15
|
+
from prompt_toolkit.application import get_app
|
|
16
|
+
|
|
17
|
+
text = text.expandtabs(4)
|
|
18
|
+
if text:
|
|
19
|
+
if self._is_first_write:
|
|
20
|
+
self.ui_callback("\n", end="")
|
|
21
|
+
self._is_first_write = False
|
|
22
|
+
self.ui_callback(text, end="")
|
|
23
|
+
get_app().invalidate()
|
|
24
|
+
return len(text)
|
|
25
|
+
|
|
26
|
+
def flush(self):
|
|
27
|
+
self.original_stdout.flush()
|
|
28
|
+
self.original_stderr.flush()
|
zrb/llm/app/style.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from prompt_toolkit.styles import Style
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def create_style() -> Style:
|
|
5
|
+
return Style.from_dict(
|
|
6
|
+
{
|
|
7
|
+
"frame.label": "bg:#000000 #ffff00",
|
|
8
|
+
"thinking": "ansigreen italic",
|
|
9
|
+
"faint": "#888888",
|
|
10
|
+
"output_field": "bg:#000000 #eeeeee",
|
|
11
|
+
"input_field": "bg:#000000 #eeeeee",
|
|
12
|
+
"text": "#eeeeee",
|
|
13
|
+
"status": "reverse",
|
|
14
|
+
"bottom-toolbar": "bg:#333333 #aaaaaa",
|
|
15
|
+
}
|
|
16
|
+
)
|