borisxdave 0.3.3__py3-none-any.whl → 0.3.5__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.
- boris.py +59 -16
- {borisxdave-0.3.3.dist-info → borisxdave-0.3.5.dist-info}/METADATA +1 -1
- {borisxdave-0.3.3.dist-info → borisxdave-0.3.5.dist-info}/RECORD +6 -6
- {borisxdave-0.3.3.dist-info → borisxdave-0.3.5.dist-info}/WHEEL +0 -0
- {borisxdave-0.3.3.dist-info → borisxdave-0.3.5.dist-info}/entry_points.txt +0 -0
- {borisxdave-0.3.3.dist-info → borisxdave-0.3.5.dist-info}/top_level.txt +0 -0
boris.py
CHANGED
|
@@ -14,6 +14,8 @@ if hasattr(sys.stdout, "reconfigure"):
|
|
|
14
14
|
pass
|
|
15
15
|
os.environ["PYTHONUNBUFFERED"] = "1"
|
|
16
16
|
|
|
17
|
+
import threading
|
|
18
|
+
import time as _time
|
|
17
19
|
import engine
|
|
18
20
|
import git_manager
|
|
19
21
|
import prompts
|
|
@@ -811,30 +813,39 @@ def _print_swarm_dashboard(project_dir: str, batch_num: int, batch_milestones: l
|
|
|
811
813
|
return
|
|
812
814
|
|
|
813
815
|
active = sum(1 for s in statuses.values() if s.get("state") in ("starting", "working"))
|
|
816
|
+
done = sum(1 for s in statuses.values() if s.get("state") == "done")
|
|
814
817
|
total_actions = sum(s.get("actions", 0) for s in statuses.values())
|
|
815
818
|
|
|
819
|
+
elapsed = ""
|
|
820
|
+
started_times = [s.get("started_at", 0) for s in statuses.values() if s.get("started_at")]
|
|
821
|
+
if started_times:
|
|
822
|
+
elapsed_sec = int(_time.time() - min(started_times))
|
|
823
|
+
elapsed = f" | Elapsed: {elapsed_sec // 60}m {elapsed_sec % 60}s"
|
|
824
|
+
|
|
816
825
|
print(flush=True)
|
|
817
|
-
print("
|
|
818
|
-
print(f"Batch {batch_num}
|
|
819
|
-
print(flush=True)
|
|
826
|
+
print("╔══════════════════════════════════════════════════════════════════╗", flush=True)
|
|
827
|
+
print(f"║ BORIS SWARM DASHBOARD │ Batch {batch_num} │ {active} active / {done} done / {len(statuses)} total{elapsed}", flush=True)
|
|
828
|
+
print("╠══════════════════════════════════════════════════════════════════╣", flush=True)
|
|
820
829
|
|
|
821
830
|
for m in batch_milestones:
|
|
822
831
|
status = statuses.get(m.id, {})
|
|
823
|
-
state = status.get("state", "
|
|
832
|
+
state = status.get("state", "waiting")
|
|
824
833
|
actions = status.get("actions", 0)
|
|
825
834
|
reasoning = status.get("reasoning_blocks", 0)
|
|
826
835
|
interrupts = status.get("interrupts", 0)
|
|
827
836
|
last = status.get("last_action", "")
|
|
828
837
|
|
|
829
838
|
# Progress indicator based on reasoning blocks (rough proxy)
|
|
830
|
-
bar_len = min(reasoning,
|
|
831
|
-
bar = "
|
|
839
|
+
bar_len = min(reasoning, 20)
|
|
840
|
+
bar = "█" * bar_len + "░" * (20 - bar_len)
|
|
832
841
|
|
|
842
|
+
state_icons = {"starting": "⏳", "working": "⚙️", "done": "✅", "failed": "❌"}
|
|
843
|
+
icon = state_icons.get(state, "⏸️")
|
|
833
844
|
state_str = state.upper()
|
|
834
|
-
interrupt_str = f"
|
|
835
|
-
print(f"[{m.id}] {m.title[:
|
|
845
|
+
interrupt_str = f" │ ⚠ {interrupts} interrupts" if interrupts > 0 else ""
|
|
846
|
+
print(f"║ {icon} [{m.id}] {m.title[:28]:<28} [{bar}] {state_str:>8} │ {actions:>3} actions{interrupt_str}", flush=True)
|
|
836
847
|
if last:
|
|
837
|
-
print(f"
|
|
848
|
+
print(f"║ └─ {last[:60]}", flush=True)
|
|
838
849
|
|
|
839
850
|
# Show file locks if file_lock.py is available
|
|
840
851
|
try:
|
|
@@ -843,14 +854,29 @@ def _print_swarm_dashboard(project_dir: str, batch_num: int, batch_milestones: l
|
|
|
843
854
|
locks = flm.get_locked_files()
|
|
844
855
|
if locks:
|
|
845
856
|
lock_strs = [f"{os.path.basename(f)} ({owner})" for f, owner in locks.items()]
|
|
846
|
-
print(f"
|
|
857
|
+
print(f"║ 🔒 Locks: {', '.join(lock_strs)}", flush=True)
|
|
847
858
|
except ImportError:
|
|
848
859
|
pass
|
|
849
860
|
|
|
850
|
-
print("
|
|
861
|
+
print("╚══════════════════════════════════════════════════════════════════╝", flush=True)
|
|
851
862
|
print(flush=True)
|
|
852
863
|
|
|
853
864
|
|
|
865
|
+
def _start_live_dashboard(project_dir: str, batch_num: int, batch_milestones: list, interval: float = 10.0):
|
|
866
|
+
"""Start a background thread that prints the swarm dashboard periodically."""
|
|
867
|
+
stop_event = threading.Event()
|
|
868
|
+
|
|
869
|
+
def _loop():
|
|
870
|
+
while not stop_event.is_set():
|
|
871
|
+
stop_event.wait(interval)
|
|
872
|
+
if not stop_event.is_set():
|
|
873
|
+
_print_swarm_dashboard(project_dir, batch_num, batch_milestones)
|
|
874
|
+
|
|
875
|
+
t = threading.Thread(target=_loop, daemon=True)
|
|
876
|
+
t.start()
|
|
877
|
+
return stop_event
|
|
878
|
+
|
|
879
|
+
|
|
854
880
|
def _apply_preset(args):
|
|
855
881
|
"""Apply a swarm preset to args if specified. Preset implies --swarm."""
|
|
856
882
|
if not args.preset:
|
|
@@ -907,15 +933,29 @@ def main():
|
|
|
907
933
|
print("[Boris] Error: No saved state found. Cannot resume.", flush=True)
|
|
908
934
|
sys.exit(1)
|
|
909
935
|
plan = st.plan
|
|
910
|
-
|
|
936
|
+
|
|
937
|
+
# Reset skipped milestones to pending so they get retried
|
|
938
|
+
retried = []
|
|
939
|
+
for m in plan.milestones:
|
|
940
|
+
if m.status == "skipped":
|
|
941
|
+
m.status = "pending"
|
|
942
|
+
retried.append(m.id)
|
|
943
|
+
if retried:
|
|
944
|
+
print(f"[Boris] Retrying previously skipped milestones: {', '.join(retried)}", flush=True)
|
|
945
|
+
logger.info("Reset skipped milestones to pending: %s", retried)
|
|
946
|
+
|
|
947
|
+
# Start from 0 so we scan all milestones (completed ones are skipped automatically)
|
|
948
|
+
start_index = 0
|
|
949
|
+
st.current_milestone_index = 0
|
|
950
|
+
state_module.save(st)
|
|
911
951
|
|
|
912
952
|
# If already in UI testing phase, skip straight to UI loop
|
|
913
953
|
if st.phase == "ui_testing":
|
|
914
954
|
print(f"[Boris] Resuming UI Testing phase...", flush=True)
|
|
915
955
|
logger.info("Resuming UI testing phase")
|
|
916
956
|
else:
|
|
917
|
-
print(f"[Boris] Resuming
|
|
918
|
-
logger.info("Resuming
|
|
957
|
+
print(f"[Boris] Resuming - {len(retried)} skipped milestone(s) queued for retry...", flush=True)
|
|
958
|
+
logger.info("Resuming with %d milestones to retry", len(retried))
|
|
919
959
|
elif args.exec_only:
|
|
920
960
|
# Exec-only mode - load an existing plan file and execute it
|
|
921
961
|
plan_file = os.path.abspath(args.exec_only)
|
|
@@ -1127,11 +1167,14 @@ def main():
|
|
|
1127
1167
|
tasks.append((prompt, m))
|
|
1128
1168
|
prompt_map[m.id] = prompt
|
|
1129
1169
|
|
|
1130
|
-
# Run all DaveLoops in parallel
|
|
1170
|
+
# Run all DaveLoops in parallel with live dashboard
|
|
1131
1171
|
isolation = getattr(args, 'isolation', 'none') if getattr(args, 'swarm', False) else 'none'
|
|
1172
|
+
_print_swarm_dashboard(project_dir, batch_num, ready)
|
|
1173
|
+
dashboard_stop = _start_live_dashboard(project_dir, batch_num, ready, interval=15.0)
|
|
1132
1174
|
parallel_results = engine.run_parallel(tasks, project_dir, args.max_iter, isolation=isolation)
|
|
1175
|
+
dashboard_stop.set()
|
|
1133
1176
|
|
|
1134
|
-
# Print swarm dashboard after parallel run completes (B7)
|
|
1177
|
+
# Print final swarm dashboard after parallel run completes (B7)
|
|
1135
1178
|
_print_swarm_dashboard(project_dir, batch_num, ready)
|
|
1136
1179
|
engine.clear_worker_statuses(project_dir)
|
|
1137
1180
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
boris.py,sha256=
|
|
1
|
+
boris.py,sha256=EyqRUeVvPl8775cq3x8cUnsc26zc0W2tVp0xI0ET8_c,65767
|
|
2
2
|
boris_prompt_data.py,sha256=ZBvWMrQOBrl07cNFzgeGumJ54cYg0Be9RSSnK6a3YQY,7940
|
|
3
3
|
config.py,sha256=KfFKyCGasdm1yBvIRFv-ykzA_oRo-zu1Euu9YC7V1Cg,324
|
|
4
4
|
engine.py,sha256=Pdu0i4XrNxiU246EV8MjXvYp9CBvuJWGLA18QMIYvFM,37468
|
|
@@ -7,8 +7,8 @@ git_manager.py,sha256=BuuTT4naPb5-jLhOik1xHM2ztzuKvJ_bnecZmlYgwFs,8493
|
|
|
7
7
|
planner.py,sha256=UrU--kBvzvyD1gOVxIn-kdbJiu8tt4rcowsln66WkGw,5670
|
|
8
8
|
prompts.py,sha256=-eSwZ-oTBR12Wx4Md57sVF816T9vHEFlMsvT4zMkwOg,35187
|
|
9
9
|
state.py,sha256=2DCPlcM7SBlCkwWvcnIabltcduv74W46FZ7DxKurWkw,5752
|
|
10
|
-
borisxdave-0.3.
|
|
11
|
-
borisxdave-0.3.
|
|
12
|
-
borisxdave-0.3.
|
|
13
|
-
borisxdave-0.3.
|
|
14
|
-
borisxdave-0.3.
|
|
10
|
+
borisxdave-0.3.5.dist-info/METADATA,sha256=Dtf07RlDONn9a_8nRi2elIb3mi6w7CTEy2hJQ_UIOU4,175
|
|
11
|
+
borisxdave-0.3.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
12
|
+
borisxdave-0.3.5.dist-info/entry_points.txt,sha256=a6FLWgxiQjGMJIRSV5sDxaaaaQchunm04ZuzX8N7-6I,61
|
|
13
|
+
borisxdave-0.3.5.dist-info/top_level.txt,sha256=C3fTm1vt0QEQyJtvSZiFiOvmR4d0hWmmr6hujJqFrQE,82
|
|
14
|
+
borisxdave-0.3.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|