agent-relay-runner 0.17.0 → 0.18.0
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/package.json +2 -2
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/src/adapter.ts +1 -4
- package/src/adapters/claude-delivery.ts +1 -4
- package/src/adapters/codex.ts +1 -7
- package/src/attachment-cache.ts +1 -4
- package/src/config.ts +1 -4
- package/src/control-server.ts +1 -4
- package/src/index.ts +2 -1
- package/src/relay-instructions.ts +19 -1
- package/src/version.ts +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-relay-runner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Unified provider lifecycle runner for Agent Relay",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"directory": "runner"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"agent-relay-sdk": "0.2.
|
|
23
|
+
"agent-relay-sdk": "0.2.9"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/bun": "latest",
|
package/src/adapter.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentProfile, Message } from "agent-relay-sdk";
|
|
2
|
+
import { isRecord } from "agent-relay-sdk";
|
|
2
3
|
|
|
3
4
|
export type SemanticStatus = "idle" | "busy" | "offline" | "error";
|
|
4
5
|
type ProviderWorkKind = "provider-turn" | "subagent";
|
|
@@ -160,10 +161,6 @@ export const RELAY_CONTEXT = `[agent-relay] You are connected to Agent Relay, a
|
|
|
160
161
|
|
|
161
162
|
const PROVIDER_MESSAGE_BODY_PREVIEW_CHARS = 4000;
|
|
162
163
|
|
|
163
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
164
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
165
|
-
}
|
|
166
|
-
|
|
167
164
|
function attachmentRefs(message: Message): Record<string, unknown>[] {
|
|
168
165
|
const payloadRefs = message.payload?.attachments;
|
|
169
166
|
const topLevelRefs = (message as Message & { attachments?: unknown }).attachments;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Message } from "agent-relay-sdk";
|
|
2
|
+
import { isRecord } from "agent-relay-sdk";
|
|
2
3
|
import { providerAttachmentText } from "../adapter";
|
|
3
4
|
|
|
4
5
|
const PROVIDER_MESSAGE_BODY_PREVIEW_CHARS = 4000;
|
|
@@ -30,10 +31,6 @@ function stripRelayScaffolding(body: string): string {
|
|
|
30
31
|
return lines.join("\n");
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
34
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
34
|
function isMemoryInjection(message: Message): boolean {
|
|
38
35
|
return isRecord(message.payload) && message.payload.memoryInjection === true;
|
|
39
36
|
}
|
package/src/adapters/codex.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { accessSync, constants, existsSync, readFileSync, realpathSync, readdirS
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { basename, join, resolve } from "node:path";
|
|
4
4
|
import type { ContextState, Message } from "agent-relay-sdk";
|
|
5
|
+
import { isRecord, stringValue } from "agent-relay-sdk";
|
|
5
6
|
import { profileAllowsRelayFeature, providerMessageText, RELAY_CONTEXT, type ManagedProcess, type ProviderAdapter, type ProviderConfig, type ProviderPermissionDecisionInput, type ProviderSessionEvent, type ProviderStatusUpdate, type RunnerSpawnConfig, type SpawnArgs, type TerminalAttachSpec } from "../adapter";
|
|
6
7
|
import { workspaceDepsNoteFromEnv } from "../relay-instructions";
|
|
7
8
|
import { logger } from "../logger";
|
|
@@ -742,10 +743,6 @@ function activeFlags(value: unknown): string[] {
|
|
|
742
743
|
return value.activeFlags.filter((flag): flag is string => typeof flag === "string" && flag.length > 0);
|
|
743
744
|
}
|
|
744
745
|
|
|
745
|
-
function stringValue(value: unknown): string | undefined {
|
|
746
|
-
return typeof value === "string" && value ? value : undefined;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
746
|
function numberValue(value: unknown): number | undefined {
|
|
750
747
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
751
748
|
}
|
|
@@ -759,9 +756,6 @@ function isContextState(value: unknown): value is ContextState {
|
|
|
759
756
|
typeof state.confidence === "string";
|
|
760
757
|
}
|
|
761
758
|
|
|
762
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
763
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
764
|
-
}
|
|
765
759
|
|
|
766
760
|
export function codexModelConfigArgs(model?: string, effort?: string): string[] {
|
|
767
761
|
const args: string[] = [];
|
package/src/attachment-cache.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, readdirSync, renameSync, rmSync, statSync, write
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { basename, join } from "node:path";
|
|
4
4
|
import type { Artifact, Message } from "agent-relay-sdk";
|
|
5
|
+
import { isRecord } from "agent-relay-sdk";
|
|
5
6
|
|
|
6
7
|
const DEFAULT_CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
7
8
|
|
|
@@ -25,10 +26,6 @@ interface CachedAttachment {
|
|
|
25
26
|
digest: string;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
29
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
29
|
function attachmentRefs(message: Message): Record<string, unknown>[] {
|
|
33
30
|
const payloadRefs = message.payload?.attachments;
|
|
34
31
|
const topLevelRefs = (message as Message & { attachments?: unknown }).attachments;
|
package/src/config.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { homedir, hostname } from "node:os";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
|
+
import { stringValue } from "agent-relay-sdk";
|
|
4
5
|
import type { ProviderConfig } from "./adapter";
|
|
5
6
|
|
|
6
7
|
interface GlobalRunnerConfig {
|
|
@@ -115,10 +116,6 @@ function readJson(path: string): Record<string, unknown> {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
function stringValue(value: unknown): string | undefined {
|
|
119
|
-
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
119
|
function positiveInteger(value: unknown): number | undefined {
|
|
123
120
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : undefined;
|
|
124
121
|
}
|
package/src/control-server.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Server, ServerWebSocket } from "bun";
|
|
2
2
|
import type { Message, ReplyObligation } from "agent-relay-sdk";
|
|
3
|
+
import { isRecord } from "agent-relay-sdk";
|
|
3
4
|
import type { ProviderPermissionDecisionInput, ProviderStatusEvent, SemanticStatus, TerminalAttachSpec } from "./adapter";
|
|
4
5
|
import { logger, parseLogLevel, LOG_LEVELS } from "./logger";
|
|
5
6
|
|
|
@@ -453,7 +454,3 @@ function parseJson(raw: string | Buffer): Record<string, unknown> | null {
|
|
|
453
454
|
return null;
|
|
454
455
|
}
|
|
455
456
|
}
|
|
456
|
-
|
|
457
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
458
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
459
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { AgentRunner } from "./runner";
|
|
|
8
8
|
import { loadGlobalConfig, loadProviderConfig, resolveCwd, runnerId } from "./config";
|
|
9
9
|
import { VERSION } from "./version";
|
|
10
10
|
import type { AgentProfile, WorkspaceMetadata } from "agent-relay-sdk";
|
|
11
|
+
import { RELAY_TOKEN_HEADER } from "agent-relay-sdk";
|
|
11
12
|
|
|
12
13
|
interface CliOptions {
|
|
13
14
|
provider: "claude" | "codex";
|
|
@@ -139,7 +140,7 @@ export async function resolveRunnerToken(input: {
|
|
|
139
140
|
method: "POST",
|
|
140
141
|
headers: {
|
|
141
142
|
"Content-Type": "application/json",
|
|
142
|
-
|
|
143
|
+
[RELAY_TOKEN_HEADER]: input.token,
|
|
143
144
|
},
|
|
144
145
|
body: JSON.stringify({
|
|
145
146
|
provider: input.provider,
|
|
@@ -45,6 +45,23 @@ export function workspaceDepsNote(input: { mode?: string | null; depsMode?: stri
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Lifecycle briefing for an agent spawned into an isolated workspace (#205).
|
|
50
|
+
* Tells it, in plain terms, that it is on an isolated branch off a base that
|
|
51
|
+
* other agents move in parallel, and how to hand off — so it doesn't re-derive
|
|
52
|
+
* "I seem to be in a clone, not on main" every session or hand-roll a rebase/push.
|
|
53
|
+
* Returns "" for shared workspaces. Branch/base come from the resolved metadata.
|
|
54
|
+
*/
|
|
55
|
+
export function workspaceLifecycleNote(input: { mode?: string | null; branch?: string | null; baseRef?: string | null }): string {
|
|
56
|
+
if (input.mode !== "isolated") return "";
|
|
57
|
+
const branch = input.branch ? `\`${input.branch}\`` : "an isolated agent branch";
|
|
58
|
+
const base = input.baseRef ? `\`${input.baseRef}\`` : "the base branch";
|
|
59
|
+
return [
|
|
60
|
+
`[agent-relay] Isolated workspace: you are in a git worktree on branch ${branch}, based on ${base} — NOT the main checkout. Other agents may work in parallel and land to ${base}, so ${base} will move under you. That is expected; don't fight it.`,
|
|
61
|
+
`Do NOT manually rebase, merge, or \`git push\` your branch. Just commit your work here. When the task is done, run \`agent-relay workspace ready\` — Relay rebases onto the latest ${base}, lands your work, and pushes for you. (\`agent-relay workspace status\` shows the current state.)`,
|
|
62
|
+
].join("\n");
|
|
63
|
+
}
|
|
64
|
+
|
|
48
65
|
/**
|
|
49
66
|
* Caveat for untracked paths symlinked from main into an isolated worktree
|
|
50
67
|
* (WorkspaceConfig.symlinkPaths, e.g. AGENTS.md, .claude-rig). Edits to these
|
|
@@ -63,8 +80,9 @@ export function workspaceDepsNoteFromEnv(env: Record<string, string | undefined>
|
|
|
63
80
|
const json = env.AGENT_RELAY_WORKSPACE_JSON;
|
|
64
81
|
if (!json) return "";
|
|
65
82
|
try {
|
|
66
|
-
const parsed = JSON.parse(json) as { mode?: string; deps?: { mode?: string }; symlinks?: { linked?: string[] } };
|
|
83
|
+
const parsed = JSON.parse(json) as { mode?: string; branch?: string; baseRef?: string; deps?: { mode?: string }; symlinks?: { linked?: string[] } };
|
|
67
84
|
return [
|
|
85
|
+
workspaceLifecycleNote({ mode: parsed.mode ?? null, branch: parsed.branch ?? null, baseRef: parsed.baseRef ?? null }),
|
|
68
86
|
workspaceDepsNote({ mode: parsed.mode ?? null, depsMode: parsed.deps?.mode ?? null }),
|
|
69
87
|
parsed.mode === "isolated" ? workspaceSymlinksNote(parsed.symlinks?.linked ?? []) : "",
|
|
70
88
|
].filter(Boolean).join("\n\n");
|
package/src/version.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { CONTRACT_VERSIONS } from "agent-relay-sdk";
|
|
4
5
|
|
|
5
6
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
7
|
const pkg = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf8")) as { name?: string; version?: string };
|
|
7
8
|
|
|
8
9
|
export const PACKAGE_NAME = pkg.name || "agent-relay-runner";
|
|
9
10
|
export const VERSION = pkg.version || "0.0.0";
|
|
10
|
-
|
|
11
|
-
export const
|
|
11
|
+
// Protocol versions are owned by the SDK (CONTRACT_VERSIONS) — derive, never redeclare.
|
|
12
|
+
export const RUNNER_PROTOCOL_VERSION = CONTRACT_VERSIONS.runnerProtocol;
|
|
13
|
+
export const PROVIDER_PLUGIN_PROTOCOL_VERSION = CONTRACT_VERSIONS.providerPluginProtocol;
|
|
12
14
|
|
|
13
15
|
export const CONTRACTS = {
|
|
14
16
|
runnerProtocol: RUNNER_PROTOCOL_VERSION,
|