code-puppy 0.0.172__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 +14 -14
- code_puppy/agents/__init__.py +4 -6
- code_puppy/agents/agent_manager.py +15 -187
- code_puppy/agents/base_agent.py +798 -4
- code_puppy/command_line/command_handler.py +40 -41
- code_puppy/command_line/mcp/add_command.py +1 -1
- code_puppy/command_line/mcp/install_command.py +1 -1
- 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 -3
- code_puppy/main.py +13 -49
- code_puppy/messaging/message_queue.py +4 -4
- 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/tools/command_runner.py +1 -1
- code_puppy/tui/app.py +49 -78
- code_puppy/tui/screens/settings.py +2 -2
- code_puppy/tui_state.py +55 -0
- {code_puppy-0.0.172.dist-info → code_puppy-0.0.174.dist-info}/METADATA +2 -2
- {code_puppy-0.0.172.dist-info → code_puppy-0.0.174.dist-info}/RECORD +29 -33
- 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 -486
- code_puppy/state_management.py +0 -159
- {code_puppy-0.0.172.data → code_puppy-0.0.174.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.172.dist-info → code_puppy-0.0.174.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.172.dist-info → code_puppy-0.0.174.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.172.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
|
)
|
|
@@ -8,7 +8,7 @@ import os
|
|
|
8
8
|
from typing import List, Optional
|
|
9
9
|
|
|
10
10
|
from code_puppy.messaging import emit_info
|
|
11
|
-
from code_puppy.
|
|
11
|
+
from code_puppy.tui_state import is_tui_mode
|
|
12
12
|
|
|
13
13
|
from .base import MCPCommandBase
|
|
14
14
|
from .wizard_utils import run_interactive_install_wizard
|
|
@@ -6,7 +6,7 @@ import logging
|
|
|
6
6
|
from typing import List, Optional
|
|
7
7
|
|
|
8
8
|
from code_puppy.messaging import emit_info
|
|
9
|
-
from code_puppy.
|
|
9
|
+
from code_puppy.tui_state import is_tui_mode
|
|
10
10
|
|
|
11
11
|
from .base import MCPCommandBase
|
|
12
12
|
from .wizard_utils import run_interactive_install_wizard
|
|
@@ -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, {})
|
|
@@ -115,7 +115,6 @@ def get_config_keys():
|
|
|
115
115
|
default_keys = [
|
|
116
116
|
"yolo_mode",
|
|
117
117
|
"model",
|
|
118
|
-
"vqa_model_name",
|
|
119
118
|
"compaction_strategy",
|
|
120
119
|
"protected_token_count",
|
|
121
120
|
"compaction_threshold",
|
|
@@ -306,7 +305,7 @@ def clear_model_cache():
|
|
|
306
305
|
_default_vqa_model_cache = None
|
|
307
306
|
|
|
308
307
|
|
|
309
|
-
def
|
|
308
|
+
def get_global_model_name():
|
|
310
309
|
"""Return a valid model name for Code Puppy to use.
|
|
311
310
|
|
|
312
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,14 +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
|
-
|
|
30
|
-
prune_interrupted_tool_calls,
|
|
31
|
-
)
|
|
32
|
-
from code_puppy.state_management import is_tui_mode, set_message_history, set_tui_mode
|
|
27
|
+
# message_history_accumulator and prune_interrupted_tool_calls have been moved to BaseAgent class
|
|
28
|
+
from code_puppy.tui_state import is_tui_mode, set_tui_mode
|
|
33
29
|
from code_puppy.tools.common import console
|
|
34
30
|
from code_puppy.version_checker import default_version_mismatch_behavior
|
|
35
|
-
|
|
36
31
|
plugins.load_plugin_callbacks()
|
|
37
32
|
|
|
38
33
|
|
|
@@ -236,9 +231,7 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
236
231
|
from code_puppy.command_line.command_handler import handle_command
|
|
237
232
|
|
|
238
233
|
"""Run the agent in interactive mode."""
|
|
239
|
-
from code_puppy.state_management import clear_message_history, get_message_history
|
|
240
234
|
|
|
241
|
-
clear_message_history()
|
|
242
235
|
display_console = message_renderer.console
|
|
243
236
|
from code_puppy.messaging import emit_info, emit_system_message
|
|
244
237
|
|
|
@@ -263,16 +256,14 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
263
256
|
from code_puppy.messaging import emit_warning
|
|
264
257
|
|
|
265
258
|
emit_warning(f"MOTD error: {e}")
|
|
266
|
-
from code_puppy.agents.runtime_manager import get_runtime_agent_manager
|
|
267
259
|
from code_puppy.messaging import emit_info
|
|
268
260
|
|
|
269
261
|
emit_info("[bold cyan]Initializing agent...[/bold cyan]")
|
|
270
262
|
# Initialize the runtime agent manager
|
|
271
|
-
agent_manager = get_runtime_agent_manager()
|
|
272
|
-
agent_manager.get_agent()
|
|
273
263
|
if initial_command:
|
|
274
264
|
from code_puppy.messaging import emit_info, emit_system_message
|
|
275
|
-
|
|
265
|
+
from code_puppy.agents import get_current_agent
|
|
266
|
+
agent = get_current_agent()
|
|
276
267
|
emit_info(
|
|
277
268
|
f"[bold blue]Processing initial command:[/bold blue] {initial_command}"
|
|
278
269
|
)
|
|
@@ -289,10 +280,9 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
289
280
|
# Run with or without spinner based on whether we're awaiting input
|
|
290
281
|
if awaiting_input:
|
|
291
282
|
# No spinner - use agent_manager's run_with_mcp method
|
|
292
|
-
|
|
283
|
+
|
|
284
|
+
response = await agent.run_with_mcp(
|
|
293
285
|
initial_command,
|
|
294
|
-
message_history=get_message_history(),
|
|
295
|
-
usage_limits=get_custom_usage_limits(),
|
|
296
286
|
)
|
|
297
287
|
else:
|
|
298
288
|
# Use our custom spinner for better compatibility with user input
|
|
@@ -300,15 +290,8 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
300
290
|
|
|
301
291
|
with ConsoleSpinner(console=display_console):
|
|
302
292
|
# Use agent_manager's run_with_mcp method
|
|
303
|
-
response = await
|
|
293
|
+
response = await agent.run_with_mcp(
|
|
304
294
|
initial_command,
|
|
305
|
-
message_history=prune_interrupted_tool_calls(
|
|
306
|
-
get_message_history()
|
|
307
|
-
),
|
|
308
|
-
usage_limits=get_custom_usage_limits(),
|
|
309
|
-
)
|
|
310
|
-
set_message_history(
|
|
311
|
-
prune_interrupted_tool_calls(get_message_history())
|
|
312
295
|
)
|
|
313
296
|
|
|
314
297
|
agent_response = response.output
|
|
@@ -316,9 +299,6 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
316
299
|
emit_system_message(
|
|
317
300
|
f"\n[bold purple]AGENT RESPONSE: [/bold purple]\n{agent_response}"
|
|
318
301
|
)
|
|
319
|
-
new_msgs = response.all_messages()
|
|
320
|
-
message_history_accumulator(new_msgs)
|
|
321
|
-
set_message_history(prune_interrupted_tool_calls(get_message_history()))
|
|
322
302
|
emit_system_message("\n" + "=" * 50)
|
|
323
303
|
emit_info("[bold green]🐶 Continuing in Interactive Mode[/bold green]")
|
|
324
304
|
emit_system_message(
|
|
@@ -358,11 +338,11 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
358
338
|
emit_warning("Falling back to basic input without tab completion")
|
|
359
339
|
|
|
360
340
|
while True:
|
|
361
|
-
from code_puppy.agents.agent_manager import
|
|
341
|
+
from code_puppy.agents.agent_manager import get_current_agent
|
|
362
342
|
from code_puppy.messaging import emit_info
|
|
363
343
|
|
|
364
344
|
# Get the custom prompt from the current agent, or use default
|
|
365
|
-
current_agent =
|
|
345
|
+
current_agent = get_current_agent()
|
|
366
346
|
user_prompt = current_agent.get_user_prompt() or "Enter your coding task:"
|
|
367
347
|
|
|
368
348
|
emit_info(f"[bold blue]{user_prompt}[/bold blue]")
|
|
@@ -398,7 +378,6 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
398
378
|
|
|
399
379
|
# Check for clear command (supports both `clear` and `/clear`)
|
|
400
380
|
if task.strip().lower() in ("clear", "/clear"):
|
|
401
|
-
clear_message_history()
|
|
402
381
|
from code_puppy.messaging import emit_system_message, emit_warning
|
|
403
382
|
|
|
404
383
|
emit_warning("Conversation history cleared!")
|
|
@@ -430,14 +409,9 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
430
409
|
from code_puppy.messaging import emit_warning
|
|
431
410
|
from code_puppy.messaging.spinner import ConsoleSpinner
|
|
432
411
|
|
|
433
|
-
runtime_manager = get_runtime_agent_manager()
|
|
434
412
|
with ConsoleSpinner(console=message_renderer.console):
|
|
435
|
-
result = await
|
|
413
|
+
result = await current_agent.run_with_mcp(
|
|
436
414
|
task,
|
|
437
|
-
get_custom_usage_limits(),
|
|
438
|
-
message_history=prune_interrupted_tool_calls(
|
|
439
|
-
get_message_history()
|
|
440
|
-
),
|
|
441
415
|
)
|
|
442
416
|
# Check if the task was cancelled (but don't show message if we just killed processes)
|
|
443
417
|
if result is None:
|
|
@@ -450,14 +424,6 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
450
424
|
f"\n[bold purple]AGENT RESPONSE: [/bold purple]\n{agent_response}"
|
|
451
425
|
)
|
|
452
426
|
|
|
453
|
-
# Update message history - the agent's history processor will handle truncation
|
|
454
|
-
new_msgs = result.all_messages()
|
|
455
|
-
message_history_accumulator(new_msgs)
|
|
456
|
-
|
|
457
|
-
emit_system_message(
|
|
458
|
-
f"Context: {len(get_message_history())} messages in history\n"
|
|
459
|
-
)
|
|
460
|
-
|
|
461
427
|
# Ensure console output is flushed before next prompt
|
|
462
428
|
# This fixes the issue where prompt doesn't appear after agent response
|
|
463
429
|
display_console.file.flush() if hasattr(
|
|
@@ -501,14 +467,12 @@ async def execute_single_prompt(prompt: str, message_renderer) -> None:
|
|
|
501
467
|
|
|
502
468
|
try:
|
|
503
469
|
# Get agent through runtime manager and use its run_with_mcp method
|
|
504
|
-
|
|
505
|
-
|
|
470
|
+
agent = get_current_agent()
|
|
506
471
|
from code_puppy.messaging.spinner import ConsoleSpinner
|
|
507
472
|
|
|
508
473
|
with ConsoleSpinner(console=message_renderer.console):
|
|
509
|
-
response = await
|
|
474
|
+
response = await agent.run_with_mcp(
|
|
510
475
|
prompt,
|
|
511
|
-
usage_limits=get_custom_usage_limits(),
|
|
512
476
|
)
|
|
513
477
|
|
|
514
478
|
agent_response = response.output
|
|
@@ -219,7 +219,7 @@ class MessageQueue:
|
|
|
219
219
|
start_time = time.time()
|
|
220
220
|
|
|
221
221
|
# Check if we're in TUI mode - if so, try to yield control to the event loop
|
|
222
|
-
from code_puppy.
|
|
222
|
+
from code_puppy.tui_state import is_tui_mode
|
|
223
223
|
|
|
224
224
|
sleep_interval = 0.05 if is_tui_mode() else 0.1
|
|
225
225
|
|
|
@@ -243,7 +243,7 @@ class MessageQueue:
|
|
|
243
243
|
|
|
244
244
|
def provide_prompt_response(self, prompt_id: str, response: str):
|
|
245
245
|
"""Provide a response to a human input request."""
|
|
246
|
-
from code_puppy.
|
|
246
|
+
from code_puppy.tui_state import is_tui_mode
|
|
247
247
|
|
|
248
248
|
if is_tui_mode():
|
|
249
249
|
print(f"[DEBUG] Providing response for {prompt_id}: {response[:20]}...")
|
|
@@ -337,7 +337,7 @@ def emit_system_message(content: Any, **metadata):
|
|
|
337
337
|
|
|
338
338
|
def emit_divider(content: str = "[dim]" + "─" * 100 + "\n" + "[/dim]", **metadata):
|
|
339
339
|
"""Emit a divider line"""
|
|
340
|
-
from code_puppy.
|
|
340
|
+
from code_puppy.tui_state import is_tui_mode
|
|
341
341
|
|
|
342
342
|
if not is_tui_mode():
|
|
343
343
|
emit_message(MessageType.DIVIDER, content, **metadata)
|
|
@@ -347,7 +347,7 @@ def emit_divider(content: str = "[dim]" + "─" * 100 + "\n" + "[/dim]", **metad
|
|
|
347
347
|
|
|
348
348
|
def emit_prompt(prompt_text: str, timeout: float = None) -> str:
|
|
349
349
|
"""Emit a human input request and wait for response."""
|
|
350
|
-
from code_puppy.
|
|
350
|
+
from code_puppy.tui_state import is_tui_mode
|
|
351
351
|
|
|
352
352
|
# In interactive mode, use direct input instead of the queue system
|
|
353
353
|
if not is_tui_mode():
|
|
@@ -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
|