code-puppy 0.0.354__py3-none-any.whl → 0.0.356__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 (38) hide show
  1. code_puppy/agents/__init__.py +2 -0
  2. code_puppy/agents/event_stream_handler.py +74 -1
  3. code_puppy/agents/subagent_stream_handler.py +276 -0
  4. code_puppy/api/__init__.py +13 -0
  5. code_puppy/api/app.py +92 -0
  6. code_puppy/api/main.py +21 -0
  7. code_puppy/api/pty_manager.py +446 -0
  8. code_puppy/api/routers/__init__.py +12 -0
  9. code_puppy/api/routers/agents.py +36 -0
  10. code_puppy/api/routers/commands.py +198 -0
  11. code_puppy/api/routers/config.py +74 -0
  12. code_puppy/api/routers/sessions.py +191 -0
  13. code_puppy/api/templates/terminal.html +361 -0
  14. code_puppy/api/websocket.py +154 -0
  15. code_puppy/callbacks.py +73 -0
  16. code_puppy/command_line/core_commands.py +85 -0
  17. code_puppy/config.py +63 -0
  18. code_puppy/messaging/__init__.py +15 -0
  19. code_puppy/messaging/messages.py +27 -0
  20. code_puppy/messaging/rich_renderer.py +34 -0
  21. code_puppy/messaging/spinner/__init__.py +20 -2
  22. code_puppy/messaging/subagent_console.py +461 -0
  23. code_puppy/plugins/frontend_emitter/__init__.py +25 -0
  24. code_puppy/plugins/frontend_emitter/emitter.py +121 -0
  25. code_puppy/plugins/frontend_emitter/register_callbacks.py +261 -0
  26. code_puppy/status_display.py +6 -2
  27. code_puppy/tools/agent_tools.py +53 -49
  28. code_puppy/tools/command_runner.py +292 -100
  29. code_puppy/tools/common.py +176 -1
  30. code_puppy/tools/display.py +6 -1
  31. code_puppy/tools/subagent_context.py +158 -0
  32. {code_puppy-0.0.354.dist-info → code_puppy-0.0.356.dist-info}/METADATA +4 -3
  33. {code_puppy-0.0.354.dist-info → code_puppy-0.0.356.dist-info}/RECORD +38 -21
  34. {code_puppy-0.0.354.data → code_puppy-0.0.356.data}/data/code_puppy/models.json +0 -0
  35. {code_puppy-0.0.354.data → code_puppy-0.0.356.data}/data/code_puppy/models_dev_api.json +0 -0
  36. {code_puppy-0.0.354.dist-info → code_puppy-0.0.356.dist-info}/WHEEL +0 -0
  37. {code_puppy-0.0.354.dist-info → code_puppy-0.0.356.dist-info}/entry_points.txt +0 -0
  38. {code_puppy-0.0.354.dist-info → code_puppy-0.0.356.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,13 @@
1
+ import asyncio
1
2
  import fnmatch
3
+ import functools
2
4
  import hashlib
5
+ import logging
3
6
  import os
4
7
  import sys
5
8
  import time
6
9
  from pathlib import Path
7
- from typing import Callable, Optional, Tuple
10
+ from typing import Any, Callable, Optional, Tuple
8
11
 
9
12
  from prompt_toolkit import Application
10
13
  from prompt_toolkit.formatted_text import HTML
@@ -1406,3 +1409,175 @@ def generate_group_id(tool_name: str, extra_context: str = "") -> str:
1406
1409
  short_hash = hash_obj.hexdigest()[:8]
1407
1410
 
1408
1411
  return f"{tool_name}_{short_hash}"
1412
+
1413
+
1414
+ # =============================================================================
1415
+ # TOOL CALLBACK WRAPPER
1416
+ # =============================================================================
1417
+
1418
+ logger = logging.getLogger(__name__)
1419
+
1420
+
1421
+ def with_tool_callbacks(tool_name: str) -> Callable:
1422
+ """Decorator that wraps tool functions with pre/post callback hooks.
1423
+
1424
+ This decorator enables plugins to hook into tool execution for:
1425
+ - Logging and analytics
1426
+ - Pre-execution validation or modification
1427
+ - Post-execution result processing
1428
+ - Performance monitoring
1429
+
1430
+ Args:
1431
+ tool_name: The name of the tool being wrapped (e.g., 'edit_file', 'list_files')
1432
+
1433
+ Returns:
1434
+ A decorator function that wraps the tool with callbacks.
1435
+
1436
+ Example:
1437
+ @with_tool_callbacks('my_tool')
1438
+ async def my_tool_impl(ctx, **kwargs):
1439
+ return result
1440
+ """
1441
+
1442
+ def decorator(func: Callable) -> Callable:
1443
+ @functools.wraps(func)
1444
+ async def async_wrapper(*args, **kwargs) -> Any:
1445
+ # Extract context from args if available (usually first arg is RunContext)
1446
+ context = None
1447
+ tool_args = kwargs.copy()
1448
+
1449
+ # Try to get session context
1450
+ try:
1451
+ from code_puppy.messaging import get_session_context
1452
+
1453
+ context = get_session_context()
1454
+ except ImportError:
1455
+ pass
1456
+
1457
+ # Fire pre-tool callback (non-blocking)
1458
+ try:
1459
+ from code_puppy import callbacks
1460
+
1461
+ asyncio.create_task(
1462
+ callbacks.on_pre_tool_call(tool_name, tool_args, context)
1463
+ )
1464
+ except ImportError:
1465
+ logger.debug("callbacks module not available for pre_tool_call")
1466
+ except Exception as e:
1467
+ logger.debug(f"Error in pre_tool_call callback: {e}")
1468
+
1469
+ # Execute the tool and measure duration
1470
+ start_time = time.perf_counter()
1471
+ result = None
1472
+ error = None
1473
+
1474
+ try:
1475
+ result = await func(*args, **kwargs)
1476
+ return result
1477
+ except Exception as e:
1478
+ error = e
1479
+ raise
1480
+ finally:
1481
+ end_time = time.perf_counter()
1482
+ duration_ms = (end_time - start_time) * 1000
1483
+
1484
+ # Fire post-tool callback (non-blocking)
1485
+ final_result = result if error is None else {"error": str(error)}
1486
+ try:
1487
+ from code_puppy import callbacks
1488
+
1489
+ asyncio.create_task(
1490
+ callbacks.on_post_tool_call(
1491
+ tool_name, tool_args, final_result, duration_ms, context
1492
+ )
1493
+ )
1494
+ except ImportError:
1495
+ logger.debug("callbacks module not available for post_tool_call")
1496
+ except Exception as e:
1497
+ logger.debug(f"Error in post_tool_call callback: {e}")
1498
+
1499
+ @functools.wraps(func)
1500
+ def sync_wrapper(*args, **kwargs) -> Any:
1501
+ """Sync wrapper for non-async tool functions."""
1502
+ # Extract context
1503
+ context = None
1504
+ tool_args = kwargs.copy()
1505
+
1506
+ try:
1507
+ from code_puppy.messaging import get_session_context
1508
+
1509
+ context = get_session_context()
1510
+ except ImportError:
1511
+ pass
1512
+
1513
+ # For sync functions, we can't use asyncio.create_task directly
1514
+ # Instead, we'll try to schedule it if there's a running loop
1515
+ def fire_pre_callback():
1516
+ try:
1517
+ from code_puppy import callbacks
1518
+
1519
+ loop = asyncio.get_running_loop()
1520
+ asyncio.run_coroutine_threadsafe(
1521
+ callbacks.on_pre_tool_call(tool_name, tool_args, context),
1522
+ loop,
1523
+ )
1524
+ except RuntimeError:
1525
+ # No running loop - skip async callback
1526
+ pass
1527
+ except ImportError:
1528
+ pass
1529
+ except Exception as e:
1530
+ logger.debug(f"Error in sync pre_tool_call: {e}")
1531
+
1532
+ fire_pre_callback()
1533
+
1534
+ # Execute the tool
1535
+ start_time = time.perf_counter()
1536
+ result = None
1537
+ error = None
1538
+
1539
+ try:
1540
+ result = func(*args, **kwargs)
1541
+ return result
1542
+ except Exception as e:
1543
+ error = e
1544
+ raise
1545
+ finally:
1546
+ end_time = time.perf_counter()
1547
+ duration_ms = (end_time - start_time) * 1000
1548
+
1549
+ # Fire post-tool callback
1550
+ final_result = result if error is None else {"error": str(error)}
1551
+
1552
+ def fire_post_callback():
1553
+ try:
1554
+ from code_puppy import callbacks
1555
+
1556
+ loop = asyncio.get_running_loop()
1557
+ asyncio.run_coroutine_threadsafe(
1558
+ callbacks.on_post_tool_call(
1559
+ tool_name,
1560
+ tool_args,
1561
+ final_result,
1562
+ duration_ms,
1563
+ context,
1564
+ ),
1565
+ loop,
1566
+ )
1567
+ except RuntimeError:
1568
+ # No running loop - skip async callback
1569
+ pass
1570
+ except ImportError:
1571
+ pass
1572
+ except Exception as e:
1573
+ logger.debug(f"Error in sync post_tool_call: {e}")
1574
+
1575
+ fire_post_callback()
1576
+
1577
+ # Return appropriate wrapper based on function type
1578
+ if asyncio.iscoroutinefunction(func):
1579
+ return async_wrapper
1580
+ else:
1581
+ return sync_wrapper
1582
+
1583
+ return decorator
@@ -8,7 +8,8 @@ from typing import Optional
8
8
 
9
9
  from rich.console import Console
10
10
 
11
- from code_puppy.config import get_banner_color
11
+ from code_puppy.config import get_banner_color, get_subagent_verbose
12
+ from code_puppy.tools.subagent_context import is_subagent
12
13
 
13
14
 
14
15
  def display_non_streamed_result(
@@ -33,6 +34,10 @@ def display_non_streamed_result(
33
34
  >>> display_non_streamed_result("# Hello\n\nThis is **bold** text.")
34
35
  # Renders with AGENT RESPONSE banner and formatted markdown
35
36
  """
37
+ # Skip display for sub-agents unless verbose mode
38
+ if is_subagent() and not get_subagent_verbose():
39
+ return
40
+
36
41
  import time
37
42
 
38
43
  from rich.text import Text
@@ -0,0 +1,158 @@
1
+ """Sub-agent context management with async-safe state tracking.
2
+
3
+ This module provides context-aware tracking of sub-agent execution state using
4
+ Python's contextvars for async-safe isolation. This ensures that sub-agent state
5
+ is properly isolated across different async tasks and execution contexts.
6
+
7
+ ## Why ContextVars?
8
+
9
+ ContextVars provide automatic context isolation in async environments:
10
+ - Each async task gets its own copy of the context
11
+ - State changes in one task don't affect others
12
+ - Perfect for tracking execution depth in nested agent calls
13
+ - Token-based reset ensures proper cleanup even with exceptions
14
+
15
+ ## Usage Example:
16
+
17
+ ```python
18
+ from code_puppy.tools.subagent_context import subagent_context, is_subagent
19
+
20
+ # Main agent
21
+ print(is_subagent()) # False
22
+
23
+ async def run_subagent():
24
+ with subagent_context("retriever"):
25
+ print(is_subagent()) # True
26
+ print(get_subagent_name()) # "retriever"
27
+ print(get_subagent_depth()) # 1
28
+
29
+ # Nested sub-agent
30
+ with subagent_context("terrier"):
31
+ print(get_subagent_depth()) # 2
32
+ print(get_subagent_name()) # "terrier"
33
+
34
+ # Back to parent sub-agent
35
+ print(get_subagent_name()) # "retriever"
36
+ print(get_subagent_depth()) # 1
37
+
38
+ # After context exits
39
+ print(is_subagent()) # False
40
+ ```
41
+
42
+ ## Benefits:
43
+
44
+ 1. **Async Safety**: Multiple sub-agents can run concurrently without interference
45
+ 2. **Nested Support**: Properly handles sub-agents calling other sub-agents
46
+ 3. **Clean Restoration**: Token-based reset ensures state is restored even on errors
47
+ 4. **Zero Overhead**: When not in a sub-agent context, minimal performance impact
48
+ """
49
+
50
+ from contextlib import contextmanager
51
+ from contextvars import ContextVar
52
+ from typing import Generator
53
+
54
+ __all__ = [
55
+ "subagent_context",
56
+ "is_subagent",
57
+ "get_subagent_name",
58
+ "get_subagent_depth",
59
+ ]
60
+
61
+ # Track sub-agent depth (0 = main agent, 1+ = sub-agent)
62
+ _subagent_depth: ContextVar[int] = ContextVar("subagent_depth", default=0)
63
+
64
+ # Track current sub-agent name (None = main agent)
65
+ _subagent_name: ContextVar[str | None] = ContextVar("subagent_name", default=None)
66
+
67
+
68
+ @contextmanager
69
+ def subagent_context(agent_name: str) -> Generator[None, None, None]:
70
+ """Context manager for tracking sub-agent execution.
71
+
72
+ Increments the sub-agent depth and sets the current agent name on entry,
73
+ then restores the previous state on exit. Uses token-based reset for
74
+ proper async isolation and exception safety.
75
+
76
+ Args:
77
+ agent_name: Name of the sub-agent being executed (e.g., "retriever", "husky")
78
+
79
+ Yields:
80
+ None
81
+
82
+ Example:
83
+ >>> with subagent_context("retriever"):
84
+ ... assert is_subagent() is True
85
+ ... assert get_subagent_name() == "retriever"
86
+ >>> assert is_subagent() is False
87
+
88
+ Note:
89
+ Token-based reset ensures that even if an exception occurs, the context
90
+ is properly restored. This is especially important in async environments
91
+ where multiple tasks may be running concurrently.
92
+ """
93
+ # Get current depth for incrementing
94
+ current_depth = _subagent_depth.get()
95
+
96
+ # Set new values and save tokens for restoration
97
+ depth_token = _subagent_depth.set(current_depth + 1)
98
+ name_token = _subagent_name.set(agent_name)
99
+
100
+ try:
101
+ yield
102
+ finally:
103
+ # Use token-based reset for proper async isolation
104
+ # This ensures the context is restored even if an exception occurs
105
+ _subagent_depth.reset(depth_token)
106
+ _subagent_name.reset(name_token)
107
+
108
+
109
+ def is_subagent() -> bool:
110
+ """Check if currently executing within a sub-agent context.
111
+
112
+ Returns:
113
+ True if depth > 0 (inside a sub-agent), False otherwise (main agent)
114
+
115
+ Example:
116
+ >>> is_subagent()
117
+ False
118
+ >>> with subagent_context("retriever"):
119
+ ... is_subagent()
120
+ True
121
+ """
122
+ return _subagent_depth.get() > 0
123
+
124
+
125
+ def get_subagent_name() -> str | None:
126
+ """Get the name of the current sub-agent.
127
+
128
+ Returns:
129
+ Current sub-agent name, or None if in main agent context
130
+
131
+ Example:
132
+ >>> get_subagent_name()
133
+ None
134
+ >>> with subagent_context("husky"):
135
+ ... get_subagent_name()
136
+ 'husky'
137
+ """
138
+ return _subagent_name.get()
139
+
140
+
141
+ def get_subagent_depth() -> int:
142
+ """Get the current sub-agent nesting depth.
143
+
144
+ Returns:
145
+ Current depth level (0 = main agent, 1 = first-level sub-agent,
146
+ 2 = nested sub-agent, etc.)
147
+
148
+ Example:
149
+ >>> get_subagent_depth()
150
+ 0
151
+ >>> with subagent_context("retriever"):
152
+ ... get_subagent_depth()
153
+ 1
154
+ ... with subagent_context("terrier"):
155
+ ... get_subagent_depth()
156
+ 2
157
+ """
158
+ return _subagent_depth.get()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.354
3
+ Version: 0.0.356
4
4
  Summary: Code generation agent
5
5
  Project-URL: repository, https://github.com/mpfaffenberger/code_puppy
6
6
  Project-URL: HomePage, https://github.com/mpfaffenberger/code_puppy
@@ -17,7 +17,7 @@ Classifier: Topic :: Software Development :: Code Generators
17
17
  Requires-Python: <3.14,>=3.11
18
18
  Requires-Dist: camoufox>=0.4.11
19
19
  Requires-Dist: dbos>=2.5.0
20
- Requires-Dist: fastapi>=0.111.0
20
+ Requires-Dist: fastapi>=0.109.0
21
21
  Requires-Dist: httpx[http2]>=0.24.1
22
22
  Requires-Dist: json-repair>=0.46.2
23
23
  Requires-Dist: logfire>=0.7.1
@@ -36,7 +36,8 @@ Requires-Dist: ripgrep==14.1.0
36
36
  Requires-Dist: ruff>=0.11.11
37
37
  Requires-Dist: tenacity>=8.2.0
38
38
  Requires-Dist: termflow-md>=0.1.8
39
- Requires-Dist: uvicorn>=0.30.0
39
+ Requires-Dist: uvicorn[standard]>=0.27.0
40
+ Requires-Dist: websockets>=12.0
40
41
  Description-Content-Type: text/markdown
41
42
 
42
43
  <div align="center">
@@ -1,10 +1,10 @@
1
1
  code_puppy/__init__.py,sha256=xMPewo9RNHb3yfFNIk5WCbv2cvSPtJOCgK2-GqLbNnU,373
2
2
  code_puppy/__main__.py,sha256=pDVssJOWP8A83iFkxMLY9YteHYat0EyWDQqMkKHpWp4,203
3
- code_puppy/callbacks.py,sha256=hqTV--dNxG5vwWWm3MrEjmb8MZuHFFdmHePl23NXPHk,8621
3
+ code_puppy/callbacks.py,sha256=Pp0VyeXJBEtk-N_RSWr5pbveelovsdLUiJ4f11dzwGw,10775
4
4
  code_puppy/chatgpt_codex_client.py,sha256=Om0ANB_kpHubhCwNzF9ENf8RvKBqs0IYzBLl_SNw0Vk,9833
5
5
  code_puppy/claude_cache_client.py,sha256=Gl6um5ZaKpcnxOvoFSM8Lwm_Vu4-VyWz8Nli8DnRLa4,22508
6
6
  code_puppy/cli_runner.py,sha256=w5CLKgQYYaT7My3Cga2StXYol-u6DBxNzzUuhhsfhsA,34952
7
- code_puppy/config.py,sha256=RlnrLkyFXm7h2Htf8rQA7vqoAyzLPMrESle417uLmFw,52373
7
+ code_puppy/config.py,sha256=1bga5PP_usHkxRx2Vqaz_s820YhADo9K8R5pcaE9O90,54338
8
8
  code_puppy/error_logging.py,sha256=a80OILCUtJhexI6a9GM-r5LqIdjvSRzggfgPp2jv1X0,3297
9
9
  code_puppy/gemini_code_assist.py,sha256=KGS7sO5OLc83nDF3xxS-QiU6vxW9vcm6hmzilu79Ef8,13867
10
10
  code_puppy/http_utils.py,sha256=H3N5Qz2B1CcsGUYOycGWAqoNMr2P1NCVluKX3aRwRqI,10358
@@ -19,12 +19,12 @@ code_puppy/pydantic_patches.py,sha256=YecAEeCOjSIwIBu2O5vEw72atMSL37cXGrbEuukI07
19
19
  code_puppy/reopenable_async_client.py,sha256=pD34chyBFcC7_OVPJ8fp6aRI5jYdN-7VDycObMZPwG8,8292
20
20
  code_puppy/round_robin_model.py,sha256=kSawwPUiPgg0yg8r4AAVgvjzsWkptxpSORd75-HP7W4,5335
21
21
  code_puppy/session_storage.py,sha256=T4hOsAl9z0yz2JZCptjJBOnN8fCmkLZx5eLy1hTdv6Q,9631
22
- code_puppy/status_display.py,sha256=qHzIQGAPEa2_-4gQSg7_rE1ihOosBq8WO73MWFNmmlo,8938
22
+ code_puppy/status_display.py,sha256=r2jlosF4VNn9CUYJNcsroRQPModh9ZQNsleDwMby1Z4,9158
23
23
  code_puppy/summarization_agent.py,sha256=6Pu_Wp_rF-HAhoX9u2uXTabRVkOZUYwRoMP1lzNS4ew,4485
24
24
  code_puppy/terminal_utils.py,sha256=TaS19x7EZqudlBUAQwLMzBMNxBHBNInvQQREXqRGtkM,12984
25
25
  code_puppy/uvx_detection.py,sha256=tP9X9Nvzow--KIqtqjgrHQkSxMJ3EevfoaeoB9VLY2o,7224
26
26
  code_puppy/version_checker.py,sha256=aq2Mwxl1CR9sEFBgrPt3OQOowLOBUp9VaQYWJhuUv8Q,1780
27
- code_puppy/agents/__init__.py,sha256=PtPB7Z5MSwmUKipgt_qxvIuGggcuVaYwNbnp1UP4tPc,518
27
+ code_puppy/agents/__init__.py,sha256=9giVbeBb8YAc51PC9EhR0h15NGwbzKLB3HECCK5iaKo,610
28
28
  code_puppy/agents/agent_c_reviewer.py,sha256=1kO_89hcrhlS4sJ6elDLSEx-h43jAaWGgvIL0SZUuKo,8214
29
29
  code_puppy/agents/agent_code_puppy.py,sha256=-u9VkqoE_GuB8zae9OeFMv64qt94cFs-_tzK2stIk5A,8406
30
30
  code_puppy/agents/agent_code_reviewer.py,sha256=V9pznpi7z1XTYBjRj1Em8S71PbFXLvU8z0gCmPAQxSc,4635
@@ -42,9 +42,10 @@ code_puppy/agents/agent_qa_kitten.py,sha256=5PeFFSwCFlTUvP6h5bGntx0xv5NmRwBiw0Hn
42
42
  code_puppy/agents/agent_security_auditor.py,sha256=SpiYNA0XAsIwBj7S2_EQPRslRUmF_-b89pIJyW7DYtY,12022
43
43
  code_puppy/agents/agent_typescript_reviewer.py,sha256=vsnpp98xg6cIoFAEJrRTUM_i4wLEWGm5nJxs6fhHobM,10275
44
44
  code_puppy/agents/base_agent.py,sha256=oKlX9CEIWSvdXyQDVi9F1jauA6rjKleY_n6044Ux5DY,73840
45
- code_puppy/agents/event_stream_handler.py,sha256=C1TDkp9eTHEFvnTQzaGFh_q9izL1r-EnCRTez9kqO2Y,11438
45
+ code_puppy/agents/event_stream_handler.py,sha256=HM62_THZpMVnqKIB6Vbo6IwmJt6Kjoc3YbyRy2FclA4,13805
46
46
  code_puppy/agents/json_agent.py,sha256=lhopDJDoiSGHvD8A6t50hi9ZBoNRKgUywfxd0Po_Dzc,4886
47
47
  code_puppy/agents/prompt_reviewer.py,sha256=JJrJ0m5q0Puxl8vFsyhAbY9ftU9n6c6UxEVdNct1E-Q,5558
48
+ code_puppy/agents/subagent_stream_handler.py,sha256=5imUFYOJCv7blfv4fTHm6OQ7JpqlyFv_luBYGSj16MA,10329
48
49
  code_puppy/agents/pack/__init__.py,sha256=evYSWr_t1B0v88DuCkTFdcGNZ0MANK_XiVRfXTbbHd4,1214
49
50
  code_puppy/agents/pack/bloodhound.py,sha256=bfYSvggVNWJKxDhZT_wIWDKGM5StIvbqeFe_xP-N1JU,9407
50
51
  code_puppy/agents/pack/husky.py,sha256=xSmHhIoiQ4rVrs3od36hnEIH5jnd_j72R9PY2gIjaTQ,9455
@@ -52,6 +53,17 @@ code_puppy/agents/pack/retriever.py,sha256=kz9sqnKMtJT3xoeplVdXFs_2YdHuW5JkB-vMD
52
53
  code_puppy/agents/pack/shepherd.py,sha256=gSsPAj7MV_AaiSUWNNoFLW0C932ToctJl2X9ySZN8CM,9878
53
54
  code_puppy/agents/pack/terrier.py,sha256=bw0f5g0fmIMVsVZsBYwDrIUwMhldg1U7tzGk1EHhgK0,7935
54
55
  code_puppy/agents/pack/watchdog.py,sha256=xgiyrGgMdf8CNJoZ0bPqZ_oZBc6cu6It8d_jeNONiy4,10039
56
+ code_puppy/api/__init__.py,sha256=q0VZ5PgiCjEL2xWPVsElwAffDscJ6JtbbIhYFmw3TA4,357
57
+ code_puppy/api/app.py,sha256=4imfbatGX0h2rIUfo4vP2H4XLOvutM0D_EJMd_dQAf8,2868
58
+ code_puppy/api/main.py,sha256=ycWD5_aWwdOQ2GPnqsQC-BjINNx_Qie6xFyjr9gYofI,453
59
+ code_puppy/api/pty_manager.py,sha256=P-SB9yuMlrwfgedV6VkzWDtGBMKAxnqV-RysQubhrS8,13714
60
+ code_puppy/api/websocket.py,sha256=j_96B2k2XQ-KGsNqGZqTjUeUH8NkDGfgSs32Bj4C634,5360
61
+ code_puppy/api/routers/__init__.py,sha256=-ifjlIm_yeFQ27vIC6OzeQFJZjnUF1e6xbFK1aNG798,430
62
+ code_puppy/api/routers/agents.py,sha256=Lshn89lIBi49if6GoJDBZQ2_8l7JfgAUy4gvYXlfmws,939
63
+ code_puppy/api/routers/commands.py,sha256=kl3ouYIg6DRWgPIDmDnN6RXJzyeQqUrh8cm1jR_eG1M,5821
64
+ code_puppy/api/routers/config.py,sha256=uDUFYZqki0fQd0U5EHpfTgqlZaRFfmhPyWrIHXNBX3A,2005
65
+ code_puppy/api/routers/sessions.py,sha256=KeTKXLj0BjPMvnSU91LmNgc0coQ7QdRRn8puqdvknsc,5346
66
+ code_puppy/api/templates/terminal.html,sha256=9alh6tTbLyXPDjBvkXw8nEWPXB-m_LIceGGRYpSLuyo,13125
55
67
  code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
56
68
  code_puppy/command_line/add_model_menu.py,sha256=CpURhxPvUhLHLBV_uwH1ODfJ-WAcGklvlsjEf5Vfvg4,43255
57
69
  code_puppy/command_line/attachments.py,sha256=4Q5I2Es4j0ltnz5wjw2z0QXMsiMJvEfWRkPf_lJeITM,13093
@@ -61,7 +73,7 @@ code_puppy/command_line/colors_menu.py,sha256=LoFVfJ-Mo-Eq9hnb2Rj5mn7oBCnadAGr-8
61
73
  code_puppy/command_line/command_handler.py,sha256=CY9F27eovZJK_kpU1YmbroYLWGTCuouCOQ-TXfDp-nw,10916
62
74
  code_puppy/command_line/command_registry.py,sha256=qFySsw1g8dol3kgi0p6cXrIDlP11_OhOoaQ5nAadWXg,4416
63
75
  code_puppy/command_line/config_commands.py,sha256=qS9Cm758DPz2QGvHLhAV4Tp_Xfgo3PyoCoLDusbnmCw,25742
64
- code_puppy/command_line/core_commands.py,sha256=ujAPD4yDbXwYGJJfR2u4ei24eBV-Ps_-BVBjFMEoJy0,27668
76
+ code_puppy/command_line/core_commands.py,sha256=q5yi_xjPSoCjX8ET4PnMVsZlGwJ2PlEXVnao_7_1rJk,30619
65
77
  code_puppy/command_line/diff_menu.py,sha256=_Gr9SP9fbItk-08dya9WTAR53s_PlyAvEnbt-8VWKPk,24141
66
78
  code_puppy/command_line/file_path_completion.py,sha256=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
67
79
  code_puppy/command_line/load_context_completion.py,sha256=a3JvLDeLLSYxVgTjAdqWzS4spjv6ccCrK2LKZgVJ1IM,2202
@@ -116,16 +128,17 @@ code_puppy/mcp_/server_registry_catalog.py,sha256=fr_wsr99BphnaDiPLcN60t4Mp62lbt
116
128
  code_puppy/mcp_/status_tracker.py,sha256=uekxrzkzIWrv3OfSVgblaPuoGFcAh_dBYwCcaHZ_CrM,12183
117
129
  code_puppy/mcp_/system_tools.py,sha256=7_oR8k0c8YjtCcYF9g7A946oAGuKOf_i-92aJH7VmlQ,7331
118
130
  code_puppy/mcp_/examples/retry_example.py,sha256=Qi5K6cNmhc5-zncZa0F_dkJUEdZ6OIgt1xfG5PUxt3Q,7234
119
- code_puppy/messaging/__init__.py,sha256=THJQDdRub3jiWIRPqF34VggXem3Y2tuUFAJGdDALgzw,6444
131
+ code_puppy/messaging/__init__.py,sha256=PmQWdm0f9RBv8I7Km3qU_OCUiBqxHIDenN9DKELzQCE,6832
120
132
  code_puppy/messaging/bus.py,sha256=TbdltJ0D5tqnaE4irq1fcXllDYm-mQ_SiX1IFm-S4sw,21406
121
133
  code_puppy/messaging/commands.py,sha256=77CtKVNaF5KS3Xyzd0ccDAisZWQxL3weVEt3J-SfYxo,5464
122
134
  code_puppy/messaging/markdown_patches.py,sha256=dMIJozzJChuHa8QNMSEz_kC-dyt7kZiDLZ7rjthbcmg,1626
123
135
  code_puppy/messaging/message_queue.py,sha256=1-5NFWIes5kpecsKnhuQQJPeT0-X102Xi1-IwXUM5_Y,11430
124
- code_puppy/messaging/messages.py,sha256=F7RwMHeQrIk-8kuSSBU76wBq1NGuLb2H5cJrSMTC3XM,16464
136
+ code_puppy/messaging/messages.py,sha256=wiDnsuFe9P-dWrzfeBwD2_zEdbDKTInCAK7rFMnex9I,17614
125
137
  code_puppy/messaging/queue_console.py,sha256=Xp-rFEpaOtMi-qHvgCi9QTNvTiNgaZ9qXubddOOmImE,9983
126
138
  code_puppy/messaging/renderers.py,sha256=GHVtMnxE1pJ-yrcRjacY81JcjlHRz3UVHzp-ohN-CGE,12058
127
- code_puppy/messaging/rich_renderer.py,sha256=5AklkFrmRqIvBi8DMgowC1iYaQTW7dU4JBwUHSeG6wM,37955
128
- code_puppy/messaging/spinner/__init__.py,sha256=KpK5tJqq9YnN3wklqvdH0BQmuwYnT83Mp4tPfQa9RqI,1664
139
+ code_puppy/messaging/rich_renderer.py,sha256=EkncFhKzoKTaFcTK23KcJ4VOiaMunILYg643lT_wlng,39114
140
+ code_puppy/messaging/subagent_console.py,sha256=HkqYPxYly24Gr1c0m8fa-RsUFA4JJpVCyA7oM0MNdv0,15976
141
+ code_puppy/messaging/spinner/__init__.py,sha256=eR221vdrDT7CtY3O7cLvIcPViazjNdpX0Oyqa3xpPSQ,2304
129
142
  code_puppy/messaging/spinner/console_spinner.py,sha256=YIReuWPD01YPy58FqWdMDWj2QhauTUxKo675Ub4-eDA,8451
130
143
  code_puppy/messaging/spinner/spinner_base.py,sha256=JiQDAhCfwrWUFunb8Xcj1caEl34JJY7Bcio7mDeckSc,2694
131
144
  code_puppy/plugins/__init__.py,sha256=gWgrXWoFpl-3Mxz2DAvxKW6SkCWrOnw-hKsY9O7nHcI,6710
@@ -161,6 +174,9 @@ code_puppy/plugins/example_custom_command/README.md,sha256=5c5Zkm7CW6BDSfe3WoLU7
161
174
  code_puppy/plugins/example_custom_command/register_callbacks.py,sha256=1vkch42NISx1BiWivcT7Va8fRV2evTOS8zFtRWS18us,1658
162
175
  code_puppy/plugins/file_permission_handler/__init__.py,sha256=yuR7qt2pTQ-E2DLf4aIy16cAiuaTKX6x1Zixs54PZFo,144
163
176
  code_puppy/plugins/file_permission_handler/register_callbacks.py,sha256=QlUqENkbN8e6lv1hjFixNPANwyQ1o2fQQkzerEXar94,17968
177
+ code_puppy/plugins/frontend_emitter/__init__.py,sha256=4_o6anYxDpJGvKyMomRy4FfLXZx6VOLnX0PcZIL-fws,661
178
+ code_puppy/plugins/frontend_emitter/emitter.py,sha256=GNcnoKLPAjrD_see82nuRutZEHxXwb2aUEKR4K8TJvQ,3787
179
+ code_puppy/plugins/frontend_emitter/register_callbacks.py,sha256=3j7Emn3VeWSJSN9ozZ_Z78ZU8JvN7yfJNQ4bSH2KGdE,7704
164
180
  code_puppy/plugins/shell_safety/__init__.py,sha256=B-RYLWKlvrws9XCHG1Z99mBMC3VC394HAlMOhhCoGGI,243
165
181
  code_puppy/plugins/shell_safety/agent_shell_safety.py,sha256=5JutYlzzTzyFcbFujlNkV4NunVvD5QIpOSumjS3Fjc8,2408
166
182
  code_puppy/plugins/shell_safety/command_cache.py,sha256=adYtSPNVOZfW_6dQdtEihO6E-JYXYrdvlS1Cl7xBkDU,4546
@@ -168,12 +184,13 @@ code_puppy/plugins/shell_safety/register_callbacks.py,sha256=W3v664RR48Fdbbbltf_
168
184
  code_puppy/prompts/antigravity_system_prompt.md,sha256=ZaTfRyY57ttROyZMmOBtqZQu1to7sdTNTv8_0fTgPNw,6807
169
185
  code_puppy/prompts/codex_system_prompt.md,sha256=hEFTCziroLqZmqNle5kG34A8kvTteOWezCiVrAEKhE0,24400
170
186
  code_puppy/tools/__init__.py,sha256=eQY-GL2ToV9IdRKlrnWlcPLyncJyU1VGZxq9yy0twNI,6137
171
- code_puppy/tools/agent_tools.py,sha256=UVLK4nHyNZGPZ28Hfv3PKRx_2qcCnncxS_e0BKwPyz0,24213
172
- code_puppy/tools/command_runner.py,sha256=3qXVnVTaBPia6y2D29As47_TRKgpyCj82yMFK-8UUYc,44954
173
- code_puppy/tools/common.py,sha256=IYf-KOcP5eN2MwTlpULSXNATn7GzloAKl7_M1Uyfe4Y,40360
174
- code_puppy/tools/display.py,sha256=T2bIyb233eds0q8C1jZRl6NjwERrLgT_APhEz9drN1w,2472
187
+ code_puppy/tools/agent_tools.py,sha256=z9Uj65aqIZ4etyq6mtH05DQEbA6dWSWAN-wH8RSmdXg,24476
188
+ code_puppy/tools/command_runner.py,sha256=OLwPUNicgiHfQj6Ux4SaVNYmX425VbMjrv-DsxZ9e_M,50996
189
+ code_puppy/tools/common.py,sha256=lVtF94cn6jtC5YKfitV7L3rk37Ts2gMoHLQrqDFD2E4,46411
190
+ code_puppy/tools/display.py,sha256=-ulDyq55178f8O_TAEmnxGoy_ZdFkbHBw-W4ul851GM,2675
175
191
  code_puppy/tools/file_modifications.py,sha256=vz9n7R0AGDSdLUArZr_55yJLkyI30M8zreAppxIx02M,29380
176
192
  code_puppy/tools/file_operations.py,sha256=CqhpuBnOFOcQCIYXOujskxq2VMLWYJhibYrH0YcPSfA,35692
193
+ code_puppy/tools/subagent_context.py,sha256=zsiKV3B3DxZ_Y5IHHhtE-SMFDg_jMrY7Hi6r5LH--IU,4781
177
194
  code_puppy/tools/tools_content.py,sha256=bsBqW-ppd1XNAS_g50B3UHDQBWEALC1UneH6-afz1zo,2365
178
195
  code_puppy/tools/browser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
179
196
  code_puppy/tools/browser/browser_control.py,sha256=MWBv_WR_A6wmm1NJCYFGQGRyYhTLplL4J0_ECZD0IhE,8388
@@ -185,10 +202,10 @@ code_puppy/tools/browser/browser_scripts.py,sha256=sNb8eLEyzhasy5hV4B9OjM8yIVMLV
185
202
  code_puppy/tools/browser/browser_workflows.py,sha256=nitW42vCf0ieTX1gLabozTugNQ8phtoFzZbiAhw1V90,6491
186
203
  code_puppy/tools/browser/camoufox_manager.py,sha256=RZjGOEftE5sI_tsercUyXFSZI2wpStXf-q0PdYh2G3I,8680
187
204
  code_puppy/tools/browser/vqa_agent.py,sha256=BZzpwPinMH-dsOBMvPVYJzDZ6fu3TlIARygcwIva9w4,2917
188
- code_puppy-0.0.354.data/data/code_puppy/models.json,sha256=FMQdE_yvP_8y0xxt3K918UkFL9cZMYAqW1SfXcQkU_k,3105
189
- code_puppy-0.0.354.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
190
- code_puppy-0.0.354.dist-info/METADATA,sha256=p2WJw8VTb0XF99Yzto2WQOaY-6SMeBheTmw8AYIlL8g,27572
191
- code_puppy-0.0.354.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
192
- code_puppy-0.0.354.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
193
- code_puppy-0.0.354.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
194
- code_puppy-0.0.354.dist-info/RECORD,,
205
+ code_puppy-0.0.356.data/data/code_puppy/models.json,sha256=FMQdE_yvP_8y0xxt3K918UkFL9cZMYAqW1SfXcQkU_k,3105
206
+ code_puppy-0.0.356.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
207
+ code_puppy-0.0.356.dist-info/METADATA,sha256=Yda4z2GGJVpp8rZTMmj5XNsqnQSMRaSrNV-_x1fNgKU,27614
208
+ code_puppy-0.0.356.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
209
+ code_puppy-0.0.356.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
210
+ code_puppy-0.0.356.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
211
+ code_puppy-0.0.356.dist-info/RECORD,,