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 +5 -4
- package/dist/adapters.js +5 -13
- package/dist/relayd.js +3 -3
- package/package.json +1 -1
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
|
|
254
|
-
|
|
255
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
280
|
-
throw new Error('
|
|
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'
|
|
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,
|
|
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
|
|
61
|
+
await ensureChatGptWebHelmReady();
|
|
62
62
|
}
|
|
63
63
|
catch (error) {
|
|
64
|
-
process.stderr.write(`
|
|
64
|
+
process.stderr.write(`WebHelm readiness check skipped: ${errorMessage(error)}\n`);
|
|
65
65
|
}
|
|
66
66
|
const noGitHub = noGitHubMode(argv);
|
|
67
67
|
if (noGitHub)
|