vibe-open-auth 1.0.2 → 1.0.5

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.
Files changed (46) hide show
  1. package/dist/src/hooks/auto-update-checker/cache.d.ts.map +1 -1
  2. package/dist/src/hooks/auto-update-checker/cache.js +10 -6
  3. package/dist/src/hooks/auto-update-checker/cache.js.map +1 -1
  4. package/dist/src/hooks/auto-update-checker/index.js +3 -3
  5. package/dist/src/hooks/auto-update-checker/index.js.map +1 -1
  6. package/dist/src/kiro/handler.d.ts.map +1 -1
  7. package/dist/src/kiro/handler.js +85 -18
  8. package/dist/src/kiro/handler.js.map +1 -1
  9. package/dist/src/kiro/request.d.ts.map +1 -1
  10. package/dist/src/kiro/request.js +5 -2
  11. package/dist/src/kiro/request.js.map +1 -1
  12. package/dist/src/plugin/accounts.d.ts +8 -0
  13. package/dist/src/plugin/accounts.d.ts.map +1 -1
  14. package/dist/src/plugin/accounts.js +53 -0
  15. package/dist/src/plugin/accounts.js.map +1 -1
  16. package/dist/src/plugin/config/schema.d.ts +18 -0
  17. package/dist/src/plugin/config/schema.d.ts.map +1 -1
  18. package/dist/src/plugin/config/schema.js +11 -0
  19. package/dist/src/plugin/config/schema.js.map +1 -1
  20. package/dist/src/plugin/recovery.d.ts.map +1 -1
  21. package/dist/src/plugin/recovery.js +25 -3
  22. package/dist/src/plugin/recovery.js.map +1 -1
  23. package/dist/src/plugin/request-helpers.d.ts.map +1 -1
  24. package/dist/src/plugin/request-helpers.js +192 -3
  25. package/dist/src/plugin/request-helpers.js.map +1 -1
  26. package/dist/src/plugin/rotation.d.ts +168 -0
  27. package/dist/src/plugin/rotation.d.ts.map +1 -0
  28. package/dist/src/plugin/rotation.js +302 -0
  29. package/dist/src/plugin/rotation.js.map +1 -0
  30. package/dist/src/plugin/server.d.ts.map +1 -1
  31. package/dist/src/plugin/server.js +103 -1
  32. package/dist/src/plugin/server.js.map +1 -1
  33. package/dist/src/plugin/transform/gemini.d.ts +16 -32
  34. package/dist/src/plugin/transform/gemini.d.ts.map +1 -1
  35. package/dist/src/plugin/transform/gemini.js +188 -43
  36. package/dist/src/plugin/transform/gemini.js.map +1 -1
  37. package/dist/src/plugin/transform/model-resolver.d.ts +2 -1
  38. package/dist/src/plugin/transform/model-resolver.d.ts.map +1 -1
  39. package/dist/src/plugin/transform/model-resolver.js +21 -3
  40. package/dist/src/plugin/transform/model-resolver.js.map +1 -1
  41. package/dist/src/plugin/transform/types.d.ts +12 -1
  42. package/dist/src/plugin/transform/types.d.ts.map +1 -1
  43. package/dist/src/plugin.d.ts.map +1 -1
  44. package/dist/src/plugin.js +17 -0
  45. package/dist/src/plugin.js.map +1 -1
  46. package/package.json +1 -1
@@ -0,0 +1,302 @@
1
+ /**
2
+ * Account Rotation System
3
+ *
4
+ * Implements advanced account selection algorithms:
5
+ * - Health Score: Track account wellness based on success/failure
6
+ * - LRU Selection: Prefer accounts with longest rest periods
7
+ * - Jitter: Add random variance to break predictable patterns
8
+ *
9
+ * Used by 'hybrid' strategy for improved ban prevention and load distribution.
10
+ */
11
+ export const DEFAULT_HEALTH_SCORE_CONFIG = {
12
+ initial: 70,
13
+ successReward: 1,
14
+ rateLimitPenalty: -10,
15
+ failurePenalty: -20,
16
+ recoveryRatePerHour: 2,
17
+ minUsable: 50,
18
+ maxScore: 100,
19
+ };
20
+ /**
21
+ * Tracks health scores for accounts.
22
+ * Higher score = healthier account = preferred for selection.
23
+ */
24
+ export class HealthScoreTracker {
25
+ scores = new Map();
26
+ config;
27
+ constructor(config = {}) {
28
+ this.config = { ...DEFAULT_HEALTH_SCORE_CONFIG, ...config };
29
+ }
30
+ /**
31
+ * Get current health score for an account, applying time-based recovery.
32
+ */
33
+ getScore(accountIndex) {
34
+ const state = this.scores.get(accountIndex);
35
+ if (!state) {
36
+ return this.config.initial;
37
+ }
38
+ // Apply passive recovery based on time since last update
39
+ const now = Date.now();
40
+ const hoursSinceUpdate = (now - state.lastUpdated) / (1000 * 60 * 60);
41
+ const recoveredPoints = Math.floor(hoursSinceUpdate * this.config.recoveryRatePerHour);
42
+ return Math.min(this.config.maxScore, state.score + recoveredPoints);
43
+ }
44
+ /**
45
+ * Record a successful request - improves health score.
46
+ */
47
+ recordSuccess(accountIndex) {
48
+ const now = Date.now();
49
+ const current = this.getScore(accountIndex);
50
+ this.scores.set(accountIndex, {
51
+ score: Math.min(this.config.maxScore, current + this.config.successReward),
52
+ lastUpdated: now,
53
+ lastSuccess: now,
54
+ consecutiveFailures: 0,
55
+ });
56
+ }
57
+ /**
58
+ * Record a rate limit hit - moderate penalty.
59
+ */
60
+ recordRateLimit(accountIndex) {
61
+ const now = Date.now();
62
+ const state = this.scores.get(accountIndex);
63
+ const current = this.getScore(accountIndex);
64
+ this.scores.set(accountIndex, {
65
+ score: Math.max(0, current + this.config.rateLimitPenalty),
66
+ lastUpdated: now,
67
+ lastSuccess: state?.lastSuccess ?? 0,
68
+ consecutiveFailures: (state?.consecutiveFailures ?? 0) + 1,
69
+ });
70
+ }
71
+ /**
72
+ * Record a failure (auth, network, etc.) - larger penalty.
73
+ */
74
+ recordFailure(accountIndex) {
75
+ const now = Date.now();
76
+ const state = this.scores.get(accountIndex);
77
+ const current = this.getScore(accountIndex);
78
+ this.scores.set(accountIndex, {
79
+ score: Math.max(0, current + this.config.failurePenalty),
80
+ lastUpdated: now,
81
+ lastSuccess: state?.lastSuccess ?? 0,
82
+ consecutiveFailures: (state?.consecutiveFailures ?? 0) + 1,
83
+ });
84
+ }
85
+ /**
86
+ * Check if account is healthy enough to use.
87
+ */
88
+ isUsable(accountIndex) {
89
+ return this.getScore(accountIndex) >= this.config.minUsable;
90
+ }
91
+ /**
92
+ * Get consecutive failure count for an account.
93
+ */
94
+ getConsecutiveFailures(accountIndex) {
95
+ return this.scores.get(accountIndex)?.consecutiveFailures ?? 0;
96
+ }
97
+ /**
98
+ * Reset health state for an account (e.g., after removal).
99
+ */
100
+ reset(accountIndex) {
101
+ this.scores.delete(accountIndex);
102
+ }
103
+ /**
104
+ * Get all scores for debugging/logging.
105
+ */
106
+ getSnapshot() {
107
+ const result = new Map();
108
+ for (const [index] of this.scores) {
109
+ result.set(index, {
110
+ score: this.getScore(index),
111
+ consecutiveFailures: this.getConsecutiveFailures(index),
112
+ });
113
+ }
114
+ return result;
115
+ }
116
+ }
117
+ // ============================================================================
118
+ // JITTER UTILITIES
119
+ // ============================================================================
120
+ /**
121
+ * Add random jitter to a delay value.
122
+ * Helps break predictable timing patterns.
123
+ *
124
+ * @param baseMs - Base delay in milliseconds
125
+ * @param jitterFactor - Fraction of base to vary (default: 0.3 = ±30%)
126
+ * @returns Jittered delay in milliseconds
127
+ */
128
+ export function addJitter(baseMs, jitterFactor = 0.3) {
129
+ const jitterRange = baseMs * jitterFactor;
130
+ const jitter = (Math.random() * 2 - 1) * jitterRange; // -jitterRange to +jitterRange
131
+ return Math.max(0, Math.round(baseMs + jitter));
132
+ }
133
+ /**
134
+ * Generate a random delay within a range.
135
+ *
136
+ * @param minMs - Minimum delay in milliseconds
137
+ * @param maxMs - Maximum delay in milliseconds
138
+ * @returns Random delay between min and max
139
+ */
140
+ export function randomDelay(minMs, maxMs) {
141
+ return Math.round(minMs + Math.random() * (maxMs - minMs));
142
+ }
143
+ /**
144
+ * Sort accounts by LRU (least recently used first) with health score tiebreaker.
145
+ *
146
+ * Priority:
147
+ * 1. Filter out rate-limited and cooling-down accounts
148
+ * 2. Filter out unhealthy accounts (score < minUsable)
149
+ * 3. Sort by lastUsed ascending (oldest first = most rested)
150
+ * 4. Tiebreaker: higher health score wins
151
+ */
152
+ export function sortByLruWithHealth(accounts, minHealthScore = 50) {
153
+ return accounts
154
+ .filter(acc => !acc.isRateLimited && !acc.isCoolingDown && acc.healthScore >= minHealthScore)
155
+ .sort((a, b) => {
156
+ // Primary: LRU (oldest lastUsed first)
157
+ const lruDiff = a.lastUsed - b.lastUsed;
158
+ if (lruDiff !== 0)
159
+ return lruDiff;
160
+ // Tiebreaker: higher health score wins
161
+ return b.healthScore - a.healthScore;
162
+ });
163
+ }
164
+ /**
165
+ * Select account using hybrid strategy:
166
+ * 1. Filter available accounts (not rate-limited, not cooling down, healthy, has tokens)
167
+ * 2. Calculate priority score: health (2x) + tokens (5x) + freshness (0.1x)
168
+ * 3. Sort by score descending
169
+ * 4. Return the best candidate (deterministic - highest score)
170
+ *
171
+ * @param accounts - All accounts with their metrics
172
+ * @param tokenTracker - Token bucket tracker for token balances
173
+ * @param minHealthScore - Minimum health score to be considered
174
+ * @returns Best account index, or null if none available
175
+ */
176
+ export function selectHybridAccount(accounts, tokenTracker, minHealthScore = 50) {
177
+ const candidates = accounts
178
+ .filter(acc => !acc.isRateLimited &&
179
+ !acc.isCoolingDown &&
180
+ acc.healthScore >= minHealthScore &&
181
+ tokenTracker.hasTokens(acc.index))
182
+ .map(acc => ({
183
+ ...acc,
184
+ tokens: tokenTracker.getTokens(acc.index)
185
+ }));
186
+ if (candidates.length === 0) {
187
+ return null;
188
+ }
189
+ const maxTokens = tokenTracker.getMaxTokens();
190
+ const scored = candidates
191
+ .map(acc => ({
192
+ index: acc.index,
193
+ score: calculateHybridScore(acc, maxTokens)
194
+ }))
195
+ .sort((a, b) => b.score - a.score);
196
+ return scored[0]?.index ?? null;
197
+ }
198
+ function calculateHybridScore(account, maxTokens) {
199
+ const healthComponent = account.healthScore * 2; // 0-200
200
+ const tokenComponent = (account.tokens / maxTokens) * 100 * 5; // 0-500
201
+ const secondsSinceUsed = (Date.now() - account.lastUsed) / 1000;
202
+ const freshnessComponent = Math.min(secondsSinceUsed, 3600) * 0.1; // 0-360
203
+ return Math.max(0, healthComponent + tokenComponent + freshnessComponent);
204
+ }
205
+ export const DEFAULT_TOKEN_BUCKET_CONFIG = {
206
+ maxTokens: 50,
207
+ regenerationRatePerMinute: 6,
208
+ initialTokens: 50,
209
+ };
210
+ /**
211
+ * Client-side rate limiting using Token Bucket algorithm.
212
+ * Helps prevent hitting server 429s by tracking "cost" of requests.
213
+ */
214
+ export class TokenBucketTracker {
215
+ buckets = new Map();
216
+ config;
217
+ constructor(config = {}) {
218
+ this.config = { ...DEFAULT_TOKEN_BUCKET_CONFIG, ...config };
219
+ }
220
+ /**
221
+ * Get current token balance for an account, applying regeneration.
222
+ */
223
+ getTokens(accountIndex) {
224
+ const state = this.buckets.get(accountIndex);
225
+ if (!state) {
226
+ return this.config.initialTokens;
227
+ }
228
+ const now = Date.now();
229
+ const minutesSinceUpdate = (now - state.lastUpdated) / (1000 * 60);
230
+ const recoveredTokens = minutesSinceUpdate * this.config.regenerationRatePerMinute;
231
+ return Math.min(this.config.maxTokens, state.tokens + recoveredTokens);
232
+ }
233
+ /**
234
+ * Check if account has enough tokens for a request.
235
+ * @param cost Cost of the request (default: 1)
236
+ */
237
+ hasTokens(accountIndex, cost = 1) {
238
+ return this.getTokens(accountIndex) >= cost;
239
+ }
240
+ /**
241
+ * Consume tokens for a request.
242
+ * @returns true if tokens were consumed, false if insufficient
243
+ */
244
+ consume(accountIndex, cost = 1) {
245
+ const current = this.getTokens(accountIndex);
246
+ if (current < cost) {
247
+ return false;
248
+ }
249
+ this.buckets.set(accountIndex, {
250
+ tokens: current - cost,
251
+ lastUpdated: Date.now(),
252
+ });
253
+ return true;
254
+ }
255
+ /**
256
+ * Refund tokens (e.g., if request wasn't actually sent).
257
+ */
258
+ refund(accountIndex, amount = 1) {
259
+ const current = this.getTokens(accountIndex);
260
+ this.buckets.set(accountIndex, {
261
+ tokens: Math.min(this.config.maxTokens, current + amount),
262
+ lastUpdated: Date.now(),
263
+ });
264
+ }
265
+ getMaxTokens() {
266
+ return this.config.maxTokens;
267
+ }
268
+ }
269
+ // ============================================================================
270
+ // SINGLETON TRACKERS
271
+ // ============================================================================
272
+ let globalTokenTracker = null;
273
+ export function getTokenTracker() {
274
+ if (!globalTokenTracker) {
275
+ globalTokenTracker = new TokenBucketTracker();
276
+ }
277
+ return globalTokenTracker;
278
+ }
279
+ export function initTokenTracker(config) {
280
+ globalTokenTracker = new TokenBucketTracker(config);
281
+ return globalTokenTracker;
282
+ }
283
+ let globalHealthTracker = null;
284
+ /**
285
+ * Get the global health score tracker instance.
286
+ * Creates one with default config if not initialized.
287
+ */
288
+ export function getHealthTracker() {
289
+ if (!globalHealthTracker) {
290
+ globalHealthTracker = new HealthScoreTracker();
291
+ }
292
+ return globalHealthTracker;
293
+ }
294
+ /**
295
+ * Initialize the global health tracker with custom config.
296
+ * Call this at plugin startup if custom config is needed.
297
+ */
298
+ export function initHealthTracker(config) {
299
+ globalHealthTracker = new HealthScoreTracker(config);
300
+ return globalHealthTracker;
301
+ }
302
+ //# sourceMappingURL=rotation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rotation.js","sourceRoot":"","sources":["../../../src/plugin/rotation.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/plugin/server.ts"],"names":[],"mappings":"AAIA,UAAU,oBAAoB;IAC5B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAKD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,SAAyB,EAAE,GAAE,oBAAyB,GACvD,OAAO,CAAC,aAAa,CAAC,CA8NxB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/plugin/server.ts"],"names":[],"mappings":"AAKA,UAAU,oBAAoB;IAC5B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAkHD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,SAAyB,EAAE,GAAE,oBAAyB,GACvD,OAAO,CAAC,aAAa,CAAC,CAgOxB"}
@@ -1,7 +1,108 @@
1
1
  import { createServer } from "node:http";
2
+ import { readFileSync, existsSync } from "node:fs";
2
3
  import { ANTIGRAVITY_REDIRECT_URI } from "../constants";
3
4
  const redirectUri = new URL(ANTIGRAVITY_REDIRECT_URI);
4
5
  const callbackPath = redirectUri.pathname || "/";
6
+ /**
7
+ * Detect if running in OrbStack Docker with --network host mode.
8
+ * OrbStack's host networking only forwards ports bound to 127.0.0.1 to macOS.
9
+ */
10
+ function isOrbStackDockerHost() {
11
+ // Check if we're in Docker
12
+ if (!existsSync("/.dockerenv")) {
13
+ return false;
14
+ }
15
+ // Check for OrbStack-specific indicators
16
+ // OrbStack sets specific environment variables or has identifiable characteristics
17
+ try {
18
+ // OrbStack containers often have /run/.containerenv or specific mount patterns
19
+ // Also check if /proc/version contains orbstack
20
+ if (existsSync("/proc/version")) {
21
+ const version = readFileSync("/proc/version", "utf8").toLowerCase();
22
+ if (version.includes("orbstack")) {
23
+ return true;
24
+ }
25
+ }
26
+ // Check hostname pattern (OrbStack uses specific patterns)
27
+ const hostname = process.env.HOSTNAME || "";
28
+ if (hostname.startsWith("orbstack-") || hostname.endsWith(".orb") || hostname === "orbstack") {
29
+ return true;
30
+ }
31
+ // Check for OrbStack's network host mode by looking at resolv.conf
32
+ // OrbStack with --network host has specific DNS configuration
33
+ if (existsSync("/etc/resolv.conf")) {
34
+ const resolv = readFileSync("/etc/resolv.conf", "utf8");
35
+ if (resolv.includes("orb.local") || resolv.includes("orbstack")) {
36
+ return true;
37
+ }
38
+ }
39
+ // Fallback: Check if running on macOS/Darwin host via Docker
40
+ // This is a heuristic - if in Docker on Linux but /proc/version shows darwin-like patterns
41
+ if (process.platform === "linux" && existsSync("/.dockerenv")) {
42
+ // Most OrbStack containers will have been caught above
43
+ // For safety, also check common OrbStack mount patterns
44
+ if (existsSync("/run/host-services")) {
45
+ return true;
46
+ }
47
+ }
48
+ }
49
+ catch {
50
+ // Ignore errors, fall through to default
51
+ }
52
+ return false;
53
+ }
54
+ /**
55
+ * Detect WSL (Windows Subsystem for Linux) environment.
56
+ */
57
+ function isWSL() {
58
+ if (process.platform !== "linux")
59
+ return false;
60
+ try {
61
+ const release = readFileSync("/proc/version", "utf8").toLowerCase();
62
+ return release.includes("microsoft") || release.includes("wsl");
63
+ }
64
+ catch {
65
+ return false;
66
+ }
67
+ }
68
+ /**
69
+ * Detect remote/SSH environment where localhost may not be accessible from browser.
70
+ */
71
+ function isRemoteEnvironment() {
72
+ if (process.env.SSH_CLIENT || process.env.SSH_TTY || process.env.SSH_CONNECTION) {
73
+ return true;
74
+ }
75
+ if (process.env.REMOTE_CONTAINERS || process.env.CODESPACES) {
76
+ return true;
77
+ }
78
+ return false;
79
+ }
80
+ /**
81
+ * Determine the best bind address for the OAuth callback server.
82
+ *
83
+ * Priority:
84
+ * 1. OPENCODE_ANTIGRAVITY_OAUTH_BIND environment variable (user override)
85
+ * 2. OrbStack Docker with --network host: 127.0.0.1 (required for port forwarding)
86
+ * 3. WSL/SSH/Remote: 0.0.0.0 (needed for cross-network access)
87
+ * 4. Default: 127.0.0.1 (most secure for local development)
88
+ */
89
+ function getBindAddress() {
90
+ // Allow user override via environment variable
91
+ const envBind = process.env.OPENCODE_ANTIGRAVITY_OAUTH_BIND;
92
+ if (envBind) {
93
+ return envBind;
94
+ }
95
+ // OrbStack Docker needs 127.0.0.1 for --network host port forwarding
96
+ if (isOrbStackDockerHost()) {
97
+ return "127.0.0.1";
98
+ }
99
+ // WSL and remote environments need 0.0.0.0 to be reachable
100
+ if (isWSL() || isRemoteEnvironment()) {
101
+ return "0.0.0.0";
102
+ }
103
+ // Default to 127.0.0.1 for security (local-only access)
104
+ return "127.0.0.1";
105
+ }
5
106
  /**
6
107
  * Starts a lightweight HTTP server that listens for the Antigravity OAuth redirect
7
108
  * and resolves with the captured callback URL.
@@ -183,6 +284,7 @@ export async function startOAuthListener({ timeoutMs = 5 * 60 * 1000 } = {}) {
183
284
  server.close();
184
285
  });
185
286
  });
287
+ const bindAddress = getBindAddress();
186
288
  await new Promise((resolve, reject) => {
187
289
  const handleError = (error) => {
188
290
  server.off("error", handleError);
@@ -195,7 +297,7 @@ export async function startOAuthListener({ timeoutMs = 5 * 60 * 1000 } = {}) {
195
297
  reject(error);
196
298
  };
197
299
  server.once("error", handleError);
198
- server.listen(port, () => {
300
+ server.listen(port, bindAddress, () => {
199
301
  server.off("error", handleError);
200
302
  resolve();
201
303
  });
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/plugin/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAoBxD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,wBAAwB,CAAC,CAAC;AACtD,MAAM,YAAY,GAAG,WAAW,CAAC,QAAQ,IAAI,GAAG,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,EAAE,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,KAA2B,EAAE;IAExD,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI;QAC3B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;QACvC,CAAC,CAAC,WAAW,CAAC,QAAQ,KAAK,QAAQ;YACnC,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;IAE9D,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,eAAmC,CAAC;IACxC,IAAI,cAAsC,CAAC;IAC3C,IAAI,aAA6B,CAAC;IAClC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAM,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3D,eAAe,GAAG,CAAC,GAAQ,EAAE,EAAE;YAC7B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,aAAa;gBAAE,YAAY,CAAC,aAAa,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC,CAAC;QACF,cAAc,GAAG,CAAC,KAAY,EAAE,EAAE;YAChC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,aAAa;gBAAE,YAAY,CAAC,aAAa,CAAC,CAAC;YAC/C,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4HhB,CAAC;IAEP,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;QAC9B,cAAc,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC;IACpE,CAAC,EAAE,SAAS,CAAC,CAAC;IACd,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC;IAExB,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAChD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACjB,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YAC1D,QAAQ,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACzC,IAAI,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAClC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YAC1D,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACxE,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAE9B,eAAe,CAAC,GAAG,CAAC,CAAC;QAErB,YAAY,CAAC,GAAG,EAAE;YAChB,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,WAAW,GAAG,CAAC,KAA4B,EAAE,EAAE;YACnD,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YACjC,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,KAAK,CACd,QAAQ,IAAI,sBAAsB;oBAClC,0CAA0C;oBAC1C,kDAAkD,CACnD,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACvB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YACjC,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3B,cAAc,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,eAAe,EAAE,GAAG,EAAE,CAAC,eAAe;QACtC,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACrB,IAAI,KAAK,IAAK,KAA+B,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;oBAChF,MAAM,CAAC,KAAK,CAAC,CAAC;oBACd,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,cAAc,CAAC,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;gBACrE,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;KACL,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/plugin/server.ts"],"names":[],"mappings":"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"}
@@ -4,60 +4,44 @@
4
4
  * Handles Gemini model-specific request transformations including:
5
5
  * - Thinking config (camelCase keys, thinkingLevel for Gemini 3)
6
6
  * - Tool normalization (function/custom format)
7
+ * - Schema transformation (JSON Schema -> Gemini Schema format)
7
8
  */
8
- import type { RequestPayload, ThinkingConfig, ThinkingTier } from "./types";
9
- /**
10
- * Check if a model is a Gemini model (not Claude).
11
- */
9
+ import type { RequestPayload, ThinkingConfig, ThinkingTier, GoogleSearchConfig } from "./types";
10
+ export declare function toGeminiSchema(schema: unknown): unknown;
12
11
  export declare function isGeminiModel(model: string): boolean;
13
- /**
14
- * Check if a model is Gemini 3 (uses thinkingLevel string).
15
- */
16
12
  export declare function isGemini3Model(model: string): boolean;
17
- /**
18
- * Check if a model is Gemini 2.5 (uses numeric thinkingBudget).
19
- */
20
13
  export declare function isGemini25Model(model: string): boolean;
21
- /**
22
- * Build Gemini 3 thinking config with thinkingLevel string.
23
- */
14
+ export declare function isImageGenerationModel(model: string): boolean;
24
15
  export declare function buildGemini3ThinkingConfig(includeThoughts: boolean, thinkingLevel: ThinkingTier): ThinkingConfig;
25
- /**
26
- * Build Gemini 2.5 thinking config with numeric thinkingBudget.
27
- */
28
16
  export declare function buildGemini25ThinkingConfig(includeThoughts: boolean, thinkingBudget?: number): ThinkingConfig;
29
- /**
30
- * Normalize tools for Gemini models.
31
- * Ensures tools have proper function-style format.
32
- *
33
- * @returns Debug info about tool normalization
34
- */
17
+ export interface ImageConfig {
18
+ aspectRatio?: string;
19
+ }
20
+ export declare function buildImageGenerationConfig(): ImageConfig;
35
21
  export declare function normalizeGeminiTools(payload: RequestPayload): {
36
22
  toolDebugMissing: number;
37
23
  toolDebugSummaries: string[];
38
24
  };
39
- /**
40
- * Apply all Gemini-specific transformations to a request payload.
41
- */
42
25
  export interface GeminiTransformOptions {
43
- /** The effective model name (resolved) */
44
26
  model: string;
45
- /** Tier-based thinking budget (from model suffix, for Gemini 2.5) */
46
27
  tierThinkingBudget?: number;
47
- /** Tier-based thinking level (from model suffix, for Gemini 3) */
48
28
  tierThinkingLevel?: ThinkingTier;
49
- /** Normalized thinking config from user settings */
50
29
  normalizedThinking?: {
51
30
  includeThoughts?: boolean;
52
31
  thinkingBudget?: number;
53
32
  };
33
+ googleSearch?: GoogleSearchConfig;
54
34
  }
55
35
  export interface GeminiTransformResult {
56
36
  toolDebugMissing: number;
57
37
  toolDebugSummaries: string[];
38
+ wrappedFunctionCount: number;
39
+ passthroughToolCount: number;
58
40
  }
59
- /**
60
- * Apply all Gemini-specific transformations.
61
- */
62
41
  export declare function applyGeminiTransforms(payload: RequestPayload, options: GeminiTransformOptions): GeminiTransformResult;
42
+ export interface WrapToolsResult {
43
+ wrappedFunctionCount: number;
44
+ passthroughToolCount: number;
45
+ }
46
+ export declare function wrapToolsAsFunctionDeclarations(payload: RequestPayload): WrapToolsResult;
63
47
  //# sourceMappingURL=gemini.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../../src/plugin/transform/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5E;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,OAAO,EACxB,aAAa,EAAE,YAAY,GAC1B,cAAc,CAKhB;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,eAAe,EAAE,OAAO,EACxB,cAAc,CAAC,EAAE,MAAM,GACtB,cAAc,CAKhB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,GACtB;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,EAAE,CAAA;CAAE,CAwG5D;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,YAAY,CAAC;IACjC,oDAAoD;IACpD,kBAAkB,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7E;AAED,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CA6BvB"}
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../../src/plugin/transform/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA2BhG,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAyDvD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGpD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG7D;AAED,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,OAAO,EACxB,aAAa,EAAE,YAAY,GAC1B,cAAc,CAKhB;AAED,wBAAgB,2BAA2B,CACzC,eAAe,EAAE,OAAO,EACxB,cAAc,CAAC,EAAE,MAAM,GACtB,cAAc,CAKhB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,wBAAgB,0BAA0B,IAAI,WAAW,CAUxD;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,cAAc,GACtB;IAAE,gBAAgB,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,EAAE,CAAA;CAAE,CAuG5D;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,YAAY,CAAC;IACjC,kBAAkB,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5E,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CAiDvB;AAED,MAAM,WAAW,eAAe;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,CAkFxF"}