@anthonyhaussman/opencode-agy-auth 1.1.1 → 1.1.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +4 -18
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/src/constants.d.ts +7 -0
- package/dist/src/fetch.d.ts +1 -0
- package/dist/src/plugin/auth.d.ts +14 -0
- package/dist/src/plugin/cache.d.ts +28 -0
- package/dist/src/plugin/notify.d.ts +9 -0
- package/dist/src/plugin/oauth-authorize.d.ts +15 -0
- package/dist/src/plugin/project/context.d.ts +13 -0
- package/dist/src/plugin/project/index.d.ts +2 -0
- package/dist/src/plugin/project/types.d.ts +84 -0
- package/dist/src/plugin/project/utils.d.ts +35 -0
- package/dist/src/plugin/provider.d.ts +12 -0
- package/dist/src/plugin/quota-summary.d.ts +14 -0
- package/dist/src/plugin/quota-utils.d.ts +5 -0
- package/dist/src/plugin/quota.d.ts +14 -0
- package/dist/src/plugin/token.d.ts +2 -0
- package/dist/src/plugin/traffic.d.ts +47 -0
- package/dist/src/plugin/types.d.ts +31 -0
- package/dist/src/plugin.d.ts +6 -0
- package/dist/src/sdk/activity-request-id.d.ts +5 -0
- package/dist/src/sdk/agy-cli-version.d.ts +1 -0
- package/dist/src/sdk/cache/signature-cache.d.ts +130 -0
- package/dist/src/sdk/chat-logger.d.ts +8 -0
- package/dist/src/sdk/fetch_models.d.ts +47 -0
- package/dist/src/sdk/fetch_project.d.ts +9 -0
- package/dist/src/sdk/fetch_quota.d.ts +9 -0
- package/dist/src/sdk/oauth.d.ts +26 -0
- package/dist/src/sdk/request/identifiers.d.ts +16 -0
- package/dist/src/sdk/request/index.d.ts +11 -0
- package/dist/src/sdk/request/openai.d.ts +16 -0
- package/dist/src/sdk/request/prepare.d.ts +14 -0
- package/dist/src/sdk/request/response.d.ts +5 -0
- package/dist/src/sdk/request/shared.d.ts +20 -0
- package/dist/src/sdk/request/thinking.d.ts +129 -0
- package/dist/src/sdk/request/turn-state-tracker.d.ts +21 -0
- package/dist/src/sdk/request-helpers/errors.d.ts +9 -0
- package/dist/src/sdk/request-helpers/index.d.ts +4 -0
- package/dist/src/sdk/request-helpers/parsing.d.ts +9 -0
- package/dist/src/sdk/request-helpers/thinking.d.ts +5 -0
- package/dist/src/sdk/request-helpers/types.d.ts +65 -0
- package/dist/src/sdk/retry/cooldown-store.d.ts +14 -0
- package/dist/src/sdk/retry/helpers.d.ts +19 -0
- package/dist/src/sdk/retry/index.d.ts +9 -0
- package/dist/src/sdk/retry/quota.d.ts +28 -0
- package/dist/src/sdk/terminal-hyperlink.d.ts +3 -0
- package/dist/src/sdk/user-agent.d.ts +5 -0
- package/package.json +5 -5
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOTE: Format/protocol conversion logic is typically in the app layer (Plugin), but is implemented here inside the SDK as a special case.
|
|
3
|
+
* Reason:
|
|
4
|
+
* Format conversion (OpenAI format to Gemini/Agy native and vice versa) is tightly coupled with Agy's unique streaming SSE data parsing,
|
|
5
|
+
* thought chain deduplication, and signature self-healing (Thinking Recovery / Signature Cache) in multi-turn dialogues.
|
|
6
|
+
* Encapsulating this conversion in the SDK completely shields the OpenCode plugin app layer from non-standard API interaction complexities,
|
|
7
|
+
* allowing the plugin to simply call and forward standard OpenAI formatted requests and response streams.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Converts OpenAI's `tool_calls` into Gemini's `functionCall` sections.
|
|
11
|
+
*/
|
|
12
|
+
export declare function transformOpenAIToolCalls(requestPayload: Record<string, unknown>): void;
|
|
13
|
+
/**
|
|
14
|
+
* Adds synthesized thoughtSignature to function calls in the flattened and wrapped payload.
|
|
15
|
+
*/
|
|
16
|
+
export declare function addThoughtSignaturesToFunctionCalls(requestPayload: Record<string, unknown>): void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ThinkingConfigDefaults {
|
|
2
|
+
provider?: unknown;
|
|
3
|
+
models?: Record<string, unknown>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Rewrites OpenAI-style requests into the format for Gemini Code Assist requests.
|
|
7
|
+
*/
|
|
8
|
+
export declare function prepareAgyRequest(input: RequestInfo, init: RequestInit | undefined, accessToken: string, projectId: string, thinkingConfigDefaults?: ThinkingConfigDefaults): {
|
|
9
|
+
request: RequestInfo;
|
|
10
|
+
init: RequestInit;
|
|
11
|
+
streaming: boolean;
|
|
12
|
+
requestedModel?: string;
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ChatLogger } from "../chat-logger";
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes Gemini/Agy responses, preserving request metadata and usage counters.
|
|
4
|
+
*/
|
|
5
|
+
export declare function transformAgyResponse(response: Response, streaming: boolean, _ignoredDebugContext?: any, requestedModel?: string, sessionId?: string, chatLogger?: ChatLogger | null): Promise<Response>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the URL string for supported RequestInfo inputs.
|
|
3
|
+
*/
|
|
4
|
+
export declare function toRequestUrlString(value: RequestInfo): string;
|
|
5
|
+
/**
|
|
6
|
+
* Detects Gemini/Generative Language API requests via URL.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isGenerativeLanguageRequest(input: RequestInfo): input is string;
|
|
9
|
+
export declare function parseGenerativeLanguageRequest(input: RequestInfo): {
|
|
10
|
+
requestedModel: string;
|
|
11
|
+
effectiveModel: string;
|
|
12
|
+
action: string;
|
|
13
|
+
} | undefined;
|
|
14
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
15
|
+
export declare function readString(value: unknown): string | undefined;
|
|
16
|
+
export declare function pickString(...values: unknown[]): string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Preserves Cloud Code trace identity for downstream clients by mapping traceId to responseId.
|
|
19
|
+
*/
|
|
20
|
+
export declare function injectResponseIdFromTrace<T extends Record<string, unknown>>(body: T): T;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOTE: Special Design - Streaming deduplication and signature state self-healing
|
|
3
|
+
* Agy/Gemini official API has the following non-standard behaviors and strict constraints that must be specially handled here:
|
|
4
|
+
* 1. [Streaming Deduplication]: In the data packets returned by the official API during streaming, thought chain (Thinking) content is output cumulatively.
|
|
5
|
+
* We must perform hash comparison and truncation on each returned delta to prevent the IDE from receiving duplicate text.
|
|
6
|
+
* 2. [Signature State Self-healing]: In multi-turn dialogues, if the thoughtSignature is lost due to tool calls or client state breakage,
|
|
7
|
+
* the official API throws a signature mismatch error. An auto-detection mechanism (e.g., needsThinkingRecovery) is designed here to, upon signature breakage,
|
|
8
|
+
* automatically backfill/align fallback thought chain fragments and signatures in context messages, allowing the dialogue chain to self-heal and continue.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Cached signed thought chain data structure
|
|
12
|
+
*/
|
|
13
|
+
export interface SignedThinking {
|
|
14
|
+
/** Full thought chain text content */
|
|
15
|
+
text: string;
|
|
16
|
+
/** Corresponding server signature */
|
|
17
|
+
signature: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* External contract interface for signature storage manager
|
|
21
|
+
*/
|
|
22
|
+
export interface SignatureStore {
|
|
23
|
+
get(sessionKey: string): SignedThinking | undefined;
|
|
24
|
+
set(sessionKey: string, value: SignedThinking): void;
|
|
25
|
+
has(sessionKey: string): boolean;
|
|
26
|
+
delete(sessionKey: string): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Custom callback functions for the streaming phase
|
|
30
|
+
*/
|
|
31
|
+
export interface StreamingCallbacks {
|
|
32
|
+
onCacheSignature?: (sessionKey: string, text: string, signature: string) => void;
|
|
33
|
+
onInjectDebug?: (response: unknown, debugText: string) => unknown;
|
|
34
|
+
transformThinkingParts?: (parts: unknown) => unknown;
|
|
35
|
+
onTurnStateUpdate?: (sessionKey: string, state: {
|
|
36
|
+
turnHasThinking: boolean;
|
|
37
|
+
lastModelHasToolCalls: boolean;
|
|
38
|
+
}) => void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Configuration parameters for the streaming phase
|
|
42
|
+
*/
|
|
43
|
+
export interface StreamingOptions {
|
|
44
|
+
/** Unique identifier for the signature session, used for cross-turn signature recovery */
|
|
45
|
+
signatureSessionKey?: string;
|
|
46
|
+
/** Debugging text to inject into the stream (optional) */
|
|
47
|
+
debugText?: string;
|
|
48
|
+
/** Whether to cache the latest generated signature in this stream */
|
|
49
|
+
cacheSignatures?: boolean;
|
|
50
|
+
/** Set of already rendered thought chain hashes, used to avoid duplicate output in tool call loops */
|
|
51
|
+
displayedThinkingHashes?: Set<string>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Text buffer for caching thought chains of a specific index or type (handles streaming chunk cumulative output)
|
|
55
|
+
*/
|
|
56
|
+
export interface ThoughtBuffer {
|
|
57
|
+
get(index: number): string | undefined;
|
|
58
|
+
set(index: number, text: string): void;
|
|
59
|
+
clear(): void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Agent and tool interaction state record during multi-turn dialogue runtime
|
|
63
|
+
*/
|
|
64
|
+
export interface ConversationState {
|
|
65
|
+
/** Whether inside an incomplete tool call loop (i.e., last turn ended with functionResponse, continuing this turn) */
|
|
66
|
+
inToolLoop: boolean;
|
|
67
|
+
/** Array index of the first model reply message in the current dialogue turn */
|
|
68
|
+
turnStartIdx: number;
|
|
69
|
+
/** Whether the start of the current dialogue turn contains a thought chain (thought) */
|
|
70
|
+
turnHasThinking: boolean;
|
|
71
|
+
/** Array index of the last model reply message */
|
|
72
|
+
lastModelIdx: number;
|
|
73
|
+
/** Whether the last model message contains a thought chain */
|
|
74
|
+
lastModelHasThinking: boolean;
|
|
75
|
+
/** Whether the last model message contains a tool call (tool_use) */
|
|
76
|
+
lastModelHasToolCalls: boolean;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Creates a memory Map-based signature storage manager
|
|
80
|
+
*/
|
|
81
|
+
export declare function createSignatureStore(): SignatureStore;
|
|
82
|
+
/**
|
|
83
|
+
* Creates a thought chain text accumulation buffer for temporarily storing streaming chunks
|
|
84
|
+
*/
|
|
85
|
+
export declare function createThoughtBuffer(): ThoughtBuffer;
|
|
86
|
+
/**
|
|
87
|
+
* Default global memory signature storage
|
|
88
|
+
*/
|
|
89
|
+
export declare const defaultSignatureStore: SignatureStore;
|
|
90
|
+
/**
|
|
91
|
+
* Analyzes multi-turn historical dialogue arrays to extract context metrics like agent interaction loop state, model message positions, whether the turn has thoughts, etc.
|
|
92
|
+
*/
|
|
93
|
+
export declare function analyzeConversationState(contents: any[]): ConversationState;
|
|
94
|
+
/**
|
|
95
|
+
* Closes the tool execution loop and injects transition content to smoothly recover the dialogue without providing the old thought chain
|
|
96
|
+
*/
|
|
97
|
+
export declare function closeToolLoopForThinking(contents: any[]): any[];
|
|
98
|
+
/**
|
|
99
|
+
* Checks if the current state meets conditions to trigger historical self-healing
|
|
100
|
+
*/
|
|
101
|
+
export declare function needsThinkingRecovery(state: ConversationState): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Determines if the current model reply message had its thought chain pruned (has only tool calls but lost its preceding thought chain description)
|
|
104
|
+
*/
|
|
105
|
+
export declare function looksLikeCompactedThinkingTurn(msg: any): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Deeply determines if the start of this Turn contains historical rounds whose thought chains might have been pruned/compressed by the system
|
|
108
|
+
*/
|
|
109
|
+
export declare function hasPossibleCompactedThinking(contents: any[], turnStartIdx: number): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* For streaming SSE data packets, calculates and locally strips duplicated thought chain text
|
|
112
|
+
* Simultaneously supports Gemini's exclusive candidates.content structure and Claude's exclusive content[type=thinking] structure
|
|
113
|
+
*/
|
|
114
|
+
export declare function deduplicateThinkingText(response: unknown, sentBuffer: ThoughtBuffer, displayedThinkingHashes?: Set<string>): unknown;
|
|
115
|
+
/**
|
|
116
|
+
* Caches thought chain content and its validation signature from the returned message body for signature alignment in the next interaction round
|
|
117
|
+
* Also supports Gemini signature mechanism (candidates[].thoughtSignature) and Claude signature mechanism (content[].signature)
|
|
118
|
+
*/
|
|
119
|
+
export declare function cacheThinkingSignaturesFromResponse(response: unknown, signatureSessionKey: string, signatureStore: SignatureStore, thoughtBuffer: ThoughtBuffer, onCacheSignature?: (sessionKey: string, text: string, signature: string) => void): void;
|
|
120
|
+
/**
|
|
121
|
+
* Transforms a single complete SSE event, triggering thought chain caching and incremental deduplication here
|
|
122
|
+
*/
|
|
123
|
+
export declare function transformSseEvent(eventText: string, signatureStore: SignatureStore, thoughtBuffer: ThoughtBuffer, sentThinkingBuffer: ThoughtBuffer, callbacks: StreamingCallbacks, options: StreamingOptions, debugState: {
|
|
124
|
+
injected: boolean;
|
|
125
|
+
}): string;
|
|
126
|
+
/**
|
|
127
|
+
* Creates a TransformStream processor to split, deduplicate, and recombine the output stream
|
|
128
|
+
*/
|
|
129
|
+
export declare function createStreamingTransformer(signatureStore: SignatureStore, callbacks: StreamingCallbacks, options?: StreamingOptions): TransformStream<Uint8Array, Uint8Array>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ConversationState } from "./thinking";
|
|
2
|
+
export type TurnState = Pick<ConversationState, "inToolLoop" | "turnHasThinking" | "lastModelHasThinking" | "lastModelHasToolCalls">;
|
|
3
|
+
export declare class TurnStateTracker {
|
|
4
|
+
private entries;
|
|
5
|
+
private dirty;
|
|
6
|
+
private lastWriteTime;
|
|
7
|
+
private writeTimer;
|
|
8
|
+
private readonly diskEnabled;
|
|
9
|
+
constructor(diskEnabled?: boolean);
|
|
10
|
+
getState(sessionId: string): TurnState | undefined;
|
|
11
|
+
needsThinkingRecovery(sessionId: string): boolean;
|
|
12
|
+
updateAfterResponse(sessionId: string, newState: TurnState): void;
|
|
13
|
+
recoverFromContents(sessionId: string, contents: any[]): TurnState;
|
|
14
|
+
clear(sessionId: string): void;
|
|
15
|
+
shutdown(): void;
|
|
16
|
+
private scheduleThrottledWrite;
|
|
17
|
+
private clearWriteTimer;
|
|
18
|
+
}
|
|
19
|
+
export declare function initTurnStateTracker(): TurnStateTracker;
|
|
20
|
+
export declare function getTurnStateTracker(): TurnStateTracker | null;
|
|
21
|
+
export declare function shutdownTurnStateTracker(): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type GeminiApiBody, type GeminiErrorEnhancement } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Enhances 404 errors for Gemini 3 models with direct preview access information.
|
|
4
|
+
*/
|
|
5
|
+
export declare function rewriteGeminiPreviewAccessError(body: GeminiApiBody, status: number, requestedModel?: string): GeminiApiBody | null;
|
|
6
|
+
/**
|
|
7
|
+
* Enhances Gemini errors with validation/quota messages and retry hints.
|
|
8
|
+
*/
|
|
9
|
+
export declare function enhanceGeminiErrorResponse(body: GeminiApiBody, status: number): GeminiErrorEnhancement | null;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { CLOUDCODE_DOMAINS, GEMINI_PREVIEW_LINK, type GeminiApiBody, type GeminiApiError, type GeminiErrorEnhancement, type GeminiUsageMetadata, type ThinkingConfig, } from "./types";
|
|
2
|
+
export { normalizeThinkingConfig } from "./thinking";
|
|
3
|
+
export { parseGeminiApiBody, extractUsageMetadata } from "./parsing";
|
|
4
|
+
export { rewriteGeminiPreviewAccessError, enhanceGeminiErrorResponse } from "./errors";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GeminiApiBody, GeminiUsageMetadata } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Parses the Gemini API response body; handles array-wrapped responses sometimes returned by the API.
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseGeminiApiBody(rawText: string): GeminiApiBody | null;
|
|
6
|
+
/**
|
|
7
|
+
* Extracts usageMetadata from the response object with type-safe guards.
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractUsageMetadata(body: GeminiApiBody): GeminiUsageMetadata | null;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export declare const GEMINI_PREVIEW_LINK = "https://goo.gle/enable-preview-features";
|
|
2
|
+
export interface GeminiApiError {
|
|
3
|
+
code?: number;
|
|
4
|
+
message?: string;
|
|
5
|
+
status?: string;
|
|
6
|
+
details?: unknown[];
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The minimal representation of the Gemini API response we touch.
|
|
11
|
+
*/
|
|
12
|
+
export interface GeminiApiBody {
|
|
13
|
+
response?: unknown;
|
|
14
|
+
error?: GeminiApiError;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface GeminiErrorEnhancement {
|
|
18
|
+
body?: GeminiApiBody;
|
|
19
|
+
retryAfterMs?: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Usage metadata exposed by Gemini responses. Fields are optional to reflect partial payloads.
|
|
23
|
+
*/
|
|
24
|
+
export interface GeminiUsageMetadata {
|
|
25
|
+
totalTokenCount?: number;
|
|
26
|
+
promptTokenCount?: number;
|
|
27
|
+
candidatesTokenCount?: number;
|
|
28
|
+
cachedContentTokenCount?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Thinking configuration accepted by Gemini.
|
|
32
|
+
*/
|
|
33
|
+
export interface ThinkingConfig {
|
|
34
|
+
thinkingBudget?: number;
|
|
35
|
+
thinkingLevel?: string;
|
|
36
|
+
includeThoughts?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface GoogleRpcErrorInfo {
|
|
39
|
+
"@type"?: string;
|
|
40
|
+
reason?: string;
|
|
41
|
+
domain?: string;
|
|
42
|
+
metadata?: Record<string, string>;
|
|
43
|
+
}
|
|
44
|
+
export interface GoogleRpcHelp {
|
|
45
|
+
"@type"?: string;
|
|
46
|
+
links?: Array<{
|
|
47
|
+
description?: string;
|
|
48
|
+
url?: string;
|
|
49
|
+
}>;
|
|
50
|
+
}
|
|
51
|
+
export interface GoogleRpcQuotaFailure {
|
|
52
|
+
"@type"?: string;
|
|
53
|
+
violations?: Array<{
|
|
54
|
+
subject?: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
}>;
|
|
57
|
+
}
|
|
58
|
+
export interface GoogleRpcRetryInfo {
|
|
59
|
+
"@type"?: string;
|
|
60
|
+
retryDelay?: string | {
|
|
61
|
+
seconds?: number;
|
|
62
|
+
nanos?: number;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export declare const CLOUDCODE_DOMAINS: string[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function loadCooldowns(): Map<string, number>;
|
|
2
|
+
export declare function saveCooldowns(entries: Map<string, number>): boolean;
|
|
3
|
+
export declare class CooldownStore {
|
|
4
|
+
private dirty;
|
|
5
|
+
private lastWriteTime;
|
|
6
|
+
private writeTimer;
|
|
7
|
+
private entries;
|
|
8
|
+
bind(entries: Map<string, number>): void;
|
|
9
|
+
markDirty(): void;
|
|
10
|
+
flush(): boolean;
|
|
11
|
+
shutdown(): void;
|
|
12
|
+
private scheduleThrottledWrite;
|
|
13
|
+
private clearWriteTimer;
|
|
14
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const DEFAULT_MAX_ATTEMPTS = 3;
|
|
2
|
+
/**
|
|
3
|
+
* Ensures the request body is replayable before attempting a retry.
|
|
4
|
+
*/
|
|
5
|
+
export declare function canRetryRequest(init: RequestInit | undefined): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Status code-based retry strategy, consistent with Gemini/Agy CLI.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isRetryableStatus(status: number): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Handles transient network failures (including error codes nested in `cause.code`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function isRetryableNetworkError(error: unknown): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Prioritizes parsing retry delay milliseconds via Retry-After header, quota info in response body, or fallback exponential backoff.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveRetryDelayMs(response: Response, attempt: number, quotaDelayMs?: number): Promise<number>;
|
|
18
|
+
export declare function getExponentialDelayWithJitter(attempt: number): number;
|
|
19
|
+
export declare function wait(ms: number): Promise<void>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { retryInternals } from "./quota";
|
|
2
|
+
declare function initCooldownPersistence(): void;
|
|
3
|
+
export { initCooldownPersistence };
|
|
4
|
+
/**
|
|
5
|
+
* Sends a request with retry/exponential backoff semantics, consistent with Gemini/Agy CLI.
|
|
6
|
+
*/
|
|
7
|
+
export declare function fetchWithRetry(input: RequestInfo, init: RequestInit | undefined): Promise<Response>;
|
|
8
|
+
export declare function shutdownRetryCooldowns(): void;
|
|
9
|
+
export { retryInternals };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface QuotaContext {
|
|
2
|
+
terminal: boolean;
|
|
3
|
+
retryDelayMs?: number;
|
|
4
|
+
reason?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* NOTE: Special Design - Granular 429 Error Classification and Retry Strategy
|
|
8
|
+
* Traditional network retry modules usually treat 429 errors uniformly as rate-limiting for retries or throwing errors.
|
|
9
|
+
* Here we parse it granularly:
|
|
10
|
+
* 1. Differentiate between "Account physical quota exhausted" and "Model instantaneous capacity overloaded (MODEL_CAPACITY_EXHAUSTED)".
|
|
11
|
+
* 2. If it's physical quota exhaustion, it's considered an unretriable terminal state to avoid meaningless network requests;
|
|
12
|
+
* If it's a momentary overload of Google's backend model capacity, it's considered retriable, parses RetryInfo delay from response, and notifies the upper layer (showing a Toast in TUI, backing off, and retrying).
|
|
13
|
+
*/
|
|
14
|
+
export declare function classifyQuotaResponse(response: Response): Promise<QuotaContext | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Extracts the RetryInfo delay hint directly from the error payload.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseRetryDelayFromBody(response: Response): Promise<number | null>;
|
|
19
|
+
declare function parseRetryDelayValue(value: string | {
|
|
20
|
+
seconds?: number;
|
|
21
|
+
nanos?: number;
|
|
22
|
+
}): number | null;
|
|
23
|
+
declare function parseRetryDelayFromMessage(message: string): number | null;
|
|
24
|
+
export declare const retryInternals: {
|
|
25
|
+
parseRetryDelayValue: typeof parseRetryDelayValue;
|
|
26
|
+
parseRetryDelayFromMessage: typeof parseRetryDelayFromMessage;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anthonyhaussman/opencode-agy-auth",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2-beta.0",
|
|
4
4
|
"author": "antigravity",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"type": "module",
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "tsup",
|
|
22
|
+
"build": "tsup && tsc -p tsconfig.build.json",
|
|
23
23
|
"typecheck": "tsc",
|
|
24
24
|
"smoke:node-import": "node -e \"import('./dist/index.js').then(() => console.log('ok')).catch((error) => { console.error(error); process.exit(1); })\"",
|
|
25
25
|
"prepack": "npm run build"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@opencode-ai/sdk": "^1.17.
|
|
28
|
+
"@opencode-ai/sdk": "^1.17.20",
|
|
29
29
|
"@types/node": "^26.1.1",
|
|
30
30
|
"tsup": "^8.5.1",
|
|
31
|
-
"typescript": "^
|
|
31
|
+
"typescript": "^7.0.2"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@openauthjs/openauth": "^0.4.3",
|
|
35
|
-
"@opencode-ai/plugin": "^1.17.
|
|
35
|
+
"@opencode-ai/plugin": "^1.17.20"
|
|
36
36
|
}
|
|
37
37
|
}
|