Compare commits
1 Commits
mimo/build
...
mimo/code/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbad1cdf0b |
@@ -7,6 +7,7 @@ routes to lanes, and spawns one-shot mimo-v2-pro workers.
|
|||||||
No new issues created. No duplicate claims. No bloat.
|
No new issues created. No duplicate claims. No bloat.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import glob
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -38,6 +39,7 @@ else:
|
|||||||
|
|
||||||
CLAIM_TIMEOUT_MINUTES = 30
|
CLAIM_TIMEOUT_MINUTES = 30
|
||||||
CLAIM_LABEL = "mimo-claimed"
|
CLAIM_LABEL = "mimo-claimed"
|
||||||
|
MAX_QUEUE_DEPTH = 10 # Don't dispatch if queue already has this many prompts
|
||||||
CLAIM_COMMENT = "/claim"
|
CLAIM_COMMENT = "/claim"
|
||||||
DONE_COMMENT = "/done"
|
DONE_COMMENT = "/done"
|
||||||
ABANDON_COMMENT = "/abandon"
|
ABANDON_COMMENT = "/abandon"
|
||||||
@@ -451,6 +453,13 @@ def dispatch(token):
|
|||||||
prefetch_pr_refs(target_repo, token)
|
prefetch_pr_refs(target_repo, token)
|
||||||
log(f" Prefetched {len(_PR_REFS)} PR references")
|
log(f" Prefetched {len(_PR_REFS)} PR references")
|
||||||
|
|
||||||
|
# Check queue depth — don't pile up if workers haven't caught up
|
||||||
|
pending_prompts = len(glob.glob(os.path.join(STATE_DIR, "prompt-*.txt")))
|
||||||
|
if pending_prompts >= MAX_QUEUE_DEPTH:
|
||||||
|
log(f" QUEUE THROTTLE: {pending_prompts} prompts pending (max {MAX_QUEUE_DEPTH}) — skipping dispatch")
|
||||||
|
save_state(state)
|
||||||
|
return 0
|
||||||
|
|
||||||
# FOCUS MODE: scan only the focus repo. FIREHOSE: scan all.
|
# FOCUS MODE: scan only the focus repo. FIREHOSE: scan all.
|
||||||
if FOCUS_MODE:
|
if FOCUS_MODE:
|
||||||
ordered = [FOCUS_REPO]
|
ordered = [FOCUS_REPO]
|
||||||
|
|||||||
@@ -24,6 +24,23 @@ def log(msg):
|
|||||||
f.write(f"[{ts}] {msg}\n")
|
f.write(f"[{ts}] {msg}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def write_result(worker_id, status, repo=None, issue=None, branch=None, pr=None, error=None):
|
||||||
|
"""Write a result file — always, even on failure."""
|
||||||
|
result_file = os.path.join(STATE_DIR, f"result-{worker_id}.json")
|
||||||
|
data = {
|
||||||
|
"status": status,
|
||||||
|
"worker": worker_id,
|
||||||
|
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||||
|
}
|
||||||
|
if repo: data["repo"] = repo
|
||||||
|
if issue: data["issue"] = int(issue) if str(issue).isdigit() else issue
|
||||||
|
if branch: data["branch"] = branch
|
||||||
|
if pr: data["pr"] = pr
|
||||||
|
if error: data["error"] = error
|
||||||
|
with open(result_file, "w") as f:
|
||||||
|
json.dump(data, f)
|
||||||
|
|
||||||
|
|
||||||
def get_oldest_prompt():
|
def get_oldest_prompt():
|
||||||
"""Get the oldest prompt file with file locking (atomic rename)."""
|
"""Get the oldest prompt file with file locking (atomic rename)."""
|
||||||
prompts = sorted(glob.glob(os.path.join(STATE_DIR, "prompt-*.txt")))
|
prompts = sorted(glob.glob(os.path.join(STATE_DIR, "prompt-*.txt")))
|
||||||
@@ -63,6 +80,7 @@ def run_worker(prompt_file):
|
|||||||
|
|
||||||
if not repo or not issue:
|
if not repo or not issue:
|
||||||
log(f" SKIPPING: couldn't parse repo/issue from prompt")
|
log(f" SKIPPING: couldn't parse repo/issue from prompt")
|
||||||
|
write_result(worker_id, "parse_error", error="could not parse repo/issue from prompt")
|
||||||
os.remove(prompt_file)
|
os.remove(prompt_file)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -79,6 +97,7 @@ def run_worker(prompt_file):
|
|||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
log(f" CLONE FAILED: {result.stderr[:200]}")
|
log(f" CLONE FAILED: {result.stderr[:200]}")
|
||||||
|
write_result(worker_id, "clone_failed", repo=repo, issue=issue, error=result.stderr[:200])
|
||||||
os.remove(prompt_file)
|
os.remove(prompt_file)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -126,6 +145,7 @@ def run_worker(prompt_file):
|
|||||||
urllib.request.urlopen(req, timeout=10)
|
urllib.request.urlopen(req, timeout=10)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
write_result(worker_id, "abandoned", repo=repo, issue=issue, error="no changes produced")
|
||||||
if os.path.exists(prompt_file):
|
if os.path.exists(prompt_file):
|
||||||
os.remove(prompt_file)
|
os.remove(prompt_file)
|
||||||
return False
|
return False
|
||||||
@@ -193,17 +213,7 @@ def run_worker(prompt_file):
|
|||||||
pr_num = "?"
|
pr_num = "?"
|
||||||
|
|
||||||
# Write result
|
# Write result
|
||||||
result_file = os.path.join(STATE_DIR, f"result-{worker_id}.json")
|
write_result(worker_id, "completed", repo=repo, issue=issue, branch=branch, pr=pr_num)
|
||||||
with open(result_file, "w") as f:
|
|
||||||
json.dump({
|
|
||||||
"status": "completed",
|
|
||||||
"worker": worker_id,
|
|
||||||
"repo": repo,
|
|
||||||
"issue": int(issue) if issue.isdigit() else issue,
|
|
||||||
"branch": branch,
|
|
||||||
"pr": pr_num,
|
|
||||||
"timestamp": datetime.now(timezone.utc).isoformat()
|
|
||||||
}, f)
|
|
||||||
|
|
||||||
# Remove prompt
|
# Remove prompt
|
||||||
# Remove prompt file (handles .processing extension)
|
# Remove prompt file (handles .processing extension)
|
||||||
|
|||||||
Reference in New Issue
Block a user