zwarm 2.0.0__tar.gz → 2.0.1__tar.gz
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-2.0.0 → zwarm-2.0.1}/PKG-INFO +2 -2
- {zwarm-2.0.0 → zwarm-2.0.1}/pyproject.toml +2 -2
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/cli/main.py +4 -2
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/orchestrator.py +43 -27
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/tools/delegation.py +5 -2
- {zwarm-2.0.0 → zwarm-2.0.1}/.gitignore +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/README.md +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/__init__.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/adapters/__init__.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/adapters/base.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/adapters/claude_code.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/adapters/codex_mcp.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/adapters/registry.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/adapters/test_codex_mcp.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/adapters/test_registry.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/cli/__init__.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/core/__init__.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/core/compact.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/core/config.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/core/environment.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/core/models.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/core/state.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/core/test_compact.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/core/test_config.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/core/test_models.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/prompts/__init__.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/prompts/orchestrator.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/sessions/__init__.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/sessions/manager.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/test_orchestrator_watchers.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/tools/__init__.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/watchers/__init__.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/watchers/base.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/watchers/builtin.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/watchers/manager.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/watchers/registry.py +0 -0
- {zwarm-2.0.0 → zwarm-2.0.1}/src/zwarm/watchers/test_watchers.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: zwarm
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
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,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "zwarm"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.1"
|
|
4
4
|
description = "Multi-Agent CLI Orchestration Research Platform"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13,<3.14"
|
|
@@ -9,7 +9,7 @@ dependencies = [
|
|
|
9
9
|
"rich>=13.0.0",
|
|
10
10
|
"python-dotenv>=1.0.0",
|
|
11
11
|
"pyyaml>=6.0",
|
|
12
|
-
"wbal>=0.
|
|
12
|
+
"wbal>=0.5.8",
|
|
13
13
|
]
|
|
14
14
|
|
|
15
15
|
[project.scripts]
|
|
@@ -1425,8 +1425,9 @@ 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
|
|
|
@@ -1663,8 +1664,9 @@ def interactive(
|
|
|
1663
1664
|
timeout = 300.0
|
|
1664
1665
|
start = time.time()
|
|
1665
1666
|
while time.time() - start < timeout:
|
|
1667
|
+
# get_session() auto-updates status based on output completion
|
|
1666
1668
|
session = manager.get_session(session.id)
|
|
1667
|
-
if
|
|
1669
|
+
if session.status != SessStatus.RUNNING:
|
|
1668
1670
|
break
|
|
1669
1671
|
time.sleep(1.0)
|
|
1670
1672
|
|
|
@@ -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:
|
|
@@ -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)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|