jeopi-ai 16.2.13 → 16.2.15
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 +3 -0
- package/dist/types/auth-broker/discover.d.ts +1 -1
- package/dist/types/auth-storage.d.ts +1 -1
- package/dist/types/utils/schema/fields.d.ts +9 -0
- package/dist/types/utils/schema/normalize.d.ts +8 -0
- package/package.json +4 -4
- package/src/auth-broker/discover.ts +7 -7
- package/src/auth-storage.ts +1 -1
- package/src/utils/harmony-leak.ts +1 -1
- package/src/utils/schema/CONSTRAINTS.md +2 -1
- package/src/utils/schema/fields.ts +31 -0
- package/src/utils/schema/normalize.ts +44 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [16.2.14] - 2026-07-02
|
|
6
|
+
|
|
5
7
|
### Added
|
|
6
8
|
|
|
7
9
|
- Added opt-in support for Anthropic's server-side fallback beta (`server-side-fallback-2026-06-01`) on the `anthropic-messages` provider, including support for `AnthropicOptions.fallbacks`, mid-stream fallback content blocks, fallback billing/usage iterations, and automatic filtering of fallback blocks during cross-provider message transformations.
|
|
@@ -13,6 +15,7 @@
|
|
|
13
15
|
|
|
14
16
|
### Fixed
|
|
15
17
|
|
|
18
|
+
- Fixed `Cloud Code Assist API error (400): Invalid value at 'request.tools[N].function_declarations[i].parameters.properties[j].value.items'` on the Gemini CLI / Antigravity `parameters` wire path. `normalizeSchemaForCCA` now coerces 2020-12 boolean subschemas (`items: true`, `properties: {x: false}` — valid JSON Schema, so AJV validation passed them through) to `{}` in schema positions while preserving booleans in `enum`/`default` values, and strips JSON Schema keywords the CCA `Schema` proto has no field for (`$id`, `$anchor`, `$comment`, `uniqueItems`, `not`, `if`/`then`/`else`, `contains`/`minContains`/`maxContains`, `dependentRequired`/`dependentSchemas`, `contentEncoding`/`contentMediaType`/`contentSchema`, `deprecated`, `readOnly`, `writeOnly`), spilling human-meaningful ones into the description. These shapes commonly arrive from MCP-server tool schemas; one bad tool no longer 400s the whole request.
|
|
16
19
|
- Fixed an issue where broker usage fetch failures were not cached, causing redundant network requests during sequential ranking passes when the broker is offline.
|
|
17
20
|
- Fixed Xiaomi MiMo API key validation to use the supported `mimo-v2.5` model.
|
|
18
21
|
- Fixed certificate verification errors for custom gateways behind private CA bundles by ensuring `NODE_EXTRA_CA_CERTS` is respected across all provider fetches (including OpenAI-compatible, Codex, Ollama, Azure, and Google).
|
|
@@ -18,7 +18,7 @@ export declare function getAuthBrokerTokenFilePath(): string;
|
|
|
18
18
|
/**
|
|
19
19
|
* Resolve broker connection configuration using the same precedence as the TUI:
|
|
20
20
|
*
|
|
21
|
-
* 1. `
|
|
21
|
+
* 1. `JEOPI_AUTH_BROKER_URL` / `JEOPI_AUTH_BROKER_TOKEN` env vars.
|
|
22
22
|
* 2. `auth.broker.url` / `auth.broker.token` in `<agentDir>/config.yml`.
|
|
23
23
|
* 3. `<config-root>/auth-broker.token` file (paired with a URL from env/config).
|
|
24
24
|
*
|
|
@@ -375,7 +375,7 @@ export type AuthStorageOptions = {
|
|
|
375
375
|
* so the TUI can show where a token came from (broker URL or local SQLite path).
|
|
376
376
|
*
|
|
377
377
|
* Examples:
|
|
378
|
-
* - `"local ~/.
|
|
378
|
+
* - `"local ~/.jeopi/agent/agent.db"`
|
|
379
379
|
* - `"broker http://omp.internal:8765"`
|
|
380
380
|
*/
|
|
381
381
|
sourceLabel?: string;
|
|
@@ -52,3 +52,12 @@ export declare const COMBINATOR_KEYS: readonly ["anyOf", "allOf", "oneOf"];
|
|
|
52
52
|
* Meta/reference keywords plus object-key validators that CCA cannot resolve are stripped.
|
|
53
53
|
*/
|
|
54
54
|
export declare const CCA_UNSUPPORTED_SCHEMA_FIELDS: Record<string, true>;
|
|
55
|
+
/**
|
|
56
|
+
* JSON Schema keywords with no counterpart field in the Cloud Code Assist
|
|
57
|
+
* `Schema` proto (the legacy `parameters` wire shape used for Claude models
|
|
58
|
+
* and every Antigravity model). Any of these reaching the wire produces a
|
|
59
|
+
* 400 INVALID_ARGUMENT ("Unknown name ..."). Stripped only on the CCA
|
|
60
|
+
* `parameters` path — the Google `parametersJsonSchema` path accepts full
|
|
61
|
+
* JSON Schema and keeps them.
|
|
62
|
+
*/
|
|
63
|
+
export declare const CCA_PROTO_UNKNOWN_SCHEMA_FIELDS: Record<string, true>;
|
|
@@ -22,6 +22,14 @@ export interface NormalizeSchemaOptions {
|
|
|
22
22
|
foldOneOfIntoAnyOf: boolean;
|
|
23
23
|
dropNonScalarEnum: boolean;
|
|
24
24
|
rejectResidualIncompatibilities?: ReadonlyArray<ResidualSchemaIncompatibility>;
|
|
25
|
+
/**
|
|
26
|
+
* Coerce 2020-12 boolean subschemas (`items: true`, `properties: {x: false}`)
|
|
27
|
+
* to `{}` in schema positions. Boolean schemas are valid JSON Schema (so AJV
|
|
28
|
+
* validation passes them) but the Cloud Code Assist `Schema` proto requires
|
|
29
|
+
* a message, and a leaked boolean fails the whole request with
|
|
30
|
+
* `Invalid value at '...parameters.properties[N].value.items'` (400).
|
|
31
|
+
*/
|
|
32
|
+
coerceBooleanSubschemas?: boolean;
|
|
25
33
|
validateAndFallback?: {
|
|
26
34
|
fallback: unknown;
|
|
27
35
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "jeopi-ai",
|
|
4
|
-
"version": "16.2.
|
|
4
|
+
"version": "16.2.15",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://github.com/akillness/jeopi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@bufbuild/protobuf": "^2.12.0",
|
|
41
|
-
"jeopi-catalog": "16.2.
|
|
42
|
-
"jeopi-utils": "16.2.
|
|
43
|
-
"jeopi-wire": "16.2.
|
|
41
|
+
"jeopi-catalog": "16.2.15",
|
|
42
|
+
"jeopi-utils": "16.2.15",
|
|
43
|
+
"jeopi-wire": "16.2.15",
|
|
44
44
|
"arktype": "^2.2.0",
|
|
45
45
|
"zod": "^4"
|
|
46
46
|
},
|
|
@@ -90,20 +90,20 @@ async function readConfigYaml(agentDir: string): Promise<ConfigSnapshot> {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
function resolveSnapshotTtlMs(): number {
|
|
93
|
-
const raw = process.env.
|
|
93
|
+
const raw = process.env.JEOPI_AUTH_BROKER_SNAPSHOT_TTL_MS;
|
|
94
94
|
if (raw === undefined) return DEFAULT_SNAPSHOT_CACHE_TTL_MS;
|
|
95
95
|
const value = raw.trim();
|
|
96
96
|
if (value === "") return DEFAULT_SNAPSHOT_CACHE_TTL_MS;
|
|
97
97
|
const ttlMs = Number(value);
|
|
98
98
|
if (Number.isFinite(ttlMs) && ttlMs >= 0) return ttlMs;
|
|
99
|
-
logger.warn("Invalid
|
|
99
|
+
logger.warn("Invalid JEOPI_AUTH_BROKER_SNAPSHOT_TTL_MS; using default", { value: raw });
|
|
100
100
|
return DEFAULT_SNAPSHOT_CACHE_TTL_MS;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
/**
|
|
104
104
|
* Resolve broker connection configuration using the same precedence as the TUI:
|
|
105
105
|
*
|
|
106
|
-
* 1. `
|
|
106
|
+
* 1. `JEOPI_AUTH_BROKER_URL` / `JEOPI_AUTH_BROKER_TOKEN` env vars.
|
|
107
107
|
* 2. `auth.broker.url` / `auth.broker.token` in `<agentDir>/config.yml`.
|
|
108
108
|
* 3. `<config-root>/auth-broker.token` file (paired with a URL from env/config).
|
|
109
109
|
*
|
|
@@ -117,8 +117,8 @@ export async function resolveAuthBrokerConfig(
|
|
|
117
117
|
const agentDir = options.agentDir ?? getAgentDir();
|
|
118
118
|
const resolveConfig = options.configValueResolver ?? defaultResolveConfigValue;
|
|
119
119
|
|
|
120
|
-
const envUrl = process.env.
|
|
121
|
-
const envToken = process.env.
|
|
120
|
+
const envUrl = process.env.JEOPI_AUTH_BROKER_URL;
|
|
121
|
+
const envToken = process.env.JEOPI_AUTH_BROKER_TOKEN;
|
|
122
122
|
|
|
123
123
|
let url = envUrl && envUrl.length > 0 ? envUrl : undefined;
|
|
124
124
|
let configToken: string | undefined;
|
|
@@ -140,8 +140,8 @@ export async function resolveAuthBrokerConfig(
|
|
|
140
140
|
if (!token) {
|
|
141
141
|
throw new AIError.MissingApiKeyError(
|
|
142
142
|
undefined,
|
|
143
|
-
`
|
|
144
|
-
`Set
|
|
143
|
+
`JEOPI_AUTH_BROKER_URL is set (${url}) but no bearer token is available. ` +
|
|
144
|
+
`Set JEOPI_AUTH_BROKER_TOKEN, the \`auth.broker.token\` config entry, or place one at ${getAuthBrokerTokenFilePath()}.`,
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
147
|
return { url, token };
|
package/src/auth-storage.ts
CHANGED
|
@@ -459,7 +459,7 @@ export type AuthStorageOptions = {
|
|
|
459
459
|
* so the TUI can show where a token came from (broker URL or local SQLite path).
|
|
460
460
|
*
|
|
461
461
|
* Examples:
|
|
462
|
-
* - `"local ~/.
|
|
462
|
+
* - `"local ~/.jeopi/agent/agent.db"`
|
|
463
463
|
* - `"broker http://omp.internal:8765"`
|
|
464
464
|
*/
|
|
465
465
|
sourceLabel?: string;
|
|
@@ -327,7 +327,7 @@ export function createHarmonyAuditEvent(params: {
|
|
|
327
327
|
removedLen: params.removed.length,
|
|
328
328
|
removedSha8: sha8(params.removed),
|
|
329
329
|
removedPreview: redactedJunkPreview(params.removed),
|
|
330
|
-
removedBlob: Bun.env.
|
|
330
|
+
removedBlob: Bun.env.JEOPI_HARMONY_DEBUG === "1" ? params.removed : undefined,
|
|
331
331
|
};
|
|
332
332
|
}
|
|
333
333
|
|
|
@@ -93,10 +93,11 @@ For Cloud Code Assist Claude tool declarations, schema MUST satisfy stricter con
|
|
|
93
93
|
|
|
94
94
|
### 3.2 Sanitization contract
|
|
95
95
|
|
|
96
|
-
1. Start with Google unsupported-key stripping behavior.
|
|
96
|
+
1. Start with Google unsupported-key stripping behavior, **plus** the CCA-proto-unknown keyword set (`CCA_PROTO_UNKNOWN_SCHEMA_FIELDS`): `$id`, `$anchor`, `$comment`, `uniqueItems`, `not`, `if`, `then`, `else`, `contains`, `minContains`, `maxContains`, `dependentRequired`, `dependentSchemas`, `contentEncoding`, `contentMediaType`, `contentSchema`, `deprecated`, `readOnly`, `writeOnly`. These keywords have no field in the CCA `Schema` proto; a leaked one 400s the whole request with "Unknown name".
|
|
97
97
|
2. **`nullable` keyword MUST be stripped** in CCA Claude path.
|
|
98
98
|
3. `type: ["T", "null"]` becomes `type: "T"` with no `nullable` marker.
|
|
99
99
|
4. Human-meaningful stripped keys are appended to `description` with the same spill format used by the Google dispatcher.
|
|
100
|
+
5. **Boolean subschemas MUST be coerced to `{}`** in schema positions (`items` values and `properties` map entries). `items: true` / `properties: {x: false}` are valid 2020-12 JSON Schema — AJV validation passes them — but the CCA proto requires a Schema message and rejects the request with `Invalid value at '...parameters.properties[N].value.items'`. Booleans in value positions (`enum` entries, `default`) MUST be preserved.
|
|
100
101
|
|
|
101
102
|
### 3.3 Combiner/union normalization contract
|
|
102
103
|
|
|
@@ -205,3 +205,34 @@ export const CCA_UNSUPPORTED_SCHEMA_FIELDS: Record<string, true> = {
|
|
|
205
205
|
$dynamicAnchor: true,
|
|
206
206
|
propertyNames: true,
|
|
207
207
|
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* JSON Schema keywords with no counterpart field in the Cloud Code Assist
|
|
211
|
+
* `Schema` proto (the legacy `parameters` wire shape used for Claude models
|
|
212
|
+
* and every Antigravity model). Any of these reaching the wire produces a
|
|
213
|
+
* 400 INVALID_ARGUMENT ("Unknown name ..."). Stripped only on the CCA
|
|
214
|
+
* `parameters` path — the Google `parametersJsonSchema` path accepts full
|
|
215
|
+
* JSON Schema and keeps them.
|
|
216
|
+
*/
|
|
217
|
+
export const CCA_PROTO_UNKNOWN_SCHEMA_FIELDS: Record<string, true> = {
|
|
218
|
+
$id: true,
|
|
219
|
+
$anchor: true,
|
|
220
|
+
$comment: true,
|
|
221
|
+
uniqueItems: true,
|
|
222
|
+
not: true,
|
|
223
|
+
if: true,
|
|
224
|
+
// biome-ignore lint/suspicious/noThenProperty: JSON Schema keyword
|
|
225
|
+
then: true,
|
|
226
|
+
else: true,
|
|
227
|
+
contains: true,
|
|
228
|
+
minContains: true,
|
|
229
|
+
maxContains: true,
|
|
230
|
+
dependentRequired: true,
|
|
231
|
+
dependentSchemas: true,
|
|
232
|
+
contentEncoding: true,
|
|
233
|
+
contentMediaType: true,
|
|
234
|
+
contentSchema: true,
|
|
235
|
+
deprecated: true,
|
|
236
|
+
readOnly: true,
|
|
237
|
+
writeOnly: true,
|
|
238
|
+
};
|
|
@@ -13,6 +13,7 @@ import { upgradeJsonSchemaTo202012 } from "./draft";
|
|
|
13
13
|
import { areJsonValuesEqual, mergeCompatibleEnumSchemas, mergePropertySchemas } from "./equality";
|
|
14
14
|
import {
|
|
15
15
|
ALL_CCA_TYPE_SPECIFIC_KEYS,
|
|
16
|
+
CCA_PROTO_UNKNOWN_SCHEMA_FIELDS,
|
|
16
17
|
CLOUD_CODE_ASSIST_SHARED_SCHEMA_KEYS,
|
|
17
18
|
CLOUD_CODE_ASSIST_TYPE_SPECIFIC_KEYS,
|
|
18
19
|
COMBINATOR_KEYS,
|
|
@@ -51,6 +52,14 @@ export interface NormalizeSchemaOptions {
|
|
|
51
52
|
foldOneOfIntoAnyOf: boolean;
|
|
52
53
|
dropNonScalarEnum: boolean;
|
|
53
54
|
rejectResidualIncompatibilities?: ReadonlyArray<ResidualSchemaIncompatibility>;
|
|
55
|
+
/**
|
|
56
|
+
* Coerce 2020-12 boolean subschemas (`items: true`, `properties: {x: false}`)
|
|
57
|
+
* to `{}` in schema positions. Boolean schemas are valid JSON Schema (so AJV
|
|
58
|
+
* validation passes them) but the Cloud Code Assist `Schema` proto requires
|
|
59
|
+
* a message, and a leaked boolean fails the whole request with
|
|
60
|
+
* `Invalid value at '...parameters.properties[N].value.items'` (400).
|
|
61
|
+
*/
|
|
62
|
+
coerceBooleanSubschemas?: boolean;
|
|
54
63
|
validateAndFallback?: { fallback: unknown };
|
|
55
64
|
}
|
|
56
65
|
|
|
@@ -84,6 +93,23 @@ function isGoogleUnsupportedSchemaField(key: string): boolean {
|
|
|
84
93
|
return Object.hasOwn(UNSUPPORTED_SCHEMA_FIELDS, key);
|
|
85
94
|
}
|
|
86
95
|
|
|
96
|
+
function isCcaUnsupportedSchemaField(key: string): boolean {
|
|
97
|
+
return Object.hasOwn(UNSUPPORTED_SCHEMA_FIELDS, key) || Object.hasOwn(CCA_PROTO_UNKNOWN_SCHEMA_FIELDS, key);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Replace a boolean subschema with `{}` when it sits in a schema position:
|
|
102
|
+
* a value inside a `properties` map, or the value of `items`. Only these
|
|
103
|
+
* positions are proto-mapped schema fields on the CCA wire; booleans in
|
|
104
|
+
* value positions (`enum` entries, `default`) are never touched because they
|
|
105
|
+
* arrive as array/scalar entries, not via this per-key assignment.
|
|
106
|
+
*/
|
|
107
|
+
function coerceBooleanSubschema(value: unknown, key: string, options: NormalizeSchemaWalkOptions): unknown {
|
|
108
|
+
if (options.coerceBooleanSubschemas !== true || typeof value !== "boolean") return value;
|
|
109
|
+
if (options.insideProperties || key === "items") return {};
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
|
|
87
113
|
function isMcpUnsupportedSchemaField(key: string): boolean {
|
|
88
114
|
return key === "$schema";
|
|
89
115
|
}
|
|
@@ -303,10 +329,14 @@ function normalizeSchemaObjectNode(value: JsonObject, options: NormalizeSchemaWa
|
|
|
303
329
|
continue;
|
|
304
330
|
}
|
|
305
331
|
if (options.stripNullableKeyword && key === "nullable") continue;
|
|
306
|
-
result[key] =
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
332
|
+
result[key] = coerceBooleanSubschema(
|
|
333
|
+
normalizeSchemaNode(entry, {
|
|
334
|
+
...options,
|
|
335
|
+
insideProperties: !options.insideProperties && key === "properties",
|
|
336
|
+
}),
|
|
337
|
+
key,
|
|
338
|
+
options,
|
|
339
|
+
);
|
|
310
340
|
}
|
|
311
341
|
applyDescriptionSpill(result, spill, options);
|
|
312
342
|
return applyNodePostProcessing(result, options);
|
|
@@ -325,10 +355,14 @@ function normalizeSchemaObjectNode(value: JsonObject, options: NormalizeSchemaWa
|
|
|
325
355
|
constValue = entry;
|
|
326
356
|
continue;
|
|
327
357
|
}
|
|
328
|
-
result[key] =
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
358
|
+
result[key] = coerceBooleanSubschema(
|
|
359
|
+
normalizeSchemaNode(entry, {
|
|
360
|
+
...options,
|
|
361
|
+
insideProperties: !options.insideProperties && key === "properties",
|
|
362
|
+
}),
|
|
363
|
+
key,
|
|
364
|
+
options,
|
|
365
|
+
);
|
|
332
366
|
}
|
|
333
367
|
|
|
334
368
|
if (options.normalizeTypeArrayToNullable && Array.isArray(result.type)) {
|
|
@@ -924,7 +958,7 @@ export function normalizeSchemaForGoogle(value: unknown): unknown {
|
|
|
924
958
|
|
|
925
959
|
export function normalizeSchemaForCCA(value: unknown): unknown {
|
|
926
960
|
return normalizeSchema(value, {
|
|
927
|
-
unsupportedFields:
|
|
961
|
+
unsupportedFields: isCcaUnsupportedSchemaField,
|
|
928
962
|
normalizeFieldNames: true,
|
|
929
963
|
collapseNullFields: false,
|
|
930
964
|
normalizeTypeArrayToNullable: true,
|
|
@@ -940,6 +974,7 @@ export function normalizeSchemaForCCA(value: unknown): unknown {
|
|
|
940
974
|
inferTypeForBareEnum: true,
|
|
941
975
|
dropNonScalarEnum: false,
|
|
942
976
|
foldOneOfIntoAnyOf: false,
|
|
977
|
+
coerceBooleanSubschemas: true,
|
|
943
978
|
rejectResidualIncompatibilities: ["type-array", "type-null", "nullable", "combiners"],
|
|
944
979
|
validateAndFallback: { fallback: CLOUD_CODE_ASSIST_CLAUDE_FALLBACK_SCHEMA },
|
|
945
980
|
});
|