@oh-my-pi/pi-ai 4.4.6 → 4.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-ai",
3
- "version": "4.4.6",
3
+ "version": "4.4.8",
4
4
  "description": "Unified LLM API with automatic model discovery and provider configuration",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -211,43 +211,73 @@ export function sanitizeSchemaForGoogle(value: unknown): unknown {
211
211
  return value;
212
212
  }
213
213
 
214
+ const obj = value as Record<string, unknown>;
214
215
  const result: Record<string, unknown> = {};
215
- let constValue: unknown | undefined;
216
216
 
217
- for (const [key, entry] of Object.entries(value)) {
218
- if (UNSUPPORTED_SCHEMA_FIELDS.has(key)) {
219
- continue;
217
+ // Collapse anyOf/oneOf of const values into enum
218
+ for (const combiner of ["anyOf", "oneOf"] as const) {
219
+ if (Array.isArray(obj[combiner])) {
220
+ const variants = obj[combiner] as Record<string, unknown>[];
221
+
222
+ // Check if ALL variants have a const field
223
+ const allHaveConst = variants.every((v) => v && typeof v === "object" && "const" in v);
224
+
225
+ if (allHaveConst && variants.length > 0) {
226
+ // Extract all const values into enum
227
+ result.enum = variants.map((v) => v.const);
228
+
229
+ // Inherit type from first variant if present
230
+ const firstType = variants[0]?.type;
231
+ if (firstType) {
232
+ result.type = firstType;
233
+ }
234
+
235
+ // Copy description and other top-level fields (not the combiner)
236
+ for (const [key, entry] of Object.entries(obj)) {
237
+ if (key !== combiner && !(key in result)) {
238
+ result[key] = sanitizeSchemaForGoogle(entry);
239
+ }
240
+ }
241
+ return result;
242
+ }
220
243
  }
244
+ }
245
+
246
+ // Regular field processing
247
+ let constValue: unknown;
248
+ for (const [key, entry] of Object.entries(obj)) {
249
+ if (UNSUPPORTED_SCHEMA_FIELDS.has(key)) continue;
221
250
  if (key === "const") {
222
251
  constValue = entry;
223
252
  continue;
224
253
  }
225
- if (key === "additionalProperties" && entry === false) {
226
- continue;
227
- }
254
+ if (key === "additionalProperties" && entry === false) continue;
228
255
  result[key] = sanitizeSchemaForGoogle(entry);
229
256
  }
230
257
 
231
258
  if (constValue !== undefined) {
232
- const existingEnum = Array.isArray(result.enum) ? [...result.enum] : undefined;
233
- const enumValues = existingEnum ?? [];
234
- if (!enumValues.some((item) => Object.is(item, constValue))) {
235
- enumValues.push(constValue);
259
+ // Convert const to enum, merging with existing enum if present
260
+ const existingEnum = Array.isArray(result.enum) ? result.enum : [];
261
+ if (!existingEnum.some((item) => Object.is(item, constValue))) {
262
+ existingEnum.push(constValue);
263
+ }
264
+ result.enum = existingEnum;
265
+ if (!result.type) {
266
+ result.type =
267
+ typeof constValue === "string"
268
+ ? "string"
269
+ : typeof constValue === "number"
270
+ ? "number"
271
+ : typeof constValue === "boolean"
272
+ ? "boolean"
273
+ : undefined;
236
274
  }
237
- result.enum = enumValues;
238
275
  }
239
276
 
240
277
  return result;
241
278
  }
242
279
 
243
- function sanitizeToolNoop(tool: Tool): Tool {
244
- return {
245
- name: tool.name,
246
- description: tool.description,
247
- parameters: structuredClone(tool.parameters),
248
- };
249
- }
250
- function sanitizeToolGoogle(tool: Tool): Tool {
280
+ function sanitizeToolForGoogle(tool: Tool): Tool {
251
281
  return {
252
282
  name: tool.name,
253
283
  description: tool.description,
@@ -260,11 +290,10 @@ function sanitizeToolGoogle(tool: Tool): Tool {
260
290
  */
261
291
  export function convertTools(
262
292
  tools: Tool[],
263
- model: Model<"google-generative-ai" | "google-gemini-cli" | "google-vertex">,
293
+ _model: Model<"google-generative-ai" | "google-gemini-cli" | "google-vertex">,
264
294
  ): { functionDeclarations: { name: string; description?: string; parameters: Schema }[] }[] | undefined {
265
295
  if (tools.length === 0) return undefined;
266
- const toolSanitizer = model?.id.startsWith("gemini-") ? sanitizeToolGoogle : sanitizeToolNoop;
267
- return [{ functionDeclarations: tools.map(toolSanitizer) }];
296
+ return [{ functionDeclarations: tools.map(sanitizeToolForGoogle) }];
268
297
  }
269
298
 
270
299
  /**
@@ -11,7 +11,7 @@ import { type TUnsafe, Type } from "@sinclair/typebox";
11
11
  *
12
12
  * type Operation = Static<typeof OperationSchema>; // "add" | "subtract" | "multiply" | "divide"
13
13
  */
14
- export function StringEnum<T extends readonly string[]>(
14
+ export function StringEnum<const T extends readonly string[]>(
15
15
  values: T,
16
16
  options?: { description?: string; default?: T[number] },
17
17
  ): TUnsafe<T[number]> {