agents-relay 2.0.184 → 2.0.186

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/README.md CHANGED
@@ -250,11 +250,12 @@ Every model-backed task declares a durable output with `--output task-pr` or `--
250
250
  For Codex and ChatGPT, **correlated worker events are authoritative lifecycle inputs**, not a separate durable store. Event publication uses the canonical Neo `events-bus` surface (`events__publish` for sandboxed/hosted workers, or `NEO_EVENTS_EMIT` for direct local workers); Agents Relay subscribes, validates correlation, applies graph transitions, persists results in RelayStore, and projects them to GitHub. Relay publishes `task.process.launched` only after successful adapter launch; `task.started` is worker-owned and must be a new, correlated start acknowledgement. Codex publishes `task.process.exited` when its synchronous runtime exits, while ChatGPT publishes `task.process.async_exited` after its one-shot submission runtime exits; neither substitutes for `task.completed`, `task.failed`, `task.blocked`, or `task.cancelled`. The executing agent must publish exactly one correlated terminal event. Relay persists the matching durable state only from that terminal event. Model-backed tasks require an event bus and time out explicitly if no terminal event arrives.
251
251
 
252
252
  External execution uses the single global `webhelm` executable installed by the
253
- WebHelm skill. Before starting Relay, install the global skill and its launcher
254
- (`npx skills add lalalic/browser-workspace -g -y -s webhelm`, then
255
- `~/.agents/skills/webhelm/scripts/install-global-cli.sh`). Relay checks
253
+ WebHelm Skill. Before starting Relay, install that Skill through the agent's
254
+ normal Skill mechanism and follow the setup instructions in its own
255
+ `SKILL.md`. The Skill can live in any directory; its installer links the
256
+ global `webhelm` command to the Skill's launcher. Relay calls
256
257
  `webhelm platform profile chatgpt` before browser workspace initialization.
257
- Do not invoke the old `browser-workspace` executable or a separate `uvx` CLI.
258
+ Relay does not discover Skill directories or invoke a separate runtime.
258
259
 
259
260
  The ChatGPT adapter uses Relay's `agents/chatgpt-worker.agent.md` lifecycle contract. A new worker uses `webhelm platform run chatgpt new-thread --session-id SESSION_ID --config <file>` in a caller-owned Session. This is a regular persistent ChatGPT thread, which supports the connected Neo MCP in the verified account. Relay closes the Session after submission, but the ChatGPT thread remains in history. Existing-thread review and handoff continue through `new-turn`. File paths are included in the worker message for Neo MCP reading; they are not uploaded as browser attachments. Submission receipts retain `status: submitted`; the event bus owns task completion.
260
261
 
package/dist/adapters.js CHANGED
@@ -2,7 +2,6 @@ import { access, readFile, realpath, writeFile, unlink } from 'node:fs/promises'
2
2
  import { join, relative, resolve, sep, basename } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
4
  import { DEFAULT_PROMPT_REFERENCE_DIRECTORY } from './agent-prompt-builder.js';
5
- import { pathToFileURL } from 'node:url';
6
5
  import { createHash, randomUUID } from 'node:crypto';
7
6
  import { taskReferencePrompt } from './task-context.js';
8
7
  import { spawnOwnedProcess, terminateOwnedProcess, ownedProcessTerminationReason } from './owned-process.js';
@@ -121,8 +120,6 @@ export class CodexAdapter {
121
120
  return execution;
122
121
  }
123
122
  }
124
- export const CHATGPT_BROWSER_WORKSPACE = 'Relay';
125
- export const CHATGPT_BROWSER_WORKSPACE_POOL_SIZE = 6;
126
123
  export function chatGptTabClosePolicy(value, fallback = 'after-start') {
127
124
  const policy = value || fallback;
128
125
  if (!['after-start', 'never', 'after-terminal'].includes(policy))
@@ -270,27 +267,22 @@ async function accessiblePromptReferences(prompt) {
270
267
  }
271
268
  return readable;
272
269
  }
273
- export async function ensureChatGptBrowserWorkspace(command = process.env.AGENTS_RELAY_WEBHELM_COMMAND) {
270
+ export async function ensureChatGptWebHelmReady(command = process.env.AGENTS_RELAY_WEBHELM_COMMAND) {
274
271
  const cli = browserWorkspaceCli(command);
275
272
  const profile = parseWorkspaceJson(await browserWorkspaceCommand(cli, ['platform', 'profile', 'chatgpt']));
276
273
  if (profile.platform !== 'chatgpt')
277
274
  throw new Error('Global WebHelm CLI cannot load the ChatGPT platform skill');
275
+ // All Relay sessions use WebHelm's default Harness workspace. No product-owned tab group.
278
276
  const status = parseWorkspaceJson(await browserWorkspaceCommand(cli, ['status']));
279
- if (typeof status.admin_helper !== 'string' || !status.admin_helper.startsWith('/')) {
280
- throw new Error('webhelm status returned no absolute admin_helper path');
281
- }
282
- const admin = await import(pathToFileURL(status.admin_helper).href);
283
- if (typeof admin.ensureWorkspace !== 'function') {
284
- throw new Error('webhelm admin helper does not export ensureWorkspace');
285
- }
286
- await admin.ensureWorkspace(CHATGPT_BROWSER_WORKSPACE, CHATGPT_BROWSER_WORKSPACE_POOL_SIZE);
277
+ if (status.daemon?.running !== true)
278
+ throw new Error('Global WebHelm daemon is not running');
287
279
  }
288
280
  async function runBrowserWorker(cli, configFile, signal, action = 'new-thread') {
289
281
  // Durable async turns are queued without browser sessions by the WebHelm runtime.
290
282
  if (action === 'new-turn') {
291
283
  return browserWorkspaceCommand(cli, ['platform', 'run', 'chatgpt', 'new-turn', '--mode', 'async', '--config', configFile], undefined, signal);
292
284
  }
293
- const session = parseWorkspaceJson(await browserWorkspaceCommand(cli, ['session', 'start', '--workspace', CHATGPT_BROWSER_WORKSPACE], undefined, signal));
285
+ const session = parseWorkspaceJson(await browserWorkspaceCommand(cli, ['session', 'start'], undefined, signal));
294
286
  const sessionId = session.session_id;
295
287
  if (typeof sessionId !== 'string' || !sessionId)
296
288
  throw new Error('webhelm session start returned no session_id');
package/dist/relayd.js CHANGED
@@ -5,7 +5,7 @@ import { spawnOwnedProcess } from './owned-process.js';
5
5
  import { readFile } from 'node:fs/promises';
6
6
  import { homedir } from 'node:os';
7
7
  import { join, basename } from 'node:path';
8
- import { ChatGptAdapter, CodexAdapter, ensureChatGptBrowserWorkspace } from './adapters.js';
8
+ import { ChatGptAdapter, CodexAdapter, ensureChatGptWebHelmReady } from './adapters.js';
9
9
  import { CodexThreadContinuation, CommandContinuation, WebhookContinuation } from './continuation.js';
10
10
  import { serveDashboard } from './dashboard.js';
11
11
  import { RepositoryWorkerPool } from './pool.js';
@@ -58,10 +58,10 @@ export async function runDaemon(argv) {
58
58
  configureDaemonObservability();
59
59
  configureExecutionRouterRulesPath(argv);
60
60
  try {
61
- await ensureChatGptBrowserWorkspace();
61
+ await ensureChatGptWebHelmReady();
62
62
  }
63
63
  catch (error) {
64
- process.stderr.write(`Browser Workspace bootstrap skipped: ${errorMessage(error)}\n`);
64
+ process.stderr.write(`WebHelm readiness check skipped: ${errorMessage(error)}\n`);
65
65
  }
66
66
  const noGitHub = noGitHubMode(argv);
67
67
  if (noGitHub)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents-relay",
3
- "version": "2.0.184",
3
+ "version": "2.0.186",
4
4
  "description": "Durable async agent jobs coordinated through GitHub pull requests",
5
5
  "repository": {
6
6
  "type": "git",