fix(tools): flatten nested anyOf schemas for Vertex AI compatibility

Claude API on Vertex AI (Cloud Code Assist) rejects nested anyOf schemas
as invalid JSON Schema draft 2020-12. This change:

- Add tryFlattenLiteralAnyOf() to convert Type.Union([Type.Literal(...)])
  patterns from anyOf with const values to flat enum arrays
- Update stringEnum helper in bash-tools to use Type.Unsafe with flat enum
- Flatten BrowserActSchema from discriminated union to single object
- Simplify TelegramToolSchema to use Type.String() for IDs

Fixes 400 errors when sending messages through WhatsApp/Telegram providers.
This commit is contained in:
Kit
2026-01-07 16:54:13 +00:00
committed by Peter Steinberger
parent de55f4e111
commit a2b3f2c18a
4 changed files with 132 additions and 80 deletions

View File

@@ -39,17 +39,19 @@ const DEFAULT_PATH =
process.env.PATH ??
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
const stringEnum = (
values: readonly string[],
options?: Parameters<typeof Type.Union>[1],
// NOTE: Using Type.Unsafe with enum instead of Type.Union([Type.Literal(...)])
// because Claude API on Vertex AI rejects nested anyOf schemas as invalid JSON Schema.
// Type.Union of literals compiles to { anyOf: [{enum:["a"]}, {enum:["b"]}, ...] }
// which is valid but not accepted. A flat enum { type: "string", enum: [...] } works.
const stringEnum = <T extends readonly string[]>(
values: T,
options?: { description?: string },
) =>
Type.Union(
values.map((value) => Type.Literal(value)) as [
ReturnType<typeof Type.Literal>,
...ReturnType<typeof Type.Literal>[],
],
options,
);
Type.Unsafe<T[number]>({
type: "string",
enum: values as unknown as string[],
...options,
});
export type BashToolDefaults = {
backgroundMs?: number;