Files
orcs-code/src/utils/semanticBoolean.ts
did:key:z6MkqDnb7Siv3Cwj7pGJq4T5EsUisECqR8KpnDLwcaZq5TPr d2542c9a62 asdf
Squash the current repository state back into one baseline commit while
preserving the README reframing and repository contents.

Constraint: User explicitly requested a single squashed commit with subject "asdf"
Confidence: high
Scope-risk: broad
Reversibility: clean
Directive: This commit intentionally rewrites published history; coordinate before future force-pushes
Tested: git status clean; local history rewritten to one commit; force-pushed main to origin and instructkr
Not-tested: Fresh clone verification after push
2026-03-31 03:34:03 -07:00

30 lines
1.1 KiB
TypeScript

import { z } from 'zod/v4'
/**
* Boolean that also accepts the string literals "true"/"false".
*
* Tool inputs arrive as model-generated JSON. The model occasionally quotes
* booleans — `"replace_all":"false"` instead of `"replace_all":false` — and
* z.boolean() rejects that with a type error. z.coerce.boolean() is the wrong
* fix: it uses JS truthiness, so "false" → true.
*
* z.preprocess emits {"type":"boolean"} to the API schema, so the model is
* still told this is a boolean — the string tolerance is invisible client-side
* coercion, not an advertised input shape.
*
* .optional()/.default() go INSIDE (on the inner schema), not chained after:
* chaining them onto ZodPipe widens z.output<> to unknown in Zod v4.
*
* semanticBoolean() → boolean
* semanticBoolean(z.boolean().optional()) → boolean | undefined
* semanticBoolean(z.boolean().default(false)) → boolean
*/
export function semanticBoolean<T extends z.ZodType>(
inner: T = z.boolean() as unknown as T,
) {
return z.preprocess(
(v: unknown) => (v === 'true' ? true : v === 'false' ? false : v),
inner,
)
}