agent-relay-orchestrator 0.12.1 → 0.12.2
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 +1 -1
- package/src/api.ts +6 -1
- package/src/spawn.ts +34 -1
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { proxyArtifactRequest } from "./artifact-proxy";
|
|
|
5
5
|
import type { OrchestratorConfig } from "./config";
|
|
6
6
|
import type { ProviderProbeCache } from "./provider-probe";
|
|
7
7
|
import type { RelayClient } from "./relay";
|
|
8
|
-
import { captureSession, captureTerminal, createTerminalGuest, listSessions, sendTerminalInput, resizeTerminal, stopTerminalGuest } from "./spawn";
|
|
8
|
+
import { captureSession, captureSessionMirror, captureTerminal, createTerminalGuest, listSessions, sendTerminalInput, resizeTerminal, stopTerminalGuest } from "./spawn";
|
|
9
9
|
import { acquireTerminalStream, type TerminalStreamHandle, type TerminalStreamSubscriber } from "./terminal-stream";
|
|
10
10
|
import { VERSION, runtimeMetadata } from "./version";
|
|
11
11
|
import { previewWorkspaceMerge, probeWorkspace, workspaceDiff, workspaceGitState } from "./workspace-probe";
|
|
@@ -545,6 +545,11 @@ export function startApiServer(config: OrchestratorConfig, probeCache: ProviderP
|
|
|
545
545
|
try {
|
|
546
546
|
const session = decodeURIComponent(logMatch[1]!);
|
|
547
547
|
const lines = Number(url.searchParams.get("lines") || "100");
|
|
548
|
+
// ?stream=mirror returns the clean session-mirror diagnostics log instead
|
|
549
|
+
// of the provider's ANSI TUI capture.
|
|
550
|
+
if (url.searchParams.get("stream") === "mirror") {
|
|
551
|
+
return json(captureSessionMirror(session, config, Number.isFinite(lines) ? lines : 200));
|
|
552
|
+
}
|
|
548
553
|
return json(captureSession(session, config, Number.isFinite(lines) ? lines : 100, {
|
|
549
554
|
raw: url.searchParams.get("raw") === "1",
|
|
550
555
|
}));
|
package/src/spawn.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { chmodSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
-
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
3
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
4
4
|
import { artifactProxyBaseUrl } from "./artifact-proxy";
|
|
5
5
|
import type { OrchestratorConfig } from "./config";
|
|
6
6
|
import type { ManagedAgentReport, ManagedSessionExitDiagnostics } from "./relay";
|
|
@@ -951,6 +951,39 @@ export function captureSession(
|
|
|
951
951
|
};
|
|
952
952
|
}
|
|
953
953
|
|
|
954
|
+
// Mirrors the runner's safeLogName so the orchestrator resolves the same filename.
|
|
955
|
+
function safeMirrorLogName(value: string): string {
|
|
956
|
+
return value.replace(/[^a-zA-Z0-9_.-]+/g, "_").slice(0, 180);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
// Read the clean, ANSI-free session-mirror diagnostics log for a managed agent.
|
|
960
|
+
// Accepts either the tmux session name or the agent id; the mirror log is keyed by
|
|
961
|
+
// agent id. Returns the same shape as captureSession so the proxy is uniform.
|
|
962
|
+
export function captureSessionMirror(
|
|
963
|
+
name: string,
|
|
964
|
+
_config: OrchestratorConfig,
|
|
965
|
+
lines = 200,
|
|
966
|
+
): { session: string; lines: string[]; running: boolean; mirror: true } {
|
|
967
|
+
const records = loadState();
|
|
968
|
+
const record = records.find((r) => r.name === name) ?? records.find((r) => r.agentId === name);
|
|
969
|
+
const agentId = record?.agentId ?? name;
|
|
970
|
+
const running = record ? isSessionRecordAlive(record) : false;
|
|
971
|
+
// The mirror log lives in the same directory as the provider log (both written
|
|
972
|
+
// by the same user on this host). Derive from the record's logFile when known so
|
|
973
|
+
// it tracks any per-session log relocation.
|
|
974
|
+
const logDir = record?.logFile ? dirname(record.logFile) : LOG_DIR;
|
|
975
|
+
const mirrorPath = join(logDir, `session-mirror-${safeMirrorLogName(agentId)}.log`);
|
|
976
|
+
let content: string;
|
|
977
|
+
try {
|
|
978
|
+
content = readFileSync(mirrorPath, "utf8");
|
|
979
|
+
} catch {
|
|
980
|
+
return { session: name, lines: [], running, mirror: true };
|
|
981
|
+
}
|
|
982
|
+
const allLines = content.split(/\r?\n/).filter(Boolean);
|
|
983
|
+
const safeLines = Math.min(Math.max(lines, 1), 2000);
|
|
984
|
+
return { session: name, lines: allLines.slice(-safeLines), running, mirror: true };
|
|
985
|
+
}
|
|
986
|
+
|
|
954
987
|
export function captureTerminal(name: string, config: OrchestratorConfig): TerminalSnapshot {
|
|
955
988
|
if (!name.startsWith(`${config.tmuxPrefix}-`)) throw new Error("session is not managed by this orchestrator");
|
|
956
989
|
|