mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 13:41:35 +00:00
chore(cli): drop dead classifiers and single-use wrappers left by fallback removal (#112191)
Follow-up to c5254f13ee (#112074): delete the legacy string-match timeout
classifier (the CLI path only sees typed GatewayTransportError from
callGateway's wrapper timer), the duplicate JSON/blank-message validation
in the private gateway command, the now-pointless getGatewayDispatchConfig
wrapper, the single-use embedded-loader alias, and the cross-os release
guard for the EMBEDDED FALLBACK marker no build can emit anymore.
This commit is contained in:
committed by
GitHub
parent
ae27ee98f0
commit
e1ff65fb77
@@ -1,6 +1,6 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { appendFileSync } from "node:fs";
|
||||
import type { AgentOutputOptions, AgentTurnResult } from "./config.ts";
|
||||
import type { AgentOutputOptions } from "./config.ts";
|
||||
import { CROSS_OS_AGENT_TURN_OPTIONAL, CROSS_OS_AGENT_TURN_TIMEOUT_SECONDS } from "./config.ts";
|
||||
import { readLogTextTail } from "./logs.ts";
|
||||
|
||||
@@ -73,24 +73,11 @@ export function buildReleaseAgentTurnArgs(sessionId: string) {
|
||||
|
||||
export function shouldRetryCrossOsAgentTurnError(error: unknown) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
return /Agent output did not contain the expected OK marker|Agent turn used embedded fallback instead of gateway|model idle timeout|did not produce a response before the model idle timeout|gateway request timeout for agent|Command timed out|timed out and could not be terminated cleanly|rate limit reached|rate_limit_exceeded|HTTP 429|HTTP 503|upstream connect error|disconnect\/reset before headers|connection timeout/u.test(
|
||||
return /Agent output did not contain the expected OK marker|model idle timeout|did not produce a response before the model idle timeout|gateway request timeout for agent|Command timed out|timed out and could not be terminated cleanly|rate limit reached|rate_limit_exceeded|HTTP 429|HTTP 503|upstream connect error|disconnect\/reset before headers|connection timeout/u.test(
|
||||
message,
|
||||
);
|
||||
}
|
||||
|
||||
export function agentTurnUsedEmbeddedFallback(
|
||||
result: Pick<AgentTurnResult, "stdout" | "stderr">,
|
||||
options: AgentOutputOptions = {},
|
||||
) {
|
||||
const logText =
|
||||
typeof options.logText === "string"
|
||||
? options.logText
|
||||
: typeof options.logPath === "string"
|
||||
? readLogTextTail(options.logPath)
|
||||
: "";
|
||||
return /EMBEDDED FALLBACK:/u.test(`${result.stdout ?? ""}\n${result.stderr ?? ""}\n${logText}`);
|
||||
}
|
||||
|
||||
export function agentOutputHasExpectedOkMarker(stdout: string, options: AgentOutputOptions = {}) {
|
||||
const payloadTexts = parseAgentPayloadTexts(stdout);
|
||||
if (payloadTexts.some((text) => text.trim() === "OK")) {
|
||||
|
||||
@@ -3,7 +3,6 @@ import { appendFileSync, createWriteStream, existsSync, mkdirSync } from "node:f
|
||||
import { dirname, join } from "node:path";
|
||||
import {
|
||||
agentOutputHasExpectedOkMarker,
|
||||
agentTurnUsedEmbeddedFallback,
|
||||
buildCrossOsReleaseAgentSessionId,
|
||||
buildReleaseAgentTurnArgs,
|
||||
maybeBuildOptionalAgentTurnSkipResult,
|
||||
@@ -766,9 +765,6 @@ export async function runInstalledAgentTurn(params: {
|
||||
if (!agentOutputHasExpectedOkMarker(result.stdout, { logText })) {
|
||||
throw new Error("Agent output did not contain the expected OK marker.");
|
||||
}
|
||||
if (agentTurnUsedEmbeddedFallback(result, { logText })) {
|
||||
throw new Error("Agent turn used embedded fallback instead of gateway.");
|
||||
}
|
||||
return result;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
|
||||
@@ -2,7 +2,6 @@ import { spawn } from "node:child_process";
|
||||
import { appendFileSync, createWriteStream } from "node:fs";
|
||||
import {
|
||||
agentOutputHasExpectedOkMarker,
|
||||
agentTurnUsedEmbeddedFallback,
|
||||
buildCrossOsReleaseAgentSessionId,
|
||||
buildReleaseAgentTurnArgs,
|
||||
maybeBuildOptionalAgentTurnSkipResult,
|
||||
@@ -308,9 +307,6 @@ export async function runAgentTurn(
|
||||
if (!agentOutputHasExpectedOkMarker(result.stdout, { logText })) {
|
||||
throw new Error("Agent output did not contain the expected OK marker.");
|
||||
}
|
||||
if (agentTurnUsedEmbeddedFallback(result, { logText })) {
|
||||
throw new Error("Agent turn used embedded fallback instead of gateway.");
|
||||
}
|
||||
return result;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
|
||||
@@ -136,7 +136,6 @@ function resolveGatewayAbortRetryDelaysMs(): readonly number[] {
|
||||
return gatewayAbortRetryDelaysMsForTests ?? GATEWAY_ABORT_RETRY_DELAYS_MS;
|
||||
}
|
||||
|
||||
const loadEmbeddedAgentCommand = embeddedAgentCommandLoader.load;
|
||||
const loadAgentSessionModule = agentSessionModuleCache.load;
|
||||
|
||||
async function loadRuntimeConfig(): Promise<OpenClawConfig> {
|
||||
@@ -273,17 +272,6 @@ function resolveGatewayAgentTimeoutMs(timeoutSeconds: number): number {
|
||||
return resolveTimerTimeoutMs((timeoutSeconds + 30) * 1000, 10_000, 10_000);
|
||||
}
|
||||
|
||||
async function getGatewayDispatchConfig(options?: {
|
||||
skipShellEnvFallback?: boolean;
|
||||
}): Promise<OpenClawConfig> {
|
||||
// Scoped gateway turns need core agent/session/gateway fields only. The
|
||||
// running gateway owns plugin validation and plugin metadata freshness.
|
||||
if (options?.skipShellEnvFallback === false) {
|
||||
return await readGatewayDispatchConfigWithShellEnvFallback();
|
||||
}
|
||||
return readGatewayDispatchConfig();
|
||||
}
|
||||
|
||||
async function formatPayloadForLog(payload: {
|
||||
text?: string;
|
||||
mediaUrls?: string[];
|
||||
@@ -305,13 +293,6 @@ async function formatPayloadForLog(payload: {
|
||||
return lines.join("\n").trimEnd();
|
||||
}
|
||||
|
||||
function isGatewayAgentTimeoutError(err: unknown): boolean {
|
||||
if (isGatewayTransportError(err)) {
|
||||
return err.kind === "timeout";
|
||||
}
|
||||
return err instanceof Error && err.message.includes("gateway request timeout for agent");
|
||||
}
|
||||
|
||||
function isCompactControlCommand(message: string): boolean {
|
||||
return /^\/compact(?:\s|:|$)/iu.test(message.trim());
|
||||
}
|
||||
@@ -331,10 +312,12 @@ function shouldRetryGatewayDispatchWithShellEnvFallback(err: unknown): boolean {
|
||||
function resolveGatewayAgentFailureHint(
|
||||
err: unknown,
|
||||
): "timed out" | "connection closed" | undefined {
|
||||
if (isGatewayAgentTimeoutError(err)) {
|
||||
return "timed out";
|
||||
if (!isGatewayTransportError(err)) {
|
||||
return undefined;
|
||||
}
|
||||
return isGatewayTransportError(err) && err.kind === "closed" ? "connection closed" : undefined;
|
||||
// callGateway's wrapper timer gives this CLI path typed transport errors.
|
||||
// Legacy request-timeout strings belong to lower-level and in-process callers.
|
||||
return err.kind === "timeout" ? "timed out" : "connection closed";
|
||||
}
|
||||
|
||||
function isTransientGatewayAgentConnectClose(err: unknown): boolean {
|
||||
@@ -394,7 +377,7 @@ async function normalizeSessionKeyOptsForDispatch(
|
||||
isLegacySessionKey && (agentIdRaw || shouldScopeDefaultAgentKey)
|
||||
? opts.local === true
|
||||
? await loadRuntimeConfig()
|
||||
: await getGatewayDispatchConfig()
|
||||
: readGatewayDispatchConfig()
|
||||
: undefined;
|
||||
const sessionKey = scopeLegacySessionKeyToAgent({
|
||||
agentId: agentIdRaw ?? (shouldScopeDefaultAgentKey ? resolveDefaultAgentId(cfg!) : undefined),
|
||||
@@ -663,19 +646,17 @@ async function agentViaGatewayCommand(
|
||||
runtime: RuntimeEnv,
|
||||
signalBridge: ReturnType<typeof createAgentCliSignalBridge>,
|
||||
) {
|
||||
protectJsonStdout(opts);
|
||||
const body = opts.message;
|
||||
const explicitSessionKey = opts.sessionKey?.trim();
|
||||
if (!body.trim()) {
|
||||
throw missingAgentMessageError();
|
||||
}
|
||||
if (!opts.to && !opts.sessionId && !opts.agent && !explicitSessionKey) {
|
||||
throw new Error(
|
||||
`No target session selected. Use --agent <id>, --session-key <key>, --session-id <id>, or --to <E.164>. Run ${formatCliCommand("openclaw agents list")} to see agents.`,
|
||||
);
|
||||
}
|
||||
|
||||
let cfg = await getGatewayDispatchConfig();
|
||||
// Scoped gateway turns need core agent/session/gateway fields only. The
|
||||
// running gateway owns plugin validation and plugin metadata freshness.
|
||||
let cfg: OpenClawConfig = readGatewayDispatchConfig();
|
||||
const agentIdRaw = opts.agent?.trim();
|
||||
const agentId = agentIdRaw ? normalizeAgentId(agentIdRaw) : undefined;
|
||||
if (agentId) {
|
||||
@@ -806,7 +787,7 @@ async function agentViaGatewayCommand(
|
||||
shouldRetryGatewayDispatchWithShellEnvFallback(err) &&
|
||||
consumeShellEnvFallbackRetry()
|
||||
) {
|
||||
cfg = await getGatewayDispatchConfig({ skipShellEnvFallback: false });
|
||||
cfg = await readGatewayDispatchConfigWithShellEnvFallback();
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
@@ -914,7 +895,7 @@ export async function agentCliCommand(
|
||||
const signalBridge = createAgentCliSignalBridge(resolveAgentCliProcessLike(deps));
|
||||
try {
|
||||
if (dispatchOpts.local === true) {
|
||||
const agentCommand = await loadEmbeddedAgentCommand();
|
||||
const agentCommand = await embeddedAgentCommandLoader.load();
|
||||
const result = await agentCommand(
|
||||
{
|
||||
...gatewayDispatchOpts,
|
||||
|
||||
@@ -19,7 +19,6 @@ import { pathToFileURL } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
agentOutputHasExpectedOkMarker,
|
||||
agentTurnUsedEmbeddedFallback,
|
||||
buildCrossOsDiscordRoundtripNonces,
|
||||
buildCrossOsReleaseAgentSessionId,
|
||||
buildCrossOsReleaseSmokePluginAllowlist,
|
||||
@@ -455,11 +454,6 @@ describe("scripts/openclaw-cross-os-release-checks", () => {
|
||||
new Error("Command timed out and could not be terminated cleanly"),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
shouldRetryCrossOsAgentTurnError(
|
||||
new Error("Agent turn used embedded fallback instead of gateway."),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(
|
||||
shouldRetryCrossOsAgentTurnError(
|
||||
new Error(
|
||||
@@ -486,35 +480,6 @@ describe("scripts/openclaw-cross-os-release-checks", () => {
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("detects embedded fallback agent turns as non-gateway proof", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "openclaw-cross-os-agent-fallback-"));
|
||||
const logPath = join(dir, "agent.log");
|
||||
expect(
|
||||
agentTurnUsedEmbeddedFallback({
|
||||
stdout: JSON.stringify({ payloads: [{ text: "OK" }] }),
|
||||
stderr: "EMBEDDED FALLBACK: Gateway agent failed; running embedded agent: gateway closed",
|
||||
}),
|
||||
).toBe(true);
|
||||
expect(
|
||||
agentTurnUsedEmbeddedFallback({
|
||||
stdout: JSON.stringify({ payloads: [{ text: "OK" }] }),
|
||||
stderr: "",
|
||||
}),
|
||||
).toBe(false);
|
||||
expect(
|
||||
agentTurnUsedEmbeddedFallback(
|
||||
{ stdout: "", stderr: "" },
|
||||
{ logText: 'EMBEDDED FALLBACK: Gateway agent failed\n{"payloads":[{"text":"OK"}]}' },
|
||||
),
|
||||
).toBe(true);
|
||||
try {
|
||||
writeFileSync(logPath, "EMBEDDED FALLBACK: Gateway agent failed\n");
|
||||
expect(agentTurnUsedEmbeddedFallback({ stdout: "", stderr: "" }, { logPath })).toBe(true);
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("skips optional live agent turns only for model availability failures", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "openclaw-cross-os-agent-skip-"));
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user