deer-agent-framework 0.2a1__tar.gz → 0.2.3__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.
- {deer_agent_framework-0.2a1/deer_agent_framework.egg-info → deer_agent_framework-0.2.3}/PKG-INFO +1 -1
- {deer_agent_framework-0.2a1/deer/builtins/agents → deer_agent_framework-0.2.3/deer/builtins_agents}/__init__.py +1 -1
- {deer_agent_framework-0.2a1/deer/builtins/agents → deer_agent_framework-0.2.3/deer/builtins_agents}/operating_system.py +1 -1
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/cli/main.py +6 -8
- deer_agent_framework-0.2.3/deer/cli/repl.py +368 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/core/agent.py +50 -9
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/core/executor.py +1 -1
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/core/planner.py +2 -2
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/core/validator.py +1 -1
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/drivers/base.py +6 -4
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/drivers/ollama.py +8 -5
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/memory/vector.py +1 -1
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/models.py +3 -3
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3/deer_agent_framework.egg-info}/PKG-INFO +1 -1
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer_agent_framework.egg-info/SOURCES.txt +3 -3
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/pyproject.toml +1 -1
- deer_agent_framework-0.2a1/deer/cli/repl.py +0 -263
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/LICENSE +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/README.md +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/__init__.py +0 -0
- {deer_agent_framework-0.2a1/deer/builtins/agents → deer_agent_framework-0.2.3/deer/builtins_agents}/python_architect.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/cli/__init__.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/cli/parser.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/core/__init__.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/drivers/__init__.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/drivers/azure.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/drivers/gemini.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/drivers/openai.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/evals/__init__.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/evals/runner.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/memory/__init__.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/__init__.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/base.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/decorators.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/presets.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/__init__.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/code_searcher.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/csv_manager.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/dependency_analyzer.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/file_manager.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/git_manager.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/http_client.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/json_editor.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/logic_provider.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/process_manager.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/python_struct_editor.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/runtime_manager.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/sqlite_manager.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/system_observer.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/toml_editor.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/xml_editor.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/yaml_editor.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/registry.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/schemas.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/utils/__init__.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/utils/console.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/utils/plots/__init__.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/utils/plots/plot_traces.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer_agent_framework.egg-info/dependency_links.txt +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer_agent_framework.egg-info/entry_points.txt +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer_agent_framework.egg-info/requires.txt +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer_agent_framework.egg-info/top_level.txt +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/setup.cfg +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/tests/test_driver.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/tests/test_executor.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/tests/test_planner.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/tests/test_tools.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/tests/test_tools_definition.py +0 -0
- {deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/tests/test_vector_memory.py +0 -0
|
@@ -15,7 +15,7 @@ registry = ToolRegistry(Preset.SYSTEM_ADMIN | {HTTPClient})
|
|
|
15
15
|
working_dir = get_path_from_parser() or Path.cwd()
|
|
16
16
|
|
|
17
17
|
agent = DeterministicAgent(
|
|
18
|
-
description="OS Agent",
|
|
18
|
+
description="Advanced OS Agent for secure system management.",
|
|
19
19
|
identity=(
|
|
20
20
|
"You are a capable Operating System Agent. "
|
|
21
21
|
"Your goal is to assist the user by managing the system, executing tasks, and solving problems efficiently. "
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from rich.text import Text
|
|
2
2
|
from deer.utils.console import console, error, info
|
|
3
|
-
from deer.
|
|
3
|
+
from deer.builtins_agents import agents
|
|
4
4
|
import importlib.util
|
|
5
5
|
import sys
|
|
6
6
|
import logging
|
|
7
7
|
|
|
8
8
|
from .parser import drivers_parser
|
|
9
9
|
|
|
10
|
-
logger = logging.getLogger("DEER")
|
|
10
|
+
logger = logging.getLogger(f"DEER.{__name__}")
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def title():
|
|
@@ -28,13 +28,13 @@ def title():
|
|
|
28
28
|
def agents_list():
|
|
29
29
|
console.print()
|
|
30
30
|
console.print("[bold]Available agents[/bold]")
|
|
31
|
-
for name in
|
|
31
|
+
for name in agents:
|
|
32
32
|
console.print(f" • [green]{name}[/green]")
|
|
33
33
|
console.print()
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def example():
|
|
37
|
-
console.print(f"[dim]Example:[/dim] deer {list(
|
|
37
|
+
console.print(f"[dim]Example:[/dim] deer {list(agents.keys())[0]}")
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
def run_agent_in_process(agent_path, backend=None, model=None):
|
|
@@ -64,11 +64,9 @@ def main():
|
|
|
64
64
|
|
|
65
65
|
if selected_agent := args.agent:
|
|
66
66
|
|
|
67
|
-
if selected_agent in
|
|
67
|
+
if selected_agent in agents:
|
|
68
68
|
info(f"Launching agent '{selected_agent}'")
|
|
69
|
-
run_agent_in_process(
|
|
70
|
-
available_agents[selected_agent], args.backend, args.model
|
|
71
|
-
)
|
|
69
|
+
run_agent_in_process(agents[selected_agent], args.backend, args.model)
|
|
72
70
|
sys.exit(0)
|
|
73
71
|
|
|
74
72
|
error(f"Unknown agent '{selected_agent}'")
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import pickle
|
|
3
|
+
import logging
|
|
4
|
+
import subprocess
|
|
5
|
+
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from rich.markdown import Markdown
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
from rich.text import Text
|
|
10
|
+
from prompt_toolkit import prompt, PromptSession
|
|
11
|
+
from prompt_toolkit.formatted_text import HTML
|
|
12
|
+
from prompt_toolkit.history import InMemoryHistory
|
|
13
|
+
from prompt_toolkit.completion import Completer, WordCompleter
|
|
14
|
+
|
|
15
|
+
from deer.core import DeterministicAgent
|
|
16
|
+
from deer import __version__
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger(f"DEER.{__name__}")
|
|
19
|
+
|
|
20
|
+
COMMANDS = {
|
|
21
|
+
"/tools": "Show tools and capabilities",
|
|
22
|
+
"/clear": "Clear the console and reset the session",
|
|
23
|
+
"/exit": "Terminate the session",
|
|
24
|
+
"/rollback": "Revert the system to the last stable state",
|
|
25
|
+
"/trace": "Display the detailed execution trace and variable resolution of the last plan.",
|
|
26
|
+
"/history": "Display the history of messages and commands",
|
|
27
|
+
"/clearhistory": "Purge all session history and reset memory state.",
|
|
28
|
+
# "/vhistory": "Display the history of verifier messages and commands",
|
|
29
|
+
"/infocontext": "Displays context memory usage information.",
|
|
30
|
+
"/loadcontext": "Restore a saved session context",
|
|
31
|
+
"/savecontext": "Save the current session context",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
WELCOME_MESSAGE = """
|
|
35
|
+
# DEER - Deterministic Executable Engine for Runtime Agents - v{version}
|
|
36
|
+
|
|
37
|
+
An LLM agent orchestration framework built for:
|
|
38
|
+
- Strict runtime control
|
|
39
|
+
- Enforced tool contracts
|
|
40
|
+
- Full execution traceability
|
|
41
|
+
- Guaranteed reproducibility
|
|
42
|
+
|
|
43
|
+
## Runtime Pipeline
|
|
44
|
+
|
|
45
|
+
1. Plan → Generate a structured execution strategy
|
|
46
|
+
2. Validate → Verify contracts, dependencies, and safety
|
|
47
|
+
3. Execute → Run approved tools and workflows
|
|
48
|
+
4. Verify → Validate outputs against expected objectives
|
|
49
|
+
|
|
50
|
+
## System Guarantees
|
|
51
|
+
|
|
52
|
+
- Deterministic execution flow
|
|
53
|
+
- Typed tool interfaces
|
|
54
|
+
- Structured validation layers
|
|
55
|
+
- Full execution traceability
|
|
56
|
+
- Backend-governed orchestration
|
|
57
|
+
|
|
58
|
+
## Commands
|
|
59
|
+
|
|
60
|
+
{commands}
|
|
61
|
+
|
|
62
|
+
## System Escapes
|
|
63
|
+
|
|
64
|
+
- `!<command>` → Execute an OS shell command (e.g., `!ls -la` or `!pwd`)
|
|
65
|
+
|
|
66
|
+
## Shortcuts
|
|
67
|
+
|
|
68
|
+
- `Tab` → Auto-complete commands and navigate suggestions
|
|
69
|
+
- `Ctrl+C` → Stop processing the current task
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class SmartCommandCompleter(Completer):
|
|
74
|
+
def __init__(self, commands):
|
|
75
|
+
self.base_completer = WordCompleter(commands, ignore_case=False)
|
|
76
|
+
|
|
77
|
+
def get_completions(self, document, complete_event):
|
|
78
|
+
word_before_cursor = document.get_word_before_cursor()
|
|
79
|
+
if not word_before_cursor:
|
|
80
|
+
return []
|
|
81
|
+
return self.base_completer.get_completions(document, complete_event)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class AgentREPL:
|
|
85
|
+
|
|
86
|
+
def __init__(self, agent: DeterministicAgent):
|
|
87
|
+
self.agent = agent
|
|
88
|
+
|
|
89
|
+
self.prompt_history: InMemoryHistory
|
|
90
|
+
self.load_prompt_history()
|
|
91
|
+
|
|
92
|
+
self.console = Console()
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def completer(self):
|
|
96
|
+
internal_commands = list(COMMANDS.keys())
|
|
97
|
+
return SmartCommandCompleter(internal_commands)
|
|
98
|
+
|
|
99
|
+
def load_prompt_history(self):
|
|
100
|
+
history_file = self.agent.agent_dir / "prompt_history"
|
|
101
|
+
|
|
102
|
+
if not history_file.exists():
|
|
103
|
+
self.prompt_history = InMemoryHistory()
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
with open(history_file, "rb") as f:
|
|
107
|
+
self.prompt_history = pickle.load(f)
|
|
108
|
+
return
|
|
109
|
+
|
|
110
|
+
def save_prompt_history(self):
|
|
111
|
+
history_file = self.agent.agent_dir / "prompt_history"
|
|
112
|
+
with open(history_file, "wb") as f:
|
|
113
|
+
pickle.dump(self.prompt_history, f)
|
|
114
|
+
|
|
115
|
+
def clear_history(self):
|
|
116
|
+
self.history = []
|
|
117
|
+
self.trace = []
|
|
118
|
+
|
|
119
|
+
def pretty_print(self, out: str):
|
|
120
|
+
self.console.print(Markdown(out))
|
|
121
|
+
|
|
122
|
+
def show_identity(self):
|
|
123
|
+
self.pretty_print(
|
|
124
|
+
f">**Agent Profile** \n"
|
|
125
|
+
f"*{self.agent.description}* \n"
|
|
126
|
+
f"root: {self.agent.tool_registry.jail_path} \n"
|
|
127
|
+
f"{self.agent.driver}: {self.agent.driver.model_name} \n"
|
|
128
|
+
)
|
|
129
|
+
print("")
|
|
130
|
+
|
|
131
|
+
def show_welcome(self):
|
|
132
|
+
commands_formated = ""
|
|
133
|
+
for command in COMMANDS:
|
|
134
|
+
commands_formated += (
|
|
135
|
+
f"- {('`'+command+'`').ljust(12, ' ')} → {COMMANDS[command]}\n "
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
self.console.clear()
|
|
139
|
+
self.pretty_print(
|
|
140
|
+
WELCOME_MESSAGE.format(version=__version__, commands=commands_formated)
|
|
141
|
+
)
|
|
142
|
+
self.show_identity()
|
|
143
|
+
|
|
144
|
+
def run_command(self, command):
|
|
145
|
+
match command:
|
|
146
|
+
case "/exit":
|
|
147
|
+
self.agent.persist_state()
|
|
148
|
+
self.console.print(
|
|
149
|
+
"[dim]Context state persisted to disk.[/dim]\n",
|
|
150
|
+
Markdown("----"),
|
|
151
|
+
)
|
|
152
|
+
sys.exit(0)
|
|
153
|
+
|
|
154
|
+
case "/clear":
|
|
155
|
+
self.console.clear()
|
|
156
|
+
self.show_identity()
|
|
157
|
+
self.console.print(
|
|
158
|
+
"[dim]Console buffer cleared. Session state persists. Use /clearhistory for a full purge.[/dim]\n",
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
case "/clearhistory":
|
|
162
|
+
self.clear_history()
|
|
163
|
+
self.console.clear()
|
|
164
|
+
self.agent.clear_agent_history()
|
|
165
|
+
self.agent.clear_traces()
|
|
166
|
+
self.agent.persist_state()
|
|
167
|
+
self.show_identity()
|
|
168
|
+
self.console.print(
|
|
169
|
+
"[dim]Session history purged. Memory state reset.[/dim]\n",
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
case "/tools":
|
|
173
|
+
tools_description = self.agent.tool_registry.describe()
|
|
174
|
+
self.console.print(
|
|
175
|
+
Markdown(tools_description),
|
|
176
|
+
"\n",
|
|
177
|
+
f"[dim]Tool registry: {len(self.agent.tool_registry._tools)} modules active.[/dim]\n",
|
|
178
|
+
f"[dim]Registry description payload: {self.agent.format_bytes(len(tools_description))}[/dim]\n",
|
|
179
|
+
sep="",
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
case "/rollback":
|
|
183
|
+
self.console.print(
|
|
184
|
+
"[dim][bold]Rollback executed.[/bold] System reverted to the last stable state.[/dim]\n",
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
case "/trace":
|
|
188
|
+
trace = self.agent.traces["solution"]
|
|
189
|
+
for i, step in enumerate(trace):
|
|
190
|
+
self.console.print(f"[bold yellow]Trace {i+1}:[/bold yellow]")
|
|
191
|
+
print(f"{step}\n")
|
|
192
|
+
|
|
193
|
+
case "/history":
|
|
194
|
+
for i, chat in enumerate(self.agent.agent_history[1:]):
|
|
195
|
+
self.console.print(f"[bold yellow]Chat {i+1}:[/bold yellow]")
|
|
196
|
+
print(f"{chat}\n")
|
|
197
|
+
self.console.print(
|
|
198
|
+
f"[dim]Session history payload: {self.agent.format_bytes(len(str(self.agent.agent_history)))}[/dim]\n",
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# case "/vhistory":
|
|
202
|
+
# for i, chat in enumerate(self.agent.verificator_history[1:]):
|
|
203
|
+
# self.console.print(f"[bold yellow]Chat {i+1}:[/bold yellow]")
|
|
204
|
+
# print(f"{chat}\n")
|
|
205
|
+
|
|
206
|
+
case "/infocontext":
|
|
207
|
+
bytes = sum(len(str(item)) for item in self.agent.agent_history)
|
|
208
|
+
self.console.print(
|
|
209
|
+
f"[dim][bold]History:[/bold] {len(self.agent.agent_history)} messages[/dim]\n",
|
|
210
|
+
f"[dim][bold]Context size:[/bold] ~{self.agent.format_bytes(bytes)}[/dim]\n",
|
|
211
|
+
sep="",
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
case "/savecontext":
|
|
215
|
+
try:
|
|
216
|
+
self.agent.persist_state()
|
|
217
|
+
self.console.print("[dim]Context state persisted to disk.[/dim]\n")
|
|
218
|
+
except Exception as e:
|
|
219
|
+
self.console.print(
|
|
220
|
+
f"[bold red]Context persistence error:[/bold red] {e}\n"
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
case "/loadcontext":
|
|
224
|
+
try:
|
|
225
|
+
self.agent.restore_state()
|
|
226
|
+
self.console.print(
|
|
227
|
+
"[dim]Context recovered. Session state synchronized.[/dim]\n"
|
|
228
|
+
)
|
|
229
|
+
except Exception as e:
|
|
230
|
+
self.console.print(
|
|
231
|
+
f"[bold red]Context restoration error:[/bold red] {e}\n"
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
self.console.print(
|
|
235
|
+
Markdown("----"),
|
|
236
|
+
end="",
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
def repl(self):
|
|
240
|
+
logger.setLevel(logging.CRITICAL)
|
|
241
|
+
self.show_welcome()
|
|
242
|
+
self.pretty_print(f"----")
|
|
243
|
+
|
|
244
|
+
session = PromptSession(
|
|
245
|
+
erase_when_done=True,
|
|
246
|
+
history=self.prompt_history,
|
|
247
|
+
completer=self.completer,
|
|
248
|
+
mouse_support=True,
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
def as_table(prompt, message="", color="cyan"):
|
|
252
|
+
table = Table.grid(expand=True)
|
|
253
|
+
table.add_column(width=len(prompt) + 1)
|
|
254
|
+
table.add_column()
|
|
255
|
+
|
|
256
|
+
table.add_row(
|
|
257
|
+
Text(prompt, style=f"bold {color}"),
|
|
258
|
+
Markdown(message),
|
|
259
|
+
)
|
|
260
|
+
return table
|
|
261
|
+
|
|
262
|
+
input_prompt = ">>> " # >>>
|
|
263
|
+
input_prompt_history = "USER |"
|
|
264
|
+
output_prompt_history = "DEER |"
|
|
265
|
+
|
|
266
|
+
while True:
|
|
267
|
+
try:
|
|
268
|
+
msg = session.prompt(
|
|
269
|
+
HTML(f"<ansicyan><b>{input_prompt}</b></ansicyan>")
|
|
270
|
+
)
|
|
271
|
+
self.save_prompt_history()
|
|
272
|
+
|
|
273
|
+
if self.agent.load_context:
|
|
274
|
+
self.agent.persist_state()
|
|
275
|
+
|
|
276
|
+
except KeyboardInterrupt:
|
|
277
|
+
continue
|
|
278
|
+
except EOFError:
|
|
279
|
+
break
|
|
280
|
+
|
|
281
|
+
msg = msg.strip()
|
|
282
|
+
if not msg:
|
|
283
|
+
continue
|
|
284
|
+
|
|
285
|
+
match msg:
|
|
286
|
+
case command if command in COMMANDS:
|
|
287
|
+
self.console.print(
|
|
288
|
+
as_table(f"[{command}]", color="cyan"),
|
|
289
|
+
Text("\n"),
|
|
290
|
+
end="",
|
|
291
|
+
)
|
|
292
|
+
self.run_command(command)
|
|
293
|
+
|
|
294
|
+
case command if command.startswith("!"):
|
|
295
|
+
# Remove the '!' from the start to get only the command
|
|
296
|
+
cmd_to_run = command[1:].strip()
|
|
297
|
+
|
|
298
|
+
self.console.print(
|
|
299
|
+
as_table(f"[{cmd_to_run}]", color="cyan"),
|
|
300
|
+
Text("\n"),
|
|
301
|
+
end="",
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
try:
|
|
305
|
+
# Execute the command
|
|
306
|
+
result = subprocess.run(
|
|
307
|
+
cmd_to_run,
|
|
308
|
+
shell=True,
|
|
309
|
+
capture_output=True,
|
|
310
|
+
text=True,
|
|
311
|
+
check=True,
|
|
312
|
+
)
|
|
313
|
+
self.console.print(
|
|
314
|
+
Text(result.stdout),
|
|
315
|
+
Markdown("----"),
|
|
316
|
+
sep="",
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
except subprocess.CalledProcessError as e:
|
|
320
|
+
self.console.print(
|
|
321
|
+
f"[dim]Error executing command: {e.stderr}[/dim]",
|
|
322
|
+
Markdown("----"),
|
|
323
|
+
sep="",
|
|
324
|
+
)
|
|
325
|
+
except Exception as e:
|
|
326
|
+
self.console.print(
|
|
327
|
+
f"[dim]An unexpected error occurred: {e}[/dim]",
|
|
328
|
+
Markdown("----"),
|
|
329
|
+
sep="",
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
case _:
|
|
333
|
+
if msg.startswith("/"):
|
|
334
|
+
self.pretty_print(
|
|
335
|
+
f"Command `{msg}` not recognized. Did you mean one of these: {list(COMMANDS)}"
|
|
336
|
+
)
|
|
337
|
+
continue
|
|
338
|
+
with self.console.status(
|
|
339
|
+
"[dim]processing request[/]",
|
|
340
|
+
spinner="point",
|
|
341
|
+
spinner_style="dim",
|
|
342
|
+
):
|
|
343
|
+
try:
|
|
344
|
+
self.console.print(
|
|
345
|
+
as_table(input_prompt_history, msg),
|
|
346
|
+
Text("\n"),
|
|
347
|
+
end="",
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
# Call the LLM model
|
|
351
|
+
response = self.agent.run(msg)
|
|
352
|
+
|
|
353
|
+
self.console.print(
|
|
354
|
+
as_table(output_prompt_history, response),
|
|
355
|
+
Text("\n"),
|
|
356
|
+
Markdown("----"),
|
|
357
|
+
end="",
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
except KeyboardInterrupt:
|
|
361
|
+
self.console.print(
|
|
362
|
+
"[dim]Command aborted by user[/dim]\n",
|
|
363
|
+
Markdown("----"),
|
|
364
|
+
sep="",
|
|
365
|
+
)
|
|
366
|
+
continue
|
|
367
|
+
except EOFError:
|
|
368
|
+
break
|
|
@@ -17,7 +17,7 @@ from .validator import PlanValidator
|
|
|
17
17
|
|
|
18
18
|
import pickle
|
|
19
19
|
|
|
20
|
-
logger = logging.getLogger("DEER")
|
|
20
|
+
logger = logging.getLogger(f"DEER.{__name__}")
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class DeterministicAgent:
|
|
@@ -32,6 +32,7 @@ class DeterministicAgent:
|
|
|
32
32
|
vector_memory: Optional[VectorMemory] = None,
|
|
33
33
|
max_attempts: int = 3,
|
|
34
34
|
enable_verification: bool = True,
|
|
35
|
+
load_context: bool = False,
|
|
35
36
|
):
|
|
36
37
|
|
|
37
38
|
# Context
|
|
@@ -41,6 +42,7 @@ class DeterministicAgent:
|
|
|
41
42
|
self.agent_dir = (working_dir / ".deer").resolve()
|
|
42
43
|
self.working_dir = working_dir.resolve()
|
|
43
44
|
self.enable_verification = enable_verification
|
|
45
|
+
self.contex_file = self.agent_dir / "context"
|
|
44
46
|
|
|
45
47
|
# LLMDriver
|
|
46
48
|
self.driver = driver
|
|
@@ -78,13 +80,18 @@ class DeterministicAgent:
|
|
|
78
80
|
# Pipeline Executer
|
|
79
81
|
self.pipeline_executor = PipelineExecutor(tool_registry=self.tool_registry)
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
self.load_context = load_context
|
|
84
|
+
if load_context:
|
|
85
|
+
self.persist_state()
|
|
84
86
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
else:
|
|
88
|
+
# Agent History
|
|
89
|
+
self.agent_history: list[ChatMessage] = []
|
|
90
|
+
self.clear_agent_history()
|
|
91
|
+
|
|
92
|
+
# Validator History
|
|
93
|
+
self.verificator_history: list[ChatMessage] = []
|
|
94
|
+
self.clear_verificator_history()
|
|
88
95
|
|
|
89
96
|
# Traces
|
|
90
97
|
self.traces: dict[Literal["solution", "verification"], list[Any]] = {}
|
|
@@ -116,6 +123,31 @@ class DeterministicAgent:
|
|
|
116
123
|
)
|
|
117
124
|
]
|
|
118
125
|
|
|
126
|
+
def format_bytes(self, size):
|
|
127
|
+
for unit in ["B", "KB", "MB", "GB"]:
|
|
128
|
+
if size < 1024:
|
|
129
|
+
return f"{size:.1f} {unit}"
|
|
130
|
+
size /= 1024
|
|
131
|
+
|
|
132
|
+
def persist_state(self):
|
|
133
|
+
context = {
|
|
134
|
+
"agent_history": self.agent_history,
|
|
135
|
+
"verificator_history": self.verificator_history,
|
|
136
|
+
}
|
|
137
|
+
with self.contex_file.open("wb") as f:
|
|
138
|
+
pickle.dump(context, f)
|
|
139
|
+
|
|
140
|
+
def restore_state(self):
|
|
141
|
+
if not self.contex_file.exists():
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
with self.contex_file.open("rb") as f:
|
|
145
|
+
context = pickle.load(f)
|
|
146
|
+
self.agent_history = context.get("agent_history", self.agent_history)
|
|
147
|
+
self.verificator_history = context.get(
|
|
148
|
+
"verificator_history", self.verificator_history
|
|
149
|
+
)
|
|
150
|
+
|
|
119
151
|
def save_trace(self):
|
|
120
152
|
obj = {
|
|
121
153
|
"tools": list(self.tool_registry.list_tools()),
|
|
@@ -222,11 +254,20 @@ class DeterministicAgent:
|
|
|
222
254
|
trace_verification = self.run_verification(goal)
|
|
223
255
|
self.save_trace_verification(trace_verification)
|
|
224
256
|
|
|
257
|
+
if (
|
|
258
|
+
not trace_solution.steps
|
|
259
|
+
and not self.enable_verification
|
|
260
|
+
and trace_solution.response
|
|
261
|
+
):
|
|
262
|
+
# Return a response without validation when the request does not have steps
|
|
263
|
+
return trace_solution.response
|
|
264
|
+
|
|
225
265
|
# Conclusion
|
|
266
|
+
# The request has steps and validation is requested
|
|
226
267
|
conclusion = self.generate_conclusion(goal, trace_solution, trace_verification)
|
|
227
268
|
|
|
228
269
|
if conclusion.goal_achieved:
|
|
229
|
-
#
|
|
270
|
+
# The conclusion finds that the goal has been achieved
|
|
230
271
|
return conclusion.user_message
|
|
231
272
|
else:
|
|
232
273
|
if iteration >= self.max_attempts:
|
|
@@ -267,7 +308,7 @@ class DeterministicAgent:
|
|
|
267
308
|
goal: str,
|
|
268
309
|
trace_solution: ExecutionTrace,
|
|
269
310
|
trace_verification: ExecutionTrace,
|
|
270
|
-
) ->
|
|
311
|
+
) -> AgentConclusion:
|
|
271
312
|
|
|
272
313
|
messages = [
|
|
273
314
|
ChatMessage(
|
|
@@ -5,7 +5,7 @@ from typing import List, Dict
|
|
|
5
5
|
from deer.tools import ToolRegistry
|
|
6
6
|
from deer.models import ExecutionPlan, ChatMessage, Role
|
|
7
7
|
|
|
8
|
-
logger = logging.getLogger("DEER
|
|
8
|
+
logger = logging.getLogger(f"DEER.{__name__}")
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Planner:
|
|
@@ -55,7 +55,7 @@ class Planner:
|
|
|
55
55
|
"Respond exclusively with the JSON object. Do NOT wrap the response in markdown code blocks or add any introductory text."
|
|
56
56
|
)
|
|
57
57
|
|
|
58
|
-
def build_conclusion_prompt(self, goal, trace_solution, trace_verification):
|
|
58
|
+
def build_conclusion_prompt(self, goal, trace_solution, trace_verification) -> str:
|
|
59
59
|
|
|
60
60
|
if not trace_verification:
|
|
61
61
|
verification = "VERIFICATION NO NEEDED"
|
|
@@ -10,7 +10,7 @@ from deer.models import ChatMessage
|
|
|
10
10
|
from pydantic import BaseModel
|
|
11
11
|
|
|
12
12
|
T = TypeVar("T", bound=BaseModel)
|
|
13
|
-
logger = logging.getLogger("DEER
|
|
13
|
+
logger = logging.getLogger(f"DEER.{__name__}")
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class LLMDriver(ABC):
|
|
@@ -90,8 +90,10 @@ class LLMDriver(ABC):
|
|
|
90
90
|
|
|
91
91
|
@abstractmethod
|
|
92
92
|
def generate(
|
|
93
|
-
self,
|
|
94
|
-
|
|
93
|
+
self,
|
|
94
|
+
messages: list[ChatMessage],
|
|
95
|
+
response_model: type[T] | None = None,
|
|
96
|
+
) -> str | T:
|
|
95
97
|
pass
|
|
96
98
|
|
|
97
99
|
@abstractmethod
|
|
@@ -104,7 +106,7 @@ class LLMDriver(ABC):
|
|
|
104
106
|
"""
|
|
105
107
|
pass
|
|
106
108
|
|
|
107
|
-
def extract_json(self, text: str) ->
|
|
109
|
+
def extract_json(self, text: str) -> str:
|
|
108
110
|
text = text.strip()
|
|
109
111
|
text = re.sub(r"^```(?:json)?\s*", "", text)
|
|
110
112
|
text = re.sub(r"^json\s*", "", text)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from typing import
|
|
3
|
-
from pydantic import BaseModel
|
|
2
|
+
from typing import Generator, TypeVar
|
|
4
3
|
from .base import LLMDriver, logger
|
|
5
4
|
from deer.models import ChatMessage
|
|
5
|
+
from pydantic import BaseModel
|
|
6
6
|
|
|
7
7
|
T = TypeVar("T", bound=BaseModel)
|
|
8
8
|
|
|
@@ -26,8 +26,10 @@ class OllamaDriver(LLMDriver):
|
|
|
26
26
|
return "Ollama"
|
|
27
27
|
|
|
28
28
|
def generate(
|
|
29
|
-
self,
|
|
30
|
-
|
|
29
|
+
self,
|
|
30
|
+
messages: list[ChatMessage],
|
|
31
|
+
response_model: type[T] | None = None,
|
|
32
|
+
) -> str | T:
|
|
31
33
|
"""
|
|
32
34
|
Generates a response from Ollama.
|
|
33
35
|
If response_model is provided, it forces the model to follow the schema.
|
|
@@ -72,7 +74,8 @@ class OllamaDriver(LLMDriver):
|
|
|
72
74
|
)
|
|
73
75
|
|
|
74
76
|
def generate_stream(
|
|
75
|
-
self,
|
|
77
|
+
self,
|
|
78
|
+
messages: list[ChatMessage],
|
|
76
79
|
) -> Generator[str, None, None]:
|
|
77
80
|
"""
|
|
78
81
|
Implementation of streaming for Ollama.
|
|
@@ -26,7 +26,7 @@ class ChatMessage(BaseModel):
|
|
|
26
26
|
content: str = Field(..., description="The actual text content of the message.")
|
|
27
27
|
|
|
28
28
|
def __str__(self) -> str:
|
|
29
|
-
return f"Role: {self.role.value}\n" f"Content: {self.content}"
|
|
29
|
+
return f"Role: {self.role.value}\n" f"Content: {self.content.strip()}"
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class ToolStep(BaseModel):
|
|
@@ -87,7 +87,7 @@ class StepTrace(BaseModel):
|
|
|
87
87
|
|
|
88
88
|
def __str__(self):
|
|
89
89
|
if self.error:
|
|
90
|
-
line = f"
|
|
90
|
+
line = f"\nError: {self.error}"
|
|
91
91
|
else:
|
|
92
92
|
line = ""
|
|
93
93
|
return (
|
|
@@ -95,7 +95,7 @@ class StepTrace(BaseModel):
|
|
|
95
95
|
f"Resolved args: {self.resolved_args}\n"
|
|
96
96
|
f"Output: {self.output}\n"
|
|
97
97
|
f"Status: {self.status}\n"
|
|
98
|
-
f"Execution time: {self.execution_time}
|
|
98
|
+
f"Execution time: {self.execution_time}"
|
|
99
99
|
f"{line}"
|
|
100
100
|
)
|
|
101
101
|
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer_agent_framework.egg-info/SOURCES.txt
RENAMED
|
@@ -3,9 +3,9 @@ README.md
|
|
|
3
3
|
pyproject.toml
|
|
4
4
|
deer/__init__.py
|
|
5
5
|
deer/models.py
|
|
6
|
-
deer/
|
|
7
|
-
deer/
|
|
8
|
-
deer/
|
|
6
|
+
deer/builtins_agents/__init__.py
|
|
7
|
+
deer/builtins_agents/operating_system.py
|
|
8
|
+
deer/builtins_agents/python_architect.py
|
|
9
9
|
deer/cli/__init__.py
|
|
10
10
|
deer/cli/main.py
|
|
11
11
|
deer/cli/parser.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "deer-agent-framework"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.3"
|
|
8
8
|
description = "DEER - Deterministic Executable Engine for Runtime-agents"
|
|
9
9
|
authors = [{ name = "Yeison" }]
|
|
10
10
|
license = { text = "BSD-2-Clause" }
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import sys
|
|
3
|
-
import logging
|
|
4
|
-
|
|
5
|
-
from deer.core import DeterministicAgent
|
|
6
|
-
import pickle
|
|
7
|
-
from prompt_toolkit import prompt
|
|
8
|
-
from prompt_toolkit.formatted_text import HTML
|
|
9
|
-
from prompt_toolkit.history import InMemoryHistory
|
|
10
|
-
from prompt_toolkit.completion import WordCompleter
|
|
11
|
-
from rich.console import Console
|
|
12
|
-
from rich.markdown import Markdown
|
|
13
|
-
import subprocess
|
|
14
|
-
|
|
15
|
-
from prompt_toolkit.completion import Completer, WordCompleter
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
from deer import __version__
|
|
19
|
-
|
|
20
|
-
logger = logging.getLogger("DEER")
|
|
21
|
-
|
|
22
|
-
COMMANDS = {
|
|
23
|
-
"/tools": "Show tools and capabilities",
|
|
24
|
-
"/clear": "Clear the console and reset the session",
|
|
25
|
-
"/exit": "Terminate the session",
|
|
26
|
-
"/rollback": "Revert the system to the last stable state",
|
|
27
|
-
"/trace": "Display the detailed execution trace and variable resolution of the last plan.",
|
|
28
|
-
"/history": "Display the history of messages and commands",
|
|
29
|
-
"/vhistory": "Display the history of verifier messages and commands",
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
WELCOME_MESSAGE = """
|
|
33
|
-
# DEER - Deterministic Executable Engine for Runtime Agents - v{version}
|
|
34
|
-
|
|
35
|
-
An LLM agent orchestration framework built for:
|
|
36
|
-
- Strict runtime control
|
|
37
|
-
- Enforced tool contracts
|
|
38
|
-
- Full execution traceability
|
|
39
|
-
- Guaranteed reproducibility
|
|
40
|
-
|
|
41
|
-
## Runtime Pipeline
|
|
42
|
-
|
|
43
|
-
1. Plan → Generate a structured execution strategy
|
|
44
|
-
2. Validate → Verify contracts, dependencies, and safety
|
|
45
|
-
3. Execute → Run approved tools and workflows
|
|
46
|
-
4. Verify → Validate outputs against expected objectives
|
|
47
|
-
|
|
48
|
-
## System Guarantees
|
|
49
|
-
|
|
50
|
-
- Deterministic execution flow
|
|
51
|
-
- Typed tool interfaces
|
|
52
|
-
- Structured validation layers
|
|
53
|
-
- Full execution traceability
|
|
54
|
-
- Backend-governed orchestration
|
|
55
|
-
|
|
56
|
-
## Commands
|
|
57
|
-
|
|
58
|
-
{commands}
|
|
59
|
-
|
|
60
|
-
## System Escapes
|
|
61
|
-
|
|
62
|
-
- `!<command>` → Execute an OS shell command (e.g., `!ls -la` or `!pwd`)
|
|
63
|
-
|
|
64
|
-
## Shortcuts
|
|
65
|
-
|
|
66
|
-
- `Tab` → Auto-complete commands and navigate suggestions
|
|
67
|
-
- `Ctrl+C` → Stop processing the current task
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
class SmartCommandCompleter(Completer):
|
|
72
|
-
def __init__(self, commands):
|
|
73
|
-
self.base_completer = WordCompleter(commands, ignore_case=False)
|
|
74
|
-
|
|
75
|
-
def get_completions(self, document, complete_event):
|
|
76
|
-
word_before_cursor = document.get_word_before_cursor()
|
|
77
|
-
if not word_before_cursor:
|
|
78
|
-
return []
|
|
79
|
-
return self.base_completer.get_completions(document, complete_event)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
class AgentREPL:
|
|
83
|
-
|
|
84
|
-
def __init__(self, agent: DeterministicAgent):
|
|
85
|
-
self.agent = agent
|
|
86
|
-
|
|
87
|
-
self.prompt_history: InMemoryHistory
|
|
88
|
-
self.load_prompt_history()
|
|
89
|
-
|
|
90
|
-
self.console = Console()
|
|
91
|
-
|
|
92
|
-
@property
|
|
93
|
-
def completer(self):
|
|
94
|
-
internal_commands = list(COMMANDS.keys())
|
|
95
|
-
return SmartCommandCompleter(internal_commands)
|
|
96
|
-
|
|
97
|
-
def load_prompt_history(self):
|
|
98
|
-
history_file = self.agent.agent_dir / "prompt_history"
|
|
99
|
-
|
|
100
|
-
if not history_file.exists():
|
|
101
|
-
self.prompt_history = InMemoryHistory()
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
with open(history_file, "rb") as f:
|
|
105
|
-
self.prompt_history = pickle.load(f)
|
|
106
|
-
return
|
|
107
|
-
|
|
108
|
-
def save_history(self):
|
|
109
|
-
history_file = self.agent.agent_dir / "prompt_history"
|
|
110
|
-
with open(history_file, "wb") as f:
|
|
111
|
-
pickle.dump(self.prompt_history, f)
|
|
112
|
-
|
|
113
|
-
def clear_history(self):
|
|
114
|
-
self.history = []
|
|
115
|
-
self.trace = []
|
|
116
|
-
|
|
117
|
-
def pretty_print(self, out: str):
|
|
118
|
-
self.console.print(Markdown(out))
|
|
119
|
-
|
|
120
|
-
def show_welcome(self):
|
|
121
|
-
commands_formated = ""
|
|
122
|
-
for command in COMMANDS:
|
|
123
|
-
commands_formated += (
|
|
124
|
-
f"- {('`'+command+'`').ljust(12, ' ')} → {COMMANDS[command]}\n "
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
self.console.clear()
|
|
128
|
-
self.pretty_print(
|
|
129
|
-
WELCOME_MESSAGE.format(version=__version__, commands=commands_formated)
|
|
130
|
-
)
|
|
131
|
-
self.pretty_print(
|
|
132
|
-
f">**Agent Profile** \n"
|
|
133
|
-
f"*{self.agent.description}* \n"
|
|
134
|
-
f"root: {self.agent.tool_registry.jail_path} \n"
|
|
135
|
-
f"{self.agent.driver}: {self.agent.driver.model_name} \n"
|
|
136
|
-
)
|
|
137
|
-
print("\n")
|
|
138
|
-
|
|
139
|
-
def run_command(self, command):
|
|
140
|
-
match command:
|
|
141
|
-
case "/exit":
|
|
142
|
-
sys.exit(0)
|
|
143
|
-
|
|
144
|
-
case "/clear":
|
|
145
|
-
self.clear_history()
|
|
146
|
-
self.console.clear()
|
|
147
|
-
self.agent.clear_agent_history()
|
|
148
|
-
self.agent.clear_traces()
|
|
149
|
-
self.pretty_print(f">**Agent Profile** \n*{self.agent.description}*")
|
|
150
|
-
print("\n")
|
|
151
|
-
|
|
152
|
-
case "/tools":
|
|
153
|
-
self.pretty_print(self.agent.tool_registry.describe())
|
|
154
|
-
print("\n")
|
|
155
|
-
|
|
156
|
-
case "/rollback":
|
|
157
|
-
# self.state_restore()
|
|
158
|
-
self.pretty_print(
|
|
159
|
-
"**Rollback executed.** System reverted to the last stable state."
|
|
160
|
-
)
|
|
161
|
-
print("\n")
|
|
162
|
-
|
|
163
|
-
case "/trace":
|
|
164
|
-
trace = self.agent.traces["solution"]
|
|
165
|
-
for i, step in enumerate(trace):
|
|
166
|
-
self.console.print(f"[bold yellow]Trace {i+1}:[/bold yellow]")
|
|
167
|
-
print(f"{step}")
|
|
168
|
-
# self.pretty_print(str(step))
|
|
169
|
-
print("\n")
|
|
170
|
-
|
|
171
|
-
case "/history":
|
|
172
|
-
for i, chat in enumerate(self.agent.agent_history[1:]):
|
|
173
|
-
self.console.print(f"[bold yellow]Chat {i+1}:[/bold yellow]")
|
|
174
|
-
print(f"{chat}")
|
|
175
|
-
# self.pretty_print(str(chat))
|
|
176
|
-
print("\n")
|
|
177
|
-
|
|
178
|
-
case "/vhistory":
|
|
179
|
-
for i, chat in enumerate(self.agent.verificator_history[1:]):
|
|
180
|
-
self.console.print(f"[bold yellow]Chat {i+1}:[/bold yellow]")
|
|
181
|
-
print(f"{chat}")
|
|
182
|
-
# self.pretty_print(str(chat))
|
|
183
|
-
print("\n")
|
|
184
|
-
|
|
185
|
-
def repl(self):
|
|
186
|
-
logger.setLevel(logging.CRITICAL)
|
|
187
|
-
self.show_welcome()
|
|
188
|
-
|
|
189
|
-
while True:
|
|
190
|
-
try:
|
|
191
|
-
msg = prompt(
|
|
192
|
-
HTML("<ansicyan><b>>>> </b></ansicyan>"),
|
|
193
|
-
history=self.prompt_history,
|
|
194
|
-
completer=self.completer,
|
|
195
|
-
# multiline=True,
|
|
196
|
-
)
|
|
197
|
-
self.save_history()
|
|
198
|
-
except KeyboardInterrupt:
|
|
199
|
-
continue
|
|
200
|
-
except EOFError:
|
|
201
|
-
break
|
|
202
|
-
|
|
203
|
-
msg = msg.strip()
|
|
204
|
-
if not msg:
|
|
205
|
-
continue
|
|
206
|
-
|
|
207
|
-
match msg:
|
|
208
|
-
case command if command in COMMANDS:
|
|
209
|
-
self.run_command(command)
|
|
210
|
-
|
|
211
|
-
case command if command.startswith("!"):
|
|
212
|
-
# Remove the '!' from the start to get only the command
|
|
213
|
-
cmd_to_run = command[1:].strip()
|
|
214
|
-
|
|
215
|
-
try:
|
|
216
|
-
# Execute the command
|
|
217
|
-
result = subprocess.run(
|
|
218
|
-
cmd_to_run,
|
|
219
|
-
shell=True,
|
|
220
|
-
capture_output=True,
|
|
221
|
-
text=True,
|
|
222
|
-
check=True,
|
|
223
|
-
)
|
|
224
|
-
print(result.stdout)
|
|
225
|
-
except subprocess.CalledProcessError as e:
|
|
226
|
-
print(f"Error executing command: {e.stderr}")
|
|
227
|
-
except Exception as e:
|
|
228
|
-
print(f"An unexpected error occurred: {e}")
|
|
229
|
-
|
|
230
|
-
case _:
|
|
231
|
-
if msg.startswith("/"):
|
|
232
|
-
self.pretty_print(
|
|
233
|
-
f"Command `{msg}` not recognized. Did you mean one of these: {list(COMMANDS)}"
|
|
234
|
-
)
|
|
235
|
-
continue
|
|
236
|
-
with self.console.status(
|
|
237
|
-
"[dim]processing request[/]",
|
|
238
|
-
spinner="point",
|
|
239
|
-
spinner_style="dim",
|
|
240
|
-
):
|
|
241
|
-
try:
|
|
242
|
-
output = self.send(msg)
|
|
243
|
-
self.pretty_print(f" {output}")
|
|
244
|
-
|
|
245
|
-
print("\n")
|
|
246
|
-
except KeyboardInterrupt:
|
|
247
|
-
self.console.print("[dim]Command aborted by user[/]\n")
|
|
248
|
-
# self.state_restore()
|
|
249
|
-
continue
|
|
250
|
-
except EOFError:
|
|
251
|
-
break
|
|
252
|
-
|
|
253
|
-
def send(self, message, print_chat: bool = False):
|
|
254
|
-
|
|
255
|
-
if print_chat:
|
|
256
|
-
print(f">>> {message}")
|
|
257
|
-
|
|
258
|
-
response = self.agent.run(message)
|
|
259
|
-
|
|
260
|
-
if print_chat:
|
|
261
|
-
print(f" {response}")
|
|
262
|
-
|
|
263
|
-
return response
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/code_searcher.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/csv_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/file_manager.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/git_manager.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/http_client.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/json_editor.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/logic_provider.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/process_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/runtime_manager.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/sqlite_manager.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/system_observer.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/toml_editor.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/xml_editor.py
RENAMED
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer/tools/providers/yaml_editor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deer_agent_framework-0.2a1 → deer_agent_framework-0.2.3}/deer_agent_framework.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|