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.
Files changed (29) hide show
  1. code_puppy/agent.py +11 -11
  2. code_puppy/agents/__init__.py +4 -6
  3. code_puppy/agents/agent_manager.py +15 -187
  4. code_puppy/agents/base_agent.py +470 -63
  5. code_puppy/command_line/command_handler.py +40 -41
  6. code_puppy/command_line/mcp/start_all_command.py +3 -6
  7. code_puppy/command_line/mcp/start_command.py +0 -5
  8. code_puppy/command_line/mcp/stop_all_command.py +3 -6
  9. code_puppy/command_line/mcp/stop_command.py +2 -6
  10. code_puppy/command_line/model_picker_completion.py +2 -2
  11. code_puppy/command_line/prompt_toolkit_completion.py +2 -2
  12. code_puppy/config.py +2 -2
  13. code_puppy/main.py +12 -49
  14. code_puppy/summarization_agent.py +2 -2
  15. code_puppy/tools/agent_tools.py +5 -4
  16. code_puppy/tools/browser/vqa_agent.py +1 -3
  17. code_puppy/tui/app.py +48 -77
  18. code_puppy/tui/screens/settings.py +2 -2
  19. {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/METADATA +2 -2
  20. {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/RECORD +24 -29
  21. code_puppy/agents/agent_orchestrator.json +0 -26
  22. code_puppy/agents/runtime_manager.py +0 -272
  23. code_puppy/command_line/meta_command_handler.py +0 -153
  24. code_puppy/message_history_processor.py +0 -408
  25. code_puppy/state_management.py +0 -58
  26. {code_puppy-0.0.173.data → code_puppy-0.0.174.data}/data/code_puppy/models.json +0 -0
  27. {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/WHEEL +0 -0
  28. {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/entry_points.txt +0 -0
  29. {code_puppy-0.0.173.dist-info → code_puppy-0.0.174.dist-info}/licenses/LICENSE +0 -0
code_puppy/agent.py CHANGED
@@ -125,22 +125,22 @@ def reload_code_generation_agent(message_group: str | None):
125
125
  message_group = str(uuid.uuid4())
126
126
  global _code_generation_agent, _LAST_MODEL_NAME
127
127
  from code_puppy.agents import clear_agent_cache
128
- from code_puppy.config import clear_model_cache, get_model_name
128
+ from code_puppy.config import clear_model_cache, get_global_model_name
129
129
 
130
130
  # Clear both ModelFactory cache and config cache when force reloading
131
131
  clear_model_cache()
132
132
  clear_agent_cache()
133
133
 
134
134
  # Check if current agent has a pinned model
135
- from code_puppy.agents import get_current_agent_config
135
+ from code_puppy.agents import get_current_agent
136
136
 
137
- agent_config = get_current_agent_config()
137
+ agent_config = get_current_agent()
138
138
  agent_model_name = None
139
139
  if hasattr(agent_config, "get_model_name"):
140
140
  agent_model_name = agent_config.get_model_name()
141
141
 
142
142
  # Use agent-specific model if pinned, otherwise use global model
143
- model_name = agent_model_name if agent_model_name else get_model_name()
143
+ model_name = agent_model_name if agent_model_name else get_global_model_name()
144
144
  emit_info(
145
145
  f"[bold cyan]Loading Model: {model_name}[/bold cyan]",
146
146
  message_group=message_group,
@@ -149,7 +149,7 @@ def reload_code_generation_agent(message_group: str | None):
149
149
  model = ModelFactory.get_model(model_name, models_config)
150
150
 
151
151
  # Get agent-specific system prompt
152
- agent_config = get_current_agent_config()
152
+ agent_config = get_current_agent()
153
153
  emit_info(
154
154
  f"[bold magenta]Loading Agent: {agent_config.display_name}[/bold magenta]",
155
155
  message_group=message_group,
@@ -165,8 +165,8 @@ def reload_code_generation_agent(message_group: str | None):
165
165
  # Configure model settings with max_tokens if set
166
166
  model_settings_dict = {"seed": 42}
167
167
  # Get current agent to use its method
168
- from code_puppy.agents import get_current_agent_config
169
- current_agent = get_current_agent_config()
168
+ from code_puppy.agents import get_current_agent
169
+ current_agent = get_current_agent()
170
170
  output_tokens = max(2048, min(int(0.05 * current_agent.get_model_context_length()) - 1024, 16384))
171
171
  console.print(f"Max output tokens per message: {output_tokens}")
172
172
  model_settings_dict["max_tokens"] = output_tokens
@@ -207,15 +207,15 @@ def get_code_generation_agent(force_reload=False, message_group: str | None = No
207
207
  global _code_generation_agent, _LAST_MODEL_NAME
208
208
  if message_group is None:
209
209
  message_group = str(uuid.uuid4())
210
- from code_puppy.config import get_model_name
210
+ from code_puppy.config import get_global_model_name
211
211
 
212
212
  # Get the global model name
213
- global_model_name = get_model_name()
213
+ global_model_name = get_global_model_name()
214
214
 
215
215
  # Check if current agent has a pinned model
216
- from code_puppy.agents import get_current_agent_config
216
+ from code_puppy.agents import get_current_agent
217
217
 
218
- agent_config = get_current_agent_config()
218
+ agent_config = get_current_agent()
219
219
  agent_model_name = None
220
220
  if hasattr(agent_config, "get_model_name"):
221
221
  agent_model_name = agent_config.get_model_name()
@@ -6,20 +6,18 @@ configurations, each with their own system prompts and tool sets.
6
6
 
7
7
  from .agent_manager import (
8
8
  get_available_agents,
9
- get_current_agent_config,
9
+ get_current_agent,
10
10
  set_current_agent,
11
- load_agent_config,
11
+ load_agent,
12
12
  get_agent_descriptions,
13
- clear_agent_cache,
14
13
  refresh_agents,
15
14
  )
16
15
 
17
16
  __all__ = [
18
17
  "get_available_agents",
19
- "get_current_agent_config",
18
+ "get_current_agent",
20
19
  "set_current_agent",
21
- "load_agent_config",
20
+ "load_agent",
22
21
  "get_agent_descriptions",
23
- "clear_agent_cache",
24
22
  "refresh_agents",
25
23
  ]
@@ -8,14 +8,14 @@ import uuid
8
8
  from pathlib import Path
9
9
  from typing import Dict, Optional, Type, Union
10
10
 
11
- from ..callbacks import on_agent_reload
12
- from ..messaging import emit_warning
13
- from .base_agent import BaseAgent
14
- from .json_agent import JSONAgent, discover_json_agents
11
+ from code_puppy.callbacks import on_agent_reload
12
+ from code_puppy.messaging import emit_warning
13
+ from code_puppy.agents.base_agent import BaseAgent
14
+ from code_puppy.agents.json_agent import JSONAgent, discover_json_agents
15
15
 
16
16
  # Registry of available agents (Python classes and JSON file paths)
17
17
  _AGENT_REGISTRY: Dict[str, Union[Type[BaseAgent], str]] = {}
18
- _CURRENT_AGENT_CONFIG: Optional[BaseAgent] = None
18
+ _CURRENT_AGENT: Optional[BaseAgent] = None
19
19
 
20
20
  # Terminal session-based agent selection
21
21
  _SESSION_AGENTS_CACHE: dict[str, str] = {}
@@ -146,40 +146,6 @@ def _ensure_session_cache_loaded() -> None:
146
146
  _SESSION_FILE_LOADED = True
147
147
 
148
148
 
149
- # Persistent storage for agent message histories
150
- _AGENT_HISTORIES: Dict[str, Dict[str, any]] = {}
151
- # Structure: {agent_name: {"message_history": [...], "compacted_hashes": set(...)}}
152
-
153
-
154
- def _save_agent_history(agent_name: str, agent: BaseAgent) -> None:
155
- """Save an agent's message history to persistent storage.
156
-
157
- Args:
158
- agent_name: The name of the agent
159
- agent: The agent instance to save history from
160
- """
161
- global _AGENT_HISTORIES
162
- _AGENT_HISTORIES[agent_name] = {
163
- "message_history": agent.get_message_history().copy(),
164
- "compacted_hashes": agent.get_compacted_message_hashes().copy(),
165
- }
166
-
167
-
168
- def _restore_agent_history(agent_name: str, agent: BaseAgent) -> None:
169
- """Restore an agent's message history from persistent storage.
170
-
171
- Args:
172
- agent_name: The name of the agent
173
- agent: The agent instance to restore history to
174
- """
175
- global _AGENT_HISTORIES
176
- if agent_name in _AGENT_HISTORIES:
177
- stored_data = _AGENT_HISTORIES[agent_name]
178
- agent.set_message_history(stored_data["message_history"])
179
- # Restore compacted hashes
180
- for hash_val in stored_data["compacted_hashes"]:
181
- agent.add_compacted_message_hash(hash_val)
182
-
183
149
 
184
150
  def _discover_agents(message_group_id: Optional[str] = None):
185
151
  """Dynamically discover all agent classes and JSON agents."""
@@ -281,21 +247,17 @@ def set_current_agent(agent_name: str) -> bool:
281
247
  Returns:
282
248
  True if the agent was set successfully, False if agent not found.
283
249
  """
250
+ global _CURRENT_AGENT
251
+
284
252
  # Generate a message group ID for agent switching
285
253
  message_group_id = str(uuid.uuid4())
286
254
  _discover_agents(message_group_id=message_group_id)
287
255
 
288
256
  # Save current agent's history before switching
289
- global _CURRENT_AGENT_CONFIG, _CURRENT_AGENT_NAME
290
- if _CURRENT_AGENT_CONFIG is not None:
291
- _save_agent_history(_CURRENT_AGENT_CONFIG.name, _CURRENT_AGENT_CONFIG)
292
257
 
293
258
  # Clear the cached config when switching agents
294
- _CURRENT_AGENT_CONFIG = None
295
- agent_obj = load_agent_config(agent_name)
296
-
297
- # Restore the agent's history if it exists
298
- _restore_agent_history(agent_name, agent_obj)
259
+ agent_obj = load_agent(agent_name)
260
+ _CURRENT_AGENT = agent_obj
299
261
 
300
262
  # Update session-based agent selection and persist to disk
301
263
  _ensure_session_cache_loaded()
@@ -307,24 +269,22 @@ def set_current_agent(agent_name: str) -> bool:
307
269
  return True
308
270
 
309
271
 
310
- def get_current_agent_config() -> BaseAgent:
272
+ def get_current_agent() -> BaseAgent:
311
273
  """Get the current agent configuration.
312
274
 
313
275
  Returns:
314
276
  The current agent configuration instance.
315
277
  """
316
- global _CURRENT_AGENT_CONFIG
278
+ global _CURRENT_AGENT
317
279
 
318
- if _CURRENT_AGENT_CONFIG is None:
280
+ if _CURRENT_AGENT is None:
319
281
  agent_name = get_current_agent_name()
320
- _CURRENT_AGENT_CONFIG = load_agent_config(agent_name)
321
- # Restore the agent's history if it exists
322
- _restore_agent_history(agent_name, _CURRENT_AGENT_CONFIG)
282
+ _CURRENT_AGENT = load_agent(agent_name)
323
283
 
324
- return _CURRENT_AGENT_CONFIG
284
+ return _CURRENT_AGENT
325
285
 
326
286
 
327
- def load_agent_config(agent_name: str) -> BaseAgent:
287
+ def load_agent(agent_name: str) -> BaseAgent:
328
288
  """Load an agent configuration by name.
329
289
 
330
290
  Args:
@@ -380,26 +340,6 @@ def get_agent_descriptions() -> Dict[str, str]:
380
340
  return descriptions
381
341
 
382
342
 
383
- def clear_agent_cache():
384
- """Clear the cached agent configuration to force reload."""
385
- global _CURRENT_AGENT_CONFIG
386
- _CURRENT_AGENT_CONFIG = None
387
-
388
-
389
- def reset_to_default_agent():
390
- """Reset the current agent to the default (code-puppy) for this terminal session.
391
-
392
- This is useful for testing or when you want to start fresh.
393
- """
394
- global _CURRENT_AGENT_CONFIG
395
- _ensure_session_cache_loaded()
396
- session_id = get_terminal_session_id()
397
- if session_id in _SESSION_AGENTS_CACHE:
398
- del _SESSION_AGENTS_CACHE[session_id]
399
- _save_session_data(_SESSION_AGENTS_CACHE)
400
- _CURRENT_AGENT_CONFIG = None
401
-
402
-
403
343
  def refresh_agents():
404
344
  """Refresh the agent discovery to pick up newly created agents.
405
345
 
@@ -408,115 +348,3 @@ def refresh_agents():
408
348
  # Generate a message group ID for agent refreshing
409
349
  message_group_id = str(uuid.uuid4())
410
350
  _discover_agents(message_group_id=message_group_id)
411
-
412
-
413
- def clear_all_agent_histories():
414
- """Clear all agent message histories from persistent storage.
415
-
416
- This is useful for debugging or when you want a fresh start.
417
- """
418
- global _AGENT_HISTORIES
419
- _AGENT_HISTORIES.clear()
420
- # Also clear the current agent's history
421
- if _CURRENT_AGENT_CONFIG is not None:
422
- _CURRENT_AGENT_CONFIG.messages = []
423
-
424
-
425
- def cleanup_dead_terminal_sessions() -> int:
426
- """Clean up terminal sessions for processes that no longer exist.
427
-
428
- Returns:
429
- int: Number of dead sessions removed
430
- """
431
- _ensure_session_cache_loaded()
432
- original_count = len(_SESSION_AGENTS_CACHE)
433
- cleaned_cache = _cleanup_dead_sessions(_SESSION_AGENTS_CACHE)
434
-
435
- if len(cleaned_cache) != original_count:
436
- _SESSION_AGENTS_CACHE.clear()
437
- _SESSION_AGENTS_CACHE.update(cleaned_cache)
438
- _save_session_data(_SESSION_AGENTS_CACHE)
439
-
440
- return original_count - len(cleaned_cache)
441
-
442
-
443
- # Agent-aware message history functions
444
- def get_current_agent_message_history():
445
- """Get the message history for the currently active agent.
446
-
447
- Returns:
448
- List of messages from the current agent's conversation history.
449
- """
450
- current_agent = get_current_agent_config()
451
- return current_agent.get_message_history()
452
-
453
-
454
- def set_current_agent_message_history(history):
455
- """Set the message history for the currently active agent.
456
-
457
- Args:
458
- history: List of messages to set as the current agent's conversation history.
459
- """
460
- current_agent = get_current_agent_config()
461
- current_agent.set_message_history(history)
462
- # Also update persistent storage
463
- _save_agent_history(current_agent.name, current_agent)
464
-
465
-
466
- def clear_current_agent_message_history():
467
- """Clear the message history for the currently active agent."""
468
- current_agent = get_current_agent_config()
469
- current_agent.clear_message_history()
470
- # Also clear from persistent storage
471
- global _AGENT_HISTORIES
472
- if current_agent.name in _AGENT_HISTORIES:
473
- _AGENT_HISTORIES[current_agent.name] = {
474
- "message_history": [],
475
- "compacted_hashes": set(),
476
- }
477
-
478
-
479
- def append_to_current_agent_message_history(message):
480
- """Append a message to the currently active agent's history.
481
-
482
- Args:
483
- message: Message to append to the current agent's conversation history.
484
- """
485
- current_agent = get_current_agent_config()
486
- current_agent.append_to_message_history(message)
487
- # Also update persistent storage
488
- _save_agent_history(current_agent.name, current_agent)
489
-
490
-
491
- def extend_current_agent_message_history(history):
492
- """Extend the currently active agent's message history with multiple messages.
493
-
494
- Args:
495
- history: List of messages to append to the current agent's conversation history.
496
- """
497
- current_agent = get_current_agent_config()
498
- current_agent.extend_message_history(history)
499
- # Also update persistent storage
500
- _save_agent_history(current_agent.name, current_agent)
501
-
502
-
503
- def get_current_agent_compacted_message_hashes():
504
- """Get the set of compacted message hashes for the currently active agent.
505
-
506
- Returns:
507
- Set of hashes for messages that have been compacted/summarized.
508
- """
509
- current_agent = get_current_agent_config()
510
- return current_agent.get_compacted_message_hashes()
511
-
512
-
513
- def add_current_agent_compacted_message_hash(message_hash: str):
514
- """Add a message hash to the current agent's set of compacted message hashes.
515
-
516
- Args:
517
- message_hash: Hash of a message that has been compacted/summarized.
518
- """
519
- current_agent = get_current_agent_config()
520
- current_agent.add_compacted_message_hash(message_hash)
521
- # Also update persistent storage
522
- _save_agent_history(current_agent.name, current_agent)