@gajae-code/ai 0.15.5 → 0.16.0
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/CHANGELOG.md +40 -0
- package/dist/types/adapter-internals/aws-region.d.ts +7 -0
- package/dist/types/auth-broker/client.d.ts +6 -2
- package/dist/types/auth-broker/remote-store.d.ts +14 -2
- package/dist/types/auth-broker/types.d.ts +6 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +19 -0
- package/dist/types/auth-gateway/server.d.ts +39 -5
- package/dist/types/auth-gateway/types.d.ts +16 -2
- package/dist/types/auth-storage.d.ts +92 -24
- package/dist/types/core.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/provider-models/openai-compat.d.ts +1 -0
- package/dist/types/providers/anthropic.d.ts +1 -1
- package/dist/types/providers/google-gemini-headers.d.ts +1 -1
- package/dist/types/providers/openai-codex-responses.d.ts +6 -0
- package/dist/types/providers/register-builtins.d.ts +12 -12
- package/dist/types/stream.d.ts +2 -1
- package/dist/types/types.d.ts +22 -2
- package/dist/types/utils/oauth/api-key-login.d.ts +4 -1
- package/dist/types/utils/oauth/api-key-validation.d.ts +12 -6
- package/dist/types/utils/oauth/commandcode.d.ts +1 -0
- package/dist/types/utils/oauth/types.d.ts +1 -1
- package/dist/types/utils/retry.d.ts +2 -0
- package/dist/types/utils/schema/normalize.d.ts +0 -5
- package/dist/types/utils/sqlite-errors.d.ts +4 -0
- package/package.json +3 -3
- package/src/adapter-internals/aws-region.d.ts +7 -0
- package/src/adapter-internals/aws-region.ts +14 -0
- package/src/auth-broker/client.ts +41 -13
- package/src/auth-broker/redact.ts +25 -1
- package/src/auth-broker/remote-store.ts +374 -115
- package/src/auth-broker/server.ts +131 -91
- package/src/auth-broker/types.ts +6 -0
- package/src/auth-broker/wire-schemas.ts +6 -0
- package/src/auth-gateway/server.ts +447 -79
- package/src/auth-gateway/types.ts +28 -2
- package/src/auth-storage.ts +672 -168
- package/src/cli.ts +1 -0
- package/src/core.ts +1 -0
- package/src/index.ts +1 -0
- package/src/model-thinking.ts +8 -0
- package/src/models.json +1224 -3
- package/src/provider-models/descriptors.ts +3 -1
- package/src/provider-models/openai-compat.ts +102 -1
- package/src/providers/amazon-bedrock.ts +5 -1
- package/src/providers/anthropic.d.ts +1 -1
- package/src/providers/anthropic.ts +8 -2
- package/src/providers/aws-credentials.ts +6 -0
- package/src/providers/azure-openai-responses.ts +4 -1
- package/src/providers/cursor.ts +256 -101
- package/src/providers/gitlab-duo.ts +18 -1
- package/src/providers/google-gemini-cli.ts +3 -0
- package/src/providers/google-gemini-headers.d.ts +1 -1
- package/src/providers/google-gemini-headers.ts +1 -1
- package/src/providers/google-shared.ts +3 -0
- package/src/providers/kiro-api-key.ts +33 -8
- package/src/providers/kiro-codewhisperer.ts +28 -9
- package/src/providers/ollama.ts +3 -0
- package/src/providers/openai-codex-responses.d.ts +6 -0
- package/src/providers/openai-codex-responses.ts +37 -8
- package/src/providers/openai-completions.ts +11 -1
- package/src/providers/openai-responses.ts +10 -1
- package/src/providers/pi-native-client.ts +25 -1
- package/src/providers/pi-native-server.ts +24 -0
- package/src/providers/register-builtins.d.ts +12 -12
- package/src/providers/register-builtins.ts +16 -3
- package/src/stream.d.ts +2 -1
- package/src/stream.ts +175 -67
- package/src/types.d.ts +22 -2
- package/src/types.ts +27 -1
- package/src/utils/oauth/api-key-login.ts +13 -2
- package/src/utils/oauth/api-key-validation.ts +242 -41
- package/src/utils/oauth/commandcode.ts +17 -0
- package/src/utils/oauth/index.ts +20 -5
- package/src/utils/oauth/kiro.ts +91 -22
- package/src/utils/oauth/types.d.ts +1 -1
- package/src/utils/oauth/types.ts +1 -0
- package/src/utils/retry.d.ts +2 -0
- package/src/utils/retry.ts +15 -2
- package/src/utils/schema/dereference.ts +169 -49
- package/src/utils/schema/draft.ts +46 -23
- package/src/utils/schema/normalize.d.ts +0 -5
- package/src/utils/schema/normalize.ts +396 -119
- package/src/utils/schema/types.ts +3 -1
- package/src/utils/schema/zod-decontaminate.ts +83 -29
- package/src/utils/sqlite-errors.d.ts +4 -0
- package/src/utils/sqlite-errors.ts +13 -0
- package/src/utils/tool-choice-capability.ts +2 -3
|
@@ -6,6 +6,8 @@ export function isJsonObject(value: unknown): value is JsonObject {
|
|
|
6
6
|
|
|
7
7
|
/** True when `value` is a plain JSON object with no own enumerable keys. */
|
|
8
8
|
export function isJsonObjectEmpty(value: JsonObject): boolean {
|
|
9
|
-
for (const
|
|
9
|
+
for (const key in value) {
|
|
10
|
+
if (Object.hasOwn(value, key)) return false;
|
|
11
|
+
}
|
|
10
12
|
return true;
|
|
11
13
|
}
|
|
@@ -114,17 +114,40 @@ const KEYS_THAT_ACCEPT_NULL: Record<string, true> = {
|
|
|
114
114
|
const: true,
|
|
115
115
|
examples: true,
|
|
116
116
|
};
|
|
117
|
+
const JSON_SCHEMA_LITERAL_PAYLOAD_KEYS = new Set(["default", "const", "enum", "examples"]);
|
|
118
|
+
const JSON_SCHEMA_MAP_KEYS = new Set([
|
|
119
|
+
"properties",
|
|
120
|
+
"patternProperties",
|
|
121
|
+
"dependencies",
|
|
122
|
+
"dependentSchemas",
|
|
123
|
+
"$defs",
|
|
124
|
+
"definitions",
|
|
125
|
+
]);
|
|
126
|
+
|
|
127
|
+
function setOwnKey(target: JsonObject, key: string, value: unknown): void {
|
|
128
|
+
if (key === "__proto__") {
|
|
129
|
+
Object.defineProperty(target, key, { value, writable: true, enumerable: true, configurable: true });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
target[key] = value;
|
|
133
|
+
}
|
|
117
134
|
|
|
118
135
|
function isZodLeak(node: JsonObject): boolean {
|
|
136
|
+
if (!Object.hasOwn(node, "def") || !Object.hasOwn(node, "type")) return false;
|
|
119
137
|
const def = node.def;
|
|
120
138
|
if (!isJsonObject(def)) return false;
|
|
139
|
+
if (!Object.hasOwn(def, "type")) return false;
|
|
121
140
|
const defType = def.type;
|
|
122
|
-
if (typeof defType !== "string" || !ZOD_KINDS
|
|
141
|
+
if (typeof defType !== "string" || !Object.hasOwn(ZOD_KINDS, defType)) return false;
|
|
123
142
|
// Both surface and inner `.type` must agree — Zod always mirrors `_def.type`
|
|
124
143
|
// onto the instance, so this is a near-zero false-positive guard.
|
|
125
144
|
return node.type === defType;
|
|
126
145
|
}
|
|
127
146
|
|
|
147
|
+
function ownValue(object: JsonObject, key: string): unknown {
|
|
148
|
+
return Object.hasOwn(object, key) ? object[key] : undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
128
151
|
function inferTypeFromValues(values: readonly unknown[]): string {
|
|
129
152
|
if (values.length === 0) return "string";
|
|
130
153
|
const first = values[0];
|
|
@@ -139,16 +162,20 @@ function unwrapInnerSchema(def: JsonObject): unknown {
|
|
|
139
162
|
// optional/nullable/readonly/brand/default → `innerType`
|
|
140
163
|
// pipe → `in` (or `out`)
|
|
141
164
|
// lazy → `getter` (a function — gone after JSON.stringify); fall back to {}
|
|
142
|
-
|
|
165
|
+
for (const key of ["innerType", "in", "out", "schema", "element"]) {
|
|
166
|
+
if (Object.hasOwn(def, key) && def[key] !== undefined) return def[key];
|
|
167
|
+
}
|
|
168
|
+
return {};
|
|
143
169
|
}
|
|
144
170
|
|
|
145
171
|
function copyWithoutNoise(node: JsonObject): JsonObject {
|
|
146
172
|
const out: JsonObject = {};
|
|
147
173
|
for (const key in node) {
|
|
148
|
-
if (
|
|
174
|
+
if (!Object.hasOwn(node, key)) continue;
|
|
175
|
+
if (Object.hasOwn(ZOD_NOISE_KEYS, key)) continue;
|
|
149
176
|
const value = node[key];
|
|
150
|
-
if (value === null && !KEYS_THAT_ACCEPT_NULL
|
|
151
|
-
out
|
|
177
|
+
if (value === null && !Object.hasOwn(KEYS_THAT_ACCEPT_NULL, key)) continue;
|
|
178
|
+
setOwnKey(out, key, value);
|
|
152
179
|
}
|
|
153
180
|
return out;
|
|
154
181
|
}
|
|
@@ -161,15 +188,19 @@ function rewriteZodNode(node: JsonObject, seen: WeakSet<object>): unknown {
|
|
|
161
188
|
case "enum": {
|
|
162
189
|
// Prefer node.options (array form Zod exposes) → def.entries values →
|
|
163
190
|
// object-shaped node.enum values. All three carry the same data.
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
const
|
|
191
|
+
const optionsValue = Object.hasOwn(node, "options") ? node.options : undefined;
|
|
192
|
+
const entriesValue = Object.hasOwn(def, "entries") ? def.entries : undefined;
|
|
193
|
+
const enumValue = Object.hasOwn(node, "enum") ? node.enum : undefined;
|
|
194
|
+
const optionsArray = Array.isArray(optionsValue) ? optionsValue : null;
|
|
195
|
+
const entries = isJsonObject(entriesValue) ? Object.values(entriesValue) : null;
|
|
196
|
+
const enumObj = isJsonObject(enumValue) ? Object.values(enumValue) : null;
|
|
167
197
|
const values = optionsArray ?? entries ?? enumObj ?? [];
|
|
168
198
|
return { type: inferTypeFromValues(values), enum: values };
|
|
169
199
|
}
|
|
170
200
|
|
|
171
201
|
case "literal": {
|
|
172
|
-
const
|
|
202
|
+
const valuesValue = ownValue(def, "values");
|
|
203
|
+
const values = Array.isArray(valuesValue) ? valuesValue : [];
|
|
173
204
|
if (values.length === 1) {
|
|
174
205
|
return { const: values[0] };
|
|
175
206
|
}
|
|
@@ -181,49 +212,50 @@ function rewriteZodNode(node: JsonObject, seen: WeakSet<object>): unknown {
|
|
|
181
212
|
|
|
182
213
|
case "union":
|
|
183
214
|
case "discriminatedUnion": {
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
? (node.options as unknown[])
|
|
188
|
-
: [];
|
|
215
|
+
const defOptions = Object.hasOwn(def, "options") ? def.options : undefined;
|
|
216
|
+
const nodeOptions = Object.hasOwn(node, "options") ? node.options : undefined;
|
|
217
|
+
const arms = Array.isArray(defOptions) ? defOptions : Array.isArray(nodeOptions) ? nodeOptions : [];
|
|
189
218
|
return { anyOf: arms.map(x => walk(x, seen)) };
|
|
190
219
|
}
|
|
191
220
|
|
|
192
221
|
case "intersection": {
|
|
193
222
|
return {
|
|
194
|
-
allOf: [walk(def
|
|
223
|
+
allOf: [walk(ownValue(def, "left"), seen), walk(ownValue(def, "right"), seen)],
|
|
195
224
|
};
|
|
196
225
|
}
|
|
197
226
|
|
|
198
227
|
case "array": {
|
|
199
|
-
return { type: "array", items: walk(def
|
|
228
|
+
return { type: "array", items: walk(ownValue(def, "element"), seen) };
|
|
200
229
|
}
|
|
201
230
|
|
|
202
231
|
case "set": {
|
|
203
|
-
const element = def
|
|
232
|
+
const element = ownValue(def, "valueType") ?? ownValue(def, "element");
|
|
204
233
|
return { type: "array", uniqueItems: true, items: walk(element, seen) };
|
|
205
234
|
}
|
|
206
235
|
|
|
207
236
|
case "tuple": {
|
|
208
|
-
const
|
|
237
|
+
const itemsValue = ownValue(def, "items");
|
|
238
|
+
const items = Array.isArray(itemsValue) ? itemsValue : [];
|
|
209
239
|
const out: JsonObject = { type: "array", prefixItems: items.map(x => walk(x, seen)) };
|
|
210
|
-
const rest = def
|
|
240
|
+
const rest = ownValue(def, "rest");
|
|
211
241
|
if (rest != null) out.items = walk(rest, seen);
|
|
212
242
|
return out;
|
|
213
243
|
}
|
|
214
244
|
|
|
215
245
|
case "record":
|
|
216
246
|
case "map": {
|
|
217
|
-
return { type: "object", additionalProperties: walk(def
|
|
247
|
+
return { type: "object", additionalProperties: walk(ownValue(def, "valueType"), seen) };
|
|
218
248
|
}
|
|
219
249
|
|
|
220
250
|
case "object": {
|
|
221
|
-
const
|
|
251
|
+
const shapeValue = ownValue(def, "shape");
|
|
252
|
+
const shape = isJsonObject(shapeValue) ? shapeValue : ({} as JsonObject);
|
|
222
253
|
const properties: JsonObject = {};
|
|
223
254
|
const required: string[] = [];
|
|
224
255
|
for (const key in shape) {
|
|
256
|
+
if (!Object.hasOwn(shape, key)) continue;
|
|
225
257
|
const inner = walk(shape[key], seen);
|
|
226
|
-
properties
|
|
258
|
+
setOwnKey(properties, key, inner);
|
|
227
259
|
if (!isOptionalEntry(shape[key])) required.push(key);
|
|
228
260
|
}
|
|
229
261
|
const out: JsonObject = { type: "object", properties };
|
|
@@ -244,10 +276,10 @@ function rewriteZodNode(node: JsonObject, seen: WeakSet<object>): unknown {
|
|
|
244
276
|
case "transform": {
|
|
245
277
|
const inner = walk(unwrapInnerSchema(def), seen);
|
|
246
278
|
if (kind === "nullable" && isJsonObject(inner)) {
|
|
247
|
-
if (typeof inner.type === "string") {
|
|
279
|
+
if (Object.hasOwn(inner, "type") && typeof inner.type === "string") {
|
|
248
280
|
return { ...inner, type: [inner.type, "null"] };
|
|
249
281
|
}
|
|
250
|
-
if (Array.isArray(inner.type)) {
|
|
282
|
+
if (Object.hasOwn(inner, "type") && Array.isArray(inner.type)) {
|
|
251
283
|
return (inner.type as string[]).includes("null")
|
|
252
284
|
? inner
|
|
253
285
|
: { ...inner, type: [...(inner.type as string[]), "null"] };
|
|
@@ -266,7 +298,7 @@ function rewriteZodNode(node: JsonObject, seen: WeakSet<object>): unknown {
|
|
|
266
298
|
const mapped = ZOD_SCALAR_TO_JSON_TYPE[kind];
|
|
267
299
|
if (mapped) {
|
|
268
300
|
cleaned.type = mapped;
|
|
269
|
-
} else if (typeof cleaned.type === "string" && !VALID_JSON_SCHEMA_TYPES
|
|
301
|
+
} else if (typeof cleaned.type === "string" && !Object.hasOwn(VALID_JSON_SCHEMA_TYPES, cleaned.type)) {
|
|
270
302
|
delete cleaned.type;
|
|
271
303
|
}
|
|
272
304
|
// Object-shaped `enum` survives as a noise field — remove if present.
|
|
@@ -281,7 +313,8 @@ function rewriteZodNode(node: JsonObject, seen: WeakSet<object>): unknown {
|
|
|
281
313
|
function isOptionalEntry(value: unknown): boolean {
|
|
282
314
|
if (!isJsonObject(value)) return false;
|
|
283
315
|
if (!isZodLeak(value)) return false;
|
|
284
|
-
const
|
|
316
|
+
const def = value.def as JsonObject;
|
|
317
|
+
const kind = Object.hasOwn(def, "type") ? def.type : undefined;
|
|
285
318
|
return kind === "optional" || kind === "default" || kind === "prefault";
|
|
286
319
|
}
|
|
287
320
|
|
|
@@ -294,7 +327,20 @@ export function decontaminateZodInstance(value: unknown): unknown {
|
|
|
294
327
|
return walk(value, new WeakSet());
|
|
295
328
|
}
|
|
296
329
|
|
|
297
|
-
function
|
|
330
|
+
function walkSchemaMap(value: JsonObject, seen: WeakSet<object>): JsonObject {
|
|
331
|
+
let changed = false;
|
|
332
|
+
const out: JsonObject = {};
|
|
333
|
+
for (const key in value) {
|
|
334
|
+
if (!Object.hasOwn(value, key)) continue;
|
|
335
|
+
const child = value[key];
|
|
336
|
+
const rewritten = walk(child, seen);
|
|
337
|
+
if (rewritten !== child) changed = true;
|
|
338
|
+
setOwnKey(out, key, rewritten);
|
|
339
|
+
}
|
|
340
|
+
return changed ? out : value;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function walk(value: unknown, seen: WeakSet<object>, inSchemaMap = false): unknown {
|
|
298
344
|
if (Array.isArray(value)) {
|
|
299
345
|
if (seen.has(value)) return value;
|
|
300
346
|
seen.add(value);
|
|
@@ -322,10 +368,18 @@ function walk(value: unknown, seen: WeakSet<object>): unknown {
|
|
|
322
368
|
let changed = false;
|
|
323
369
|
const out: JsonObject = {};
|
|
324
370
|
for (const key in value) {
|
|
371
|
+
if (!Object.hasOwn(value, key)) continue;
|
|
325
372
|
const child = value[key];
|
|
326
|
-
|
|
373
|
+
if (!inSchemaMap && JSON_SCHEMA_LITERAL_PAYLOAD_KEYS.has(key)) {
|
|
374
|
+
setOwnKey(out, key, child);
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
const rewritten =
|
|
378
|
+
!inSchemaMap && JSON_SCHEMA_MAP_KEYS.has(key) && isJsonObject(child)
|
|
379
|
+
? walkSchemaMap(child, seen)
|
|
380
|
+
: walk(child, seen);
|
|
327
381
|
if (rewritten !== child) changed = true;
|
|
328
|
-
out
|
|
382
|
+
setOwnKey(out, key, rewritten);
|
|
329
383
|
}
|
|
330
384
|
return changed ? out : value;
|
|
331
385
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Return whether an error carries a SQLite result code. */
|
|
2
|
+
export declare function isSqliteError(error: unknown): boolean;
|
|
3
|
+
/** Return whether an error is one of SQLite's explicit database-corruption classes. */
|
|
4
|
+
export declare function isSqliteCorruptionError(error: unknown): boolean;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Return whether an error carries a SQLite result code. */
|
|
2
|
+
export function isSqliteError(error: unknown): boolean {
|
|
3
|
+
if (!error || typeof error !== "object") return false;
|
|
4
|
+
const code = (error as { code?: unknown }).code;
|
|
5
|
+
return typeof code === "string" && code.startsWith("SQLITE_");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Return whether an error is one of SQLite's explicit database-corruption classes. */
|
|
9
|
+
export function isSqliteCorruptionError(error: unknown): boolean {
|
|
10
|
+
if (!isSqliteError(error)) return false;
|
|
11
|
+
const code = (error as { code?: unknown }).code;
|
|
12
|
+
return code === "SQLITE_CORRUPT" || code === "SQLITE_NOTADB";
|
|
13
|
+
}
|
|
@@ -6,6 +6,7 @@ import { getToolChoiceCapabilityCachePath } from "@gajae-code/utils/dirs";
|
|
|
6
6
|
import { extractHttpStatusFromError } from "@gajae-code/utils/fetch-retry";
|
|
7
7
|
import * as logger from "@gajae-code/utils/logger";
|
|
8
8
|
import type { Api, Model, ToolChoice, ToolChoiceCompat, ToolChoiceSupport, ToolChoiceSupportSource } from "../types";
|
|
9
|
+
import { isSqliteCorruptionError } from "./sqlite-errors";
|
|
9
10
|
|
|
10
11
|
const supportRank: Record<ToolChoiceSupport, number> = {
|
|
11
12
|
none: 0,
|
|
@@ -575,9 +576,7 @@ class CapabilityCacheCorruptionError extends Error {}
|
|
|
575
576
|
|
|
576
577
|
function isCorruptCapabilityCacheError(error: unknown): boolean {
|
|
577
578
|
if (error instanceof CapabilityCacheCorruptionError) return true;
|
|
578
|
-
|
|
579
|
-
const code = (error as { code?: unknown }).code;
|
|
580
|
-
return code === "SQLITE_CORRUPT" || code === "SQLITE_NOTADB";
|
|
579
|
+
return isSqliteCorruptionError(error);
|
|
581
580
|
}
|
|
582
581
|
|
|
583
582
|
/**
|