fix: agents self-assign unassigned issues for max throughput

Workers now pick ANY open issue (assigned to them OR unassigned) and
self-assign via Gitea API before starting work. No more empty queues.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alexander Whitestone
2026-03-22 19:39:46 -04:00
parent 5f8129d346
commit edee9b8dcc
2 changed files with 31 additions and 13 deletions

View File

@@ -160,9 +160,9 @@ def priority(i):
all_issues.sort(key=priority) all_issues.sort(key=priority)
for i in all_issues: for i in all_issues:
# Must be assigned to claude
assignees = [a['login'] for a in (i.get('assignees') or [])] assignees = [a['login'] for a in (i.get('assignees') or [])]
if 'claude' not in assignees: # Take issues assigned to claude OR unassigned (self-assign)
if assignees and 'claude' not in assignees:
continue continue
title = i['title'].lower() title = i['title'].lower()
@@ -171,23 +171,28 @@ for i in all_issues:
if '[showcase]' in title: continue if '[showcase]' in title: continue
num_str = str(i['number']) num_str = str(i['number'])
if num_str in active_issues: continue
# Skip if already being worked on by another worker
if num_str in active_issues:
continue
# Check skip list
entry = skips.get(num_str, {}) entry = skips.get(num_str, {})
if entry and entry.get('until', 0) > time.time(): if entry and entry.get('until', 0) > time.time(): continue
continue
# Check lock dir
lock = '${LOCK_DIR}/' + i['_repo'].replace('/', '-') + '-' + num_str + '.lock' lock = '${LOCK_DIR}/' + i['_repo'].replace('/', '-') + '-' + num_str + '.lock'
if os.path.isdir(lock): if os.path.isdir(lock): continue
continue
repo = i['_repo'] repo = i['_repo']
owner, name = repo.split('/') owner, name = repo.split('/')
# Self-assign if unassigned
if not assignees:
try:
data = json.dumps({'assignees': ['claude']}).encode()
req2 = urllib.request.Request(
f'{base}/api/v1/repos/{repo}/issues/{i[\"number\"]}',
data=data, method='PATCH',
headers={'Authorization': f'token {token}', 'Content-Type': 'application/json'})
urllib.request.urlopen(req2, timeout=5)
except: pass
print(json.dumps({ print(json.dumps({
'number': i['number'], 'number': i['number'],
'title': i['title'], 'title': i['title'],

View File

@@ -149,7 +149,8 @@ all_issues.sort(key=priority)
for i in all_issues: for i in all_issues:
assignees = [a['login'] for a in (i.get('assignees') or [])] assignees = [a['login'] for a in (i.get('assignees') or [])]
if 'gemini' not in assignees: # Take issues assigned to gemini OR unassigned (self-assign)
if assignees and 'gemini' not in assignees:
continue continue
title = i['title'].lower() title = i['title'].lower()
@@ -168,6 +169,18 @@ for i in all_issues:
repo = i['_repo'] repo = i['_repo']
owner, name = repo.split('/') owner, name = repo.split('/')
# Self-assign if unassigned
if not assignees:
try:
data = json.dumps({'assignees': ['gemini']}).encode()
req2 = urllib.request.Request(
f'{base}/api/v1/repos/{repo}/issues/{i["number"]}',
data=data, method='PATCH',
headers={'Authorization': f'token {token}', 'Content-Type': 'application/json'})
urllib.request.urlopen(req2, timeout=5)
except: pass
print(json.dumps({ print(json.dumps({
'number': i['number'], 'number': i['number'],
'title': i['title'], 'title': i['title'],