zwarm 2.0.1__py3-none-any.whl → 2.3__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.
- zwarm/cli/main.py +15 -8
- zwarm/sessions/manager.py +13 -1
- zwarm/tools/delegation.py +46 -6
- {zwarm-2.0.1.dist-info → zwarm-2.3.dist-info}/METADATA +1 -1
- {zwarm-2.0.1.dist-info → zwarm-2.3.dist-info}/RECORD +7 -7
- {zwarm-2.0.1.dist-info → zwarm-2.3.dist-info}/WHEEL +0 -0
- {zwarm-2.0.1.dist-info → zwarm-2.3.dist-info}/entry_points.txt +0 -0
zwarm/cli/main.py
CHANGED
|
@@ -1375,7 +1375,7 @@ def interactive(
|
|
|
1375
1375
|
|
|
1376
1376
|
def do_spawn(args: list[str]):
|
|
1377
1377
|
"""Spawn a new coding agent session using CodexSessionManager (same as orchestrator)."""
|
|
1378
|
-
from zwarm.sessions import CodexSessionManager
|
|
1378
|
+
from zwarm.sessions import CodexSessionManager, SessionStatus as SessStatus
|
|
1379
1379
|
import time
|
|
1380
1380
|
|
|
1381
1381
|
parsed = parse_spawn_args(args)
|
|
@@ -1431,15 +1431,18 @@ def interactive(
|
|
|
1431
1431
|
break
|
|
1432
1432
|
time.sleep(1.0)
|
|
1433
1433
|
|
|
1434
|
-
# Get
|
|
1434
|
+
# Get all assistant responses
|
|
1435
1435
|
messages = manager.get_messages(session.id)
|
|
1436
|
-
for
|
|
1437
|
-
|
|
1438
|
-
|
|
1436
|
+
assistant_msgs = [m for m in messages if m.role == "assistant"]
|
|
1437
|
+
if assistant_msgs:
|
|
1438
|
+
console.print(f"\n[bold]Response ({len(assistant_msgs)} message{'s' if len(assistant_msgs) > 1 else ''}):[/]")
|
|
1439
|
+
for msg in assistant_msgs:
|
|
1440
|
+
preview = msg.content[:300]
|
|
1439
1441
|
if len(msg.content) > 300:
|
|
1440
|
-
|
|
1441
|
-
console.print(
|
|
1442
|
-
|
|
1442
|
+
preview += "..."
|
|
1443
|
+
console.print(preview)
|
|
1444
|
+
if len(assistant_msgs) > 1:
|
|
1445
|
+
console.print() # Blank line between multiple messages
|
|
1443
1446
|
|
|
1444
1447
|
console.print(f"\n[dim]Use 'show {session.short_id}' to see full details[/]")
|
|
1445
1448
|
console.print(f"[dim]Use 'c {session.short_id} \"message\"' to continue[/]")
|
|
@@ -1580,6 +1583,10 @@ def interactive(
|
|
|
1580
1583
|
console.print(f"[dim]Source:[/] {session.source_display} [dim]│[/] [dim]Runtime:[/] {session.runtime}")
|
|
1581
1584
|
if session.pid:
|
|
1582
1585
|
console.print(f"[dim]PID:[/] {session.pid}")
|
|
1586
|
+
|
|
1587
|
+
# Show log file path
|
|
1588
|
+
log_path = default_dir / ".zwarm" / "sessions" / session.id / "turns" / f"turn_{session.turn}.jsonl"
|
|
1589
|
+
console.print(f"[dim]Log:[/] {log_path}")
|
|
1583
1590
|
console.print()
|
|
1584
1591
|
|
|
1585
1592
|
# Get messages from manager
|
zwarm/sessions/manager.py
CHANGED
|
@@ -301,9 +301,18 @@ class CodexSessionManager:
|
|
|
301
301
|
session.messages = messages
|
|
302
302
|
session.token_usage = usage
|
|
303
303
|
|
|
304
|
-
if
|
|
304
|
+
# Check if we got actual assistant responses
|
|
305
|
+
has_response = any(m.role == "assistant" for m in messages)
|
|
306
|
+
|
|
307
|
+
if error and not has_response:
|
|
308
|
+
# Only mark as failed if we have an error AND no response
|
|
305
309
|
session.status = SessionStatus.FAILED
|
|
306
310
|
session.error = error
|
|
311
|
+
elif error and has_response:
|
|
312
|
+
# Got response but also an error (e.g., network disconnect at end)
|
|
313
|
+
# Treat as completed but note the error
|
|
314
|
+
session.status = SessionStatus.COMPLETED
|
|
315
|
+
session.error = f"Completed with error: {error}"
|
|
307
316
|
else:
|
|
308
317
|
session.status = SessionStatus.COMPLETED
|
|
309
318
|
else:
|
|
@@ -634,6 +643,9 @@ Continue from where you left off, addressing the user's new message."""
|
|
|
634
643
|
turn_usage = event.get("usage", {})
|
|
635
644
|
for key, value in turn_usage.items():
|
|
636
645
|
usage[key] = usage.get(key, 0) + value
|
|
646
|
+
# Compute total_tokens if not present
|
|
647
|
+
if "total_tokens" not in usage:
|
|
648
|
+
usage["total_tokens"] = usage.get("input_tokens", 0) + usage.get("output_tokens", 0)
|
|
637
649
|
|
|
638
650
|
elif event_type == "error":
|
|
639
651
|
error = event.get("message", str(event))
|
zwarm/tools/delegation.py
CHANGED
|
@@ -83,6 +83,14 @@ def _format_session_header(session) -> str:
|
|
|
83
83
|
return f"[{session.short_id}] codex ({session.status.value})"
|
|
84
84
|
|
|
85
85
|
|
|
86
|
+
def _get_total_tokens(session) -> int:
|
|
87
|
+
"""Get total tokens, computing from input+output if not present."""
|
|
88
|
+
usage = session.token_usage
|
|
89
|
+
if "total_tokens" in usage:
|
|
90
|
+
return usage["total_tokens"]
|
|
91
|
+
return usage.get("input_tokens", 0) + usage.get("output_tokens", 0)
|
|
92
|
+
|
|
93
|
+
|
|
86
94
|
def _validate_working_dir(
|
|
87
95
|
requested_dir: Path | str | None,
|
|
88
96
|
default_dir: Path,
|
|
@@ -238,6 +246,25 @@ def delegate(
|
|
|
238
246
|
response_text = msg.content
|
|
239
247
|
break # Take first assistant message
|
|
240
248
|
|
|
249
|
+
# Build log path for debugging
|
|
250
|
+
log_path = str(manager._output_path(session.id, session.turn))
|
|
251
|
+
|
|
252
|
+
# Check if session failed
|
|
253
|
+
from zwarm.sessions import SessionStatus
|
|
254
|
+
if session.status == SessionStatus.FAILED:
|
|
255
|
+
return {
|
|
256
|
+
"success": False,
|
|
257
|
+
"session": _format_session_header(session),
|
|
258
|
+
"session_id": session.id,
|
|
259
|
+
"status": "failed",
|
|
260
|
+
"task": _truncate(task, 100),
|
|
261
|
+
"error": session.error or "Unknown error",
|
|
262
|
+
"response": response_text or "(no response captured)",
|
|
263
|
+
"tokens": _get_total_tokens(session),
|
|
264
|
+
"log_file": log_path,
|
|
265
|
+
"hint": "Check log_file for raw codex output. Use bash('cat <log_file>') to inspect.",
|
|
266
|
+
}
|
|
267
|
+
|
|
241
268
|
return {
|
|
242
269
|
"success": True,
|
|
243
270
|
"session": _format_session_header(session),
|
|
@@ -245,7 +272,8 @@ def delegate(
|
|
|
245
272
|
"status": session.status.value,
|
|
246
273
|
"task": _truncate(task, 100),
|
|
247
274
|
"response": response_text or "(no response captured)",
|
|
248
|
-
"tokens": session
|
|
275
|
+
"tokens": _get_total_tokens(session),
|
|
276
|
+
"log_file": log_path,
|
|
249
277
|
"hint": "Use converse(session_id, message) to send follow-up messages",
|
|
250
278
|
}
|
|
251
279
|
else:
|
|
@@ -382,7 +410,7 @@ def converse(
|
|
|
382
410
|
"turn": session.turn,
|
|
383
411
|
"you_said": _truncate(message, 100),
|
|
384
412
|
"response": response_text or "(no response captured)",
|
|
385
|
-
"tokens": session
|
|
413
|
+
"tokens": _get_total_tokens(session),
|
|
386
414
|
}
|
|
387
415
|
|
|
388
416
|
|
|
@@ -423,7 +451,10 @@ def check_session(
|
|
|
423
451
|
response_text = msg.content
|
|
424
452
|
break
|
|
425
453
|
|
|
426
|
-
|
|
454
|
+
# Build log path
|
|
455
|
+
log_path = str(manager._output_path(session.id, session.turn))
|
|
456
|
+
|
|
457
|
+
result = {
|
|
427
458
|
"success": True,
|
|
428
459
|
"session": _format_session_header(session),
|
|
429
460
|
"session_id": session_id,
|
|
@@ -433,10 +464,19 @@ def check_session(
|
|
|
433
464
|
"message_count": len(messages),
|
|
434
465
|
"task": _truncate(session.task, 80),
|
|
435
466
|
"response": _truncate(response_text, 500) if response_text else "(no response yet)",
|
|
436
|
-
"tokens": session
|
|
467
|
+
"tokens": _get_total_tokens(session),
|
|
437
468
|
"runtime": session.runtime,
|
|
469
|
+
"log_file": log_path,
|
|
438
470
|
}
|
|
439
471
|
|
|
472
|
+
# Add error info if failed
|
|
473
|
+
from zwarm.sessions import SessionStatus
|
|
474
|
+
if session.status == SessionStatus.FAILED:
|
|
475
|
+
result["success"] = False
|
|
476
|
+
result["error"] = session.error or "Unknown error"
|
|
477
|
+
|
|
478
|
+
return result
|
|
479
|
+
|
|
440
480
|
|
|
441
481
|
@weaveTool
|
|
442
482
|
def peek_session(
|
|
@@ -539,7 +579,7 @@ def end_session(
|
|
|
539
579
|
"status": session.status.value,
|
|
540
580
|
"reason": reason or "ended by orchestrator",
|
|
541
581
|
"turn": session.turn,
|
|
542
|
-
"tokens": session
|
|
582
|
+
"tokens": _get_total_tokens(session),
|
|
543
583
|
}
|
|
544
584
|
|
|
545
585
|
|
|
@@ -646,7 +686,7 @@ def list_sessions(
|
|
|
646
686
|
"updated_secs": int(updated_secs),
|
|
647
687
|
"last_message": _truncate(last_message, 100) if last_message else "(no response yet)",
|
|
648
688
|
"needs_attention": needs_attention,
|
|
649
|
-
"tokens": s
|
|
689
|
+
"tokens": _get_total_tokens(s),
|
|
650
690
|
})
|
|
651
691
|
|
|
652
692
|
# Summary counts
|
|
@@ -9,7 +9,7 @@ zwarm/adapters/registry.py,sha256=EdyHECaNA5Kv1od64pYFBJyA_r_6I1r_eJTNP1XYLr4,17
|
|
|
9
9
|
zwarm/adapters/test_codex_mcp.py,sha256=0qhVzxn_KF-XUS30gXSJKwMdR3kWGsDY9iPk1Ihqn3w,10698
|
|
10
10
|
zwarm/adapters/test_registry.py,sha256=otxcVDONwFCMisyANToF3iy7Y8dSbCL8bTmZNhxNuF4,2383
|
|
11
11
|
zwarm/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
-
zwarm/cli/main.py,sha256=
|
|
12
|
+
zwarm/cli/main.py,sha256=fQT9oP03zsru1_80WfVBdX48kdpLIVfEgS8eJQxRxUM,88668
|
|
13
13
|
zwarm/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
zwarm/core/compact.py,sha256=Y8C7Gs-5-WOU43WRvQ863Qzd5xtuEqR6Aw3r2p8_-i8,10907
|
|
15
15
|
zwarm/core/config.py,sha256=331i4io9uEnloFwUMjTPJ5_lQFKJR1nhTpA4SPfSpiI,11748
|
|
@@ -22,16 +22,16 @@ zwarm/core/test_models.py,sha256=sWTIhMZvuLP5AooGR6y8OR2EyWydqVfhmGrE7NPBBnk,845
|
|
|
22
22
|
zwarm/prompts/__init__.py,sha256=FiaIOniLrIyfD3_osxT6I7FfyKjtctbf8jNs5QTPs_s,213
|
|
23
23
|
zwarm/prompts/orchestrator.py,sha256=-VZ3B5t-2ALOTpdZyNZGSjjzaHiTufAuLzrTLgwg70M,15442
|
|
24
24
|
zwarm/sessions/__init__.py,sha256=jRibY8IfmNcnkgNmrgK2T81oa1w71wP_KQp9A1hPL7Q,568
|
|
25
|
-
zwarm/sessions/manager.py,sha256=
|
|
25
|
+
zwarm/sessions/manager.py,sha256=XDwXXZKJwxgBXOl4Mf61_BCdYoKU7lpJHxE_7Lyzuy4,22946
|
|
26
26
|
zwarm/tools/__init__.py,sha256=FpqxwXJA6-fQ7C-oLj30jjK_0qqcE7MbI0dQuaB56kU,290
|
|
27
|
-
zwarm/tools/delegation.py,sha256=
|
|
27
|
+
zwarm/tools/delegation.py,sha256=FFfZvDnppbbqsTeoYUned6gjqwE9m1gkJ09jSkiiWps,22307
|
|
28
28
|
zwarm/watchers/__init__.py,sha256=yYGTbhuImQLESUdtfrYbHYBJNvCNX3B-Ei-vY5BizX8,760
|
|
29
29
|
zwarm/watchers/base.py,sha256=r1GoPlj06nOT2xp4fghfSjxbRyFFFQUB6HpZbEyO2OY,3834
|
|
30
30
|
zwarm/watchers/builtin.py,sha256=IL5QwwKOIqWEfJ_uQWb321Px4i5OLtI_vnWQMudqKoA,19064
|
|
31
31
|
zwarm/watchers/manager.py,sha256=XZjBVeHjgCUlkTUeHqdvBvHoBC862U1ik0fG6nlRGog,5587
|
|
32
32
|
zwarm/watchers/registry.py,sha256=A9iBIVIFNtO7KPX0kLpUaP8dAK7ozqWLA44ocJGnOw4,1219
|
|
33
33
|
zwarm/watchers/test_watchers.py,sha256=zOsxumBqKfR5ZVGxrNlxz6KcWjkcdp0QhW9WB0_20zM,7855
|
|
34
|
-
zwarm-2.
|
|
35
|
-
zwarm-2.
|
|
36
|
-
zwarm-2.
|
|
37
|
-
zwarm-2.
|
|
34
|
+
zwarm-2.3.dist-info/METADATA,sha256=fBqubqwFUeool8DcYfqk66WQsG42plPI27JLbrTpg3Q,7678
|
|
35
|
+
zwarm-2.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
36
|
+
zwarm-2.3.dist-info/entry_points.txt,sha256=u0OXq4q8d3yJ3EkUXwZfkS-Y8Lcy0F8cWrcQfoRxM6Q,46
|
|
37
|
+
zwarm-2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|