zwarm 2.0.0__py3-none-any.whl → 2.0.2__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 +19 -10
- zwarm/orchestrator.py +43 -27
- zwarm/tools/delegation.py +5 -2
- {zwarm-2.0.0.dist-info → zwarm-2.0.2.dist-info}/METADATA +2 -2
- {zwarm-2.0.0.dist-info → zwarm-2.0.2.dist-info}/RECORD +7 -7
- {zwarm-2.0.0.dist-info → zwarm-2.0.2.dist-info}/WHEEL +0 -0
- {zwarm-2.0.0.dist-info → zwarm-2.0.2.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)
|
|
@@ -1425,20 +1425,24 @@ def interactive(
|
|
|
1425
1425
|
timeout = 300.0
|
|
1426
1426
|
start = time.time()
|
|
1427
1427
|
while time.time() - start < timeout:
|
|
1428
|
+
# get_session() auto-updates status based on output completion
|
|
1428
1429
|
session = manager.get_session(session.id)
|
|
1429
|
-
if
|
|
1430
|
+
if session.status != SessStatus.RUNNING:
|
|
1430
1431
|
break
|
|
1431
1432
|
time.sleep(1.0)
|
|
1432
1433
|
|
|
1433
|
-
# Get
|
|
1434
|
+
# Get all assistant responses
|
|
1434
1435
|
messages = manager.get_messages(session.id)
|
|
1435
|
-
for
|
|
1436
|
-
|
|
1437
|
-
|
|
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]
|
|
1438
1441
|
if len(msg.content) > 300:
|
|
1439
|
-
|
|
1440
|
-
console.print(
|
|
1441
|
-
|
|
1442
|
+
preview += "..."
|
|
1443
|
+
console.print(preview)
|
|
1444
|
+
if len(assistant_msgs) > 1:
|
|
1445
|
+
console.print() # Blank line between multiple messages
|
|
1442
1446
|
|
|
1443
1447
|
console.print(f"\n[dim]Use 'show {session.short_id}' to see full details[/]")
|
|
1444
1448
|
console.print(f"[dim]Use 'c {session.short_id} \"message\"' to continue[/]")
|
|
@@ -1579,6 +1583,10 @@ def interactive(
|
|
|
1579
1583
|
console.print(f"[dim]Source:[/] {session.source_display} [dim]│[/] [dim]Runtime:[/] {session.runtime}")
|
|
1580
1584
|
if session.pid:
|
|
1581
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}")
|
|
1582
1590
|
console.print()
|
|
1583
1591
|
|
|
1584
1592
|
# Get messages from manager
|
|
@@ -1663,8 +1671,9 @@ def interactive(
|
|
|
1663
1671
|
timeout = 300.0
|
|
1664
1672
|
start = time.time()
|
|
1665
1673
|
while time.time() - start < timeout:
|
|
1674
|
+
# get_session() auto-updates status based on output completion
|
|
1666
1675
|
session = manager.get_session(session.id)
|
|
1667
|
-
if
|
|
1676
|
+
if session.status != SessStatus.RUNNING:
|
|
1668
1677
|
break
|
|
1669
1678
|
time.sleep(1.0)
|
|
1670
1679
|
|
zwarm/orchestrator.py
CHANGED
|
@@ -20,6 +20,8 @@ import weave
|
|
|
20
20
|
from pydantic import Field, PrivateAttr
|
|
21
21
|
from wbal.agents.yaml_agent import YamlAgent
|
|
22
22
|
from wbal.helper import TOOL_CALL_TYPE, format_openai_tool_response
|
|
23
|
+
from wbal.lm import LM as wbalLMGeneric
|
|
24
|
+
from wbal.lm import GPT5LargeVerbose
|
|
23
25
|
|
|
24
26
|
from zwarm.adapters import ExecutorAdapter, get_adapter
|
|
25
27
|
from zwarm.core.compact import compact_messages, should_compact
|
|
@@ -29,9 +31,9 @@ from zwarm.core.models import ConversationSession
|
|
|
29
31
|
from zwarm.core.state import StateManager
|
|
30
32
|
from zwarm.prompts import get_orchestrator_prompt
|
|
31
33
|
from zwarm.watchers import (
|
|
32
|
-
WatcherManager,
|
|
33
|
-
WatcherContext,
|
|
34
34
|
WatcherAction,
|
|
35
|
+
WatcherContext,
|
|
36
|
+
WatcherManager,
|
|
35
37
|
build_watcher_manager,
|
|
36
38
|
)
|
|
37
39
|
|
|
@@ -48,6 +50,9 @@ class Orchestrator(YamlAgent):
|
|
|
48
50
|
- Weave integration
|
|
49
51
|
"""
|
|
50
52
|
|
|
53
|
+
# LM definition override:
|
|
54
|
+
lm: wbalLMGeneric = Field(default_factory=GPT5LargeVerbose)
|
|
55
|
+
|
|
51
56
|
# Configuration
|
|
52
57
|
config: ZwarmConfig = Field(default_factory=ZwarmConfig)
|
|
53
58
|
working_dir: Path = Field(default_factory=Path.cwd)
|
|
@@ -71,11 +76,13 @@ class Orchestrator(YamlAgent):
|
|
|
71
76
|
_watcher_manager: WatcherManager | None = PrivateAttr(default=None)
|
|
72
77
|
_resumed: bool = PrivateAttr(default=False)
|
|
73
78
|
_total_tokens: int = PrivateAttr(default=0) # Cumulative orchestrator tokens
|
|
74
|
-
_executor_usage: dict[str, int] = PrivateAttr(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
_executor_usage: dict[str, int] = PrivateAttr(
|
|
80
|
+
default_factory=lambda: {
|
|
81
|
+
"input_tokens": 0,
|
|
82
|
+
"output_tokens": 0,
|
|
83
|
+
"total_tokens": 0,
|
|
84
|
+
}
|
|
85
|
+
)
|
|
79
86
|
|
|
80
87
|
def model_post_init(self, __context: Any) -> None:
|
|
81
88
|
"""Initialize state and adapters after model creation."""
|
|
@@ -93,6 +100,7 @@ class Orchestrator(YamlAgent):
|
|
|
93
100
|
# Register instance if using instance isolation
|
|
94
101
|
if self.instance_id:
|
|
95
102
|
from zwarm.core.state import register_instance
|
|
103
|
+
|
|
96
104
|
register_instance(
|
|
97
105
|
instance_id=self.instance_id,
|
|
98
106
|
name=self.instance_name,
|
|
@@ -149,7 +157,9 @@ class Orchestrator(YamlAgent):
|
|
|
149
157
|
if not config_path.exists():
|
|
150
158
|
config_path = None # Fallback to adapter defaults
|
|
151
159
|
|
|
152
|
-
self._adapters[name] = get_adapter(
|
|
160
|
+
self._adapters[name] = get_adapter(
|
|
161
|
+
name, model=model, config_path=config_path
|
|
162
|
+
)
|
|
153
163
|
return self._adapters[name]
|
|
154
164
|
|
|
155
165
|
def get_executor_usage(self) -> dict[str, int]:
|
|
@@ -253,15 +263,18 @@ class Orchestrator(YamlAgent):
|
|
|
253
263
|
|
|
254
264
|
# Log compaction event
|
|
255
265
|
from zwarm.core.models import Event
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
"
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
266
|
+
|
|
267
|
+
self._state.log_event(
|
|
268
|
+
Event(
|
|
269
|
+
kind="context_compacted",
|
|
270
|
+
payload={
|
|
271
|
+
"step": self._step_count,
|
|
272
|
+
"original_count": result.original_count,
|
|
273
|
+
"new_count": len(result.messages),
|
|
274
|
+
"removed_count": result.removed_count,
|
|
275
|
+
},
|
|
276
|
+
)
|
|
277
|
+
)
|
|
265
278
|
|
|
266
279
|
return True
|
|
267
280
|
|
|
@@ -377,17 +390,20 @@ Review what was accomplished in the previous session and delegate new tasks as n
|
|
|
377
390
|
|
|
378
391
|
# Log watcher execution to events
|
|
379
392
|
from zwarm.core.models import Event
|
|
393
|
+
|
|
380
394
|
watcher_names = [w.name for w in self.config.watchers.watchers if w.enabled]
|
|
381
|
-
self.state.log_event(
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
395
|
+
self.state.log_event(
|
|
396
|
+
Event(
|
|
397
|
+
kind="watchers_run",
|
|
398
|
+
payload={
|
|
399
|
+
"step": self._step_count,
|
|
400
|
+
"watchers": watcher_names,
|
|
401
|
+
"action": result.action.value,
|
|
402
|
+
"triggered_by": result.metadata.get("triggered_by"),
|
|
403
|
+
"reason": result.metadata.get("reason"),
|
|
404
|
+
},
|
|
405
|
+
)
|
|
406
|
+
)
|
|
391
407
|
|
|
392
408
|
# Handle watcher result
|
|
393
409
|
if result.action == WatcherAction.NUDGE and result.guidance:
|
zwarm/tools/delegation.py
CHANGED
|
@@ -53,14 +53,17 @@ def _wait_for_completion(manager, session_id: str, timeout: float = 300.0, poll_
|
|
|
53
53
|
Returns:
|
|
54
54
|
True if completed, False if timed out
|
|
55
55
|
"""
|
|
56
|
+
from zwarm.sessions import SessionStatus
|
|
57
|
+
|
|
56
58
|
start = time.time()
|
|
57
59
|
while time.time() - start < timeout:
|
|
60
|
+
# get_session() auto-updates status based on output completion markers
|
|
58
61
|
session = manager.get_session(session_id)
|
|
59
62
|
if not session:
|
|
60
63
|
return False
|
|
61
64
|
|
|
62
|
-
# Check
|
|
63
|
-
if
|
|
65
|
+
# Check status (not is_running - PID check is unreliable due to reuse)
|
|
66
|
+
if session.status in (SessionStatus.COMPLETED, SessionStatus.FAILED, SessionStatus.KILLED):
|
|
64
67
|
return True
|
|
65
68
|
|
|
66
69
|
time.sleep(poll_interval)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: zwarm
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: Multi-Agent CLI Orchestration Research Platform
|
|
5
5
|
Requires-Python: <3.14,>=3.13
|
|
6
6
|
Requires-Dist: python-dotenv>=1.0.0
|
|
7
7
|
Requires-Dist: pyyaml>=6.0
|
|
8
8
|
Requires-Dist: rich>=13.0.0
|
|
9
9
|
Requires-Dist: typer>=0.9.0
|
|
10
|
-
Requires-Dist: wbal>=0.
|
|
10
|
+
Requires-Dist: wbal>=0.5.8
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
|
|
13
13
|
# zwarm
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
zwarm/__init__.py,sha256=3i3LMjHwIzE-LFIS2aUrwv3EZmpkvVMe-xj1h97rcSM,837
|
|
2
|
-
zwarm/orchestrator.py,sha256=
|
|
2
|
+
zwarm/orchestrator.py,sha256=IdOd7xNH6IKfvpajh6pOKh2nwTjopS2nQ8GYrj7OsSc,23307
|
|
3
3
|
zwarm/test_orchestrator_watchers.py,sha256=QpoaehPU7ekT4XshbTOWnJ2H0wRveV3QOZjxbgyJJLY,807
|
|
4
4
|
zwarm/adapters/__init__.py,sha256=O0b-SfZpb6txeNqFkXZ2aaf34yLFYreznyrAV25jF_Q,656
|
|
5
5
|
zwarm/adapters/base.py,sha256=fZlQviTgVvOcwnxduTla6WuM6FzQJ_yoHMW5SxwVgQg,2527
|
|
@@ -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
|
|
@@ -24,14 +24,14 @@ zwarm/prompts/orchestrator.py,sha256=-VZ3B5t-2ALOTpdZyNZGSjjzaHiTufAuLzrTLgwg70M
|
|
|
24
24
|
zwarm/sessions/__init__.py,sha256=jRibY8IfmNcnkgNmrgK2T81oa1w71wP_KQp9A1hPL7Q,568
|
|
25
25
|
zwarm/sessions/manager.py,sha256=slCDE0n9-pw6iZ08YZMjxZRwH0aoEi6MAAChLlAsuPw,22212
|
|
26
26
|
zwarm/tools/__init__.py,sha256=FpqxwXJA6-fQ7C-oLj30jjK_0qqcE7MbI0dQuaB56kU,290
|
|
27
|
-
zwarm/tools/delegation.py,sha256=
|
|
27
|
+
zwarm/tools/delegation.py,sha256=2NI9J2VArVUbqOTZJY8Vgz5Rd5nI7BdZ8GNaYVIR_JU,20886
|
|
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.0.
|
|
35
|
-
zwarm-2.0.
|
|
36
|
-
zwarm-2.0.
|
|
37
|
-
zwarm-2.0.
|
|
34
|
+
zwarm-2.0.2.dist-info/METADATA,sha256=1V6Ceu1nSd_HK9mDD2saHTqF3efZ8bV4Ip06X1lHoqw,7680
|
|
35
|
+
zwarm-2.0.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
36
|
+
zwarm-2.0.2.dist-info/entry_points.txt,sha256=u0OXq4q8d3yJ3EkUXwZfkS-Y8Lcy0F8cWrcQfoRxM6Q,46
|
|
37
|
+
zwarm-2.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|