code-puppy 0.0.319__py3-none-any.whl → 0.0.320__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/agents/base_agent.py +26 -70
- {code_puppy-0.0.319.dist-info → code_puppy-0.0.320.dist-info}/METADATA +1 -1
- {code_puppy-0.0.319.dist-info → code_puppy-0.0.320.dist-info}/RECORD +8 -8
- {code_puppy-0.0.319.data → code_puppy-0.0.320.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.319.data → code_puppy-0.0.320.data}/data/code_puppy/models_dev_api.json +0 -0
- {code_puppy-0.0.319.dist-info → code_puppy-0.0.320.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.319.dist-info → code_puppy-0.0.320.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.319.dist-info → code_puppy-0.0.320.dist-info}/licenses/LICENSE +0 -0
code_puppy/agents/base_agent.py
CHANGED
|
@@ -1267,13 +1267,9 @@ class BaseAgent(ABC):
|
|
|
1267
1267
|
ctx: The run context.
|
|
1268
1268
|
events: Async iterable of streaming events (PartStartEvent, PartDeltaEvent, etc.).
|
|
1269
1269
|
"""
|
|
1270
|
-
import os
|
|
1271
|
-
import time as time_module
|
|
1272
|
-
|
|
1273
1270
|
from pydantic_ai import PartDeltaEvent, PartStartEvent
|
|
1274
1271
|
from pydantic_ai.messages import TextPartDelta, ThinkingPartDelta
|
|
1275
1272
|
from rich.console import Console
|
|
1276
|
-
from rich.live import Live
|
|
1277
1273
|
from rich.markdown import Markdown
|
|
1278
1274
|
from rich.markup import escape
|
|
1279
1275
|
|
|
@@ -1288,14 +1284,6 @@ class BaseAgent(ABC):
|
|
|
1288
1284
|
# Fallback if console not set (shouldn't happen in normal use)
|
|
1289
1285
|
console = Console()
|
|
1290
1286
|
|
|
1291
|
-
# Disable Live display in test mode or non-interactive environments
|
|
1292
|
-
# This fixes issues with pexpect PTY where Live() hangs
|
|
1293
|
-
use_live_display = (
|
|
1294
|
-
console.is_terminal
|
|
1295
|
-
and os.environ.get("CODE_PUPPY_TEST_FAST", "").lower() not in ("1", "true")
|
|
1296
|
-
and os.environ.get("CI", "").lower() not in ("1", "true")
|
|
1297
|
-
)
|
|
1298
|
-
|
|
1299
1287
|
# Track which part indices we're currently streaming (for Text/Thinking parts)
|
|
1300
1288
|
streaming_parts: set[int] = set()
|
|
1301
1289
|
thinking_parts: set[int] = (
|
|
@@ -1303,11 +1291,9 @@ class BaseAgent(ABC):
|
|
|
1303
1291
|
) # Track which parts are thinking (for dim style)
|
|
1304
1292
|
text_parts: set[int] = set() # Track which parts are text
|
|
1305
1293
|
banner_printed: set[int] = set() # Track if banner was already printed
|
|
1306
|
-
text_buffer: dict[int, list[str]] = {} # Buffer text for markdown
|
|
1307
|
-
|
|
1294
|
+
text_buffer: dict[int, list[str]] = {} # Buffer text for final markdown render
|
|
1295
|
+
token_count: dict[int, int] = {} # Track token count per text part
|
|
1308
1296
|
did_stream_anything = False # Track if we streamed any content
|
|
1309
|
-
last_render_time: dict[int, float] = {} # Track last render time per part
|
|
1310
|
-
render_interval = 0.1 # Only re-render markdown every 100ms (throttle)
|
|
1311
1297
|
|
|
1312
1298
|
def _print_thinking_banner() -> None:
|
|
1313
1299
|
"""Print the THINKING banner with spinner pause and line clear."""
|
|
@@ -1372,9 +1358,11 @@ class BaseAgent(ABC):
|
|
|
1372
1358
|
streaming_parts.add(event.index)
|
|
1373
1359
|
text_parts.add(event.index)
|
|
1374
1360
|
text_buffer[event.index] = [] # Initialize buffer
|
|
1361
|
+
token_count[event.index] = 0 # Initialize token counter
|
|
1375
1362
|
# Buffer initial content if present
|
|
1376
1363
|
if part.content and part.content.strip():
|
|
1377
1364
|
text_buffer[event.index].append(part.content)
|
|
1365
|
+
token_count[event.index] += 1
|
|
1378
1366
|
|
|
1379
1367
|
# PartDeltaEvent - stream the content as it arrives
|
|
1380
1368
|
elif isinstance(event, PartDeltaEvent):
|
|
@@ -1382,43 +1370,23 @@ class BaseAgent(ABC):
|
|
|
1382
1370
|
delta = event.delta
|
|
1383
1371
|
if isinstance(delta, (TextPartDelta, ThinkingPartDelta)):
|
|
1384
1372
|
if delta.content_delta:
|
|
1385
|
-
# For text parts,
|
|
1373
|
+
# For text parts, show token counter then render at end
|
|
1386
1374
|
if event.index in text_parts:
|
|
1387
|
-
|
|
1375
|
+
import sys
|
|
1376
|
+
|
|
1377
|
+
# Print banner on first content
|
|
1388
1378
|
if event.index not in banner_printed:
|
|
1389
1379
|
_print_response_banner()
|
|
1390
1380
|
banner_printed.add(event.index)
|
|
1391
|
-
|
|
1392
|
-
if use_live_display:
|
|
1393
|
-
live = Live(
|
|
1394
|
-
Markdown(""),
|
|
1395
|
-
console=console,
|
|
1396
|
-
refresh_per_second=10,
|
|
1397
|
-
vertical_overflow="visible", # Allow scrolling for long content
|
|
1398
|
-
)
|
|
1399
|
-
live.start()
|
|
1400
|
-
live_displays[event.index] = live
|
|
1401
|
-
# Accumulate text and throttle markdown rendering
|
|
1402
|
-
# (Markdown parsing is O(n), doing it on every token = O(n²) death)
|
|
1381
|
+
# Accumulate text for final markdown render
|
|
1403
1382
|
text_buffer[event.index].append(delta.content_delta)
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
and now - last_render >= render_interval
|
|
1412
|
-
):
|
|
1413
|
-
content = "".join(text_buffer[event.index])
|
|
1414
|
-
if event.index in live_displays:
|
|
1415
|
-
try:
|
|
1416
|
-
live_displays[event.index].update(
|
|
1417
|
-
Markdown(content)
|
|
1418
|
-
)
|
|
1419
|
-
last_render_time[event.index] = now
|
|
1420
|
-
except Exception:
|
|
1421
|
-
pass
|
|
1383
|
+
token_count[event.index] += 1
|
|
1384
|
+
# Update token counter in place (single line)
|
|
1385
|
+
count = token_count[event.index]
|
|
1386
|
+
sys.stdout.write(
|
|
1387
|
+
f"\r\x1b[K ⏳ Receiving... {count} tokens"
|
|
1388
|
+
)
|
|
1389
|
+
sys.stdout.flush()
|
|
1422
1390
|
else:
|
|
1423
1391
|
# For thinking parts, stream immediately (dim)
|
|
1424
1392
|
if event.index not in banner_printed:
|
|
@@ -1430,36 +1398,24 @@ class BaseAgent(ABC):
|
|
|
1430
1398
|
# PartEndEvent - finish the streaming with a newline
|
|
1431
1399
|
elif isinstance(event, PartEndEvent):
|
|
1432
1400
|
if event.index in streaming_parts:
|
|
1433
|
-
# For text parts,
|
|
1401
|
+
# For text parts, clear counter line and render markdown
|
|
1434
1402
|
if event.index in text_parts:
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
)
|
|
1443
|
-
except Exception:
|
|
1444
|
-
pass
|
|
1445
|
-
if event.index in live_displays:
|
|
1446
|
-
try:
|
|
1447
|
-
live_displays[event.index].stop()
|
|
1448
|
-
except Exception:
|
|
1449
|
-
pass
|
|
1450
|
-
del live_displays[event.index]
|
|
1451
|
-
# When not using Live display, print the final content as markdown
|
|
1452
|
-
elif event.index in text_buffer:
|
|
1403
|
+
import sys
|
|
1404
|
+
|
|
1405
|
+
# Clear the token counter line
|
|
1406
|
+
sys.stdout.write("\r\x1b[K")
|
|
1407
|
+
sys.stdout.flush()
|
|
1408
|
+
# Render the final markdown nicely
|
|
1409
|
+
if event.index in text_buffer:
|
|
1453
1410
|
try:
|
|
1454
1411
|
final_content = "".join(text_buffer[event.index])
|
|
1455
1412
|
if final_content.strip():
|
|
1456
1413
|
console.print(Markdown(final_content))
|
|
1457
1414
|
except Exception:
|
|
1458
1415
|
pass
|
|
1459
|
-
if event.index in text_buffer:
|
|
1460
1416
|
del text_buffer[event.index]
|
|
1461
|
-
# Clean up
|
|
1462
|
-
|
|
1417
|
+
# Clean up token count
|
|
1418
|
+
token_count.pop(event.index, None)
|
|
1463
1419
|
# For thinking parts, just print newline
|
|
1464
1420
|
elif event.index in banner_printed:
|
|
1465
1421
|
console.print() # Final newline after streaming
|
|
@@ -39,7 +39,7 @@ code_puppy/agents/agent_qa_expert.py,sha256=5Ikb4U3SZQknUEfwlHZiyZXKqnffnOTQagr_
|
|
|
39
39
|
code_puppy/agents/agent_qa_kitten.py,sha256=5PeFFSwCFlTUvP6h5bGntx0xv5NmRwBiw0HnMqY8nLI,9107
|
|
40
40
|
code_puppy/agents/agent_security_auditor.py,sha256=SpiYNA0XAsIwBj7S2_EQPRslRUmF_-b89pIJyW7DYtY,12022
|
|
41
41
|
code_puppy/agents/agent_typescript_reviewer.py,sha256=vsnpp98xg6cIoFAEJrRTUM_i4wLEWGm5nJxs6fhHobM,10275
|
|
42
|
-
code_puppy/agents/base_agent.py,sha256=
|
|
42
|
+
code_puppy/agents/base_agent.py,sha256=sT5bNdF2c-SnSdy1pwfZKnv2P-jwB7i67h353UqUN20,77624
|
|
43
43
|
code_puppy/agents/json_agent.py,sha256=lhopDJDoiSGHvD8A6t50hi9ZBoNRKgUywfxd0Po_Dzc,4886
|
|
44
44
|
code_puppy/agents/prompt_reviewer.py,sha256=JJrJ0m5q0Puxl8vFsyhAbY9ftU9n6c6UxEVdNct1E-Q,5558
|
|
45
45
|
code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
|
|
@@ -159,10 +159,10 @@ code_puppy/tools/browser/browser_scripts.py,sha256=sNb8eLEyzhasy5hV4B9OjM8yIVMLV
|
|
|
159
159
|
code_puppy/tools/browser/browser_workflows.py,sha256=nitW42vCf0ieTX1gLabozTugNQ8phtoFzZbiAhw1V90,6491
|
|
160
160
|
code_puppy/tools/browser/camoufox_manager.py,sha256=RZjGOEftE5sI_tsercUyXFSZI2wpStXf-q0PdYh2G3I,8680
|
|
161
161
|
code_puppy/tools/browser/vqa_agent.py,sha256=DBn9HKloILqJSTSdNZzH_PYWT0B2h9VwmY6akFQI_uU,2913
|
|
162
|
-
code_puppy-0.0.
|
|
163
|
-
code_puppy-0.0.
|
|
164
|
-
code_puppy-0.0.
|
|
165
|
-
code_puppy-0.0.
|
|
166
|
-
code_puppy-0.0.
|
|
167
|
-
code_puppy-0.0.
|
|
168
|
-
code_puppy-0.0.
|
|
162
|
+
code_puppy-0.0.320.data/data/code_puppy/models.json,sha256=mTpmJH0UJlmX8M2KVPbxMWb99de3IxKXCWO-B23b6xo,3101
|
|
163
|
+
code_puppy-0.0.320.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
|
|
164
|
+
code_puppy-0.0.320.dist-info/METADATA,sha256=Ah_-U-dxX8DnEHjQ0G8--g_1lDfyI3WMGcjnJOEfiBk,28030
|
|
165
|
+
code_puppy-0.0.320.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
166
|
+
code_puppy-0.0.320.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
|
|
167
|
+
code_puppy-0.0.320.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
|
|
168
|
+
code_puppy-0.0.320.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|