mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:20:43 +00:00
fix(acpx): ignore Codex ACP timeout config
This commit is contained in:
@@ -17,6 +17,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Agents/ACPX: stop forwarding Codex ACP timeout config controls that Codex rejects while preserving OpenClaw's run-timeout watchdog for ACP subagents. Fixes #73052. Thanks @pfrederiksen and @richa65.
|
||||
- Docs/tools: clarify that `tools.profile: "messaging"` is intentionally narrow and that `tools.profile: "full"` is the unrestricted baseline for broader command/control access. Carries forward #39954. Thanks @posigit.
|
||||
- Control UI/Agents: redact tool-call args, partial/final results, derived exec output, and configured custom secret patterns before streaming tool events to the Control UI, so tool output cannot expose provider or channel credentials. Fixes #72283. (#72319) Thanks @volcano303 and @BunsDev.
|
||||
- Agents/sessions: keep `sessions_history` recall redaction enabled even when general log redaction is disabled, and clarify that safety-boundary UI/tool/diagnostic payloads still redact independently of `logging.redactSensitive`. Carries forward #72319. Thanks @volcano303 and @BunsDev.
|
||||
|
||||
@@ -353,6 +353,68 @@ describe("AcpxRuntime fresh reset wrapper", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("ignores unsupported Codex ACP timeout config controls", async () => {
|
||||
const baseStore: TestSessionStore = {
|
||||
load: vi.fn(async () => ({
|
||||
acpxRecordId: "agent:codex:acp:test",
|
||||
agentCommand: CODEX_ACP_COMMAND,
|
||||
})),
|
||||
save: vi.fn(async () => {}),
|
||||
};
|
||||
const { runtime, delegate } = makeRuntime(baseStore);
|
||||
const setConfigOption = vi.spyOn(delegate, "setConfigOption").mockResolvedValue(undefined);
|
||||
const handle: Parameters<NonNullable<AcpRuntime["setConfigOption"]>>[0]["handle"] = {
|
||||
sessionKey: "agent:codex:acp:test",
|
||||
backend: "acpx",
|
||||
runtimeSessionName: "agent:codex:acp:test",
|
||||
acpxRecordId: "agent:codex:acp:test",
|
||||
};
|
||||
|
||||
await runtime.setConfigOption({
|
||||
handle,
|
||||
key: "timeout",
|
||||
value: "60000",
|
||||
});
|
||||
await runtime.setConfigOption({
|
||||
handle,
|
||||
key: "Timeout_Seconds",
|
||||
value: "60",
|
||||
});
|
||||
|
||||
expect(setConfigOption).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("forwards timeout config controls for non-Codex ACP agents", async () => {
|
||||
const baseStore: TestSessionStore = {
|
||||
load: vi.fn(async () => ({
|
||||
acpxRecordId: "agent:claude:acp:test",
|
||||
agentCommand: "npx @agentclientprotocol/claude-agent-acp",
|
||||
})),
|
||||
save: vi.fn(async () => {}),
|
||||
};
|
||||
const { runtime, delegate } = makeRuntime(baseStore);
|
||||
const setConfigOption = vi.spyOn(delegate, "setConfigOption").mockResolvedValue(undefined);
|
||||
const handle: Parameters<NonNullable<AcpRuntime["setConfigOption"]>>[0]["handle"] = {
|
||||
sessionKey: "agent:claude:acp:test",
|
||||
backend: "acpx",
|
||||
runtimeSessionName: "agent:claude:acp:test",
|
||||
acpxRecordId: "agent:claude:acp:test",
|
||||
};
|
||||
|
||||
await runtime.setConfigOption({
|
||||
handle,
|
||||
key: "timeout",
|
||||
value: "60",
|
||||
});
|
||||
|
||||
expect(setConfigOption).toHaveBeenCalledOnce();
|
||||
expect(setConfigOption).toHaveBeenCalledWith({
|
||||
handle,
|
||||
key: "timeout",
|
||||
value: "60",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps stale persistent loads hidden until a fresh record is saved", async () => {
|
||||
const baseStore: TestSessionStore = {
|
||||
load: vi.fn(async () => ({ acpxRecordId: "stale" }) as never),
|
||||
|
||||
@@ -510,36 +510,41 @@ export class AcpxRuntime implements AcpRuntime {
|
||||
): Promise<void> {
|
||||
const delegate = await this.resolveDelegateForHandle(input.handle);
|
||||
const command = await this.resolveCommandForHandle(input.handle);
|
||||
if (
|
||||
(input.key === "model" ||
|
||||
input.key === "thinking" ||
|
||||
input.key === "thought_level" ||
|
||||
input.key === "reasoning_effort") &&
|
||||
isCodexAcpCommand(command)
|
||||
) {
|
||||
const override =
|
||||
input.key === "model"
|
||||
? normalizeCodexAcpModelOverride(input.value)
|
||||
: normalizeCodexAcpModelOverride(undefined, input.value);
|
||||
if (!override && input.key !== "model") {
|
||||
const key = input.key.trim().toLowerCase();
|
||||
if (isCodexAcpCommand(command)) {
|
||||
if (key === "timeout" || key === "timeout_seconds") {
|
||||
return;
|
||||
}
|
||||
if (override) {
|
||||
if (override.model) {
|
||||
await delegate.setConfigOption({
|
||||
...input,
|
||||
key: "model",
|
||||
value: override.model,
|
||||
});
|
||||
if (
|
||||
key === "model" ||
|
||||
key === "thinking" ||
|
||||
key === "thought_level" ||
|
||||
key === "reasoning_effort"
|
||||
) {
|
||||
const override =
|
||||
key === "model"
|
||||
? normalizeCodexAcpModelOverride(input.value)
|
||||
: normalizeCodexAcpModelOverride(undefined, input.value);
|
||||
if (!override && key !== "model") {
|
||||
return;
|
||||
}
|
||||
if (override.reasoningEffort) {
|
||||
await delegate.setConfigOption({
|
||||
...input,
|
||||
key: "reasoning_effort",
|
||||
value: override.reasoningEffort,
|
||||
});
|
||||
if (override) {
|
||||
if (override.model) {
|
||||
await delegate.setConfigOption({
|
||||
...input,
|
||||
key: "model",
|
||||
value: override.model,
|
||||
});
|
||||
}
|
||||
if (override.reasoningEffort) {
|
||||
await delegate.setConfigOption({
|
||||
...input,
|
||||
key: "reasoning_effort",
|
||||
value: override.reasoningEffort,
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
await delegate.setConfigOption(input);
|
||||
|
||||
Reference in New Issue
Block a user