agents-relay 1.0.170 → 1.0.172
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.
- package/dist/dashboard-html.js +28 -38
- package/dist/reconciler-review.js +1 -1
- package/package.json +1 -1
package/dist/dashboard-html.js
CHANGED
|
@@ -70,14 +70,6 @@ export const dashboardHtml = `<!doctype html>
|
|
|
70
70
|
.detail-label { margin:0; color:var(--muted); font-size:.66rem; text-transform:uppercase; letter-spacing:.04em; }
|
|
71
71
|
.detail-value { margin:.12rem 0 0; font-weight:650; overflow-wrap:anywhere; }
|
|
72
72
|
.section-title { margin:.8rem 0 .35rem; color:var(--muted); font-size:.72rem; letter-spacing:.05em; text-transform:uppercase; }
|
|
73
|
-
.chat-shortcuts { margin-top:.7rem; padding-top:.65rem; border-top:1px solid var(--border); }
|
|
74
|
-
.chat-shortcut-tabs,.chat-shortcut-list { display:flex; gap:.35rem; flex-wrap:wrap; }
|
|
75
|
-
.chat-shortcut-tab,.chat-shortcut-button { border:1px solid var(--border); border-radius:.35rem; background:var(--surface); color:var(--text); padding:.3rem .5rem; font:inherit; font-size:.72rem; cursor:pointer; }
|
|
76
|
-
.chat-shortcut-tab[aria-selected="true"] { border-color:var(--accent); background:var(--accent2); color:var(--accent); font-weight:750; }
|
|
77
|
-
.chat-shortcut-button { color:var(--accent); font-weight:700; }
|
|
78
|
-
.chat-shortcut-editor { display:grid; gap:.4rem; margin-top:.45rem; }
|
|
79
|
-
.chat-shortcut-editor textarea { width:100%; min-height:7rem; resize:vertical; border:1px solid var(--border); border-radius:.4rem; background:var(--surface2); color:var(--text); padding:.55rem; font:12px/1.45 ui-monospace,SFMono-Regular,Menlo,monospace; }
|
|
80
|
-
.chat-shortcut-help { margin:0; color:var(--muted); font-size:.7rem; }
|
|
81
73
|
ul.tree { display:grid; gap:.25rem; min-width:0; max-width:100%; }
|
|
82
74
|
ul.tree li { min-width:0; max-width:100%; }
|
|
83
75
|
ul.tree ul { width:calc(100% - .6rem); min-width:0; max-width:calc(100% - .6rem); list-style:none; margin:.2rem 0 .1rem .6rem; padding-left:.6rem; border-left:1px solid var(--border); }
|
|
@@ -99,7 +91,7 @@ export const dashboardHtml = `<!doctype html>
|
|
|
99
91
|
.event-meta { display:flex; flex-wrap:wrap; gap:.4rem; color:var(--muted); font-size:.68rem; }
|
|
100
92
|
.event-kind { color:var(--accent); font-weight:800; }
|
|
101
93
|
.event-message { margin:.12rem 0 0; overflow-wrap:anywhere; }
|
|
102
|
-
#usage-view,#rules-view,#worker-rules-view { grid-column:1 / -1; }
|
|
94
|
+
#usage-view,#rules-view,#shortcuts-view,#worker-rules-view { grid-column:1 / -1; }
|
|
103
95
|
.rules-editor { display:grid; gap:.65rem; }
|
|
104
96
|
.rules-help { margin:0; color:var(--muted); font-size:.8rem; }
|
|
105
97
|
.rules-textarea { width:100%; min-height:55vh; resize:vertical; border:1px solid var(--border); border-radius:.45rem; background:var(--surface2); color:var(--text); padding:.8rem; font:13px/1.55 ui-monospace,SFMono-Regular,Menlo,monospace; }
|
|
@@ -179,6 +171,7 @@ export const dashboardHtml = `<!doctype html>
|
|
|
179
171
|
<button id="jobs-tab" type="button" role="tab" aria-selected="true" aria-controls="jobs-view">Jobs</button>
|
|
180
172
|
<button id="usage-tab" type="button" role="tab" aria-selected="false" aria-controls="usage-view">Usage</button>
|
|
181
173
|
<button id="rules-tab" type="button" role="tab" aria-selected="false" aria-controls="rules-view">Execution Rules</button>
|
|
174
|
+
<button id="shortcuts-tab" type="button" role="tab" aria-selected="false" aria-controls="shortcuts-view">Shortcuts</button>
|
|
182
175
|
</nav>
|
|
183
176
|
</header>
|
|
184
177
|
<main>
|
|
@@ -220,6 +213,18 @@ export const dashboardHtml = `<!doctype html>
|
|
|
220
213
|
</div>
|
|
221
214
|
</div>
|
|
222
215
|
</section>
|
|
216
|
+
<section id="shortcuts-view" role="tabpanel" aria-labelledby="shortcuts-tab" hidden>
|
|
217
|
+
<div class="panel">
|
|
218
|
+
<div class="panel-head"><h2>ChatGPT Shortcuts</h2><span class="subtle">One per line · %1 = current repo/pr</span></div>
|
|
219
|
+
<div class="panel-body">
|
|
220
|
+
<div class="rules-editor">
|
|
221
|
+
<p class="rules-help">Format: <name>: <prompt>. Use %1 where the current Job reference should appear.</p>
|
|
222
|
+
<textarea id="shortcuts-text" class="rules-textarea" spellcheck="true" aria-label="ChatGPT shortcuts"></textarea>
|
|
223
|
+
<div class="rules-footer"><span id="shortcuts-status" class="subtle" aria-live="polite"></span><button id="shortcuts-save" class="rules-save" type="button">Save shortcuts</button></div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
</section>
|
|
223
228
|
</main>
|
|
224
229
|
<script>
|
|
225
230
|
'use strict';
|
|
@@ -240,9 +245,11 @@ const DASHBOARD_VERSION=${JSON.stringify(dashboardVersion)};
|
|
|
240
245
|
const jobsTab=document.querySelector('#jobs-tab');
|
|
241
246
|
const usageTab=document.querySelector('#usage-tab');
|
|
242
247
|
const rulesTab=document.querySelector('#rules-tab');
|
|
248
|
+
const shortcutsTab=document.querySelector('#shortcuts-tab');
|
|
243
249
|
const jobsView=document.querySelector('#jobs-view');
|
|
244
250
|
const usageView=document.querySelector('#usage-view');
|
|
245
251
|
const rulesView=document.querySelector('#rules-view');
|
|
252
|
+
const shortcutsView=document.querySelector('#shortcuts-view');
|
|
246
253
|
const jobsWorkspace=document.querySelector('#jobs-workspace');
|
|
247
254
|
const jobList=document.querySelector('#job-list');
|
|
248
255
|
const jobsRefresh=document.querySelector('#jobs-refresh');
|
|
@@ -268,6 +275,9 @@ const rulesText=document.querySelector('#rules-text');
|
|
|
268
275
|
const rulesMeta=document.querySelector('#rules-meta');
|
|
269
276
|
const rulesStatus=document.querySelector('#rules-status');
|
|
270
277
|
const rulesSave=document.querySelector('#rules-save');
|
|
278
|
+
const shortcutsText=document.querySelector('#shortcuts-text');
|
|
279
|
+
const shortcutsStatus=document.querySelector('#shortcuts-status');
|
|
280
|
+
const shortcutsSave=document.querySelector('#shortcuts-save');
|
|
271
281
|
const rateLimitWarning=document.querySelector('#rate-limit-warning');
|
|
272
282
|
const runtimeSummary=document.querySelector('#runtime-summary');
|
|
273
283
|
let jobs=[];
|
|
@@ -339,31 +349,7 @@ function chatShortcutText(){return localStorage.getItem(CHAT_SHORTCUTS_KEY)||DEF
|
|
|
339
349
|
function parseChatShortcuts(source){return String(source||'').split(/\\r?\\n/).map(line=>line.trim()).filter(Boolean).map(line=>{const split=line.indexOf(':');return split>0?{name:line.slice(0,split).trim(),prompt:line.slice(split+1).trim()}:null;}).filter(item=>item&&item.name&&item.prompt);}
|
|
340
350
|
function jobChatRef(job){return repoName(job?.repository)+'/pr#'+value(job?.prNumber);}
|
|
341
351
|
function chatShortcutUrl(prompt){return 'https://chatgpt.com/?prompt='+encodeURIComponent(prompt);}
|
|
342
|
-
function
|
|
343
|
-
const root=element('section','chat-shortcuts');
|
|
344
|
-
const tabs=element('div','chat-shortcut-tabs');
|
|
345
|
-
const shortcutsTab=element('button','chat-shortcut-tab',text('Shortcuts'));shortcutsTab.type='button';shortcutsTab.setAttribute('aria-selected','true');
|
|
346
|
-
const editTab=element('button','chat-shortcut-tab',text('Edit'));editTab.type='button';editTab.setAttribute('aria-selected','false');
|
|
347
|
-
tabs.append(shortcutsTab,editTab);
|
|
348
|
-
const body=element('div');
|
|
349
|
-
function showShortcuts(){
|
|
350
|
-
shortcutsTab.setAttribute('aria-selected','true');editTab.setAttribute('aria-selected','false');
|
|
351
|
-
const list=element('div','chat-shortcut-list');
|
|
352
|
-
for(const item of parseChatShortcuts(chatShortcutText())){const button=element('button','chat-shortcut-button',text(item.name));button.type='button';button.addEventListener('click',()=>{const prompt=item.prompt.replaceAll('%1',jobChatRef(job));window.open(chatShortcutUrl(prompt),'_blank','noopener');});list.append(button);}
|
|
353
|
-
body.replaceChildren(list.children.length?list:element('p','empty',text('No shortcuts configured.')));
|
|
354
|
-
}
|
|
355
|
-
function showEditor(){
|
|
356
|
-
shortcutsTab.setAttribute('aria-selected','false');editTab.setAttribute('aria-selected','true');
|
|
357
|
-
const editor=element('div','chat-shortcut-editor');
|
|
358
|
-
const help=element('p','chat-shortcut-help',text('One per line: <name>: <prompt>. Use %1 for '+jobChatRef(job)+'.'));
|
|
359
|
-
const textarea=document.createElement('textarea');textarea.value=chatShortcutText();textarea.setAttribute('aria-label','ChatGPT shortcut entries');
|
|
360
|
-
const save=element('button','refresh-button',text('Save'));save.type='button';save.addEventListener('click',()=>{const value=textarea.value.trim();if(value)localStorage.setItem(CHAT_SHORTCUTS_KEY,value);else localStorage.removeItem(CHAT_SHORTCUTS_KEY);showShortcuts();});
|
|
361
|
-
editor.append(help,textarea,save);body.replaceChildren(editor);
|
|
362
|
-
}
|
|
363
|
-
shortcutsTab.addEventListener('click',showShortcuts);editTab.addEventListener('click',showEditor);
|
|
364
|
-
root.append(tabs,body);showShortcuts();return root;
|
|
365
|
-
}
|
|
366
|
-
|
|
352
|
+
function chatShortcutField(job){const box=element('div','detail-group');box.append(element('p','detail-label',text('ChatGPT shortcut')));const select=document.createElement('select');select.className='job-filter job-chat-shortcut-select';select.setAttribute('aria-label','ChatGPT shortcut');select.append(new Option('',''));for(const item of parseChatShortcuts(chatShortcutText()))select.append(new Option(item.name,item.prompt));select.value='';select.addEventListener('change',()=>{if(!select.value)return;const prompt=select.value.replaceAll('%1',jobChatRef(job));window.open(chatShortcutUrl(prompt),'_blank','noopener');select.value='';});box.append(select);return box;}
|
|
367
353
|
function renderJobList(){jobList.replaceChildren();const visible=filteredJobs();if(!jobs.length){jobList.append(element('li','empty',text('No durable jobs discovered.')));return;}if(!visible.length){jobList.append(element('li','empty',text('No jobs match the selected repo.')));return;}for(const job of visible){const row=element('div','job-row'+(isCompleteUnmerged(job)?' complete-unmerged':''));row.setAttribute('aria-current',String(job.id===selectedJob));row.addEventListener('click',()=>selectJob(job.id));const content=element('div','job-content');const select=document.createElement('button');select.type='button';select.className='job-button';select.setAttribute('aria-current',String(job.id===selectedJob));select.title=job.title||job.id;select.addEventListener('click',event=>{event.stopPropagation();selectJob(job.id);});select.append(element('span','job-title',text(repoName(job.repository)+'/PR#'+value(job.prNumber)+': '+value(job.title||job.id))));const states=element('span','job-status-line');states.append(element('span','badge '+value(job.state),text(value(job.state))),element('span','badge '+value(job.runtimeStatus||'IDLE'),text(value(job.runtimeStatus||'IDLE'))));if(job.executionMode==='autonomous')states.append(element('span','badge flag-autonomous',text('AUTONOMOUS')));if(job.reviewEnabled!==false&&job.githubState!=='MERGED')states.append(element('span','badge flag-review',text('REVIEW REQUIRED')));if(job.githubState==='MERGED'&&job.publication?.version)states.append(element('span','badge SUCCEEDED',text('v'+job.publication.version)));if(isCompleteUnmerged(job))states.append(element('span','badge MERGE_PENDING',text('MERGE PENDING')));const primary=element('div','job-primary');primary.append(states);const lastLine=element('div','job-last-line');lastLine.append(element('span','subtle',text(compactCounts(counts(job.tasks)))),element('span','subtle',text(relativeTime(job.updatedAt))));content.append(select,primary,lastLine);row.append(content);jobList.append(element('li','',row));}}
|
|
368
354
|
function taskTagDisplay(job,task){const display=task.tag&&job?.tag?.values?.[task.tag];return typeof display==='string'&&display?display:null;}
|
|
369
355
|
function taskSubtreeComplete(task,children){return ['SUCCEEDED','CANCELLED'].includes(task.state)&&(children.get(task.id)||[]).every(child=>taskSubtreeComplete(child,children));}
|
|
@@ -379,7 +365,7 @@ function taskStateField(task){const box=element('div','detail-group');box.append
|
|
|
379
365
|
function manualOverrideField(task){const rows=Array.isArray(task.manualStateOverrides)?task.manualStateOverrides:[];const last=rows.at(-1);return field('Manual override',last?last.from+' → '+last.to+' · '+relativeTime(last.at):'—');}
|
|
380
366
|
function renderTaskDetail(task){taskDetailRoot.replaceChildren();if(!task){taskDetailRoot.append(element('p','empty',text('Select a task to inspect execution details.')));return;}const routing=task.routing||{};const groups=element('div','detail-groups');groups.append(field('Task',task.id),field('Kind',task.kind||'work'),taskStateField(task),manualOverrideField(task),field('Planning decision',task.planningDecisionId||'—'),field('Planning source',task.planningSource||'—'),field('Planning round',task.planningRound===undefined?'—':String(task.planningRound)),field('Project / agent',value(task.projectName)+' / '+value(task.agentName)),field('Parent task',task.parentTaskId||'root'),field('Adapter',task.adapter),field('Provider / model',value(routing.provider)+' / '+value(routing.model)),field('Reasoning / profile',value(routing.reasoning||routing.profile)),field('Attempt',attemptBudget(task)),field('Dependencies',Array.isArray(task.dependencies)&&task.dependencies.length?task.dependencies.join(', '):'none'),taskCommentField(task),chatField(task));const job=selected();if(task.reviewHeadSha&&job)groups.append(commitField('HEAD commit',job,task.reviewHeadSha));const graph=agentGraphField(task);if(graph)groups.append(graph);if(task.plannerResult)groups.append(field('Objective status',task.plannerResult.objective_status),markdownField('Assessment',task.plannerResult.assessment));if(task.error)groups.append(field('Error',task.error));taskDetailRoot.append(groups);}
|
|
381
367
|
function reviewStatus(job){const review=job?.review;if(!review)return 'Not started';if(review.outcome==='approved'&&review.headSha===job.headSha)return 'MERGE READY · approved';const stale=Array.isArray(job?.tasks)&&job.tasks.some(task=>task.agentName==='reviewer'&&task.reviewHeadSha&&job.headSha&&task.reviewHeadSha!==job.headSha);if(stale)return 'STALE · awaiting review';return String(review.outcome||'pending').replace('_',' ').toUpperCase();}
|
|
382
|
-
function renderSelectedJob(){jobDetail.replaceChildren();const job=selected();if(!job){selectedJobTitle.textContent='';jobDetail.append(element('div','empty',text('No durable jobs discovered.')));buildTree([]);renderTaskDetail(null);return;}selectedJobTitle.textContent=value(job.title||job.id);if(job.id!==selectedJob){selectedJob=job.id;selectedTaskId=null;eventTaskId=null;clearEvents();rememberSelection();}const summary=element('div','job-summary');summary.append(field('PR state',job.githubState||'UNKNOWN'),jobStateField(job),field('Runtime status',job.runtimeStatus||'IDLE'),field('Execution mode',job.executionMode||'fixed'),field('Cadence',cadence(job)),field('Review',reviewStatus(job)),commitField('Review head SHA',job,job.review?.headSha||job.headSha||''),prField(job),field('Repository',job.repository||'—'),field('Last activity',relativeTime(job.updatedAt)),field('Task states',compactCounts(job.tasks)));jobDetail.append(summary
|
|
368
|
+
function renderSelectedJob(){jobDetail.replaceChildren();const job=selected();if(!job){selectedJobTitle.textContent='';jobDetail.append(element('div','empty',text('No durable jobs discovered.')));buildTree([]);renderTaskDetail(null);return;}selectedJobTitle.textContent=value(job.title||job.id);if(job.id!==selectedJob){selectedJob=job.id;selectedTaskId=null;eventTaskId=null;clearEvents();rememberSelection();}const summary=element('div','job-summary');summary.append(field('PR state',job.githubState||'UNKNOWN'),jobStateField(job),field('Runtime status',job.runtimeStatus||'IDLE'),field('Execution mode',job.executionMode||'fixed'),field('Cadence',cadence(job)),field('Review',reviewStatus(job)),commitField('Review head SHA',job,job.review?.headSha||job.headSha||''),prField(job),field('Repository',job.repository||'—'),field('Last activity',relativeTime(job.updatedAt)),field('Task states',compactCounts(job.tasks)),chatShortcutField(job));jobDetail.append(summary);const selectedTask=(job.tasks||[]).find(task=>task.id===selectedTaskId)||null;if(selectedTaskId&&!selectedTask){selectedTaskId=null;eventTaskId=null;clearEvents();rememberSelection();}buildTree(job.tasks||[]);renderTaskDetail(selectedTask);renderEventScope();}
|
|
383
369
|
function renderAll(){jobs.sort(compareJobs);syncFilters();renderJobList();renderSelectedJob();syncMobileJobsView();}
|
|
384
370
|
function isCompleteUnmerged(job){return job.runtimeStatus==='MERGE_PENDING';}
|
|
385
371
|
function isTerminalJob(job){return ['COMPLETED','CANCELLED'].includes(job.state)||['MERGED','CLOSED'].includes(job.githubState);}
|
|
@@ -431,7 +417,9 @@ function githubUsageCard(snapshot,status){
|
|
|
431
417
|
async function drawUsage(){try{const overview=await loadJSON('/api/usage');usageRoot.replaceChildren();usageMeta.textContent='Real account telemetry when available';const providers=Array.isArray(overview.providers)?overview.providers:[];const credits=Array.isArray(overview.credits)?overview.credits:[];const grid=element('div','usage-providers');if(overview.github||overview.githubStatus)grid.append(githubUsageCard(overview.github,overview.githubStatus));for(const provider of providers)grid.append(usageProvider(provider));for(const provider of credits)grid.append(creditProvider(provider));if(!grid.children.length){usageRoot.append(element('p','empty',text('Usage telemetry is unavailable.')));return;}usageRoot.append(grid);}catch(error){usageMeta.textContent='Unavailable';usageRoot.replaceChildren(element('p','error-state',text('Usage unavailable: '+error.message)));}}
|
|
432
418
|
async function drawRules(){rulesStatus.textContent='';try{const rules=await loadJSON('/api/execution-router-rules');rulesText.value=typeof rules.text==='string'?rules.text:'';rulesMeta.textContent=rules.hash&&rules.hash!=='none'?'Loaded · '+rules.hash.slice(0,12):'No custom rules saved';}catch(error){rulesMeta.textContent='Unavailable';rulesStatus.textContent='Could not load rules: '+error.message;}}
|
|
433
419
|
async function saveRules(){rulesSave.disabled=true;rulesStatus.textContent='Saving…';try{const response=await fetch('/api/execution-router-rules',{method:'PUT',headers:{'content-type':'text/plain; charset=utf-8'},body:rulesText.value});if(!response.ok)throw new Error(response.status+' '+await response.text());const rules=await response.json();rulesMeta.textContent='Saved · '+rules.hash.slice(0,12);rulesStatus.textContent='Saved. New routing decisions will load these rules.';}catch(error){rulesStatus.textContent='Save failed: '+error.message;}finally{rulesSave.disabled=false;}}
|
|
434
|
-
function
|
|
420
|
+
async function drawShortcuts(){shortcutsStatus.textContent='';shortcutsText.value=chatShortcutText();}
|
|
421
|
+
function saveShortcuts(){const value=shortcutsText.value.trim();if(value)localStorage.setItem(CHAT_SHORTCUTS_KEY,value);else localStorage.removeItem(CHAT_SHORTCUTS_KEY);shortcutsText.value=chatShortcutText();shortcutsStatus.textContent='Saved.';}
|
|
422
|
+
function showView(view){const isJobs=view==='jobs';const isUsage=view==='usage';const isRules=view==='rules';const isShortcuts=view==='shortcuts';jobsView.hidden=!isJobs;jobsWorkspace.hidden=!isJobs;usageView.hidden=!isUsage;rulesView.hidden=!isRules;shortcutsView.hidden=!isShortcuts;jobsTab.setAttribute('aria-selected',String(isJobs));usageTab.setAttribute('aria-selected',String(isUsage));rulesTab.setAttribute('aria-selected',String(isRules));shortcutsTab.setAttribute('aria-selected',String(isShortcuts));if(isJobs)void refresh();else if(isUsage)void drawUsage();else if(isRules)void drawRules();else void drawShortcuts();}
|
|
435
423
|
jobsTab.addEventListener('click',()=>{location.hash=selectedJob?'#/jobs/'+encodeURIComponent(selectedJob):'#/jobs';showView('jobs');});
|
|
436
424
|
jobsRefresh.addEventListener('click',()=>void refresh(true));
|
|
437
425
|
eventsAllTasks.addEventListener('click',()=>{eventTaskId=null;clearEvents();renderEventScope();void loadEventHistory();});
|
|
@@ -446,7 +434,9 @@ mobileJobs.addEventListener('change',syncMobileJobsView);
|
|
|
446
434
|
window.addEventListener('hashchange',syncMobileJobsView);
|
|
447
435
|
usageTab.addEventListener('click',()=>{location.hash='#/usage';showView('usage');});
|
|
448
436
|
rulesTab.addEventListener('click',()=>{location.hash='#/execution-router-rules';showView('rules');});
|
|
437
|
+
shortcutsTab.addEventListener('click',()=>{location.hash='#/shortcuts';showView('shortcuts');});
|
|
449
438
|
rulesSave.addEventListener('click',()=>void saveRules());
|
|
439
|
+
shortcutsSave.addEventListener('click',saveShortcuts);
|
|
450
440
|
window.addEventListener('keydown',event=>{if(event.key==='Tab'&&event.altKey){event.preventDefault();const next=location.hash==='#/usage'?'rules':location.hash==='#/execution-router-rules'?'jobs':'usage';location.hash=next==='usage'?'#/usage':next==='rules'?'#/execution-router-rules':(selectedJob?'#/jobs/'+encodeURIComponent(selectedJob):'#/jobs');showView(next);}});
|
|
451
441
|
function parseMessage(message){try{return JSON.parse(message.data);}catch{return null;}}
|
|
452
442
|
const stream=new EventSource('/events');
|
|
@@ -454,8 +444,8 @@ stream.onopen=()=>{connection.textContent='';connection.setAttribute('aria-label
|
|
|
454
444
|
stream.onerror=()=>{connection.textContent='';connection.setAttribute('aria-label','Event stream reconnecting');connection.className='status-pill warn';};
|
|
455
445
|
stream.onmessage=message=>{const payload=parseMessage(message);if(payload?.job){const index=jobs.findIndex(job=>job.id===payload.job.id);if(index>=0)jobs[index]=payload.job;else jobs.push(payload.job);renderAll();void drawRuntimeSummary();}};
|
|
456
446
|
stream.addEventListener('relay',message=>{const payload=parseMessage(message);if(payload?.job){const index=jobs.findIndex(job=>job.id===payload.job.id);if(index>=0)jobs[index]=payload.job;else jobs.push(payload.job);}if(payload?.event)addEvent(payload.event);renderAll();void drawRuntimeSummary();});
|
|
457
|
-
if(location.hash==='#/usage')showView('usage');else if(location.hash==='#/execution-router-rules')showView('rules');else showView('jobs');
|
|
458
|
-
setInterval(()=>{if(location.hash!=='#/usage'&&location.hash!=='#/execution-router-rules')void refresh();},300000);
|
|
447
|
+
if(location.hash==='#/usage')showView('usage');else if(location.hash==='#/execution-router-rules')showView('rules');else if(location.hash==='#/shortcuts')showView('shortcuts');else showView('jobs');
|
|
448
|
+
setInterval(()=>{if(location.hash!=='#/usage'&&location.hash!=='#/execution-router-rules'&&location.hash!=='#/shortcuts')void refresh();},300000);
|
|
459
449
|
setInterval(()=>{if(location.hash==='#/usage')void drawUsage();},30000);
|
|
460
450
|
setInterval(()=>void refreshVersion(),30000);
|
|
461
451
|
async function refreshSelected(){if(!selectedJob){await refresh();return;}selectedJobRefresh.disabled=true;selectedJobRefresh.textContent='Refreshing…';try{const updated=await loadJSON('/api/job?id='+encodeURIComponent(selectedJob));const index=jobs.findIndex(job=>job.id===selectedJob);if(index>=0)jobs[index]=updated;else jobs.push(updated);rememberSelection();renderAll();connection.textContent='';connection.setAttribute('aria-label','Live durable state connected');connection.className='status-pill ok';}catch(error){connection.textContent='';connection.setAttribute('aria-label','Durable state unavailable');connection.className='status-pill bad';}finally{selectedJobRefresh.disabled=false;selectedJobRefresh.textContent='Refresh';}}
|
|
@@ -104,7 +104,7 @@ export class ReconcilerReviewBase extends ReconcilerRuntimeBase {
|
|
|
104
104
|
const registered = await this.store.listAgents();
|
|
105
105
|
const candidates = workerCandidates(this.options.adapters, registered, usage);
|
|
106
106
|
const runtimeSummary = this.options.runtimeSummaryProvider?.();
|
|
107
|
-
for (const task of job.tasks.filter(item => item.kind !== 'planner' && item.
|
|
107
|
+
for (const task of job.tasks.filter(item => item.kind !== 'planner' && item.adapter !== 'orchestrator' && ['QUEUED', 'BLOCKED'].includes(item.state) && item.output && !item.workerSelection && (item.workerRequirements || item.planningSource === 'model-planner'))) {
|
|
108
108
|
const requirements = task.workerRequirements ?? { capabilities: [] };
|
|
109
109
|
const taskFacts = {
|
|
110
110
|
id: task.id,
|