@gajae-code/ai 0.18.11 → 0.18.12
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 +68 -0
- package/README.md +1 -1
- package/dist/types/auth-broker/wire-schemas.d.ts +30 -0
- package/dist/types/auth-storage.d.ts +80 -8
- package/dist/types/bedrock-claude-cache-policy.d.ts +1 -1
- package/dist/types/model-cache.d.ts +6 -4
- package/dist/types/model-manager.d.ts +2 -0
- package/dist/types/openai-completions-compat.d.ts +2 -1
- package/dist/types/providers/anthropic.d.ts +10 -0
- package/dist/types/providers/aws-credential-config.d.ts +5 -0
- package/dist/types/providers/google-auth.d.ts +7 -0
- package/dist/types/providers/google-gemini-headers.d.ts +10 -5
- package/dist/types/providers/kiro-api-key.d.ts +5 -0
- package/dist/types/providers/openai-chat-server-schema.d.ts +2 -1
- package/dist/types/providers/openai-completions.d.ts +1 -1
- package/dist/types/providers/openai-responses-shared.d.ts +2 -1
- package/dist/types/stream.d.ts +33 -1
- package/dist/types/types.d.ts +26 -3
- package/dist/types/usage.d.ts +3 -0
- package/dist/types/utils/discovery/antigravity.d.ts +11 -0
- package/dist/types/utils/idle-iterator.d.ts +3 -2
- package/dist/types/utils/oauth/types.d.ts +9 -0
- package/package.json +4 -4
- package/src/auth-broker/remote-store.ts +62 -11
- package/src/auth-broker/wire-schemas.ts +2 -0
- package/src/auth-gateway/server.ts +3 -2
- package/src/auth-storage.ts +647 -194
- package/src/bedrock-claude-cache-policy.d.ts +1 -1
- package/src/bedrock-claude-cache-policy.ts +2 -2
- package/src/model-cache.ts +45 -10
- package/src/model-manager.ts +18 -6
- package/src/model-thinking.ts +37 -7
- package/src/models.json +2931 -1670
- package/src/openai-completions-compat.d.ts +2 -1
- package/src/openai-completions-compat.ts +5 -0
- package/src/provider-models/google.ts +7 -1
- package/src/provider-models/openai-compat.ts +26 -0
- package/src/providers/amazon-bedrock.ts +20 -11
- package/src/providers/anthropic.d.ts +10 -0
- package/src/providers/anthropic.ts +139 -4
- package/src/providers/aws-credential-config.d.ts +5 -0
- package/src/providers/aws-credential-config.ts +29 -1
- package/src/providers/google-auth.d.ts +7 -0
- package/src/providers/google-auth.ts +165 -4
- package/src/providers/google-gemini-headers.d.ts +10 -5
- package/src/providers/google-gemini-headers.ts +11 -6
- package/src/providers/google-vertex.ts +2 -4
- package/src/providers/kiro-api-key.d.ts +5 -0
- package/src/providers/kiro-api-key.ts +379 -68
- package/src/providers/ollama.ts +19 -9
- package/src/providers/openai-anthropic-shim.ts +1 -0
- package/src/providers/openai-chat-server-schema.ts +1 -1
- package/src/providers/openai-chat-server.ts +14 -2
- package/src/providers/openai-codex-responses.ts +21 -14
- package/src/providers/openai-completions.d.ts +1 -1
- package/src/providers/openai-completions.ts +65 -4
- package/src/providers/openai-responses-server.ts +10 -1
- package/src/providers/openai-responses-shared.d.ts +2 -1
- package/src/providers/openai-responses-shared.ts +42 -1
- package/src/providers/openai-responses.ts +51 -10
- package/src/providers/pi-native-server.ts +1 -1
- package/src/stream.d.ts +33 -1
- package/src/stream.ts +107 -13
- package/src/types.d.ts +26 -3
- package/src/types.ts +55 -2
- package/src/usage/claude.ts +4 -2
- package/src/usage.ts +3 -0
- package/src/utils/discovery/antigravity.ts +144 -2
- package/src/utils/idle-iterator.d.ts +3 -2
- package/src/utils/idle-iterator.ts +30 -10
- package/src/utils/oauth/anthropic.ts +23 -22
- package/src/utils/oauth/api-key-validation.ts +34 -11
- package/src/utils/oauth/types.d.ts +9 -0
- package/src/utils/oauth/types.ts +9 -0
- package/src/utils/parse-bind.d.ts +35 -0
package/src/stream.d.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import type { Effort } from "./model-thinking";
|
|
2
2
|
import type { AnthropicOptions } from "./providers/anthropic";
|
|
3
|
-
import type { Api, AssistantMessage, Context, Model, OptionsForApi, SimpleStreamOptions, ToolChoice } from "./types";
|
|
3
|
+
import type { Api, AssistantMessage, Context, FetchImpl, Model, OptionsForApi, SimpleStreamOptions, ToolChoice } from "./types";
|
|
4
4
|
import { AssistantMessageEventStream } from "./utils/event-stream";
|
|
5
|
+
export type EnvApiKeyCredentialSource = {
|
|
6
|
+
kind: "environment";
|
|
7
|
+
name: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: "google-adc";
|
|
10
|
+
source: "explicit-file" | "default-file" | "metadata-server";
|
|
11
|
+
} | {
|
|
12
|
+
kind: "aws";
|
|
13
|
+
source: "bearer-token" | "environment-credentials" | "profile" | "instance-profile";
|
|
14
|
+
} | {
|
|
15
|
+
kind: "unknown";
|
|
16
|
+
};
|
|
5
17
|
/**
|
|
6
18
|
* Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.
|
|
7
19
|
*
|
|
@@ -9,6 +21,26 @@ import { AssistantMessageEventStream } from "./utils/event-stream";
|
|
|
9
21
|
* loaded into $env for app/tool execution, but must not silently fund GJC model requests.
|
|
10
22
|
*/
|
|
11
23
|
export declare function getEnvApiKey(provider: string): string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* List configured environment variable names consulted for a provider's
|
|
26
|
+
* environment credential. Values are never returned. This intentionally uses
|
|
27
|
+
* the same credential-only environment reader as {@link getEnvApiKey}.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getEnvApiKeyEnvNames(provider: string): string[];
|
|
30
|
+
/** Describe the selected source without exposing credential values or unvalidated ADC files. */
|
|
31
|
+
export declare function getEnvApiKeyCredentialSource(provider: string, options?: {
|
|
32
|
+
fetch?: FetchImpl;
|
|
33
|
+
}): Promise<EnvApiKeyCredentialSource | undefined>;
|
|
34
|
+
/** Enumerate usable credential candidates in provider dispatch precedence without exposing credentials. */
|
|
35
|
+
export declare function getEnvApiKeyCredentialSources(provider: string, options?: {
|
|
36
|
+
fetch?: FetchImpl;
|
|
37
|
+
}): Promise<EnvApiKeyCredentialSource[]>;
|
|
38
|
+
/** Resolve Vertex ADC provenance, including metadata-server credentials, without acquiring a token. */
|
|
39
|
+
export declare function getGoogleVertexCredentialSource(options?: {
|
|
40
|
+
fetch?: FetchImpl;
|
|
41
|
+
}): Promise<EnvApiKeyCredentialSource | undefined>;
|
|
42
|
+
/** Name of the environment variable whose value is selected by `getEnvApiKey`, when identifiable. */
|
|
43
|
+
export declare function getEnvApiKeyEnvName(provider: string): Promise<string | undefined>;
|
|
12
44
|
/**
|
|
13
45
|
* Enumerate every provider that has an env-var fallback for `getEnvApiKey`.
|
|
14
46
|
* Used by `gjc auth-broker migrate --include-env` to discover env-sourced keys
|
package/src/stream.ts
CHANGED
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
import type { BedrockOptions } from "./providers/amazon-bedrock";
|
|
37
37
|
import type { AnthropicOptions } from "./providers/anthropic";
|
|
38
38
|
import {
|
|
39
|
+
hasAwsInstanceProfileCredentialSource,
|
|
39
40
|
hasResolvableAwsProfileSource,
|
|
40
41
|
isValidBedrockBearerToken,
|
|
41
42
|
readAwsStaticEnvironmentCredentials,
|
|
@@ -43,6 +44,7 @@ import {
|
|
|
43
44
|
import type { CursorOptions } from "./providers/cursor";
|
|
44
45
|
import type { DevinAcpOptions } from "./providers/devin-acp";
|
|
45
46
|
import type { GoogleOptions } from "./providers/google";
|
|
47
|
+
import { getVertexCredentialSource, isValidVertexLocation } from "./providers/google-auth";
|
|
46
48
|
import type { GoogleGeminiCliOptions } from "./providers/google-gemini-cli";
|
|
47
49
|
import type { GoogleVertexOptions } from "./providers/google-vertex";
|
|
48
50
|
import type { KiroCodeWhispererOptions } from "./providers/kiro-codewhisperer";
|
|
@@ -73,6 +75,7 @@ import type {
|
|
|
73
75
|
AssistantMessageEvent,
|
|
74
76
|
AuthRetryCredential,
|
|
75
77
|
Context,
|
|
78
|
+
FetchImpl,
|
|
76
79
|
Model,
|
|
77
80
|
OptionsForApi,
|
|
78
81
|
SimpleStreamOptions,
|
|
@@ -83,8 +86,6 @@ import type {
|
|
|
83
86
|
import { AssistantMessageEventStream } from "./utils/event-stream";
|
|
84
87
|
import { isFoundryEnabled } from "./utils/foundry";
|
|
85
88
|
|
|
86
|
-
let cachedVertexAdcCredentialsExists: boolean | null = null;
|
|
87
|
-
|
|
88
89
|
function assertCustomApiRegistryActive(registry: CustomApiRegistry | undefined): void {
|
|
89
90
|
if (registry !== undefined) CustomApiRegistry.assertActive(registry);
|
|
90
91
|
}
|
|
@@ -111,21 +112,19 @@ function isBuiltInApi(api: Api): boolean {
|
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
function hasVertexAdcCredentials(): boolean {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
cachedVertexAdcCredentialsExists = fs.existsSync(gacPath);
|
|
118
|
-
} else {
|
|
119
|
-
cachedVertexAdcCredentialsExists = fs.existsSync(
|
|
120
|
-
path.join(getTrustedHomeDir(), ".config", "gcloud", "application_default_credentials.json"),
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return cachedVertexAdcCredentialsExists;
|
|
115
|
+
const gacPath = $credentialEnv("GOOGLE_APPLICATION_CREDENTIALS");
|
|
116
|
+
if (gacPath) return fs.existsSync(gacPath);
|
|
117
|
+
return fs.existsSync(path.join(getTrustedHomeDir(), ".config", "gcloud", "application_default_credentials.json"));
|
|
125
118
|
}
|
|
126
119
|
|
|
127
120
|
type KeyResolver = string | (() => string | undefined);
|
|
128
121
|
|
|
122
|
+
export type EnvApiKeyCredentialSource =
|
|
123
|
+
| { kind: "environment"; name: string }
|
|
124
|
+
| { kind: "google-adc"; source: "explicit-file" | "default-file" | "metadata-server" }
|
|
125
|
+
| { kind: "aws"; source: "bearer-token" | "environment-credentials" | "profile" | "instance-profile" }
|
|
126
|
+
| { kind: "unknown" };
|
|
127
|
+
|
|
129
128
|
const serviceProviderMap: Record<string, KeyResolver> = {
|
|
130
129
|
"alibaba-token-plan": "ALIBABA_TOKEN_PLAN_API_KEY",
|
|
131
130
|
openai: () => $credentialEnv("OPENAI_API_KEY"),
|
|
@@ -223,6 +222,25 @@ const serviceProviderMap: Record<string, KeyResolver> = {
|
|
|
223
222
|
xiaomi: "XIAOMI_API_KEY",
|
|
224
223
|
};
|
|
225
224
|
|
|
225
|
+
const functionResolverEnvNames: Record<string, readonly string[]> = {
|
|
226
|
+
openai: ["OPENAI_API_KEY"],
|
|
227
|
+
kiro: ["KIRO_API_KEY", "AWS_BEARER_TOKEN_KIRO"],
|
|
228
|
+
"github-copilot": ["COPILOT_GITHUB_TOKEN", "GH_TOKEN", "GITHUB_TOKEN"],
|
|
229
|
+
"google-vertex": ["GOOGLE_CLOUD_API_KEY"],
|
|
230
|
+
"amazon-bedrock": ["AWS_BEARER_TOKEN_BEDROCK"],
|
|
231
|
+
huggingface: ["HUGGINGFACE_HUB_TOKEN", "HF_TOKEN"],
|
|
232
|
+
"qwen-portal": ["QWEN_OAUTH_TOKEN", "QWEN_PORTAL_API_KEY"],
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
function getFunctionResolverEnvNames(provider: string): readonly string[] {
|
|
236
|
+
if (provider === "anthropic") {
|
|
237
|
+
return isFoundryEnabled()
|
|
238
|
+
? ["ANTHROPIC_FOUNDRY_API_KEY", "ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"]
|
|
239
|
+
: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"];
|
|
240
|
+
}
|
|
241
|
+
return functionResolverEnvNames[provider] ?? [];
|
|
242
|
+
}
|
|
243
|
+
|
|
226
244
|
/**
|
|
227
245
|
* Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.
|
|
228
246
|
*
|
|
@@ -237,6 +255,82 @@ export function getEnvApiKey(provider: string): string | undefined {
|
|
|
237
255
|
return resolver?.();
|
|
238
256
|
}
|
|
239
257
|
|
|
258
|
+
/**
|
|
259
|
+
* List configured environment variable names consulted for a provider's
|
|
260
|
+
* environment credential. Values are never returned. This intentionally uses
|
|
261
|
+
* the same credential-only environment reader as {@link getEnvApiKey}.
|
|
262
|
+
*/
|
|
263
|
+
export function getEnvApiKeyEnvNames(provider: string): string[] {
|
|
264
|
+
const resolver = serviceProviderMap[provider];
|
|
265
|
+
const names = typeof resolver === "string" ? [resolver] : getFunctionResolverEnvNames(provider);
|
|
266
|
+
return names.filter(name => {
|
|
267
|
+
const value = $credentialEnv(name);
|
|
268
|
+
if (value === undefined) return false;
|
|
269
|
+
if (provider === "kiro" && name === "KIRO_API_KEY") {
|
|
270
|
+
return value.trim().startsWith("ksk_") && !/[\x00-\x1f\x7f]/.test(value);
|
|
271
|
+
}
|
|
272
|
+
if (provider === "amazon-bedrock" && name === "AWS_BEARER_TOKEN_BEDROCK") {
|
|
273
|
+
return isValidBedrockBearerToken(value);
|
|
274
|
+
}
|
|
275
|
+
return true;
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** Describe the selected source without exposing credential values or unvalidated ADC files. */
|
|
280
|
+
export async function getEnvApiKeyCredentialSource(
|
|
281
|
+
provider: string,
|
|
282
|
+
options?: { fetch?: FetchImpl },
|
|
283
|
+
): Promise<EnvApiKeyCredentialSource | undefined> {
|
|
284
|
+
return (await getEnvApiKeyCredentialSources(provider, options))[0];
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/** Enumerate usable credential candidates in provider dispatch precedence without exposing credentials. */
|
|
288
|
+
export async function getEnvApiKeyCredentialSources(
|
|
289
|
+
provider: string,
|
|
290
|
+
options?: { fetch?: FetchImpl },
|
|
291
|
+
): Promise<EnvApiKeyCredentialSource[]> {
|
|
292
|
+
const sources: EnvApiKeyCredentialSource[] = getEnvApiKeyEnvNames(provider).map(
|
|
293
|
+
(name): EnvApiKeyCredentialSource =>
|
|
294
|
+
provider === "amazon-bedrock" && name === "AWS_BEARER_TOKEN_BEDROCK"
|
|
295
|
+
? { kind: "aws", source: "bearer-token" }
|
|
296
|
+
: { kind: "environment", name },
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
if (provider === "google-vertex") {
|
|
300
|
+
const project = $credentialEnv("GOOGLE_CLOUD_PROJECT") || $credentialEnv("GCLOUD_PROJECT");
|
|
301
|
+
const location = $credentialEnv("GOOGLE_CLOUD_LOCATION");
|
|
302
|
+
if (project && location && isValidVertexLocation(location)) {
|
|
303
|
+
const source = await getVertexCredentialSource({ fetch: options?.fetch });
|
|
304
|
+
if (source) sources.push({ kind: "google-adc", source });
|
|
305
|
+
}
|
|
306
|
+
} else if (provider === "amazon-bedrock") {
|
|
307
|
+
const bearerToken = $credentialEnv("AWS_BEARER_TOKEN_BEDROCK");
|
|
308
|
+
if (bearerToken && !isValidBedrockBearerToken(bearerToken)) return sources;
|
|
309
|
+
if (readAwsStaticEnvironmentCredentials()) {
|
|
310
|
+
sources.push({ kind: "aws", source: "environment-credentials" });
|
|
311
|
+
}
|
|
312
|
+
if (hasResolvableAwsProfileSource()) sources.push({ kind: "aws", source: "profile" });
|
|
313
|
+
if (await hasAwsInstanceProfileCredentialSource({ fetch: options?.fetch })) {
|
|
314
|
+
sources.push({ kind: "aws", source: "instance-profile" });
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return sources;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/** Resolve Vertex ADC provenance, including metadata-server credentials, without acquiring a token. */
|
|
322
|
+
export async function getGoogleVertexCredentialSource(options?: {
|
|
323
|
+
fetch?: FetchImpl;
|
|
324
|
+
}): Promise<EnvApiKeyCredentialSource | undefined> {
|
|
325
|
+
return (await getEnvApiKeyCredentialSources("google-vertex", options))[0];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** Name of the environment variable whose value is selected by `getEnvApiKey`, when identifiable. */
|
|
329
|
+
export async function getEnvApiKeyEnvName(provider: string): Promise<string | undefined> {
|
|
330
|
+
const source = await getEnvApiKeyCredentialSource(provider);
|
|
331
|
+
return source?.kind === "environment" ? source.name : undefined;
|
|
332
|
+
}
|
|
333
|
+
|
|
240
334
|
/**
|
|
241
335
|
* Enumerate every provider that has an env-var fallback for `getEnvApiKey`.
|
|
242
336
|
* Used by `gjc auth-broker migrate --include-env` to discover env-sourced keys
|
package/src/types.d.ts
CHANGED
|
@@ -89,6 +89,8 @@ export interface ToolChoiceCompat {
|
|
|
89
89
|
supportsToolChoice?: boolean;
|
|
90
90
|
/** Legacy flag for forced tool_choice support. */
|
|
91
91
|
supportsForcedToolChoice?: boolean;
|
|
92
|
+
/** Whether the provider supports OpenAI ultrafast service tier. Default: false. */
|
|
93
|
+
supportsUltrafastTier?: boolean;
|
|
92
94
|
}
|
|
93
95
|
export type CacheRetention = "none" | "short" | "long";
|
|
94
96
|
/**
|
|
@@ -107,9 +109,11 @@ export type CacheRetention = "none" | "short" | "long";
|
|
|
107
109
|
* - `"openai-only"` → `"priority"` on `openai` and `OpenAI code provider`; ignored elsewhere.
|
|
108
110
|
* - `"Anthropic model-only"` → `"priority"` on direct `anthropic` (not Bedrock/Vertex Anthropic model).
|
|
109
111
|
*/
|
|
110
|
-
export type ServiceTier = "auto" | "default" | "flex" | "scale" | "priority" | "openai-only" | "claude-only";
|
|
112
|
+
export type ServiceTier = "auto" | "default" | "flex" | "scale" | "priority" | "ultrafast" | "openai-only" | "claude-only";
|
|
111
113
|
/** Resolved tier — one of the values that providers actually consume on the wire. */
|
|
112
114
|
export type ResolvedServiceTier = Exclude<ServiceTier, "openai-only" | "claude-only">;
|
|
115
|
+
/** Parse a provider-reported service tier, leaving unknown response values for request fallback. */
|
|
116
|
+
export declare function parseResolvedServiceTier(value: unknown): ResolvedServiceTier | undefined;
|
|
113
117
|
/**
|
|
114
118
|
* Resolves a possibly scoped `ServiceTier` to the effective tier for the
|
|
115
119
|
* given provider. Scoped values match their target family and otherwise
|
|
@@ -119,13 +123,19 @@ export declare function resolveServiceTier(serviceTier: ServiceTier | null | und
|
|
|
119
123
|
/**
|
|
120
124
|
* True when the (possibly scoped) tier should be sent as an OpenAI-compatible
|
|
121
125
|
* `service_tier` request field. Custom providers must explicitly opt in through
|
|
122
|
-
* `compat.supportsServiceTier
|
|
126
|
+
* `compat.supportsServiceTier` for the existing tiers or a model-specific
|
|
127
|
+
* `supportsUltrafastTier` capability for ultrafast; unknown providers remain fail-closed.
|
|
128
|
+
*
|
|
129
|
+
* Note: ultrafast has an additional gating requirement via `modelSupportsUltrafastTier`
|
|
130
|
+
* to ensure it is only sent to models that explicitly support it.
|
|
123
131
|
*/
|
|
124
|
-
export declare function shouldSendServiceTier(serviceTier: ServiceTier | null | undefined, provider: Provider | undefined, supportsServiceTier?: boolean): boolean;
|
|
132
|
+
export declare function shouldSendServiceTier(serviceTier: ServiceTier | null | undefined, provider: Provider | undefined, supportsServiceTier?: boolean, supportsUltrafastTier?: boolean): boolean;
|
|
125
133
|
/**
|
|
126
134
|
* True when a priority tier is realized as a fast-mode request on the provider's
|
|
127
135
|
* wire protocol. Custom OpenAI-compatible proxies opt in explicitly rather than
|
|
128
136
|
* inheriting support merely because their API shape resembles OpenAI.
|
|
137
|
+
*
|
|
138
|
+
* Note: ultrafast is distinct from priority and is not considered fast-mode.
|
|
129
139
|
*/
|
|
130
140
|
export declare function isFastModeEffectiveForProvider(serviceTier: ServiceTier | null | undefined, provider: Provider | undefined, supportsServiceTier?: boolean): boolean;
|
|
131
141
|
/**
|
|
@@ -611,6 +621,8 @@ export interface AssistantMessage {
|
|
|
611
621
|
provider: Provider;
|
|
612
622
|
model: string;
|
|
613
623
|
responseId?: string;
|
|
624
|
+
/** Effective service tier reported by the provider, or the sent tier when the provider omits it. */
|
|
625
|
+
serviceTier?: ResolvedServiceTier;
|
|
614
626
|
usage: Usage;
|
|
615
627
|
stopReason: StopReason;
|
|
616
628
|
errorMessage?: string;
|
|
@@ -905,6 +917,7 @@ export type AssistantMessageEvent = {
|
|
|
905
917
|
contentIndex?: undefined;
|
|
906
918
|
reason: Extract<StopReason, "aborted" | "error">;
|
|
907
919
|
error: AssistantMessage;
|
|
920
|
+
partial?: AssistantMessage;
|
|
908
921
|
} | {
|
|
909
922
|
type: "toolChoiceIncapability";
|
|
910
923
|
contentIndex?: undefined;
|
|
@@ -949,6 +962,12 @@ export interface OpenAICompat extends ToolChoiceCompat {
|
|
|
949
962
|
* preserves or intentionally realizes OpenAI priority processing.
|
|
950
963
|
*/
|
|
951
964
|
supportsServiceTier?: boolean;
|
|
965
|
+
/**
|
|
966
|
+
* Whether the model explicitly supports the ultrafast service tier.
|
|
967
|
+
* Only models that set this flag will send ultrafast tier to the API.
|
|
968
|
+
* Models: gpt-6-astra and gpt-6.1-sol.
|
|
969
|
+
*/
|
|
970
|
+
supportsUltrafastTier?: boolean;
|
|
952
971
|
/**
|
|
953
972
|
* Tool names the provider reserves for its own built-ins and refuses to
|
|
954
973
|
* accept as custom function declarations. A colliding tool is **dropped**
|
|
@@ -1170,6 +1189,8 @@ export interface Model<TApi extends Api = any> {
|
|
|
1170
1189
|
requestTransform?: ModelRequestTransform;
|
|
1171
1190
|
/** Default prompt-cache retention preference for this model when the request omits one. */
|
|
1172
1191
|
cacheRetention?: CacheRetention;
|
|
1192
|
+
/** Configured inter-event idle timeout for this model, in milliseconds. */
|
|
1193
|
+
streamIdleTimeoutMs?: number;
|
|
1173
1194
|
/** Provider-assigned priority value (lower = higher priority). */
|
|
1174
1195
|
priority?: number;
|
|
1175
1196
|
/** Canonical thinking capability metadata for this model. */
|
|
@@ -1194,3 +1215,5 @@ export interface Model<TApi extends Api = any> {
|
|
|
1194
1215
|
}
|
|
1195
1216
|
/** True when a model explicitly opts into OpenAI-compatible `service_tier` forwarding. */
|
|
1196
1217
|
export declare function modelSupportsServiceTier(model: Pick<Model, "compat"> | undefined): boolean;
|
|
1218
|
+
/** True when a model explicitly opts into OpenAI ultrafast service tier support. */
|
|
1219
|
+
export declare function modelSupportsUltrafastTier(model: Pick<Model, "compat"> | undefined): boolean;
|
package/src/types.ts
CHANGED
|
@@ -237,6 +237,8 @@ export interface ToolChoiceCompat {
|
|
|
237
237
|
supportsToolChoice?: boolean;
|
|
238
238
|
/** Legacy flag for forced tool_choice support. */
|
|
239
239
|
supportsForcedToolChoice?: boolean;
|
|
240
|
+
/** Whether the provider supports OpenAI ultrafast service tier. Default: false. */
|
|
241
|
+
supportsUltrafastTier?: boolean;
|
|
240
242
|
}
|
|
241
243
|
|
|
242
244
|
// Base options all providers share
|
|
@@ -258,11 +260,34 @@ export type CacheRetention = "none" | "short" | "long";
|
|
|
258
260
|
* - `"openai-only"` → `"priority"` on `openai` and `OpenAI code provider`; ignored elsewhere.
|
|
259
261
|
* - `"Anthropic model-only"` → `"priority"` on direct `anthropic` (not Bedrock/Vertex Anthropic model).
|
|
260
262
|
*/
|
|
261
|
-
export type ServiceTier =
|
|
263
|
+
export type ServiceTier =
|
|
264
|
+
| "auto"
|
|
265
|
+
| "default"
|
|
266
|
+
| "flex"
|
|
267
|
+
| "scale"
|
|
268
|
+
| "priority"
|
|
269
|
+
| "ultrafast"
|
|
270
|
+
| "openai-only"
|
|
271
|
+
| "claude-only";
|
|
262
272
|
|
|
263
273
|
/** Resolved tier — one of the values that providers actually consume on the wire. */
|
|
264
274
|
export type ResolvedServiceTier = Exclude<ServiceTier, "openai-only" | "claude-only">;
|
|
265
275
|
|
|
276
|
+
/** Parse a provider-reported service tier, leaving unknown response values for request fallback. */
|
|
277
|
+
export function parseResolvedServiceTier(value: unknown): ResolvedServiceTier | undefined {
|
|
278
|
+
switch (value) {
|
|
279
|
+
case "auto":
|
|
280
|
+
case "default":
|
|
281
|
+
case "flex":
|
|
282
|
+
case "scale":
|
|
283
|
+
case "priority":
|
|
284
|
+
case "ultrafast":
|
|
285
|
+
return value;
|
|
286
|
+
default:
|
|
287
|
+
return undefined;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
266
291
|
/**
|
|
267
292
|
* Resolves a possibly scoped `ServiceTier` to the effective tier for the
|
|
268
293
|
* given provider. Scoped values match their target family and otherwise
|
|
@@ -286,15 +311,23 @@ export function resolveServiceTier(
|
|
|
286
311
|
/**
|
|
287
312
|
* True when the (possibly scoped) tier should be sent as an OpenAI-compatible
|
|
288
313
|
* `service_tier` request field. Custom providers must explicitly opt in through
|
|
289
|
-
* `compat.supportsServiceTier
|
|
314
|
+
* `compat.supportsServiceTier` for the existing tiers or a model-specific
|
|
315
|
+
* `supportsUltrafastTier` capability for ultrafast; unknown providers remain fail-closed.
|
|
316
|
+
*
|
|
317
|
+
* Note: ultrafast has an additional gating requirement via `modelSupportsUltrafastTier`
|
|
318
|
+
* to ensure it is only sent to models that explicitly support it.
|
|
290
319
|
*/
|
|
291
320
|
export function shouldSendServiceTier(
|
|
292
321
|
serviceTier: ServiceTier | null | undefined,
|
|
293
322
|
provider: Provider | undefined,
|
|
294
323
|
supportsServiceTier = false,
|
|
324
|
+
supportsUltrafastTier = false,
|
|
295
325
|
): boolean {
|
|
296
326
|
const resolved = resolveServiceTier(serviceTier, provider);
|
|
297
327
|
if (provider === "deepinfra") return resolved === "priority";
|
|
328
|
+
if (resolved === "ultrafast") {
|
|
329
|
+
return provider === "openai" || provider === "openai-codex" || supportsUltrafastTier;
|
|
330
|
+
}
|
|
298
331
|
if (provider !== "openai" && provider !== "openai-codex" && !supportsServiceTier) return false;
|
|
299
332
|
return resolved === "flex" || resolved === "scale" || resolved === "priority";
|
|
300
333
|
}
|
|
@@ -303,6 +336,8 @@ export function shouldSendServiceTier(
|
|
|
303
336
|
* True when a priority tier is realized as a fast-mode request on the provider's
|
|
304
337
|
* wire protocol. Custom OpenAI-compatible proxies opt in explicitly rather than
|
|
305
338
|
* inheriting support merely because their API shape resembles OpenAI.
|
|
339
|
+
*
|
|
340
|
+
* Note: ultrafast is distinct from priority and is not considered fast-mode.
|
|
306
341
|
*/
|
|
307
342
|
export function isFastModeEffectiveForProvider(
|
|
308
343
|
serviceTier: ServiceTier | null | undefined,
|
|
@@ -856,6 +891,8 @@ export interface AssistantMessage {
|
|
|
856
891
|
provider: Provider;
|
|
857
892
|
model: string;
|
|
858
893
|
responseId?: string; // Provider-specific response/message identifier when the upstream API exposes one
|
|
894
|
+
/** Effective service tier reported by the provider, or the sent tier when the provider omits it. */
|
|
895
|
+
serviceTier?: ResolvedServiceTier;
|
|
859
896
|
usage: Usage;
|
|
860
897
|
stopReason: StopReason;
|
|
861
898
|
errorMessage?: string;
|
|
@@ -1143,6 +1180,7 @@ export type AssistantMessageEvent =
|
|
|
1143
1180
|
contentIndex?: undefined;
|
|
1144
1181
|
reason: Extract<StopReason, "aborted" | "error">;
|
|
1145
1182
|
error: AssistantMessage;
|
|
1183
|
+
partial?: AssistantMessage;
|
|
1146
1184
|
}
|
|
1147
1185
|
| {
|
|
1148
1186
|
type: "toolChoiceIncapability";
|
|
@@ -1189,6 +1227,12 @@ export interface OpenAICompat extends ToolChoiceCompat {
|
|
|
1189
1227
|
* preserves or intentionally realizes OpenAI priority processing.
|
|
1190
1228
|
*/
|
|
1191
1229
|
supportsServiceTier?: boolean;
|
|
1230
|
+
/**
|
|
1231
|
+
* Whether the model explicitly supports the ultrafast service tier.
|
|
1232
|
+
* Only models that set this flag will send ultrafast tier to the API.
|
|
1233
|
+
* Models: gpt-6-astra and gpt-6.1-sol.
|
|
1234
|
+
*/
|
|
1235
|
+
supportsUltrafastTier?: boolean;
|
|
1192
1236
|
/**
|
|
1193
1237
|
* Tool names the provider reserves for its own built-ins and refuses to
|
|
1194
1238
|
* accept as custom function declarations. A colliding tool is **dropped**
|
|
@@ -1420,6 +1464,8 @@ export interface Model<TApi extends Api = any> {
|
|
|
1420
1464
|
requestTransform?: ModelRequestTransform;
|
|
1421
1465
|
/** Default prompt-cache retention preference for this model when the request omits one. */
|
|
1422
1466
|
cacheRetention?: CacheRetention;
|
|
1467
|
+
/** Configured inter-event idle timeout for this model, in milliseconds. */
|
|
1468
|
+
streamIdleTimeoutMs?: number;
|
|
1423
1469
|
/** Provider-assigned priority value (lower = higher priority). */
|
|
1424
1470
|
priority?: number;
|
|
1425
1471
|
/** Canonical thinking capability metadata for this model. */
|
|
@@ -1460,3 +1506,10 @@ export interface Model<TApi extends Api = any> {
|
|
|
1460
1506
|
export function modelSupportsServiceTier(model: Pick<Model, "compat"> | undefined): boolean {
|
|
1461
1507
|
return Boolean(model?.compat && "supportsServiceTier" in model.compat && model.compat.supportsServiceTier === true);
|
|
1462
1508
|
}
|
|
1509
|
+
|
|
1510
|
+
/** True when a model explicitly opts into OpenAI ultrafast service tier support. */
|
|
1511
|
+
export function modelSupportsUltrafastTier(model: Pick<Model, "compat"> | undefined): boolean {
|
|
1512
|
+
return Boolean(
|
|
1513
|
+
model?.compat && "supportsUltrafastTier" in model.compat && model.compat.supportsUltrafastTier === true,
|
|
1514
|
+
);
|
|
1515
|
+
}
|
package/src/usage/claude.ts
CHANGED
|
@@ -357,7 +357,9 @@ async function fetchClaudeUsage(params: UsageFetchParams, ctx: UsageFetchContext
|
|
|
357
357
|
|
|
358
358
|
const payloadResult = await fetchUsagePayload(url, headers, ctx, params.signal);
|
|
359
359
|
if (!payloadResult || !isRecord(payloadResult.payload)) return null;
|
|
360
|
-
const { payload
|
|
360
|
+
const { payload } = payloadResult;
|
|
361
|
+
// Limits are per organization, and one account can sign in to several of them.
|
|
362
|
+
const orgId = payloadResult.orgId ?? credential.organizationId;
|
|
361
363
|
|
|
362
364
|
const fiveHour = parseBucket(payload.five_hour);
|
|
363
365
|
const sevenDay = parseBucket(payload.seven_day);
|
|
@@ -408,7 +410,7 @@ async function fetchClaudeUsage(params: UsageFetchParams, ctx: UsageFetchContext
|
|
|
408
410
|
].filter((limit): limit is UsageLimit => limit !== null);
|
|
409
411
|
|
|
410
412
|
if (limits.length === 0) return null;
|
|
411
|
-
const identity = extractUsageIdentity(payload, orgId);
|
|
413
|
+
const identity = extractUsageIdentity(payload, payloadResult.orgId);
|
|
412
414
|
let accountId = identity.accountId ?? credential.accountId;
|
|
413
415
|
let email = identity.email ?? credential.email;
|
|
414
416
|
if ((!accountId || !email) && !params.signal?.aborted) {
|
package/src/usage.ts
CHANGED
|
@@ -156,6 +156,9 @@ export interface UsageCredential {
|
|
|
156
156
|
email?: string;
|
|
157
157
|
enterpriseUrl?: string;
|
|
158
158
|
profileArn?: string;
|
|
159
|
+
/** Organization the OAuth token is scoped to; usage limits are per organization. */
|
|
160
|
+
organizationId?: string;
|
|
161
|
+
organizationName?: string;
|
|
159
162
|
mcpBinding?: UsageMCPOAuthBinding;
|
|
160
163
|
metadata?: Record<string, unknown>;
|
|
161
164
|
}
|
|
@@ -3,6 +3,14 @@ import { isRetiredModelKey } from "../../model-retirements";
|
|
|
3
3
|
import { getAntigravityUserAgent } from "../../providers/google-gemini-headers";
|
|
4
4
|
import type { Model } from "../../types";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Returns the default Antigravity discovery User-Agent.
|
|
8
|
+
* Can be overridden via PI_AI_ANTIGRAVITY_USER_AGENT environment variable.
|
|
9
|
+
*/
|
|
10
|
+
export function getDefaultAntigravityUserAgent(): string {
|
|
11
|
+
return getAntigravityUserAgent();
|
|
12
|
+
}
|
|
13
|
+
|
|
6
14
|
const DEFAULT_ANTIGRAVITY_DISCOVERY_ENDPOINTS = [
|
|
7
15
|
"https://daily-cloudcode-pa.googleapis.com",
|
|
8
16
|
"https://daily-cloudcode-pa.sandbox.googleapis.com",
|
|
@@ -35,6 +43,12 @@ export interface AntigravityDiscoveryApiModel {
|
|
|
35
43
|
modelProvider?: string;
|
|
36
44
|
isInternal?: boolean;
|
|
37
45
|
supportsVideo?: boolean;
|
|
46
|
+
/** Account-specific entitlement status */
|
|
47
|
+
entitlement?: string;
|
|
48
|
+
/** Whether the model is disabled for this account */
|
|
49
|
+
disabled?: boolean;
|
|
50
|
+
/** Per-account quota/tier information */
|
|
51
|
+
quota?: string;
|
|
38
52
|
}
|
|
39
53
|
|
|
40
54
|
/**
|
|
@@ -81,6 +95,9 @@ const AntigravityDiscoveryApiModelSchema: z.ZodType<AntigravityDiscoveryApiModel
|
|
|
81
95
|
modelProvider: z.preprocess(value => (typeof value === "string" ? value : undefined), z.string().optional()),
|
|
82
96
|
isInternal: z.preprocess(value => (typeof value === "boolean" ? value : undefined), z.boolean().optional()),
|
|
83
97
|
supportsVideo: z.preprocess(value => (typeof value === "boolean" ? value : undefined), z.boolean().optional()),
|
|
98
|
+
entitlement: z.preprocess(value => (typeof value === "string" ? value : undefined), z.string().optional()),
|
|
99
|
+
disabled: z.preprocess(value => (typeof value === "boolean" ? value : undefined), z.boolean().optional()),
|
|
100
|
+
quota: z.preprocess(value => (typeof value === "string" ? value : undefined), z.string().optional()),
|
|
84
101
|
})
|
|
85
102
|
.loose();
|
|
86
103
|
const AntigravityDiscoveryAgentModelGroupSchema: z.ZodType<AntigravityDiscoveryAgentModelGroup> = z
|
|
@@ -182,6 +199,7 @@ export async function fetchAntigravityDiscoveryModels(
|
|
|
182
199
|
const fetcher = options.fetcher ?? fetch;
|
|
183
200
|
const signal = options.signal ?? AbortSignal.timeout(5_000);
|
|
184
201
|
const targetProvider = options.targetProvider ?? "google-antigravity";
|
|
202
|
+
const userAgent = options.userAgent ?? getAntigravityUserAgent();
|
|
185
203
|
const endpoints = options.endpoint
|
|
186
204
|
? [trimTrailingSlashes(options.endpoint)]
|
|
187
205
|
: DEFAULT_ANTIGRAVITY_DISCOVERY_ENDPOINTS.map(trimTrailingSlashes);
|
|
@@ -194,7 +212,7 @@ export async function fetchAntigravityDiscoveryModels(
|
|
|
194
212
|
headers: {
|
|
195
213
|
Authorization: `Bearer ${options.token}`,
|
|
196
214
|
"Content-Type": "application/json",
|
|
197
|
-
"User-Agent":
|
|
215
|
+
"User-Agent": userAgent,
|
|
198
216
|
},
|
|
199
217
|
body: JSON.stringify({}),
|
|
200
218
|
signal,
|
|
@@ -228,15 +246,56 @@ export async function fetchAntigravityDiscoveryModels(
|
|
|
228
246
|
}
|
|
229
247
|
}
|
|
230
248
|
|
|
249
|
+
const debugEnabled = process.env.GJC_DEBUG_ANTIGRAVITY_DISCOVERY === "1";
|
|
250
|
+
const keptModelIds: string[] = [];
|
|
251
|
+
const filteredByDenylist: string[] = [];
|
|
252
|
+
const filteredByRetirement: string[] = [];
|
|
253
|
+
const filteredByInternal: string[] = [];
|
|
254
|
+
const filteredByDisabled: string[] = [];
|
|
255
|
+
const keptModelDetails: Record<string, Partial<AntigravityDiscoveryApiModel>> = {};
|
|
256
|
+
const filteredModelDetails: Record<string, Partial<AntigravityDiscoveryApiModel> & { reason: string }> = {};
|
|
257
|
+
|
|
231
258
|
const models: Model<"google-gemini-cli">[] = [];
|
|
232
259
|
|
|
233
260
|
for (const [modelId, model] of Object.entries(parsed.models ?? {})) {
|
|
234
|
-
if (ANTIGRAVITY_DISCOVERY_DENYLIST.has(modelId)
|
|
261
|
+
if (ANTIGRAVITY_DISCOVERY_DENYLIST.has(modelId)) {
|
|
262
|
+
if (debugEnabled) {
|
|
263
|
+
filteredByDenylist.push(modelId);
|
|
264
|
+
filteredModelDetails[modelId] = { ...model, reason: "denylist" };
|
|
265
|
+
}
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (isRetiredModelKey(targetProvider, modelId)) {
|
|
269
|
+
if (debugEnabled) {
|
|
270
|
+
filteredByRetirement.push(modelId);
|
|
271
|
+
filteredModelDetails[modelId] = { ...model, reason: `retired-${targetProvider}` };
|
|
272
|
+
}
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (model.disabled === true) {
|
|
276
|
+
if (debugEnabled) {
|
|
277
|
+
filteredByDisabled.push(modelId);
|
|
278
|
+
filteredModelDetails[modelId] = { ...model, reason: "disabled" };
|
|
279
|
+
}
|
|
235
280
|
continue;
|
|
236
281
|
}
|
|
237
282
|
if (model.isInternal === true && !surfacedModelIds.has(modelId)) {
|
|
283
|
+
if (debugEnabled) {
|
|
284
|
+
filteredByInternal.push(modelId);
|
|
285
|
+
filteredModelDetails[modelId] = { ...model, reason: "internal-not-surfaced" };
|
|
286
|
+
}
|
|
238
287
|
continue;
|
|
239
288
|
}
|
|
289
|
+
if (debugEnabled) {
|
|
290
|
+
keptModelIds.push(modelId);
|
|
291
|
+
keptModelDetails[modelId] = {
|
|
292
|
+
displayName: model.displayName,
|
|
293
|
+
isInternal: model.isInternal,
|
|
294
|
+
entitlement: model.entitlement,
|
|
295
|
+
disabled: model.disabled,
|
|
296
|
+
quota: model.quota,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
240
299
|
|
|
241
300
|
const supportsImages = model.supportsImages === true;
|
|
242
301
|
models.push({
|
|
@@ -259,6 +318,89 @@ export async function fetchAntigravityDiscoveryModels(
|
|
|
259
318
|
}
|
|
260
319
|
|
|
261
320
|
models.sort((a, b) => a.name.localeCompare(b.name) || a.id.localeCompare(b.id));
|
|
321
|
+
|
|
322
|
+
if (debugEnabled) {
|
|
323
|
+
const allRawModelIds = Object.keys(parsed.models ?? {}).sort();
|
|
324
|
+
console.error("[GJC_DEBUG_ANTIGRAVITY_DISCOVERY]");
|
|
325
|
+
console.error(` HTTP Status: ${response.status}`);
|
|
326
|
+
console.error(` User-Agent: ${userAgent}`);
|
|
327
|
+
console.error(` Endpoint: ${endpoint}`);
|
|
328
|
+
console.error(` Total raw models from response: ${allRawModelIds.length}`);
|
|
329
|
+
console.error("\n === KEPT MODELS ===");
|
|
330
|
+
console.error(` Count: ${keptModelIds.length}`);
|
|
331
|
+
for (const modelId of keptModelIds) {
|
|
332
|
+
const details = keptModelDetails[modelId];
|
|
333
|
+
const attrs = [];
|
|
334
|
+
if (details?.entitlement) attrs.push(`entitlement=${details.entitlement}`);
|
|
335
|
+
if (details?.disabled === true) attrs.push("disabled=true");
|
|
336
|
+
if (details?.quota) attrs.push(`quota=${details.quota}`);
|
|
337
|
+
if (details?.isInternal === true) attrs.push("isInternal=true");
|
|
338
|
+
const attrStr = attrs.length > 0 ? ` [${attrs.join(", ")}]` : "";
|
|
339
|
+
console.error(` ${modelId}${attrStr}`);
|
|
340
|
+
}
|
|
341
|
+
if (filteredByDenylist.length > 0) {
|
|
342
|
+
console.error(`\n === FILTERED BY DENYLIST ===`);
|
|
343
|
+
console.error(` Count: ${filteredByDenylist.length}`);
|
|
344
|
+
for (const modelId of filteredByDenylist) {
|
|
345
|
+
const details = filteredModelDetails[modelId];
|
|
346
|
+
const attrs = [];
|
|
347
|
+
if (details?.entitlement) attrs.push(`entitlement=${details.entitlement}`);
|
|
348
|
+
if (details?.disabled === true) attrs.push("disabled=true");
|
|
349
|
+
if (details?.quota) attrs.push(`quota=${details.quota}`);
|
|
350
|
+
if (details?.isInternal === true) attrs.push("isInternal=true");
|
|
351
|
+
const attrStr = attrs.length > 0 ? ` [${attrs.join(", ")}]` : "";
|
|
352
|
+
console.error(` ${modelId}${attrStr}`);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (filteredByRetirement.length > 0) {
|
|
356
|
+
console.error(`\n === FILTERED BY RETIREMENT (${targetProvider}) ===`);
|
|
357
|
+
console.error(` Count: ${filteredByRetirement.length}`);
|
|
358
|
+
for (const modelId of filteredByRetirement) {
|
|
359
|
+
const details = filteredModelDetails[modelId];
|
|
360
|
+
const attrs = [];
|
|
361
|
+
if (details?.entitlement) attrs.push(`entitlement=${details.entitlement}`);
|
|
362
|
+
if (details?.disabled === true) attrs.push("disabled=true");
|
|
363
|
+
if (details?.quota) attrs.push(`quota=${details.quota}`);
|
|
364
|
+
if (details?.isInternal === true) attrs.push("isInternal=true");
|
|
365
|
+
const attrStr = attrs.length > 0 ? ` [${attrs.join(", ")}]` : "";
|
|
366
|
+
console.error(` ${modelId}${attrStr}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (filteredByDisabled.length > 0) {
|
|
370
|
+
console.error(`\n === FILTERED (disabled) ===`);
|
|
371
|
+
console.error(` Count: ${filteredByDisabled.length}`);
|
|
372
|
+
for (const modelId of filteredByDisabled) {
|
|
373
|
+
const details = filteredModelDetails[modelId];
|
|
374
|
+
const attrs = [];
|
|
375
|
+
if (details?.entitlement) attrs.push(`entitlement=${details.entitlement}`);
|
|
376
|
+
if (details?.disabled === true) attrs.push("disabled=true");
|
|
377
|
+
if (details?.quota) attrs.push(`quota=${details.quota}`);
|
|
378
|
+
if (details?.isInternal === true) attrs.push("isInternal=true");
|
|
379
|
+
const attrStr = attrs.length > 0 ? ` [${attrs.join(", ")}]` : "";
|
|
380
|
+
console.error(` ${modelId}${attrStr}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (filteredByInternal.length > 0) {
|
|
384
|
+
console.error(`\n === FILTERED (internal, not surfaced) ===`);
|
|
385
|
+
console.error(` Count: ${filteredByInternal.length}`);
|
|
386
|
+
for (const modelId of filteredByInternal) {
|
|
387
|
+
const details = filteredModelDetails[modelId];
|
|
388
|
+
const attrs = [];
|
|
389
|
+
if (details?.entitlement) attrs.push(`entitlement=${details.entitlement}`);
|
|
390
|
+
if (details?.disabled === true) attrs.push("disabled=true");
|
|
391
|
+
if (details?.quota) attrs.push(`quota=${details.quota}`);
|
|
392
|
+
if (details?.isInternal === true) attrs.push("isInternal=true");
|
|
393
|
+
const attrStr = attrs.length > 0 ? ` [${attrs.join(", ")}]` : "";
|
|
394
|
+
console.error(` ${modelId}${attrStr}`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
console.error(`\n === SURFACE INFO ===`);
|
|
398
|
+
console.error(` agentModelSorts surfaced: ${surfacedModelIds.size}`);
|
|
399
|
+
if (surfacedModelIds.size > 0) {
|
|
400
|
+
console.error(` ${Array.from(surfacedModelIds).sort().join(", ")}`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
262
404
|
return models;
|
|
263
405
|
}
|
|
264
406
|
|