@gajae-code/ai 0.15.5 → 0.15.6
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 +15 -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/provider-models/openai-compat.d.ts +1 -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/package.json +3 -3
- 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 +658 -154
- package/src/cli.ts +1 -0
- package/src/models.json +1023 -0
- package/src/provider-models/descriptors.ts +3 -1
- package/src/provider-models/openai-compat.ts +41 -1
- package/src/providers/anthropic.ts +7 -1
- 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-shared.ts +3 -0
- package/src/providers/kiro-codewhisperer.ts +24 -8
- package/src/providers/ollama.ts +3 -0
- package/src/providers/openai-codex-responses.ts +20 -6
- package/src/providers/openai-completions.ts +11 -1
- package/src/providers/openai-responses.ts +10 -1
- package/src/providers/pi-native-client.ts +1 -0
- 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/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
|
@@ -15,6 +15,11 @@ export type ApiKeyCredential = {
|
|
|
15
15
|
type: "api_key";
|
|
16
16
|
key: string;
|
|
17
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Extracts the bearer token from the structured API-key form used by OAuth
|
|
20
|
+
* providers that need to carry token metadata alongside the access token.
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractStructuredApiKeyToken(apiKey: string): string | undefined;
|
|
18
23
|
export interface MCPOAuthBinding {
|
|
19
24
|
/** Exact HTTP(S) origin of the MCP resource endpoint. */
|
|
20
25
|
resourceOrigin: string;
|
|
@@ -203,6 +208,7 @@ export interface AuthCredentialSnapshotEntry {
|
|
|
203
208
|
provider: string;
|
|
204
209
|
credential: SnapshotCredential;
|
|
205
210
|
identityKey: string | null;
|
|
211
|
+
revision?: number;
|
|
206
212
|
}
|
|
207
213
|
export type AuthCredentialIfAbsentReason = "inserted" | "updated-existing" | "skipped-existing" | "skipped-existing-runtime" | "skipped-existing-config" | "skipped-existing-env" | "skipped-existing-fallback" | "skipped-invalid";
|
|
208
214
|
export interface AuthCredentialIfAbsentResult {
|
|
@@ -253,8 +259,20 @@ export type OAuthRefreshLeaseClaim = {
|
|
|
253
259
|
} | {
|
|
254
260
|
kind: "missing";
|
|
255
261
|
};
|
|
262
|
+
/**
|
|
263
|
+
* Store-owned ticket that orders a provider admission against remote
|
|
264
|
+
* credential snapshot application. The ticket is intentionally released at
|
|
265
|
+
* provider admission, not response completion.
|
|
266
|
+
*/
|
|
267
|
+
export interface CredentialDispatchTicket {
|
|
268
|
+
release(): void;
|
|
269
|
+
}
|
|
256
270
|
export interface AuthCredentialStore {
|
|
257
271
|
close(): void;
|
|
272
|
+
refreshSnapshot?(signal?: AbortSignal): Promise<unknown>;
|
|
273
|
+
onSnapshotChanged?(listener: () => void): () => void;
|
|
274
|
+
/** Order provider admission with remote snapshot authority application. */
|
|
275
|
+
acquireCredentialDispatchTicket?(provider: Provider, signal?: AbortSignal): Promise<CredentialDispatchTicket>;
|
|
258
276
|
listAuthCredentials(provider?: string): StoredAuthCredential[];
|
|
259
277
|
/** Payload-free account inventory; active and soft-disabled rows are included. */
|
|
260
278
|
listCredentialInventory?(provider?: string): CredentialInventoryRecord[];
|
|
@@ -265,6 +283,7 @@ export interface AuthCredentialStore {
|
|
|
265
283
|
updateAuthCredential(id: number, credential: AuthCredential): void;
|
|
266
284
|
deleteAuthCredential(id: number, disabledCause: string): void;
|
|
267
285
|
tryDisableAuthCredentialIfMatches(id: number, expectedData: string, disabledCause: string): boolean;
|
|
286
|
+
tryDisableAuthCredentialIfRevision?(id: number, expectedRevision: number, disabledCause: string): boolean;
|
|
268
287
|
replaceAuthCredentialsForProvider(provider: string, credentials: AuthCredential[]): StoredAuthCredential[];
|
|
269
288
|
upsertAuthCredentialForProvider(provider: string, credential: AuthCredential): StoredAuthCredential[];
|
|
270
289
|
upsertAuthCredentialForProviderIfAbsent(provider: string, credential: AuthCredential): AuthCredentialIfAbsentResult;
|
|
@@ -273,6 +292,8 @@ export interface AuthCredentialStore {
|
|
|
273
292
|
includeExpired?: boolean;
|
|
274
293
|
}): string | null;
|
|
275
294
|
setCache(key: string, value: string, expiresAtSec: number): void;
|
|
295
|
+
/** Atomically allocate a durable sequence for broker restart epochs. */
|
|
296
|
+
allocateMonotonicSequence(key: string, expiresAtSec: number): number;
|
|
276
297
|
deleteCachePrefix?(prefix: string): void;
|
|
277
298
|
cleanExpiredCache(): void;
|
|
278
299
|
/**
|
|
@@ -320,6 +341,7 @@ export interface AuthCredentialStore {
|
|
|
320
341
|
* `signal` propagates the agent's cancel down to the broker fetch.
|
|
321
342
|
*/
|
|
322
343
|
fetchUsageReports?(signal?: AbortSignal): Promise<UsageReport[] | null>;
|
|
344
|
+
fetchUsageReportsForProvider?(provider: Provider, signal?: AbortSignal): Promise<UsageReport[] | null>;
|
|
323
345
|
/** Synchronous, zero-network usage presentation peek. */
|
|
324
346
|
peekCachedUsagePresentation?(provider: Provider, credentialId: number): CachedUsagePresentation | undefined;
|
|
325
347
|
/** Record a safe usage observation after an explicit fetch/check. */
|
|
@@ -360,6 +382,16 @@ export interface AuthCredentialStore {
|
|
|
360
382
|
markCredentialSuspect?(credentialId: number, opts?: {
|
|
361
383
|
signal?: AbortSignal;
|
|
362
384
|
}): Promise<void>;
|
|
385
|
+
/**
|
|
386
|
+
* Optional async write hook to disable one credential through an authoritative
|
|
387
|
+
* remote store. Remote clients MUST use this hook instead of the synchronous
|
|
388
|
+
* local delete methods when an OAuth refresh fails definitively.
|
|
389
|
+
*
|
|
390
|
+
* Returns `false` when the row is already absent (for example, a peer
|
|
391
|
+
* disabled it first). Implementations MUST NOT treat a failed remote write as
|
|
392
|
+
* a successful local deletion.
|
|
393
|
+
*/
|
|
394
|
+
disableAuthCredentialRemote?(credentialId: number, disabledCause: string, signal?: AbortSignal, expectedRevision?: number): Promise<boolean>;
|
|
363
395
|
/**
|
|
364
396
|
* Optional async write hook for upserting a single credential. When present,
|
|
365
397
|
* `AuthStorage.#upsertOAuthCredential` routes through this instead of the
|
|
@@ -468,10 +500,13 @@ export type AuthStorageOptions = {
|
|
|
468
500
|
* AuthStorage caller surfaces that to its own consumer unchanged.
|
|
469
501
|
*/
|
|
470
502
|
fetchUsageReports?: (signal?: AbortSignal) => Promise<UsageReport[] | null>;
|
|
503
|
+
fetchUsageReportsForProvider?: (provider: Provider, signal?: AbortSignal) => Promise<UsageReport[] | null>;
|
|
471
504
|
};
|
|
472
|
-
type AuthApiKeyOptions = {
|
|
505
|
+
export type AuthApiKeyOptions = {
|
|
473
506
|
baseUrl?: string;
|
|
474
507
|
modelId?: string;
|
|
508
|
+
/** Select config registrations owned by one caller (for example a ModelRegistry). */
|
|
509
|
+
owner?: object;
|
|
475
510
|
/**
|
|
476
511
|
* Caller's cancel signal. Threaded into any broker-bound OAuth refresh so
|
|
477
512
|
* `ESC` / request abort actually kills a hung broker fetch instead of
|
|
@@ -506,7 +541,11 @@ export interface OAuthAccess {
|
|
|
506
541
|
export interface InvalidateCredentialMatchingOptions {
|
|
507
542
|
signal?: AbortSignal;
|
|
508
543
|
sessionId?: string;
|
|
544
|
+
owner?: object;
|
|
509
545
|
}
|
|
546
|
+
/** Read optional broker error detail without allowing hostile objects to escape classification. */
|
|
547
|
+
/** @internal Tested directly because hostile accessors must preserve the original error identity. */
|
|
548
|
+
export declare function readBrokerErrorBody(error: unknown): string | undefined;
|
|
510
549
|
/**
|
|
511
550
|
* Credential storage backed by an AuthCredentialStore.
|
|
512
551
|
* Reads from storage on reload(), manages round-robin credential selection,
|
|
@@ -528,9 +567,14 @@ export declare class AuthStorage {
|
|
|
528
567
|
*/
|
|
529
568
|
close(): void;
|
|
530
569
|
getGeneration(): number;
|
|
570
|
+
getCache(key: string, options?: {
|
|
571
|
+
includeExpired?: boolean;
|
|
572
|
+
}): string | null;
|
|
573
|
+
setCache(key: string, value: string, expiresAtSec: number): void;
|
|
574
|
+
allocateMonotonicSequence(key: string, expiresAtSec: number): number;
|
|
531
575
|
getProviderConfigurationGeneration(provider: string): number;
|
|
532
576
|
getProviderOAuthRefreshGeneration(provider: string): number;
|
|
533
|
-
getProviderEvidenceGeneration(provider: string, resolvedApiKey?: string): string;
|
|
577
|
+
getProviderEvidenceGeneration(provider: string, resolvedApiKey?: string, owner?: object): string;
|
|
534
578
|
onGenerationChanged(listener: (generation: number) => void): () => void;
|
|
535
579
|
offGenerationChanged(listener: (generation: number) => void): void;
|
|
536
580
|
/**
|
|
@@ -568,8 +612,12 @@ export declare class AuthStorage {
|
|
|
568
612
|
hasCredentialScopeLease(scopeId: string): boolean;
|
|
569
613
|
/** Release one credential-scope lease; final release clears only that scope's derived state. */
|
|
570
614
|
releaseCredentialScope(scopeId: string): void;
|
|
571
|
-
/**
|
|
572
|
-
|
|
615
|
+
/**
|
|
616
|
+
* Set the selector derived from a durable session pin or a session seed.
|
|
617
|
+
* `owner` scopes config-override validation to one ModelRegistry; omitted
|
|
618
|
+
* owners retain process-wide caller semantics.
|
|
619
|
+
*/
|
|
620
|
+
setSessionCredentialSelector(scopeId: string, provider: string, selector: AuthCredentialSelector, owner?: object): void;
|
|
573
621
|
/** Explicitly mask persistent/process-global selection and return the provider to AUTO for one scope. */
|
|
574
622
|
setSessionCredentialAuto(provider: string, scopeId: string): void;
|
|
575
623
|
/** Clear a scope's explicit selector and AUTO mask, restoring normal precedence. */
|
|
@@ -581,9 +629,13 @@ export declare class AuthStorage {
|
|
|
581
629
|
/** Resolve the effective selector precedence for a provider/scope. */
|
|
582
630
|
resolveEffectiveCredentialSelector(provider: string, scopeId?: string, explicitSelector?: AuthCredentialSelector): AuthCredentialSelector | undefined;
|
|
583
631
|
/** @internal Return cache provenance for an exact stored literal API-key row without resolving its value. */
|
|
584
|
-
getStoredLiteralApiKeyEvidenceGeneration(provider: string, selector: AuthCredentialSelector): string | undefined;
|
|
585
|
-
/**
|
|
586
|
-
|
|
632
|
+
getStoredLiteralApiKeyEvidenceGeneration(provider: string, selector: AuthCredentialSelector, owner?: object): string | undefined;
|
|
633
|
+
/**
|
|
634
|
+
* Validate and canonicalize an OAuth-only selector for account pinning.
|
|
635
|
+
* `owner` scopes config-override checks to one ModelRegistry; omitted owners
|
|
636
|
+
* retain process-wide caller semantics.
|
|
637
|
+
*/
|
|
638
|
+
resolveOAuthPinTarget(provider: string, selector: AuthCredentialSelector, owner?: object): OAuthPinTarget;
|
|
587
639
|
/** Return all local inventory rows, including soft-disabled metadata, without payloads. */
|
|
588
640
|
listCredentialInventory(provider?: string): CredentialInventoryRecord[];
|
|
589
641
|
/** Return local credential hard-removal action targets, including disabled rows. */
|
|
@@ -617,7 +669,7 @@ export declare class AuthStorage {
|
|
|
617
669
|
/** Whether a provider is currently authenticated by a runtime API-key override. */
|
|
618
670
|
hasRuntimeApiKey(provider: string): boolean;
|
|
619
671
|
/** Whether a provider is currently authenticated by a config API-key override. */
|
|
620
|
-
hasConfigApiKey(provider: string): boolean;
|
|
672
|
+
hasConfigApiKey(provider: string, owner?: object): boolean;
|
|
621
673
|
/**
|
|
622
674
|
* Whether credential selection for a provider is pinned to one stored row by
|
|
623
675
|
* a runtime selector (`--credential`).
|
|
@@ -664,7 +716,8 @@ export declare class AuthStorage {
|
|
|
664
716
|
* runtime API-key override (`--api-key`), or a config-sourced API key
|
|
665
717
|
* (`models.yml` `apiKey`) would each re-decide the credential on the very
|
|
666
718
|
* next {@link AuthStorage.getApiKey} call and make this switch appear to
|
|
667
|
-
* silently do nothing.
|
|
719
|
+
* silently do nothing. `owner` scopes the config-override check to one
|
|
720
|
+
* ModelRegistry; omitted owners retain process-wide caller semantics.
|
|
668
721
|
*
|
|
669
722
|
* Deliberately does not touch credential-blocked state: if the target row
|
|
670
723
|
* is still backoff-blocked from a prior quota failure, the existing
|
|
@@ -672,7 +725,7 @@ export declare class AuthStorage {
|
|
|
672
725
|
* falls back to a usable account instead of re-issuing a request that would
|
|
673
726
|
* just draw another 429/quota error.
|
|
674
727
|
*/
|
|
675
|
-
switchSessionCredential(provider: string, sessionId: string, selector: AuthCredentialSelector): void;
|
|
728
|
+
switchSessionCredential(provider: string, sessionId: string, selector: AuthCredentialSelector, owner?: object): void;
|
|
676
729
|
/**
|
|
677
730
|
* Register a per-provider API key sourced from user configuration
|
|
678
731
|
* (e.g. `models.yml` `providers.<name>.apiKey`). Higher priority than
|
|
@@ -683,6 +736,9 @@ export declare class AuthStorage {
|
|
|
683
736
|
* Lower priority than {@link setRuntimeApiKey} so a CLI `--api-key`
|
|
684
737
|
* still wins for the duration of a single invocation.
|
|
685
738
|
*
|
|
739
|
+
* `options.owner` scopes the override to one registry or other caller. The
|
|
740
|
+
* unscoped form is process-wide and is retained for standalone callers.
|
|
741
|
+
*
|
|
686
742
|
* `options.envSourced` marks the value as resolved from a models.yml
|
|
687
743
|
* `apiKeyEnv` indirection. Unlike a literal pin, an env pointer only says
|
|
688
744
|
* where to look for a key; when the user has since run `auth login`, the
|
|
@@ -692,25 +748,33 @@ export declare class AuthStorage {
|
|
|
692
748
|
*/
|
|
693
749
|
setConfigApiKey(provider: string, apiKey: string, options?: {
|
|
694
750
|
envSourced?: boolean;
|
|
751
|
+
owner?: object;
|
|
695
752
|
}): void;
|
|
696
753
|
/**
|
|
697
754
|
* Remove a single config-sourced API key override.
|
|
698
755
|
*/
|
|
699
|
-
removeConfigApiKey(provider: string): void;
|
|
756
|
+
removeConfigApiKey(provider: string, owner?: object): void;
|
|
700
757
|
/**
|
|
701
|
-
* Drop
|
|
702
|
-
*
|
|
758
|
+
* Drop config-sourced API keys. An owner removes only its own registrations;
|
|
759
|
+
* the unscoped form remains an explicit global reset for callers that own the
|
|
760
|
+
* entire AuthStorage instance.
|
|
703
761
|
*/
|
|
704
|
-
clearConfigApiKeys(): void;
|
|
762
|
+
clearConfigApiKeys(owner?: object): void;
|
|
705
763
|
/**
|
|
706
764
|
* Set a fallback resolver for API keys not found in storage or env vars.
|
|
707
765
|
* Used for custom provider keys from models.json.
|
|
708
766
|
*/
|
|
709
|
-
setFallbackResolver(resolver: (provider: string) => string | undefined): void;
|
|
767
|
+
setFallbackResolver(resolver: (provider: string) => string | undefined, owner?: object): () => void;
|
|
710
768
|
/**
|
|
711
769
|
* Reload credentials from storage.
|
|
712
770
|
*/
|
|
713
771
|
reload(): Promise<void>;
|
|
772
|
+
/**
|
|
773
|
+
* Acquire a store-owned provider-admission ticket when the backing store
|
|
774
|
+
* provides one (for example, a remote broker snapshot store). Local stores
|
|
775
|
+
* need no additional ordering and return `undefined`.
|
|
776
|
+
*/
|
|
777
|
+
acquireCredentialDispatchTicket(provider: Provider, signal?: AbortSignal): Promise<CredentialDispatchTicket | undefined>;
|
|
714
778
|
/** Returns the credential type selected for a provider/session, if one has been recorded. */
|
|
715
779
|
getSessionCredentialType(provider: string, sessionId?: string): AuthCredential["type"] | undefined;
|
|
716
780
|
/**
|
|
@@ -721,7 +785,7 @@ export declare class AuthStorage {
|
|
|
721
785
|
* Set credential for a provider.
|
|
722
786
|
*/
|
|
723
787
|
set(provider: string, credential: AuthCredentialEntry): Promise<void>;
|
|
724
|
-
importCredentialIfAbsent(provider: string, credential: AuthCredential): Promise<AuthCredentialIfAbsentSnapshotResult>;
|
|
788
|
+
importCredentialIfAbsent(provider: string, credential: AuthCredential, owner?: object): Promise<AuthCredentialIfAbsentSnapshotResult>;
|
|
725
789
|
/**
|
|
726
790
|
* Remove credential for a provider.
|
|
727
791
|
*/
|
|
@@ -734,17 +798,18 @@ export declare class AuthStorage {
|
|
|
734
798
|
* Check if credentials exist for a provider in storage.
|
|
735
799
|
*/
|
|
736
800
|
has(provider: string): boolean;
|
|
737
|
-
|
|
801
|
+
disableCredentialByIdIfRevision(id: number, expectedRevision: number, disabledCause: string): boolean;
|
|
802
|
+
hasAuth(provider: string, sessionId?: string, options?: Pick<AuthApiKeyOptions, "owner">): boolean;
|
|
738
803
|
/**
|
|
739
804
|
* Credential type that a provider/session will dispatch first without performing I/O.
|
|
740
805
|
* Mirrors getApiKey selector validation, overrides, session OAuth stickiness,
|
|
741
806
|
* cached command-key usability, OAuth retry, and environment fallback order.
|
|
742
807
|
*/
|
|
743
|
-
getEffectiveCredentialType(provider: string, sessionId?: string): AuthCredential["type"] | undefined;
|
|
808
|
+
getEffectiveCredentialType(provider: string, sessionId?: string, options?: Pick<AuthApiKeyOptions, "owner">): AuthCredential["type"] | undefined;
|
|
744
809
|
/**
|
|
745
810
|
* Check whether configured auth is currently usable without resolving credentials.
|
|
746
811
|
*/
|
|
747
|
-
hasUsableAuth(provider: string): boolean;
|
|
812
|
+
hasUsableAuth(provider: string, options?: Pick<AuthApiKeyOptions, "owner">): boolean;
|
|
748
813
|
/**
|
|
749
814
|
* Check if OAuth credentials are configured for a provider.
|
|
750
815
|
*/
|
|
@@ -752,7 +817,7 @@ export declare class AuthStorage {
|
|
|
752
817
|
/**
|
|
753
818
|
* Get OAuth credentials for a provider.
|
|
754
819
|
*/
|
|
755
|
-
getOAuthCredential(provider: string, sessionId?: string): OAuthCredential | undefined;
|
|
820
|
+
getOAuthCredential(provider: string, sessionId?: string, options?: Pick<AuthApiKeyOptions, "owner">): OAuthCredential | undefined;
|
|
756
821
|
/**
|
|
757
822
|
* Get the OAuth `accountId` for a provider, preferring the credential that is
|
|
758
823
|
* session-sticky for `sessionId` when multiple OAuth credentials are configured.
|
|
@@ -760,7 +825,7 @@ export declare class AuthStorage {
|
|
|
760
825
|
* first call before any `getApiKey` has been issued, or single-credential setups).
|
|
761
826
|
* Returns `undefined` when no OAuth credential carries an `accountId`.
|
|
762
827
|
*/
|
|
763
|
-
getOAuthAccountId(provider: string, sessionId?: string): string | undefined;
|
|
828
|
+
getOAuthAccountId(provider: string, sessionId?: string, options?: Pick<AuthApiKeyOptions, "owner">): string | undefined;
|
|
764
829
|
/**
|
|
765
830
|
* Get all credentials.
|
|
766
831
|
*/
|
|
@@ -785,6 +850,7 @@ export declare class AuthStorage {
|
|
|
785
850
|
*/
|
|
786
851
|
logout(provider: string): Promise<void>;
|
|
787
852
|
fetchUsageReports(options?: {
|
|
853
|
+
provider?: Provider;
|
|
788
854
|
baseUrlResolver?: (provider: Provider) => string | undefined;
|
|
789
855
|
/** Caller's cancel signal; only rejects this caller, never the shared upstream fetch. */
|
|
790
856
|
signal?: AbortSignal;
|
|
@@ -829,6 +895,7 @@ export declare class AuthStorage {
|
|
|
829
895
|
retryAfterMs?: number;
|
|
830
896
|
baseUrl?: string;
|
|
831
897
|
signal?: AbortSignal;
|
|
898
|
+
owner?: object;
|
|
832
899
|
}): Promise<boolean>;
|
|
833
900
|
/**
|
|
834
901
|
* Earliest instant at which any currently blocked stored credential for this
|
|
@@ -844,7 +911,7 @@ export declare class AuthStorage {
|
|
|
844
911
|
* and get a best-effort token. For GitHub Copilot we preserve enterprise
|
|
845
912
|
* routing metadata so discovery can hit the correct host.
|
|
846
913
|
*/
|
|
847
|
-
peekApiKey(provider: string): Promise<string | undefined>;
|
|
914
|
+
peekApiKey(provider: string, options?: Pick<AuthApiKeyOptions, "owner">): Promise<string | undefined>;
|
|
848
915
|
/**
|
|
849
916
|
* Get API key for a provider.
|
|
850
917
|
* Priority:
|
|
@@ -936,7 +1003,7 @@ export declare class AuthStorage {
|
|
|
936
1003
|
*
|
|
937
1004
|
* The string is purely informational; consumers must not parse it.
|
|
938
1005
|
*/
|
|
939
|
-
describeCredentialSource(provider: string, sessionId?: string): string | undefined;
|
|
1006
|
+
describeCredentialSource(provider: string, sessionId?: string, options?: Pick<AuthApiKeyOptions, "owner">): string | undefined;
|
|
940
1007
|
}
|
|
941
1008
|
/**
|
|
942
1009
|
* Default SQLite-backed implementation of {@link AuthCredentialStore}.
|
|
@@ -969,11 +1036,13 @@ export declare class SqliteAuthCredentialStore implements AuthCredentialStore {
|
|
|
969
1036
|
* row between our pre-check and the disable.
|
|
970
1037
|
*/
|
|
971
1038
|
tryDisableAuthCredentialIfMatches(id: number, expectedData: string, disabledCause: string): boolean;
|
|
1039
|
+
tryDisableAuthCredentialIfRevision(id: number, expectedRevision: number, disabledCause: string): boolean;
|
|
972
1040
|
deleteAuthCredentialsForProvider(provider: string, disabledCause: string): void;
|
|
973
1041
|
getCache(key: string, options?: {
|
|
974
1042
|
includeExpired?: boolean;
|
|
975
1043
|
}): string | null;
|
|
976
1044
|
setCache(key: string, value: string, expiresAtSec: number): void;
|
|
1045
|
+
allocateMonotonicSequence(key: string, expiresAtSec: number): number;
|
|
977
1046
|
deleteCachePrefix(prefix: string): void;
|
|
978
1047
|
cleanExpiredCache(): void;
|
|
979
1048
|
/**
|
|
@@ -1003,4 +1072,3 @@ export declare class SqliteAuthCredentialStore implements AuthCredentialStore {
|
|
|
1003
1072
|
deleteProvider(provider: string): void;
|
|
1004
1073
|
close(): void;
|
|
1005
1074
|
}
|
|
1006
|
-
export {};
|
|
@@ -98,6 +98,7 @@ export interface OpenCodeModelManagerConfig {
|
|
|
98
98
|
}
|
|
99
99
|
export declare function opencodeZenModelManagerOptions(config?: OpenCodeModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
100
100
|
export declare function opencodeGoModelManagerOptions(config?: OpenCodeModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
101
|
+
export declare function commandCodeModelManagerOptions(config?: OpenCodeModelManagerConfig): ModelManagerOptions<Api>;
|
|
101
102
|
export interface OllamaModelManagerConfig {
|
|
102
103
|
apiKey?: string;
|
|
103
104
|
baseUrl?: string;
|
|
@@ -44,16 +44,16 @@ export declare function resolveLazyStreamFirstEventFallbackMs(provider: string,
|
|
|
44
44
|
export declare const PROVIDER_RUNTIME_DESCRIPTORS: readonly ProviderRuntimeDescriptor<Api, unknown>[];
|
|
45
45
|
/** Return the lazy descriptor for a built-in API, if one is registered. */
|
|
46
46
|
export declare function getProviderRuntimeDescriptor<TApi extends Api>(api: TApi): ProviderRuntimeDescriptor<TApi, unknown> | undefined;
|
|
47
|
-
export declare const streamAnthropic: (model: Model<"anthropic-messages">, context: Context, options: OptionsForApi<"anthropic-messages"
|
|
48
|
-
export declare const streamAzureOpenAIResponses: (model: Model<"azure-openai-responses">, context: Context, options: OptionsForApi<"azure-openai-responses"
|
|
49
|
-
export declare const streamGoogle: (model: Model<"google-generative-ai">, context: Context, options: OptionsForApi<"google-generative-ai"
|
|
50
|
-
export declare const streamGoogleGeminiCli: (model: Model<"google-gemini-cli">, context: Context, options: OptionsForApi<"google-gemini-cli"
|
|
51
|
-
export declare const streamGoogleVertex: (model: Model<"google-vertex">, context: Context, options: OptionsForApi<"google-vertex"
|
|
52
|
-
export declare const streamOpenAICodexResponses: (model: Model<"openai-codex-responses">, context: Context, options: OptionsForApi<"openai-codex-responses"
|
|
53
|
-
export declare const streamOpenAICompletions: (model: Model<"openai-completions">, context: Context, options: OptionsForApi<"openai-completions"
|
|
54
|
-
export declare const streamOpenAIResponses: (model: Model<"openai-responses">, context: Context, options: OptionsForApi<"openai-responses"
|
|
55
|
-
export declare const streamCursor: (model: Model<"cursor-agent">, context: Context, options: OptionsForApi<"cursor-agent"
|
|
56
|
-
export declare const streamOllama: (model: Model<"ollama-chat">, context: Context, options: OptionsForApi<"ollama-chat"
|
|
57
|
-
export declare const streamBedrock: (model: Model<"bedrock-converse-stream">, context: Context, options: OptionsForApi<"bedrock-converse-stream"
|
|
58
|
-
export declare const streamKiroCodeWhisperer: (model: Model<"kiro-codewhisperer-stream">, context: Context, options: OptionsForApi<"kiro-codewhisperer-stream"
|
|
47
|
+
export declare const streamAnthropic: (model: Model<"anthropic-messages">, context: Context, options: OptionsForApi<"anthropic-messages">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
48
|
+
export declare const streamAzureOpenAIResponses: (model: Model<"azure-openai-responses">, context: Context, options: OptionsForApi<"azure-openai-responses">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
49
|
+
export declare const streamGoogle: (model: Model<"google-generative-ai">, context: Context, options: OptionsForApi<"google-generative-ai">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
50
|
+
export declare const streamGoogleGeminiCli: (model: Model<"google-gemini-cli">, context: Context, options: OptionsForApi<"google-gemini-cli">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
51
|
+
export declare const streamGoogleVertex: (model: Model<"google-vertex">, context: Context, options: OptionsForApi<"google-vertex">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
52
|
+
export declare const streamOpenAICodexResponses: (model: Model<"openai-codex-responses">, context: Context, options: OptionsForApi<"openai-codex-responses">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
53
|
+
export declare const streamOpenAICompletions: (model: Model<"openai-completions">, context: Context, options: OptionsForApi<"openai-completions">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
54
|
+
export declare const streamOpenAIResponses: (model: Model<"openai-responses">, context: Context, options: OptionsForApi<"openai-responses">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
55
|
+
export declare const streamCursor: (model: Model<"cursor-agent">, context: Context, options: OptionsForApi<"cursor-agent">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
56
|
+
export declare const streamOllama: (model: Model<"ollama-chat">, context: Context, options: OptionsForApi<"ollama-chat">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
57
|
+
export declare const streamBedrock: (model: Model<"bedrock-converse-stream">, context: Context, options: OptionsForApi<"bedrock-converse-stream">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
58
|
+
export declare const streamKiroCodeWhisperer: (model: Model<"kiro-codewhisperer-stream">, context: Context, options: OptionsForApi<"kiro-codewhisperer-stream">, onStreamCreated?: () => void) => EventStreamImpl;
|
|
59
59
|
export {};
|
package/dist/types/stream.d.ts
CHANGED
|
@@ -29,12 +29,13 @@ export declare function listProvidersWithEnvKey(): string[];
|
|
|
29
29
|
* handling, so callers can append it unconditionally.
|
|
30
30
|
*/
|
|
31
31
|
export declare function formatProviderCredentialHint(provider: string): string;
|
|
32
|
+
export declare function streamFromLazyImport(createInner: () => Promise<AssistantMessageEventStream>, signal?: AbortSignal, onStreamCreated?: () => void): AssistantMessageEventStream;
|
|
32
33
|
/**
|
|
33
34
|
* Build an actionable "missing API key" error for a provider, used by the
|
|
34
35
|
* low-level `stream`/`complete` entry points (#755).
|
|
35
36
|
*/
|
|
36
37
|
export declare function formatMissingApiKeyError(provider: string): string;
|
|
37
|
-
export declare function stream<TApi extends Api>(model: Model<TApi>, context: Context, options?: OptionsForApi<TApi
|
|
38
|
+
export declare function stream<TApi extends Api>(model: Model<TApi>, context: Context, options?: OptionsForApi<TApi>, onStreamCreated?: () => void): AssistantMessageEventStream;
|
|
38
39
|
export declare function complete<TApi extends Api>(model: Model<TApi>, context: Context, options?: OptionsForApi<TApi>): Promise<AssistantMessage>;
|
|
39
40
|
export declare function streamSimple<TApi extends Api>(model: Model<TApi>, context: Context, options?: SimpleStreamOptions): AssistantMessageEventStream;
|
|
40
41
|
export declare function completeSimple<TApi extends Api>(model: Model<TApi>, context: Context, options?: SimpleStreamOptions): Promise<AssistantMessage>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export interface ThinkingConfig {
|
|
|
54
54
|
/** Provider-specific transport used to encode the selected effort. */
|
|
55
55
|
mode: ThinkingControlMode;
|
|
56
56
|
}
|
|
57
|
-
export declare const KNOWN_PROVIDERS: readonly ["alibaba-token-plan", "amazon-bedrock", "kiro", "azure-openai", "anthropic", "google", "google-gemini-cli", "google-antigravity", "google-vertex", "openai", "openai-codex", "opencodex", "kimi-code", "minimax-code", "minimax-code-cn", "github-copilot", "fireworks", "firepass", "fugu", "gitlab-duo", "cursor", "jetbrains-junie", "deepseek", "deepinfra", "xai", "groq", "cerebras", "openrouter", "kilo", "vercel-ai-gateway", "zai", "glm-zcode", "mistral", "minimax", "opencode-go", "opencode-zen", "opengateway", "bizrouter", "mara", "synthetic", "cloudflare-ai-gateway", "huggingface", "litellm", "moonshot", "nvidia", "nanogpt", "ollama", "ollama-cloud", "qianfan", "qwen-portal", "sglang", "together", "venice", "vllm", "xiaomi", "xiaomi-token-plan-sgp", "xiaomi-token-plan-ams", "xiaomi-token-plan-cn", "zenmux", "lm-studio", "omlx"];
|
|
57
|
+
export declare const KNOWN_PROVIDERS: readonly ["alibaba-token-plan", "amazon-bedrock", "kiro", "azure-openai", "anthropic", "google", "google-gemini-cli", "google-antigravity", "google-vertex", "openai", "openai-codex", "opencodex", "kimi-code", "minimax-code", "minimax-code-cn", "github-copilot", "fireworks", "firepass", "fugu", "gitlab-duo", "cursor", "jetbrains-junie", "deepseek", "deepinfra", "xai", "groq", "cerebras", "openrouter", "kilo", "vercel-ai-gateway", "zai", "glm-zcode", "mistral", "minimax", "opencode-go", "commandcode-goat", "opencode-zen", "opengateway", "bizrouter", "mara", "synthetic", "cloudflare-ai-gateway", "huggingface", "litellm", "moonshot", "nvidia", "nanogpt", "ollama", "ollama-cloud", "qianfan", "qwen-portal", "sglang", "together", "venice", "vllm", "xiaomi", "xiaomi-token-plan-sgp", "xiaomi-token-plan-ams", "xiaomi-token-plan-cn", "zenmux", "lm-studio", "omlx"];
|
|
58
58
|
export type KnownProvider = (typeof KNOWN_PROVIDERS)[number];
|
|
59
59
|
export declare function isKnownProvider(provider: string): provider is KnownProvider;
|
|
60
60
|
export type Provider = KnownProvider | string;
|
|
@@ -155,6 +155,18 @@ export interface RawSseEvent {
|
|
|
155
155
|
export type FetchImpl = ((input: string | URL | Request, init?: RequestInit) => Promise<Response>) & {
|
|
156
156
|
preconnect?: typeof globalThis.fetch.preconnect;
|
|
157
157
|
};
|
|
158
|
+
/**
|
|
159
|
+
* Credential returned by an auth retry resolver.
|
|
160
|
+
*
|
|
161
|
+
* The optional admission callback lets an authority-bearing caller retain a
|
|
162
|
+
* credential lease until the replacement provider request is actually
|
|
163
|
+
* admitted. Ordinary callers can continue returning a string from
|
|
164
|
+
* {@link StreamOptions.onAuthError}.
|
|
165
|
+
*/
|
|
166
|
+
export interface AuthRetryCredential {
|
|
167
|
+
apiKey: string;
|
|
168
|
+
onStreamCreated?: () => void;
|
|
169
|
+
}
|
|
158
170
|
export interface StreamOptions {
|
|
159
171
|
temperature?: number;
|
|
160
172
|
topP?: number;
|
|
@@ -186,7 +198,7 @@ export interface StreamOptions {
|
|
|
186
198
|
* event has been emitted. Returning a different key retries the provider
|
|
187
199
|
* request once.
|
|
188
200
|
*/
|
|
189
|
-
onAuthError?: (provider: string, apiKey: string, error: unknown) => Promise<string | undefined>;
|
|
201
|
+
onAuthError?: (provider: string, apiKey: string, error: unknown) => Promise<string | AuthRetryCredential | undefined>;
|
|
190
202
|
cacheRetention?: CacheRetention;
|
|
191
203
|
/**
|
|
192
204
|
* Additional headers to include in provider requests.
|
|
@@ -243,6 +255,14 @@ export interface StreamOptions {
|
|
|
243
255
|
* The `scope` parameter carries the per-attempt identity for execution attribution.
|
|
244
256
|
*/
|
|
245
257
|
onResponse?: (response: ProviderResponseMetadata, model?: Model<Api>, scope?: AttemptScopeRef) => void | Promise<void>;
|
|
258
|
+
/**
|
|
259
|
+
* Internal dispatch-admission hook. Providers invoke this immediately before
|
|
260
|
+
* submitting an outbound request; stream forwarding retains a first-response
|
|
261
|
+
* fallback for custom providers that do not expose a transport seam.
|
|
262
|
+
*/
|
|
263
|
+
onStreamCreated?: () => void;
|
|
264
|
+
/** Internal authority policy: disable provider-owned retries and corrective replays. */
|
|
265
|
+
disableProviderRetries?: boolean;
|
|
246
266
|
/**
|
|
247
267
|
* Optional callback for raw Server-Sent Events as they arrive from HTTP streaming providers.
|
|
248
268
|
*
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared factory for API-key-paste "login" flows.
|
|
3
3
|
*
|
|
4
|
-
* Several providers (Cerebras, Synthetic, Moonshot, Together, NanoGPT, ZenMux
|
|
4
|
+
* Several providers (Cerebras, Synthetic, Moonshot, Together, NanoGPT, ZenMux,
|
|
5
|
+
* Command Code GOAT)
|
|
5
6
|
* don't actually implement OAuth — they just ask the user to paste an API key,
|
|
6
7
|
* optionally validate it, and return the trimmed key.
|
|
7
8
|
*/
|
|
@@ -11,6 +12,7 @@ type ChatCompletionsValidation = {
|
|
|
11
12
|
provider: string;
|
|
12
13
|
baseUrl: string;
|
|
13
14
|
model: string;
|
|
15
|
+
requireInferenceResponse?: boolean;
|
|
14
16
|
};
|
|
15
17
|
type ModelsEndpointValidation = {
|
|
16
18
|
kind: "models-endpoint";
|
|
@@ -30,6 +32,7 @@ export type ApiKeyLoginConfig = {
|
|
|
30
32
|
placeholder: string;
|
|
31
33
|
/** Validation strategy, or `null` to skip validation. */
|
|
32
34
|
validation: ChatCompletionsValidation | ModelsEndpointValidation | null;
|
|
35
|
+
validationProgressMessage?: string;
|
|
33
36
|
};
|
|
34
37
|
export declare function createApiKeyLogin(config: ApiKeyLoginConfig): (options: OAuthController) => Promise<string>;
|
|
35
38
|
export {};
|
|
@@ -4,12 +4,17 @@ type OpenAICompatibleValidationOptions = {
|
|
|
4
4
|
baseUrl: string;
|
|
5
5
|
model: string;
|
|
6
6
|
signal?: AbortSignal;
|
|
7
|
+
fetch?: typeof globalThis.fetch;
|
|
8
|
+
requireInferenceResponse?: boolean;
|
|
9
|
+
timeoutMs?: number;
|
|
7
10
|
};
|
|
8
11
|
type ModelListValidationOptions = {
|
|
9
12
|
provider: string;
|
|
10
13
|
apiKey: string;
|
|
11
14
|
modelsUrl: string;
|
|
12
15
|
signal?: AbortSignal;
|
|
16
|
+
fetch?: typeof globalThis.fetch;
|
|
17
|
+
timeoutMs?: number;
|
|
13
18
|
};
|
|
14
19
|
/**
|
|
15
20
|
* Validate an API key against an OpenAI-compatible chat completions endpoint.
|
|
@@ -18,16 +23,17 @@ type ModelListValidationOptions = {
|
|
|
18
23
|
*/
|
|
19
24
|
export declare function validateOpenAICompatibleApiKey(options: OpenAICompatibleValidationOptions): Promise<void>;
|
|
20
25
|
/**
|
|
21
|
-
* Validate
|
|
26
|
+
* Validate a provider models endpoint's reachability and response shape.
|
|
22
27
|
*
|
|
23
28
|
* Useful for providers where access to specific models may vary by plan and
|
|
24
|
-
* should not block
|
|
29
|
+
* should not block login; an available model list is not proof that an
|
|
30
|
+
* authenticated inference request will succeed for the supplied key.
|
|
25
31
|
*
|
|
26
32
|
* A 200 status alone is NOT accepted: a captive portal, misrouting proxy, or
|
|
27
|
-
* broken gateway can answer 200 with an HTML page or an empty JSON object
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
33
|
+
* broken gateway can answer 200 with an HTML page or an empty JSON object.
|
|
34
|
+
* The body must parse as JSON and carry a recognizable model list before the
|
|
35
|
+
* endpoint is considered reachable. This catalog check is not proof that
|
|
36
|
+
* authenticated inference is entitled to use the supplied key.
|
|
31
37
|
*/
|
|
32
38
|
export declare function validateApiKeyAgainstModelsEndpoint(options: ModelListValidationOptions): Promise<void>;
|
|
33
39
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const loginCommandCode: (options: import("./types").OAuthController) => Promise<string>;
|
|
@@ -7,7 +7,7 @@ export type OAuthCredentials = {
|
|
|
7
7
|
email?: string;
|
|
8
8
|
accountId?: string;
|
|
9
9
|
};
|
|
10
|
-
export type OAuthProvider = "kiro" | "alibaba-token-plan" | "anthropic" | "bizrouter" | "mara" | "cerebras" | "cloudflare-ai-gateway" | "cursor" | "deepseek" | "deepinfra" | "fireworks" | "firepass" | "fugu" | "github-copilot" | "google-gemini-cli" | "google-antigravity" | "gitlab-duo" | "huggingface" | "kimi-code" | "kilo" | "kagi" | "litellm" | "lm-studio" | "minimax-code" | "minimax-code-cn" | "moonshot" | "nvidia" | "nanogpt" | "ollama" | "ollama-cloud" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "opengateway" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sglang" | "synthetic" | "tavily" | "together" | "venice" | "vercel-ai-gateway" | "vllm" | "xai" | "glm-zcode" | "xiaomi" | "xiaomi-token-plan-sgp" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "zenmux" | "opencodex" | "zai";
|
|
10
|
+
export type OAuthProvider = "kiro" | "alibaba-token-plan" | "anthropic" | "bizrouter" | "mara" | "cerebras" | "cloudflare-ai-gateway" | "cursor" | "deepseek" | "deepinfra" | "fireworks" | "firepass" | "fugu" | "github-copilot" | "google-gemini-cli" | "google-antigravity" | "gitlab-duo" | "huggingface" | "kimi-code" | "kilo" | "kagi" | "litellm" | "lm-studio" | "minimax-code" | "minimax-code-cn" | "moonshot" | "nvidia" | "nanogpt" | "ollama" | "ollama-cloud" | "openai-codex" | "openai-codex-device" | "opencode-go" | "opencode-zen" | "commandcode-goat" | "opengateway" | "openrouter" | "parallel" | "perplexity" | "qianfan" | "qwen-portal" | "sglang" | "synthetic" | "tavily" | "together" | "venice" | "vercel-ai-gateway" | "vllm" | "xai" | "glm-zcode" | "xiaomi" | "xiaomi-token-plan-sgp" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-cn" | "zenmux" | "opencodex" | "zai";
|
|
11
11
|
export type OAuthProviderId = OAuthProvider | (string & {});
|
|
12
12
|
export type OAuthPrompt = {
|
|
13
13
|
message: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@gajae-code/ai",
|
|
4
|
-
"version": "0.15.
|
|
4
|
+
"version": "0.15.6",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
7
7
|
"author": "Yeachan-Heo and Gajae Code Contributors",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@anthropic-ai/sdk": "^0.94.0",
|
|
42
42
|
"@bufbuild/protobuf": "^2.12.0",
|
|
43
|
-
"@gajae-code/natives": "0.15.
|
|
44
|
-
"@gajae-code/utils": "0.15.
|
|
43
|
+
"@gajae-code/natives": "0.15.6",
|
|
44
|
+
"@gajae-code/utils": "0.15.6",
|
|
45
45
|
"openai": "^6.36.0",
|
|
46
46
|
"partial-json": "^0.1.7",
|
|
47
47
|
"zod": "4.4.3"
|