@oh-my-pi/pi-ai 4.4.6 → 4.4.9
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
|
@@ -200,6 +200,18 @@ const UNSUPPORTED_SCHEMA_FIELDS = new Set([
|
|
|
200
200
|
"prefixItems",
|
|
201
201
|
"unevaluatedProperties",
|
|
202
202
|
"unevaluatedItems",
|
|
203
|
+
"patternProperties",
|
|
204
|
+
"additionalProperties",
|
|
205
|
+
"minItems",
|
|
206
|
+
"maxItems",
|
|
207
|
+
"minLength",
|
|
208
|
+
"maxLength",
|
|
209
|
+
"minimum",
|
|
210
|
+
"maximum",
|
|
211
|
+
"exclusiveMinimum",
|
|
212
|
+
"exclusiveMaximum",
|
|
213
|
+
"pattern",
|
|
214
|
+
"format",
|
|
203
215
|
]);
|
|
204
216
|
|
|
205
217
|
export function sanitizeSchemaForGoogle(value: unknown): unknown {
|
|
@@ -211,43 +223,73 @@ export function sanitizeSchemaForGoogle(value: unknown): unknown {
|
|
|
211
223
|
return value;
|
|
212
224
|
}
|
|
213
225
|
|
|
226
|
+
const obj = value as Record<string, unknown>;
|
|
214
227
|
const result: Record<string, unknown> = {};
|
|
215
|
-
let constValue: unknown | undefined;
|
|
216
228
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
229
|
+
// Collapse anyOf/oneOf of const values into enum
|
|
230
|
+
for (const combiner of ["anyOf", "oneOf"] as const) {
|
|
231
|
+
if (Array.isArray(obj[combiner])) {
|
|
232
|
+
const variants = obj[combiner] as Record<string, unknown>[];
|
|
233
|
+
|
|
234
|
+
// Check if ALL variants have a const field
|
|
235
|
+
const allHaveConst = variants.every((v) => v && typeof v === "object" && "const" in v);
|
|
236
|
+
|
|
237
|
+
if (allHaveConst && variants.length > 0) {
|
|
238
|
+
// Extract all const values into enum
|
|
239
|
+
result.enum = variants.map((v) => v.const);
|
|
240
|
+
|
|
241
|
+
// Inherit type from first variant if present
|
|
242
|
+
const firstType = variants[0]?.type;
|
|
243
|
+
if (firstType) {
|
|
244
|
+
result.type = firstType;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Copy description and other top-level fields (not the combiner)
|
|
248
|
+
for (const [key, entry] of Object.entries(obj)) {
|
|
249
|
+
if (key !== combiner && !(key in result)) {
|
|
250
|
+
result[key] = sanitizeSchemaForGoogle(entry);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
220
255
|
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Regular field processing
|
|
259
|
+
let constValue: unknown;
|
|
260
|
+
for (const [key, entry] of Object.entries(obj)) {
|
|
261
|
+
if (UNSUPPORTED_SCHEMA_FIELDS.has(key)) continue;
|
|
221
262
|
if (key === "const") {
|
|
222
263
|
constValue = entry;
|
|
223
264
|
continue;
|
|
224
265
|
}
|
|
225
|
-
if (key === "additionalProperties" && entry === false)
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
266
|
+
if (key === "additionalProperties" && entry === false) continue;
|
|
228
267
|
result[key] = sanitizeSchemaForGoogle(entry);
|
|
229
268
|
}
|
|
230
269
|
|
|
231
270
|
if (constValue !== undefined) {
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
if (!
|
|
235
|
-
|
|
271
|
+
// Convert const to enum, merging with existing enum if present
|
|
272
|
+
const existingEnum = Array.isArray(result.enum) ? result.enum : [];
|
|
273
|
+
if (!existingEnum.some((item) => Object.is(item, constValue))) {
|
|
274
|
+
existingEnum.push(constValue);
|
|
275
|
+
}
|
|
276
|
+
result.enum = existingEnum;
|
|
277
|
+
if (!result.type) {
|
|
278
|
+
result.type =
|
|
279
|
+
typeof constValue === "string"
|
|
280
|
+
? "string"
|
|
281
|
+
: typeof constValue === "number"
|
|
282
|
+
? "number"
|
|
283
|
+
: typeof constValue === "boolean"
|
|
284
|
+
? "boolean"
|
|
285
|
+
: undefined;
|
|
236
286
|
}
|
|
237
|
-
result.enum = enumValues;
|
|
238
287
|
}
|
|
239
288
|
|
|
240
289
|
return result;
|
|
241
290
|
}
|
|
242
291
|
|
|
243
|
-
function
|
|
244
|
-
return {
|
|
245
|
-
name: tool.name,
|
|
246
|
-
description: tool.description,
|
|
247
|
-
parameters: structuredClone(tool.parameters),
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
function sanitizeToolGoogle(tool: Tool): Tool {
|
|
292
|
+
function sanitizeToolForGoogle(tool: Tool): Tool {
|
|
251
293
|
return {
|
|
252
294
|
name: tool.name,
|
|
253
295
|
description: tool.description,
|
|
@@ -260,11 +302,10 @@ function sanitizeToolGoogle(tool: Tool): Tool {
|
|
|
260
302
|
*/
|
|
261
303
|
export function convertTools(
|
|
262
304
|
tools: Tool[],
|
|
263
|
-
|
|
305
|
+
_model: Model<"google-generative-ai" | "google-gemini-cli" | "google-vertex">,
|
|
264
306
|
): { functionDeclarations: { name: string; description?: string; parameters: Schema }[] }[] | undefined {
|
|
265
307
|
if (tools.length === 0) return undefined;
|
|
266
|
-
|
|
267
|
-
return [{ functionDeclarations: tools.map(toolSanitizer) }];
|
|
308
|
+
return [{ functionDeclarations: tools.map(sanitizeToolForGoogle) }];
|
|
268
309
|
}
|
|
269
310
|
|
|
270
311
|
/**
|
|
@@ -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]> {
|