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:
@@ -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'],
|
||||||
|
|||||||
@@ -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'],
|
||||||
|
|||||||
Reference in New Issue
Block a user