code-puppy 0.0.173__py3-none-any.whl → 0.0.174__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.
- code_puppy/agent.py +11 -11
- code_puppy/agents/__init__.py +4 -6
- code_puppy/agents/agent_manager.py +15 -187
- code_puppy/agents/base_agent.py +470 -63
- code_puppy/command_line/command_handler.py +40 -41
- code_puppy/command_line/mcp/start_all_command.py +3 -6
- code_puppy/command_line/mcp/start_command.py +0 -5
- code_puppy/command_line/mcp/stop_all_command.py +3 -6
- code_puppy/command_line/mcp/stop_command.py +2 -6
- code_puppy/command_line/model_picker_completion.py +2 -2
- code_puppy/command_line/prompt_toolkit_completion.py +2 -2
- code_puppy/config.py +2 -2
- code_puppy/main.py +12 -49
- code_puppy/summarization_agent.py +2 -2
- code_puppy/tools/agent_tools.py +5 -4
- code_puppy/tools/browser/vqa_agent.py +1 -3
- code_puppy/tui/app.py +48 -77
- code_puppy/tui/screens/settings.py +2 -2
- {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/METADATA +2 -2
- {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/RECORD +24 -29
- code_puppy/agents/agent_orchestrator.json +0 -26
- code_puppy/agents/runtime_manager.py +0 -272
- code_puppy/command_line/meta_command_handler.py +0 -153
- code_puppy/message_history_processor.py +0 -408
- code_puppy/state_management.py +0 -58
- {code_puppy-0.0.173.data → code_puppy-0.0.174.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
|
|
3
|
+
from code_puppy.agents import get_current_agent
|
|
3
4
|
from code_puppy.command_line.model_picker_completion import update_model_in_input
|
|
4
5
|
from code_puppy.command_line.motd import print_motd
|
|
5
6
|
from code_puppy.command_line.utils import make_directory_table
|
|
@@ -120,39 +121,38 @@ def handle_command(command: str):
|
|
|
120
121
|
|
|
121
122
|
if command.strip().startswith("/compact"):
|
|
122
123
|
from code_puppy.config import get_compaction_strategy
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
summarize_messages,
|
|
127
|
-
truncation,
|
|
128
|
-
)
|
|
124
|
+
# Functions have been moved to BaseAgent class
|
|
125
|
+
from code_puppy.agents.agent_manager import get_current_agent
|
|
126
|
+
from code_puppy.config import get_protected_token_count
|
|
129
127
|
from code_puppy.messaging import (
|
|
130
128
|
emit_error,
|
|
131
129
|
emit_info,
|
|
132
130
|
emit_success,
|
|
133
131
|
emit_warning,
|
|
134
132
|
)
|
|
135
|
-
from code_puppy.state_management import get_message_history, set_message_history
|
|
136
133
|
|
|
137
134
|
try:
|
|
138
|
-
|
|
135
|
+
agent = get_current_agent()
|
|
136
|
+
history = agent.get_message_history()
|
|
139
137
|
if not history:
|
|
140
138
|
emit_warning("No history to compact yet. Ask me something first!")
|
|
141
139
|
return True
|
|
142
140
|
|
|
143
|
-
|
|
141
|
+
current_agent = get_current_agent()
|
|
142
|
+
before_tokens = sum(current_agent.estimate_tokens_for_message(m) for m in history)
|
|
144
143
|
compaction_strategy = get_compaction_strategy()
|
|
145
144
|
protected_tokens = get_protected_token_count()
|
|
146
145
|
emit_info(
|
|
147
146
|
f"🤔 Compacting {len(history)} messages using {compaction_strategy} strategy... (~{before_tokens} tokens)"
|
|
148
147
|
)
|
|
149
148
|
|
|
149
|
+
current_agent = get_current_agent()
|
|
150
150
|
if compaction_strategy == "truncation":
|
|
151
|
-
compacted = truncation(history, protected_tokens)
|
|
151
|
+
compacted = current_agent.truncation(history, protected_tokens)
|
|
152
152
|
summarized_messages = [] # No summarization in truncation mode
|
|
153
153
|
else:
|
|
154
154
|
# Default to summarization
|
|
155
|
-
compacted, summarized_messages = summarize_messages(
|
|
155
|
+
compacted, summarized_messages = current_agent.summarize_messages(
|
|
156
156
|
history, with_protection=True
|
|
157
157
|
)
|
|
158
158
|
|
|
@@ -160,9 +160,10 @@ def handle_command(command: str):
|
|
|
160
160
|
emit_error("Compaction failed. History unchanged.")
|
|
161
161
|
return True
|
|
162
162
|
|
|
163
|
-
set_message_history(compacted)
|
|
163
|
+
agent.set_message_history(compacted)
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
current_agent = get_current_agent()
|
|
166
|
+
after_tokens = sum(current_agent.estimate_tokens_for_message(m) for m in compacted)
|
|
166
167
|
reduction_pct = (
|
|
167
168
|
((before_tokens - after_tokens) / before_tokens * 100)
|
|
168
169
|
if before_tokens > 0
|
|
@@ -205,7 +206,7 @@ def handle_command(command: str):
|
|
|
205
206
|
return True
|
|
206
207
|
|
|
207
208
|
if command.strip().startswith("/show"):
|
|
208
|
-
from code_puppy.agents import
|
|
209
|
+
from code_puppy.agents import get_current_agent
|
|
209
210
|
from code_puppy.command_line.model_picker_completion import get_active_model
|
|
210
211
|
from code_puppy.config import (
|
|
211
212
|
get_compaction_strategy,
|
|
@@ -225,7 +226,7 @@ def handle_command(command: str):
|
|
|
225
226
|
compaction_strategy = get_compaction_strategy()
|
|
226
227
|
|
|
227
228
|
# Get current agent info
|
|
228
|
-
current_agent =
|
|
229
|
+
current_agent = get_current_agent()
|
|
229
230
|
|
|
230
231
|
status_msg = f"""[bold magenta]🐶 Puppy Status[/bold magenta]
|
|
231
232
|
|
|
@@ -288,16 +289,15 @@ def handle_command(command: str):
|
|
|
288
289
|
from code_puppy.agents import (
|
|
289
290
|
get_agent_descriptions,
|
|
290
291
|
get_available_agents,
|
|
291
|
-
|
|
292
|
+
get_current_agent,
|
|
292
293
|
set_current_agent,
|
|
293
294
|
)
|
|
294
|
-
from code_puppy.agents.runtime_manager import get_runtime_agent_manager
|
|
295
295
|
|
|
296
296
|
tokens = command.split()
|
|
297
297
|
|
|
298
298
|
if len(tokens) == 1:
|
|
299
299
|
# Show current agent and available agents
|
|
300
|
-
current_agent =
|
|
300
|
+
current_agent = get_current_agent()
|
|
301
301
|
available_agents = get_available_agents()
|
|
302
302
|
descriptions = get_agent_descriptions()
|
|
303
303
|
|
|
@@ -343,9 +343,9 @@ def handle_command(command: str):
|
|
|
343
343
|
|
|
344
344
|
if set_current_agent(agent_name):
|
|
345
345
|
# Reload the agent with new configuration
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
new_agent =
|
|
346
|
+
agent = get_current_agent()
|
|
347
|
+
agent.reload_code_generation_agent()
|
|
348
|
+
new_agent = get_current_agent()
|
|
349
349
|
emit_success(
|
|
350
350
|
f"Switched to agent: {new_agent.display_name}",
|
|
351
351
|
message_group=group_id,
|
|
@@ -382,13 +382,10 @@ def handle_command(command: str):
|
|
|
382
382
|
|
|
383
383
|
new_input = update_model_in_input(model_command)
|
|
384
384
|
if new_input is not None:
|
|
385
|
-
from code_puppy.agents.runtime_manager import get_runtime_agent_manager
|
|
386
385
|
from code_puppy.command_line.model_picker_completion import get_active_model
|
|
387
386
|
|
|
388
387
|
model = get_active_model()
|
|
389
388
|
# Make sure this is called for the test
|
|
390
|
-
manager = get_runtime_agent_manager()
|
|
391
|
-
manager.reload_agent()
|
|
392
389
|
emit_success(f"Active model set and loaded: {model}")
|
|
393
390
|
return True
|
|
394
391
|
model_names = load_model_names()
|
|
@@ -503,13 +500,11 @@ def handle_command(command: str):
|
|
|
503
500
|
emit_success(f"Model '{model_name}' pinned to agent '{agent_name}'")
|
|
504
501
|
|
|
505
502
|
# If this is the current agent, reload it to use the new model
|
|
506
|
-
from code_puppy.agents import
|
|
507
|
-
from code_puppy.agents.runtime_manager import get_runtime_agent_manager
|
|
503
|
+
from code_puppy.agents import get_current_agent
|
|
508
504
|
|
|
509
|
-
current_agent =
|
|
505
|
+
current_agent = get_current_agent()
|
|
510
506
|
if current_agent.name == agent_name:
|
|
511
|
-
|
|
512
|
-
manager.reload_agent()
|
|
507
|
+
|
|
513
508
|
emit_info(f"Active agent reloaded with pinned model '{model_name}'")
|
|
514
509
|
|
|
515
510
|
return True
|
|
@@ -560,8 +555,8 @@ def handle_command(command: str):
|
|
|
560
555
|
from pathlib import Path
|
|
561
556
|
|
|
562
557
|
from code_puppy.config import CONFIG_DIR
|
|
563
|
-
|
|
564
|
-
from code_puppy.
|
|
558
|
+
# estimate_tokens_for_message has been moved to BaseAgent class
|
|
559
|
+
from code_puppy.agents.agent_manager import get_current_agent
|
|
565
560
|
|
|
566
561
|
tokens = command.split()
|
|
567
562
|
if len(tokens) != 2:
|
|
@@ -569,7 +564,8 @@ def handle_command(command: str):
|
|
|
569
564
|
return True
|
|
570
565
|
|
|
571
566
|
session_name = tokens[1]
|
|
572
|
-
|
|
567
|
+
agent = get_current_agent()
|
|
568
|
+
history = agent.get_message_history()
|
|
573
569
|
|
|
574
570
|
if not history:
|
|
575
571
|
emit_warning("No message history to dump!")
|
|
@@ -587,11 +583,12 @@ def handle_command(command: str):
|
|
|
587
583
|
|
|
588
584
|
# Also save metadata as JSON for readability
|
|
589
585
|
meta_file = contexts_dir / f"{session_name}_meta.json"
|
|
586
|
+
current_agent = get_current_agent()
|
|
590
587
|
metadata = {
|
|
591
588
|
"session_name": session_name,
|
|
592
589
|
"timestamp": datetime.now().isoformat(),
|
|
593
590
|
"message_count": len(history),
|
|
594
|
-
"total_tokens": sum(estimate_tokens_for_message(m) for m in history),
|
|
591
|
+
"total_tokens": sum(current_agent.estimate_tokens_for_message(m) for m in history),
|
|
595
592
|
"file_path": str(pickle_file),
|
|
596
593
|
}
|
|
597
594
|
|
|
@@ -613,8 +610,8 @@ def handle_command(command: str):
|
|
|
613
610
|
from pathlib import Path
|
|
614
611
|
|
|
615
612
|
from code_puppy.config import CONFIG_DIR
|
|
616
|
-
|
|
617
|
-
from code_puppy.
|
|
613
|
+
# estimate_tokens_for_message has been moved to BaseAgent class
|
|
614
|
+
from code_puppy.agents.agent_manager import get_current_agent
|
|
618
615
|
|
|
619
616
|
tokens = command.split()
|
|
620
617
|
if len(tokens) != 2:
|
|
@@ -638,8 +635,10 @@ def handle_command(command: str):
|
|
|
638
635
|
with open(pickle_file, "rb") as f:
|
|
639
636
|
history = pickle.load(f)
|
|
640
637
|
|
|
641
|
-
|
|
642
|
-
|
|
638
|
+
agent = get_current_agent()
|
|
639
|
+
agent.set_message_history(history)
|
|
640
|
+
current_agent = get_current_agent()
|
|
641
|
+
total_tokens = sum(current_agent.estimate_tokens_for_message(m) for m in history)
|
|
643
642
|
|
|
644
643
|
emit_success(
|
|
645
644
|
f"✅ Context loaded: {len(history)} messages ({total_tokens} tokens)\n"
|
|
@@ -652,6 +651,7 @@ def handle_command(command: str):
|
|
|
652
651
|
return True
|
|
653
652
|
|
|
654
653
|
if command.startswith("/truncate"):
|
|
654
|
+
from code_puppy.agents.agent_manager import get_current_agent
|
|
655
655
|
tokens = command.split()
|
|
656
656
|
if len(tokens) != 2:
|
|
657
657
|
emit_error(
|
|
@@ -668,9 +668,8 @@ def handle_command(command: str):
|
|
|
668
668
|
emit_error("N must be a valid integer")
|
|
669
669
|
return True
|
|
670
670
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
history = get_message_history()
|
|
671
|
+
agent = get_current_agent()
|
|
672
|
+
history = agent.get_message_history()
|
|
674
673
|
if not history:
|
|
675
674
|
emit_warning("No history to truncate yet. Ask me something first!")
|
|
676
675
|
return True
|
|
@@ -686,7 +685,7 @@ def handle_command(command: str):
|
|
|
686
685
|
[history[0]] + history[-(n - 1) :] if n > 1 else [history[0]]
|
|
687
686
|
)
|
|
688
687
|
|
|
689
|
-
set_message_history(truncated_history)
|
|
688
|
+
agent.set_message_history(truncated_history)
|
|
690
689
|
emit_success(
|
|
691
690
|
f"Truncated message history from {len(history)} to {len(truncated_history)} messages (keeping system message and {n - 1} most recent)"
|
|
692
691
|
)
|
|
@@ -10,6 +10,7 @@ from code_puppy.mcp_.managed_server import ServerState
|
|
|
10
10
|
from code_puppy.messaging import emit_info
|
|
11
11
|
|
|
12
12
|
from .base import MCPCommandBase
|
|
13
|
+
from ...agents import get_current_agent
|
|
13
14
|
|
|
14
15
|
# Configure logging
|
|
15
16
|
logger = logging.getLogger(__name__)
|
|
@@ -106,12 +107,8 @@ class StartAllCommand(MCPCommandBase):
|
|
|
106
107
|
pass # No async loop, servers will start when agent uses them
|
|
107
108
|
|
|
108
109
|
try:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
manager = get_runtime_agent_manager()
|
|
114
|
-
manager.reload_agent()
|
|
110
|
+
agent = get_current_agent()
|
|
111
|
+
agent.reload_code_generation_agent()
|
|
115
112
|
emit_info(
|
|
116
113
|
"[dim]Agent reloaded with updated servers[/dim]",
|
|
117
114
|
message_group=group_id,
|
|
@@ -75,12 +75,7 @@ class StartCommand(MCPCommandBase):
|
|
|
75
75
|
|
|
76
76
|
# Reload the agent to pick up the newly enabled server
|
|
77
77
|
try:
|
|
78
|
-
from code_puppy.agents.runtime_manager import (
|
|
79
|
-
get_runtime_agent_manager,
|
|
80
|
-
)
|
|
81
78
|
|
|
82
|
-
manager = get_runtime_agent_manager()
|
|
83
|
-
manager.reload_agent()
|
|
84
79
|
emit_info(
|
|
85
80
|
"[dim]Agent reloaded with updated servers[/dim]",
|
|
86
81
|
message_group=group_id,
|
|
@@ -10,6 +10,7 @@ from code_puppy.mcp_.managed_server import ServerState
|
|
|
10
10
|
from code_puppy.messaging import emit_info
|
|
11
11
|
|
|
12
12
|
from .base import MCPCommandBase
|
|
13
|
+
from ...agents import get_current_agent
|
|
13
14
|
|
|
14
15
|
# Configure logging
|
|
15
16
|
logger = logging.getLogger(__name__)
|
|
@@ -91,12 +92,8 @@ class StopAllCommand(MCPCommandBase):
|
|
|
91
92
|
pass # No async loop, servers will stop when needed
|
|
92
93
|
|
|
93
94
|
try:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
manager = get_runtime_agent_manager()
|
|
99
|
-
manager.reload_agent()
|
|
95
|
+
agent = get_current_agent()
|
|
96
|
+
agent.reload_code_generation_agent()
|
|
100
97
|
emit_info(
|
|
101
98
|
"[dim]Agent reloaded with updated servers[/dim]",
|
|
102
99
|
message_group=group_id,
|
|
@@ -57,12 +57,8 @@ class StopCommand(MCPCommandBase):
|
|
|
57
57
|
|
|
58
58
|
# Reload the agent to remove the disabled server
|
|
59
59
|
try:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
manager = get_runtime_agent_manager()
|
|
65
|
-
manager.reload_agent()
|
|
60
|
+
agent = get_current_agent()
|
|
61
|
+
agent.reload_code_generation_agent()
|
|
66
62
|
emit_info(
|
|
67
63
|
"[dim]Agent reloaded with updated servers[/dim]",
|
|
68
64
|
message_group=group_id,
|
|
@@ -6,7 +6,7 @@ from prompt_toolkit.completion import Completer, Completion
|
|
|
6
6
|
from prompt_toolkit.document import Document
|
|
7
7
|
from prompt_toolkit.history import FileHistory
|
|
8
8
|
|
|
9
|
-
from code_puppy.config import
|
|
9
|
+
from code_puppy.config import get_global_model_name, set_model_name
|
|
10
10
|
from code_puppy.model_factory import ModelFactory
|
|
11
11
|
|
|
12
12
|
|
|
@@ -21,7 +21,7 @@ def get_active_model():
|
|
|
21
21
|
Returns the active model from the config using get_model_name().
|
|
22
22
|
This ensures consistency across the codebase by always using the config value.
|
|
23
23
|
"""
|
|
24
|
-
return
|
|
24
|
+
return get_global_model_name()
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
def set_active_model(model_name: str):
|
|
@@ -136,13 +136,13 @@ class CDCompleter(Completer):
|
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
def get_prompt_with_active_model(base: str = ">>> "):
|
|
139
|
-
from code_puppy.agents.agent_manager import
|
|
139
|
+
from code_puppy.agents.agent_manager import get_current_agent
|
|
140
140
|
|
|
141
141
|
puppy = get_puppy_name()
|
|
142
142
|
global_model = get_active_model() or "(default)"
|
|
143
143
|
|
|
144
144
|
# Get current agent information
|
|
145
|
-
current_agent =
|
|
145
|
+
current_agent = get_current_agent()
|
|
146
146
|
agent_display = current_agent.display_name if current_agent else "code-puppy"
|
|
147
147
|
|
|
148
148
|
# Check if current agent has a pinned model
|
code_puppy/config.py
CHANGED
|
@@ -94,7 +94,7 @@ def get_model_context_length() -> int:
|
|
|
94
94
|
from code_puppy.model_factory import ModelFactory
|
|
95
95
|
|
|
96
96
|
model_configs = ModelFactory.load_config()
|
|
97
|
-
model_name =
|
|
97
|
+
model_name = get_global_model_name()
|
|
98
98
|
|
|
99
99
|
# Get context length from model config
|
|
100
100
|
model_config = model_configs.get(model_name, {})
|
|
@@ -305,7 +305,7 @@ def clear_model_cache():
|
|
|
305
305
|
_default_vqa_model_cache = None
|
|
306
306
|
|
|
307
307
|
|
|
308
|
-
def
|
|
308
|
+
def get_global_model_name():
|
|
309
309
|
"""Return a valid model name for Code Puppy to use.
|
|
310
310
|
|
|
311
311
|
1. Look at ``model`` in *puppy.cfg*.
|
code_puppy/main.py
CHANGED
|
@@ -12,8 +12,7 @@ from rich.syntax import Syntax
|
|
|
12
12
|
from rich.text import Text
|
|
13
13
|
|
|
14
14
|
from code_puppy import __version__, callbacks, plugins
|
|
15
|
-
from code_puppy.
|
|
16
|
-
from code_puppy.agents.runtime_manager import get_runtime_agent_manager
|
|
15
|
+
from code_puppy.agents import get_current_agent
|
|
17
16
|
from code_puppy.command_line.prompt_toolkit_completion import (
|
|
18
17
|
get_input_with_combined_completion,
|
|
19
18
|
get_prompt_with_active_model,
|
|
@@ -25,15 +24,10 @@ from code_puppy.config import (
|
|
|
25
24
|
save_command_to_history,
|
|
26
25
|
)
|
|
27
26
|
from code_puppy.http_utils import find_available_port
|
|
28
|
-
|
|
29
|
-
message_history_accumulator,
|
|
30
|
-
prune_interrupted_tool_calls,
|
|
31
|
-
)
|
|
32
|
-
from code_puppy.state_management import set_message_history
|
|
27
|
+
# message_history_accumulator and prune_interrupted_tool_calls have been moved to BaseAgent class
|
|
33
28
|
from code_puppy.tui_state import is_tui_mode, set_tui_mode
|
|
34
29
|
from code_puppy.tools.common import console
|
|
35
30
|
from code_puppy.version_checker import default_version_mismatch_behavior
|
|
36
|
-
|
|
37
31
|
plugins.load_plugin_callbacks()
|
|
38
32
|
|
|
39
33
|
|
|
@@ -237,9 +231,7 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
237
231
|
from code_puppy.command_line.command_handler import handle_command
|
|
238
232
|
|
|
239
233
|
"""Run the agent in interactive mode."""
|
|
240
|
-
from code_puppy.state_management import clear_message_history, get_message_history
|
|
241
234
|
|
|
242
|
-
clear_message_history()
|
|
243
235
|
display_console = message_renderer.console
|
|
244
236
|
from code_puppy.messaging import emit_info, emit_system_message
|
|
245
237
|
|
|
@@ -264,16 +256,14 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
264
256
|
from code_puppy.messaging import emit_warning
|
|
265
257
|
|
|
266
258
|
emit_warning(f"MOTD error: {e}")
|
|
267
|
-
from code_puppy.agents.runtime_manager import get_runtime_agent_manager
|
|
268
259
|
from code_puppy.messaging import emit_info
|
|
269
260
|
|
|
270
261
|
emit_info("[bold cyan]Initializing agent...[/bold cyan]")
|
|
271
262
|
# Initialize the runtime agent manager
|
|
272
|
-
agent_manager = get_runtime_agent_manager()
|
|
273
|
-
agent_manager.get_agent()
|
|
274
263
|
if initial_command:
|
|
275
264
|
from code_puppy.messaging import emit_info, emit_system_message
|
|
276
|
-
|
|
265
|
+
from code_puppy.agents import get_current_agent
|
|
266
|
+
agent = get_current_agent()
|
|
277
267
|
emit_info(
|
|
278
268
|
f"[bold blue]Processing initial command:[/bold blue] {initial_command}"
|
|
279
269
|
)
|
|
@@ -290,10 +280,9 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
290
280
|
# Run with or without spinner based on whether we're awaiting input
|
|
291
281
|
if awaiting_input:
|
|
292
282
|
# No spinner - use agent_manager's run_with_mcp method
|
|
293
|
-
|
|
283
|
+
|
|
284
|
+
response = await agent.run_with_mcp(
|
|
294
285
|
initial_command,
|
|
295
|
-
message_history=get_message_history(),
|
|
296
|
-
usage_limits=get_custom_usage_limits(),
|
|
297
286
|
)
|
|
298
287
|
else:
|
|
299
288
|
# Use our custom spinner for better compatibility with user input
|
|
@@ -301,15 +290,8 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
301
290
|
|
|
302
291
|
with ConsoleSpinner(console=display_console):
|
|
303
292
|
# Use agent_manager's run_with_mcp method
|
|
304
|
-
response = await
|
|
293
|
+
response = await agent.run_with_mcp(
|
|
305
294
|
initial_command,
|
|
306
|
-
message_history=prune_interrupted_tool_calls(
|
|
307
|
-
get_message_history()
|
|
308
|
-
),
|
|
309
|
-
usage_limits=get_custom_usage_limits(),
|
|
310
|
-
)
|
|
311
|
-
set_message_history(
|
|
312
|
-
prune_interrupted_tool_calls(get_message_history())
|
|
313
295
|
)
|
|
314
296
|
|
|
315
297
|
agent_response = response.output
|
|
@@ -317,9 +299,6 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
317
299
|
emit_system_message(
|
|
318
300
|
f"\n[bold purple]AGENT RESPONSE: [/bold purple]\n{agent_response}"
|
|
319
301
|
)
|
|
320
|
-
new_msgs = response.all_messages()
|
|
321
|
-
message_history_accumulator(new_msgs)
|
|
322
|
-
set_message_history(prune_interrupted_tool_calls(get_message_history()))
|
|
323
302
|
emit_system_message("\n" + "=" * 50)
|
|
324
303
|
emit_info("[bold green]🐶 Continuing in Interactive Mode[/bold green]")
|
|
325
304
|
emit_system_message(
|
|
@@ -359,11 +338,11 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
359
338
|
emit_warning("Falling back to basic input without tab completion")
|
|
360
339
|
|
|
361
340
|
while True:
|
|
362
|
-
from code_puppy.agents.agent_manager import
|
|
341
|
+
from code_puppy.agents.agent_manager import get_current_agent
|
|
363
342
|
from code_puppy.messaging import emit_info
|
|
364
343
|
|
|
365
344
|
# Get the custom prompt from the current agent, or use default
|
|
366
|
-
current_agent =
|
|
345
|
+
current_agent = get_current_agent()
|
|
367
346
|
user_prompt = current_agent.get_user_prompt() or "Enter your coding task:"
|
|
368
347
|
|
|
369
348
|
emit_info(f"[bold blue]{user_prompt}[/bold blue]")
|
|
@@ -399,7 +378,6 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
399
378
|
|
|
400
379
|
# Check for clear command (supports both `clear` and `/clear`)
|
|
401
380
|
if task.strip().lower() in ("clear", "/clear"):
|
|
402
|
-
clear_message_history()
|
|
403
381
|
from code_puppy.messaging import emit_system_message, emit_warning
|
|
404
382
|
|
|
405
383
|
emit_warning("Conversation history cleared!")
|
|
@@ -431,14 +409,9 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
431
409
|
from code_puppy.messaging import emit_warning
|
|
432
410
|
from code_puppy.messaging.spinner import ConsoleSpinner
|
|
433
411
|
|
|
434
|
-
runtime_manager = get_runtime_agent_manager()
|
|
435
412
|
with ConsoleSpinner(console=message_renderer.console):
|
|
436
|
-
result = await
|
|
413
|
+
result = await current_agent.run_with_mcp(
|
|
437
414
|
task,
|
|
438
|
-
get_custom_usage_limits(),
|
|
439
|
-
message_history=prune_interrupted_tool_calls(
|
|
440
|
-
get_message_history()
|
|
441
|
-
),
|
|
442
415
|
)
|
|
443
416
|
# Check if the task was cancelled (but don't show message if we just killed processes)
|
|
444
417
|
if result is None:
|
|
@@ -451,14 +424,6 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
451
424
|
f"\n[bold purple]AGENT RESPONSE: [/bold purple]\n{agent_response}"
|
|
452
425
|
)
|
|
453
426
|
|
|
454
|
-
# Update message history - the agent's history processor will handle truncation
|
|
455
|
-
new_msgs = result.all_messages()
|
|
456
|
-
message_history_accumulator(new_msgs)
|
|
457
|
-
|
|
458
|
-
emit_system_message(
|
|
459
|
-
f"Context: {len(get_message_history())} messages in history\n"
|
|
460
|
-
)
|
|
461
|
-
|
|
462
427
|
# Ensure console output is flushed before next prompt
|
|
463
428
|
# This fixes the issue where prompt doesn't appear after agent response
|
|
464
429
|
display_console.file.flush() if hasattr(
|
|
@@ -502,14 +467,12 @@ async def execute_single_prompt(prompt: str, message_renderer) -> None:
|
|
|
502
467
|
|
|
503
468
|
try:
|
|
504
469
|
# Get agent through runtime manager and use its run_with_mcp method
|
|
505
|
-
|
|
506
|
-
|
|
470
|
+
agent = get_current_agent()
|
|
507
471
|
from code_puppy.messaging.spinner import ConsoleSpinner
|
|
508
472
|
|
|
509
473
|
with ConsoleSpinner(console=message_renderer.console):
|
|
510
|
-
response = await
|
|
474
|
+
response = await agent.run_with_mcp(
|
|
511
475
|
prompt,
|
|
512
|
-
usage_limits=get_custom_usage_limits(),
|
|
513
476
|
)
|
|
514
477
|
|
|
515
478
|
agent_response = response.output
|
|
@@ -4,7 +4,7 @@ from typing import List
|
|
|
4
4
|
|
|
5
5
|
from pydantic_ai import Agent
|
|
6
6
|
|
|
7
|
-
from code_puppy.config import
|
|
7
|
+
from code_puppy.config import get_global_model_name
|
|
8
8
|
from code_puppy.model_factory import ModelFactory
|
|
9
9
|
|
|
10
10
|
# Keep a module-level agent reference to avoid rebuilding per call
|
|
@@ -53,7 +53,7 @@ def run_summarization_sync(prompt: str, message_history: List) -> List:
|
|
|
53
53
|
def reload_summarization_agent():
|
|
54
54
|
"""Create a specialized agent for summarizing messages when context limit is reached."""
|
|
55
55
|
models_config = ModelFactory.load_config()
|
|
56
|
-
model_name =
|
|
56
|
+
model_name = get_global_model_name()
|
|
57
57
|
model = ModelFactory.get_model(model_name, models_config)
|
|
58
58
|
|
|
59
59
|
# Specialized instructions for summarization
|
code_puppy/tools/agent_tools.py
CHANGED
|
@@ -11,12 +11,11 @@ from code_puppy.messaging import (
|
|
|
11
11
|
emit_error,
|
|
12
12
|
)
|
|
13
13
|
from code_puppy.tools.common import generate_group_id
|
|
14
|
-
from code_puppy.agents.agent_manager import get_available_agents, load_agent_config
|
|
15
14
|
|
|
16
15
|
# Import Agent from pydantic_ai to create temporary agents for invocation
|
|
17
16
|
from pydantic_ai import Agent
|
|
18
17
|
from code_puppy.model_factory import ModelFactory
|
|
19
|
-
from code_puppy.config import
|
|
18
|
+
from code_puppy.config import get_global_model_name
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
class AgentInfo(BaseModel):
|
|
@@ -65,6 +64,7 @@ def register_list_agents(agent):
|
|
|
65
64
|
emit_divider(message_group=group_id)
|
|
66
65
|
|
|
67
66
|
try:
|
|
67
|
+
from code_puppy.agents import get_available_agents
|
|
68
68
|
# Get available agents from the agent manager
|
|
69
69
|
agents_dict = get_available_agents()
|
|
70
70
|
|
|
@@ -113,6 +113,7 @@ def register_invoke_agent(agent):
|
|
|
113
113
|
Returns:
|
|
114
114
|
AgentInvokeOutput: The agent's response to the prompt
|
|
115
115
|
"""
|
|
116
|
+
from code_puppy.agents.agent_manager import load_agent
|
|
116
117
|
# Generate a group ID for this tool execution
|
|
117
118
|
group_id = generate_group_id("invoke_agent", agent_name)
|
|
118
119
|
|
|
@@ -126,10 +127,10 @@ def register_invoke_agent(agent):
|
|
|
126
127
|
|
|
127
128
|
try:
|
|
128
129
|
# Load the specified agent config
|
|
129
|
-
agent_config =
|
|
130
|
+
agent_config = load_agent(agent_name)
|
|
130
131
|
|
|
131
132
|
# Get the current model for creating a temporary agent
|
|
132
|
-
model_name =
|
|
133
|
+
model_name = get_global_model_name()
|
|
133
134
|
models_config = ModelFactory.load_config()
|
|
134
135
|
|
|
135
136
|
# Only proceed if we have a valid model configuration
|
|
@@ -6,7 +6,7 @@ from functools import lru_cache
|
|
|
6
6
|
from typing import Optional
|
|
7
7
|
|
|
8
8
|
from pydantic import BaseModel, Field
|
|
9
|
-
from pydantic_ai import Agent, BinaryContent
|
|
9
|
+
from pydantic_ai import Agent, BinaryContent
|
|
10
10
|
|
|
11
11
|
from code_puppy.config import get_vqa_model_name
|
|
12
12
|
from code_puppy.model_factory import ModelFactory
|
|
@@ -26,8 +26,6 @@ def _load_vqa_agent(model_name: str) -> Agent[None, VisualAnalysisResult]:
|
|
|
26
26
|
models_config = ModelFactory.load_config()
|
|
27
27
|
model = ModelFactory.get_model(model_name, models_config)
|
|
28
28
|
|
|
29
|
-
instrumentation = InstrumentationSettings(include_binary_content=False)
|
|
30
|
-
|
|
31
29
|
instructions = (
|
|
32
30
|
"You are a visual analysis specialist. Answer the user's question about the provided image. "
|
|
33
31
|
"Always respond using the structured schema: answer, confidence (0-1 float), observations. "
|