fix: browser fill default type parity (#27662) (thanks @Uface11)

This commit is contained in:
Peter Steinberger
2026-02-26 22:14:06 +01:00
parent a0b12f2ba7
commit 2ed9d633b3
3 changed files with 22 additions and 4 deletions

View File

@@ -69,6 +69,7 @@ Docs: https://docs.openclaw.ai
- Browser/Extension relay init: dedupe concurrent same-port relay startup with shared in-flight initialization promises so callers await one startup lifecycle and receive consistent success/failure results. Landed from contributor PR #21277 by @HOYALIM. (Related #20688)
- Browser/Extension relay shutdown: flush pending extension-request timers/rejections during relay `stop()` before socket/server teardown so in-flight extension waits do not survive shutdown windows. Landed from contributor PR #24142 by @kevinWangSheng.
- Browser/Extension relay reconnect resilience: keep CDP clients alive across brief MV3 extension disconnect windows, wait briefly for extension reconnect before failing in-flight CDP commands, and only tear down relay target/client state after reconnect grace expires. Landed from contributor PR #27617 by @davidemanuelDEV.
- Browser/Fill relay + CLI parity: accept `act.fill` fields without explicit `type` by defaulting missing/empty `type` to `text` in both browser relay route parsing and `openclaw browser fill` CLI field parsing, so relay calls no longer fail when the model omits field type metadata. Landed from contributor PR #27662 by @Uface11. (#27296) Thanks @Uface11.
- Browser/Route decode hardening: guard malformed percent-encoding in relay target action routes and browser route-param decoding so crafted `%` paths return `400` instead of crashing/unhandled URI decode failures. Landed from contributor PR #11880 by @Yida-Dev.
- Feishu/Permission error dispatch: merge sender-name permission notices into the main inbound dispatch so one user message produces one agent turn/reply (instead of a duplicate permission-notice turn), with regression coverage. (#27381) thanks @byungsker.
- Feishu/Inbound message metadata: include inbound `message_id` in `BodyForAgent` on a dedicated metadata line so agents can reliably correlate and act on media/message operations that require message IDs, with regression coverage. (#27253) thanks @xss925175263.

View File

@@ -0,0 +1,16 @@
import { describe, expect, it } from "vitest";
import { readFields } from "./shared.js";
describe("readFields", () => {
it("defaults missing type to text", async () => {
await expect(readFields({ fields: '[{"ref":"7","value":"world"}]' })).resolves.toEqual([
{ ref: "7", type: "text", value: "world" },
]);
});
it("requires ref", async () => {
await expect(readFields({ fields: '[{"type":"textbox","value":"world"}]' })).rejects.toThrow(
"fields[0] must include ref",
);
});
});

View File

@@ -70,18 +70,19 @@ export async function readFields(opts: {
const rec = entry as Record<string, unknown>;
const ref = typeof rec.ref === "string" ? rec.ref.trim() : "";
const type = typeof rec.type === "string" ? rec.type.trim() : "";
if (!ref || !type) {
throw new Error(`fields[${index}] must include ref and type`);
if (!ref) {
throw new Error(`fields[${index}] must include ref`);
}
const resolvedType = type || "text";
if (
typeof rec.value === "string" ||
typeof rec.value === "number" ||
typeof rec.value === "boolean"
) {
return { ref, type, value: rec.value };
return { ref, type: resolvedType, value: rec.value };
}
if (rec.value === undefined || rec.value === null) {
return { ref, type };
return { ref, type: resolvedType };
}
throw new Error(`fields[${index}].value must be string, number, boolean, or null`);
});