agents-relay 2.0.46 → 2.0.48

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.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: chatgpt-worker
3
+ description: Submit one isolated ChatGPT browser task through Browser Workspace and let Relay own task/event lifecycle.
4
+ type: worker
5
+ ---
6
+
7
+ # ChatGPT Worker Agent
8
+
9
+ You execute one complete Relay task by submitting it to a fresh worker-owned ChatGPT Temporary Chat through Browser Workspace.
10
+
11
+ ## Contract
12
+
13
+ - Browser Workspace `platforms/chatgpt` is the sole owner of ChatGPT selectors, readiness checks, attachments, Temporary Chat mechanics, and submit verification.
14
+ - Relay owns worker lifecycle, task/event barriers, routing, cancellation, and tab/session close policy.
15
+ - Execute only a one-shot submission. Do not expose a create/resume/status/result conversation lifecycle.
16
+ - Always use a fresh worker-owned Browser Workspace session/tab. Never submit through a pre-existing user tab.
17
+ - Preserve the account's current default model/thinking settings.
18
+ - A submission is accepted only after Browser Workspace returns a verified submit receipt.
19
+ - Treat observed conversation/thread identity as diagnostic only, never as a resumable handle.
20
+ - `after-start` releases the Browser Workspace session after the exact worker `task.started` barrier.
21
+ - `after-terminal` releases it after the exact task terminal barrier.
22
+ - `never` leaves the owned session open for test/debug.
23
+ - Do not wait for the assistant response. Durable task success/failure is event-owned by Relay and the executing task.
24
+ - Stop on authentication, MFA, consent, or ambiguous browser state rather than bypassing it.
@@ -376,7 +376,6 @@ function syncFilters(){
376
376
  jobSearch.value=searchQuery;
377
377
  }
378
378
  function repoName(repository){if(typeof repository!=='string'||!repository)return 'unknown-repo';const parts=repository.split('/').filter(Boolean);return parts.at(-1)||repository;}
379
-
380
379
  const CHAT_SHORTCUTS_KEY='agents-relay:chatgpt-shortcuts';
381
380
  const DEFAULT_CHAT_SHORTCUTS=[
382
381
  'Why blocked?: %1: why is it blocked? Find the root cause and move it forward.',
@@ -482,11 +481,12 @@ auditRefresh.addEventListener('click',()=>void drawAudit());
482
481
  shortcutsSave.addEventListener('click',saveShortcuts);
483
482
  window.addEventListener('keydown',event=>{if(event.key==='Tab'&&event.altKey){event.preventDefault();const views=['jobs','usage','graphs','rules','shortcuts'];const current=location.hash==='#/usage'?'usage':location.hash==='#/graphs'?'graphs':location.hash==='#/execution-router-rules'?'rules':location.hash==='#/shortcuts'?'shortcuts':'jobs';const next=views[(views.indexOf(current)+1)%views.length];location.hash=next==='usage'?'#/usage':next==='graphs'?'#/graphs':next==='rules'?'#/execution-router-rules':next==='shortcuts'?'#/shortcuts':(selectedJob?'#/jobs/'+encodeURIComponent(selectedJob):'#/jobs');showView(next);}});
484
483
  function parseMessage(message){try{return JSON.parse(message.data);}catch{return null;}}
484
+ function applyStatePatch(patch){if(!patch?.jobId)return false;const job=jobs.find(candidate=>candidate.id===patch.jobId);if(!job)return false;if(patch.jobState)job['state']=patch.jobState;if(patch.jobUpdatedAt)job.updatedAt=patch.jobUpdatedAt;if(patch.taskId&&patch.taskState){const task=(job.tasks||[]).find(candidate=>candidate.id===patch.taskId);if(task){task['state']=patch.taskState;if(patch.taskUpdatedAt)task.updatedAt=patch.taskUpdatedAt;}}return true;}
485
485
  const stream=new EventSource('/events');
486
486
  stream.onopen=()=>{connection.textContent='';connection.setAttribute('aria-label','Event stream connected');connection.className='status-pill ok';};
487
487
  stream.onerror=()=>{connection.textContent='';connection.setAttribute('aria-label','Event stream reconnecting');connection.className='status-pill warn';};
488
488
  stream.onmessage=message=>{const payload=parseMessage(message);if(payload?.job){const index=jobs.findIndex(job=>jobSelectionKey(job)===jobSelectionKey(payload.job));if(index>=0)jobs[index]=payload.job;else jobs.push(payload.job);renderAll();void drawRuntimeSummary();}};
489
- stream.addEventListener('relay',message=>{const payload=parseMessage(message);if(payload?.job){const index=jobs.findIndex(job=>jobSelectionKey(job)===jobSelectionKey(payload.job));if(index>=0)jobs[index]=payload.job;else jobs.push(payload.job);}if(payload?.event)addEvent(payload.event);renderAll();void drawRuntimeSummary();});
489
+ stream.addEventListener('relay',message=>{const payload=parseMessage(message);if(payload?.statePatch)applyStatePatch(payload.statePatch);if(payload?.event)addEvent(payload.event);renderAll();void drawRuntimeSummary();});
490
490
  if(location.hash==='#/usage')showView('usage');else if(location.hash==='#/graphs')showView('graphs');else if(location.hash==='#/execution-router-rules')showView('rules');else if(location.hash==='#/shortcuts')showView('shortcuts');else showView('jobs');
491
491
  setInterval(()=>{if(location.hash!=='#/usage'&&location.hash!=='#/graphs'&&location.hash!=='#/execution-router-rules'&&location.hash!=='#/shortcuts')void refresh();},300000);
492
492
  setInterval(()=>{if(location.hash==='#/usage')void drawUsage();},30000);
package/dist/dashboard.js CHANGED
@@ -99,8 +99,17 @@ export function serveDashboard(store, port = 8787, bus, refreshMs = 300000, jobI
99
99
  subscribedJobs.add(job.id);
100
100
  try {
101
101
  await bus.subscribe(job.id, async (event) => {
102
- const current = (await discoveredJobs()).find(candidate => candidate.id === job.id) ?? job;
103
- const payload = JSON.stringify({ event, job: current });
102
+ const durable = await store.load(job.id).catch(() => null);
103
+ const task = durable?.tasks.find(candidate => candidate.id === event.task_id) ?? null;
104
+ const statePatch = durable ? {
105
+ jobId: durable.id,
106
+ jobState: durable.state,
107
+ jobUpdatedAt: durable.updatedAt,
108
+ taskId: task?.id ?? null,
109
+ taskState: task?.state ?? null,
110
+ taskUpdatedAt: task?.updatedAt ?? null,
111
+ } : null;
112
+ const payload = JSON.stringify({ event, statePatch });
104
113
  for (const client of clients)
105
114
  client.write(`event: relay\ndata: ${payload}\n\n`);
106
115
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents-relay",
3
- "version": "2.0.46",
3
+ "version": "2.0.48",
4
4
  "description": "Durable async agent jobs coordinated through GitHub pull requests",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,6 +24,7 @@
24
24
  },
25
25
  "files": [
26
26
  "dist",
27
+ "agents",
27
28
  "skills",
28
29
  "workflow",
29
30
  "README.md",