@anthonyhaussman/opencode-agy-auth 1.0.7 → 1.0.10

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 CHANGED
@@ -8,7 +8,7 @@ interface PluginContext {
8
8
  type PluginResult = Hooks;
9
9
 
10
10
  /**
11
- * Opencode 注册 Agy OAuth 提供者。
11
+ * Registers the Agy OAuth provider for Opencode.
12
12
  */
13
13
  declare const AgyCLIOAuthPlugin: ({ client }: PluginContext) => Promise<PluginResult>;
14
14
  declare const GoogleOAuthPlugin: ({ client }: PluginContext) => Promise<PluginResult>;
package/dist/index.js CHANGED
@@ -166,10 +166,14 @@ function createAgyActivityRequestId() {
166
166
  return Math.random().toString(36).substring(7);
167
167
  }
168
168
 
169
+ // src/sdk/user-agent.ts
170
+ import os from "os";
171
+
169
172
  // src/sdk/agy-cli-version.ts
170
- var AGY_CLI_VERSION = "1.0.3";
173
+ var AGY_CLI_VERSION = "1.0.10";
171
174
 
172
175
  // src/sdk/user-agent.ts
176
+ var cachedUserAgent = null;
173
177
  function getAgyCliVersion() {
174
178
  const explicitVersion = process.env.OPENCODE_AGY_CLI_VERSION?.trim();
175
179
  if (explicitVersion) {
@@ -178,7 +182,16 @@ function getAgyCliVersion() {
178
182
  return AGY_CLI_VERSION;
179
183
  }
180
184
  function buildAgyCliUserAgent(model) {
181
- return "antigravity/cli/1.0.3 darwin/amd64";
185
+ const version2 = getAgyCliVersion();
186
+ if (cachedUserAgent && cachedUserAgent.startsWith("antigravity/cli/" + version2 + " ")) {
187
+ return cachedUserAgent;
188
+ }
189
+ const rawPlatform = os.platform();
190
+ const platform2 = rawPlatform === "win32" ? "windows" : rawPlatform;
191
+ const rawArch = os.arch();
192
+ const arch2 = rawArch === "x64" ? "amd64" : rawArch;
193
+ cachedUserAgent = "antigravity/cli/" + version2 + " " + platform2 + "/" + arch2;
194
+ return cachedUserAgent;
182
195
  }
183
196
 
184
197
  // src/sdk/fetch_quota.ts
@@ -731,8 +744,8 @@ function createOAuthAuthorizeMethod(options) {
731
744
  const message2 = error45 instanceof Error ? error45.message : String(error45);
732
745
  options.client.tui.showToast({
733
746
  body: {
734
- title: "\u7ED1\u5B9A\u9879\u76EE\u4E0A\u4E0B\u6587\u5931\u8D25",
735
- message: `\u5DF2\u6388\u6743\u6210\u529F\u4F46\u65E0\u6CD5\u7ED1\u5B9A\u9879\u76EE\uFF0C\u5C06\u65E0\u6CD5\u4F7F\u7528\u771F\u5B9E\u6A21\u578B\uFF1A${message2}`,
747
+ title: "Failed to bind project context",
748
+ message: `Authorized successfully but failed to bind project, real models will be unavailable: ${message2}`,
736
749
  variant: "warning",
737
750
  duration: 15e3
738
751
  }
@@ -752,7 +765,7 @@ function createOAuthAuthorizeMethod(options) {
752
765
  }
753
766
  return {
754
767
  url: authorization.url,
755
- instructions: "\u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210 Google \u8D26\u6237\u6388\u6743\u3002\u6388\u6743\u5B8C\u6210\u540E\uFF0C\u9875\u9762\u4F1A\u8DF3\u8F6C\u81F3 https://antigravity.google/oauth-callback?code=... \u3002\u8BF7\u5C06\u6700\u7EC8\u6D4F\u89C8\u5668\u5730\u5740\u680F\u7684\u5B8C\u6574\u8DF3\u8F6C URL \u6216\u5176\u4E2D\u7684 code \u53C2\u6570\u503C\u590D\u5236\u5E76\u7C98\u8D34\u5230\u4E0B\u65B9\u8F93\u5165\u6846\u4E2D\uFF1A",
768
+ instructions: "Please complete Google account authorization in your browser. After authorization, the page will redirect to https://antigravity.google/oauth-callback?code=... . Please copy the full redirect URL from your browser address bar, or just the code parameter value, and paste it into the input box below:",
756
769
  method: "code",
757
770
  callback: async (callbackUrl) => {
758
771
  try {
@@ -855,19 +868,19 @@ function ensureGitignoreSync(configDir) {
855
868
  }
856
869
  }
857
870
  var SignatureCache = class {
858
- // 内存缓存映射表
871
+ // Memory cache map
859
872
  cache = /* @__PURE__ */ new Map();
860
- // 配置项
873
+ // Configuration options
861
874
  memoryTtlMs;
862
875
  diskTtlMs;
863
876
  writeIntervalMs;
864
877
  cacheFilePath;
865
878
  enabled;
866
- // 状态变量
879
+ // State variables
867
880
  dirty = false;
868
881
  writeTimer = null;
869
882
  cleanupTimer = null;
870
- // 统计指标
883
+ // Statistical metrics
871
884
  stats = {
872
885
  memoryHits: 0,
873
886
  diskHits: 0,
@@ -886,16 +899,16 @@ var SignatureCache = class {
886
899
  }
887
900
  }
888
901
  // ===========================================================================
889
- // 公开的签名缓存 API (Public Signature API)
902
+ // Public Signature API
890
903
  // ===========================================================================
891
904
  /**
892
- * 基于会话 ID 和模型 ID 生成唯一的缓存键
905
+ * Generates a unique cache key based on session ID and model ID
893
906
  */
894
907
  static makeKey(sessionId, modelId) {
895
908
  return `${sessionId}:${modelId}`;
896
909
  }
897
910
  /**
898
- * 将一个签名存入缓存中(标记为脏状态,等待后台写盘)
911
+ * Stores a signature in cache (marks as dirty, awaits background disk write)
899
912
  */
900
913
  store(key, signature) {
901
914
  if (!this.enabled) return;
@@ -906,8 +919,8 @@ var SignatureCache = class {
906
919
  this.dirty = true;
907
920
  }
908
921
  /**
909
- * 从缓存中检索签名,并更新命中统计
910
- * 若过期或不存在则返回 null
922
+ * Retrieves a signature from cache and updates hit stats
923
+ * Returns null if expired or missing
911
924
  */
912
925
  retrieve(key) {
913
926
  if (!this.enabled) return null;
@@ -924,7 +937,7 @@ var SignatureCache = class {
924
937
  return null;
925
938
  }
926
939
  /**
927
- * 检查某个键在缓存中是否有效且未过期(不影响统计数据)
940
+ * Checks if a key is valid and unexpired in cache (without affecting stats)
928
941
  */
929
942
  has(key) {
930
943
  if (!this.enabled) return false;
@@ -934,11 +947,11 @@ var SignatureCache = class {
934
947
  return age <= this.memoryTtlMs;
935
948
  }
936
949
  // ===========================================================================
937
- // 思维链全量缓存 API (Full Thinking Cache API)
950
+ // Full Thinking Cache API
938
951
  // ===========================================================================
939
952
  /**
940
- * 缓存完整的思维链文本内容及签名
941
- * 即使后续的上下文遭到压缩,我们也能从中自愈和恢复历史上下文中的 thought block。
953
+ * Caches the full thought chain text content and signature
954
+ * Allows self-healing and recovery of historical thought blocks even if the context is subsequently compressed.
942
955
  */
943
956
  storeThinking(key, thinkingText, signature, toolIds) {
944
957
  if (!this.enabled || !thinkingText || !signature) return;
@@ -952,7 +965,7 @@ var SignatureCache = class {
952
965
  this.dirty = true;
953
966
  }
954
967
  /**
955
- * 从缓存中提取完整的思维链信息
968
+ * Extracts full thought chain info from cache
956
969
  */
957
970
  retrieveThinking(key) {
958
971
  if (!this.enabled) return null;
@@ -971,7 +984,7 @@ var SignatureCache = class {
971
984
  };
972
985
  }
973
986
  /**
974
- * 检查是否存在某个键的完整思维链内容
987
+ * Checks if full thought chain content exists for a key
975
988
  */
976
989
  hasThinking(key) {
977
990
  if (!this.enabled) return false;
@@ -981,7 +994,7 @@ var SignatureCache = class {
981
994
  return age <= this.memoryTtlMs;
982
995
  }
983
996
  /**
984
- * 获取当前缓存统计数据与内存占用情况
997
+ * Gets current cache stats and memory footprint
985
998
  */
986
999
  getStats() {
987
1000
  return {
@@ -992,14 +1005,14 @@ var SignatureCache = class {
992
1005
  };
993
1006
  }
994
1007
  /**
995
- * 手动触发立即保存到磁盘
1008
+ * Manually triggers immediate save to disk
996
1009
  */
997
1010
  async flush() {
998
1011
  if (!this.enabled) return true;
999
1012
  return this.saveToDisk();
1000
1013
  }
1001
1014
  /**
1002
- * 优雅关机:停止所有定时器,并将未写盘的数据保存到磁盘上
1015
+ * Graceful shutdown: stops all timers and flushes unsaved data to disk
1003
1016
  */
1004
1017
  shutdown() {
1005
1018
  if (this.writeTimer) {
@@ -1015,10 +1028,10 @@ var SignatureCache = class {
1015
1028
  }
1016
1029
  }
1017
1030
  // ===========================================================================
1018
- // 磁盘数据持久化操作 (Disk Operations)
1031
+ // Disk Operations
1019
1032
  // ===========================================================================
1020
1033
  /**
1021
- * 从磁盘中加载签名缓存,并验证 TTL 状态
1034
+ * Loads signature cache from disk and validates TTL state
1022
1035
  */
1023
1036
  loadFromDisk() {
1024
1037
  try {
@@ -1047,8 +1060,8 @@ var SignatureCache = class {
1047
1060
  }
1048
1061
  }
1049
1062
  /**
1050
- * 将内存缓存同步保存到磁盘上(采用先写临时文件后 rename 的原子写入模式)
1051
- * 写入时会与磁盘上原有的未过期数据条目进行合并
1063
+ * Synchronously saves memory cache to disk (using atomic write: temp file then rename)
1064
+ * Merges with existing unexpired entries on disk during write
1052
1065
  */
1053
1066
  saveToDisk() {
1054
1067
  try {
@@ -1116,10 +1129,10 @@ var SignatureCache = class {
1116
1129
  }
1117
1130
  }
1118
1131
  // ===========================================================================
1119
- // 后台自动定时任务 (Background Tasks)
1132
+ // Background Tasks
1120
1133
  // ===========================================================================
1121
1134
  /**
1122
- * 启动自动保存和自动清理过期内存条目的定时器
1135
+ * Starts timers for auto-saving and auto-cleaning expired memory entries
1123
1136
  */
1124
1137
  startBackgroundTasks() {
1125
1138
  this.writeTimer = setInterval(() => {
@@ -1132,7 +1145,7 @@ var SignatureCache = class {
1132
1145
  }, 30 * 60 * 1e3);
1133
1146
  }
1134
1147
  /**
1135
- * 移除内存中超过生存周期的过期缓存
1148
+ * Removes memory cache entries exceeding their TTL
1136
1149
  */
1137
1150
  cleanupExpired() {
1138
1151
  const now = Date.now();
@@ -14473,7 +14486,7 @@ async function maybeShowAgyTestToast(client, projectId) {
14473
14486
 
14474
14487
  // src/plugin/traffic.ts
14475
14488
  import { randomUUID } from "crypto";
14476
- import * as os from "os";
14489
+ import * as os2 from "os";
14477
14490
  var lastTrafficTime = 0;
14478
14491
  var TRAFFIC_INTERVAL_MS = 5 * 60 * 1e3;
14479
14492
  function simulateClientBackgroundTraffic(accessToken, projectId, userAgentModel) {
@@ -14509,8 +14522,8 @@ async function sendListExperiments(accessToken, userAgentModel) {
14509
14522
  async function sendCodeAssistMetrics(accessToken, projectId, userAgentModel) {
14510
14523
  const url2 = `${AGY_CODE_ASSIST_ENDPOINT}/v1internal:recordCodeAssistMetrics`;
14511
14524
  const userAgent = buildAgyCliUserAgent(userAgentModel);
14512
- const plat = os.platform();
14513
- const arch2 = os.arch();
14525
+ const plat = os2.platform();
14526
+ const arch2 = os2.arch();
14514
14527
  const platMap = {
14515
14528
  darwin: "DARWIN",
14516
14529
  linux: "LINUX",
@@ -14568,8 +14581,8 @@ async function sendCodeAssistMetrics(accessToken, projectId, userAgentModel) {
14568
14581
  async function sendTrajectoryAnalytics(accessToken, userAgentModel) {
14569
14582
  const url2 = `${AGY_CODE_ASSIST_ENDPOINT}/v1internal:recordTrajectoryAnalytics`;
14570
14583
  const userAgent = buildAgyCliUserAgent(userAgentModel);
14571
- const plat = os.platform();
14572
- const arch2 = os.arch();
14584
+ const plat = os2.platform();
14585
+ const arch2 = os2.arch();
14573
14586
  const platMap = {
14574
14587
  darwin: "DARWIN",
14575
14588
  linux: "LINUX",
@@ -15376,6 +15389,9 @@ function deduplicateThinkingText(response, sentBuffer, displayedThinkingHashes)
15376
15389
  return block;
15377
15390
  });
15378
15391
  const filteredContent = newContent.filter((b) => b !== null);
15392
+ if (filteredContent.length === 0) {
15393
+ return { ...resp, content: [] };
15394
+ }
15379
15395
  return { ...resp, content: filteredContent };
15380
15396
  }
15381
15397
  return response;
@@ -15518,6 +15534,11 @@ function createStreamingTransformer(signatureStore, callbacks, options = {}) {
15518
15534
  if (!hasSeenUsageMetadata) {
15519
15535
  const syntheticUsage = {
15520
15536
  response: {
15537
+ candidates: [
15538
+ {
15539
+ finishReason: "STOP"
15540
+ }
15541
+ ],
15521
15542
  usageMetadata: {
15522
15543
  promptTokenCount: 0,
15523
15544
  candidatesTokenCount: 0,
@@ -15638,22 +15659,7 @@ function transformRequestBody(body, projectId, effectiveModel, requestedModel, t
15638
15659
  contents2 = normalizeContentsSequence(contents2);
15639
15660
  injectMissingToolCallIds(contents2);
15640
15661
  const latestSig = getLatestSignature(sessionId2);
15641
- const allFunctionCalls = [];
15642
- for (const content of contents2) {
15643
- if (content && typeof content === "object" && Array.isArray(content.parts)) {
15644
- for (const part of content.parts) {
15645
- if (part && typeof part === "object" && part.functionCall) {
15646
- allFunctionCalls.push(part);
15647
- }
15648
- }
15649
- }
15650
- }
15651
- if (allFunctionCalls.length > 0 && latestSig) {
15652
- const lastFunctionCall = allFunctionCalls[allFunctionCalls.length - 1];
15653
- if (!lastFunctionCall.thoughtSignature || lastFunctionCall.thoughtSignature === "skip_thought_signature_validator") {
15654
- lastFunctionCall.thoughtSignature = latestSig;
15655
- }
15656
- }
15662
+ applyLatestSignature(contents2, latestSig);
15657
15663
  requestPayloadInside.contents = contents2;
15658
15664
  }
15659
15665
  return { body: JSON.stringify(wrappedBody2), userPromptId: userPromptId2, sessionId: sessionId2 };
@@ -15681,22 +15687,7 @@ function transformRequestBody(body, projectId, effectiveModel, requestedModel, t
15681
15687
  contents = normalizeContentsSequence(contents);
15682
15688
  injectMissingToolCallIds(contents);
15683
15689
  const latestSig = getLatestSignature(sessionId);
15684
- const allFunctionCalls = [];
15685
- for (const content of contents) {
15686
- if (content && typeof content === "object" && Array.isArray(content.parts)) {
15687
- for (const part of content.parts) {
15688
- if (part && typeof part === "object" && part.functionCall) {
15689
- allFunctionCalls.push(part);
15690
- }
15691
- }
15692
- }
15693
- }
15694
- if (allFunctionCalls.length > 0 && latestSig) {
15695
- const lastFunctionCall = allFunctionCalls[allFunctionCalls.length - 1];
15696
- if (!lastFunctionCall.thoughtSignature || lastFunctionCall.thoughtSignature === "skip_thought_signature_validator") {
15697
- lastFunctionCall.thoughtSignature = latestSig;
15698
- }
15699
- }
15690
+ applyLatestSignature(contents, latestSig);
15700
15691
  requestPayload.contents = contents;
15701
15692
  }
15702
15693
  if ("model" in requestPayload) {
@@ -15936,6 +15927,24 @@ function injectMissingToolCallIds(contents) {
15936
15927
  }
15937
15928
  }
15938
15929
  }
15930
+ function applyLatestSignature(contents, latestSig) {
15931
+ const allFunctionCalls = [];
15932
+ for (const content of contents) {
15933
+ if (content && typeof content === "object" && Array.isArray(content.parts)) {
15934
+ for (const part of content.parts) {
15935
+ if (part && typeof part === "object" && part.functionCall) {
15936
+ allFunctionCalls.push(part);
15937
+ }
15938
+ }
15939
+ }
15940
+ }
15941
+ if (allFunctionCalls.length > 0 && latestSig) {
15942
+ const lastFunctionCall = allFunctionCalls[allFunctionCalls.length - 1];
15943
+ if (!lastFunctionCall.thoughtSignature || lastFunctionCall.thoughtSignature === "skip_thought_signature_validator") {
15944
+ lastFunctionCall.thoughtSignature = latestSig;
15945
+ }
15946
+ }
15947
+ }
15939
15948
 
15940
15949
  // src/sdk/request/response.ts
15941
15950
  async function transformAgyResponse(response, streaming, _ignoredDebugContext, requestedModel, sessionId, chatLogger) {
@@ -16291,45 +16300,18 @@ var latestAgyAuthResolver;
16291
16300
  var latestAgyConfiguredProjectId;
16292
16301
  var latestAgyUserAgentModel;
16293
16302
  var STATIC_MODELS_SIMPLE = {
16294
- "gemini-3.5-flash-low": {
16295
- name: "Gemini 3.5 Flash (Medium)",
16296
- description: "Gemini 3.5 Flash \u4E2D\u914D\u7248\u672C\uFF0C\u517C\u987E\u751F\u6210\u901F\u5EA6\u4E0E\u63A8\u7406\u6027\u80FD\uFF0C\u63D0\u4F9B\u9AD8\u6027\u4EF7\u6BD4\u3002",
16297
- maxTokens: 1048576,
16298
- maxOutputTokens: 65536,
16299
- toolCall: true,
16300
- reasoning: true,
16301
- attachment: true
16302
- },
16303
- "gemini-3-flash-agent": {
16304
- name: "Gemini 3.5 Flash (High)",
16305
- description: "Gemini 3.5 Flash \u9AD8\u914D\u667A\u80FD\u4F53\u7248\uFF0C\u54CD\u5E94\u6781\u5FEB\uFF0C\u6DF1\u5EA6\u4F18\u5316\u4E86\u591A\u6B65\u9AA4\u5DE5\u5177\u8C03\u7528\u4E0E\u6D41\u7A0B\u63A7\u5236\u3002",
16306
- maxTokens: 1048576,
16307
- maxOutputTokens: 65536,
16308
- toolCall: true,
16309
- reasoning: true,
16310
- attachment: true
16311
- },
16312
- "gemini-3.5-flash-extra-low": {
16313
- name: "Gemini 3.5 Flash (Low)",
16314
- description: "Gemini 3.5 Flash \u8D85\u4F4E\u914D\u7248\u672C\uFF0C\u9002\u5408\u5927\u89C4\u6A21\u3001\u4F4E\u6210\u672C\u7684\u7B80\u5355\u6587\u672C\u5904\u7406\u4EFB\u52A1\u3002",
16303
+ "gemini-3.5-flash": {
16304
+ name: "Gemini 3.5 Flash",
16305
+ description: "Gemini 3.5 Flash base model. Select tier at runtime.",
16315
16306
  maxTokens: 1048576,
16316
16307
  maxOutputTokens: 65536,
16317
16308
  toolCall: true,
16318
16309
  reasoning: true,
16319
16310
  attachment: true
16320
16311
  },
16321
- "gemini-3.1-pro-low": {
16322
- name: "Gemini 3.1 Pro (Low)",
16323
- description: "Gemini 3.1 Pro \u4F4E\u914D\u7248\u672C\uFF0C\u9002\u5408\u9AD8\u590D\u6742\u5EA6\u7684\u903B\u8F91\u548C\u4EE3\u7801\u7F16\u5199\u4EFB\u52A1\uFF0C\u4F46\u9650\u5236\u4E86\u90E8\u5206\u5E76\u53D1\u6216\u914D\u989D\u3002",
16324
- maxTokens: 1048576,
16325
- maxOutputTokens: 65535,
16326
- toolCall: true,
16327
- reasoning: true,
16328
- attachment: true
16329
- },
16330
- "gemini-pro-agent": {
16331
- name: "Gemini 3.1 Pro (High)",
16332
- description: "Gemini 3.1 Pro \u9AD8\u914D/\u667A\u80FD\u4F53\u7248\u672C\uFF0C\u63D0\u4F9B\u6700\u5148\u8FDB\u7684\u591A\u6A21\u6001\u7406\u89E3\u4E0E\u957F\u6587\u672C\u63A8\u7406\u80FD\u529B\uFF0C\u5E76\u9488\u5BF9\u667A\u80FD\u4F53\u5DE5\u5177\u8C03\u7528\u8FDB\u884C\u4E86\u4F18\u5316\u3002",
16312
+ "gemini-3.1-pro": {
16313
+ name: "Gemini 3.1 Pro",
16314
+ description: "Gemini 3.1 Pro base model. Select tier at runtime.",
16333
16315
  maxTokens: 1048576,
16334
16316
  maxOutputTokens: 65535,
16335
16317
  toolCall: true,
@@ -16338,7 +16320,7 @@ var STATIC_MODELS_SIMPLE = {
16338
16320
  },
16339
16321
  "claude-sonnet-4-6": {
16340
16322
  name: "Claude Sonnet 4.6 (Thinking)",
16341
- description: "Claude Sonnet 4.6 \u6DF1\u5EA6\u63A8\u7406\u6A21\u578B\uFF0C\u5B8C\u7F8E\u5E73\u8861\u4E86\u601D\u8003\u8FC7\u7A0B\u3001\u5904\u7406\u901F\u5EA6\u4E0E\u8F93\u51FA\u8D28\u91CF\u3002",
16323
+ description: "Claude Sonnet 4.6 deep reasoning model, perfectly balancing thinking process, processing speed, and output quality.",
16342
16324
  maxTokens: 25e4,
16343
16325
  maxOutputTokens: 64e3,
16344
16326
  toolCall: true,
@@ -16347,7 +16329,7 @@ var STATIC_MODELS_SIMPLE = {
16347
16329
  },
16348
16330
  "claude-opus-4-6-thinking": {
16349
16331
  name: "Claude Opus 4.6 (Thinking)",
16350
- description: "Claude Opus 4.6 \u6DF1\u5EA6\u63A8\u7406\u6A21\u578B\uFF0C\u5185\u7F6E\u601D\u8003\u94FE\uFF0C\u975E\u5E38\u9002\u5408\u89E3\u51B3\u9876\u5C16\u96BE\u5EA6\u7684\u7B97\u6CD5\u548C\u903B\u8F91\u96BE\u9898\u3002",
16332
+ description: "Claude Opus 4.6 deep reasoning model, built-in chain of thought, highly suitable for top-tier algorithm and logic puzzles.",
16351
16333
  maxTokens: 25e4,
16352
16334
  maxOutputTokens: 64e3,
16353
16335
  toolCall: true,
@@ -16356,7 +16338,7 @@ var STATIC_MODELS_SIMPLE = {
16356
16338
  },
16357
16339
  "gpt-oss-120b-medium": {
16358
16340
  name: "GPT-OSS 120B (Medium)",
16359
- description: "GPT \u5F00\u6E90 120B \u53C2\u6570\u4E2D\u914D\u6A21\u578B\uFF0C\u5728\u672C\u5730\u5316\u90E8\u7F72\u6216\u7279\u5B9A\u5F00\u6E90\u57FA\u51C6\u4E0A\u8868\u73B0\u5353\u8D8A\u3002",
16341
+ description: "GPT open-source 120B parameter medium tier model, excellent performance in local deployment or specific open-source benchmarks.",
16360
16342
  maxTokens: 131072,
16361
16343
  maxOutputTokens: 32768,
16362
16344
  toolCall: true,
@@ -16364,9 +16346,29 @@ var STATIC_MODELS_SIMPLE = {
16364
16346
  attachment: false
16365
16347
  }
16366
16348
  };
16349
+ var TIER_MAPPING = {
16350
+ "gemini-3.5-flash": {
16351
+ low: "gemini-3.5-flash-extra-low",
16352
+ medium: "gemini-3.5-flash-low",
16353
+ high: "gemini-3-flash-agent"
16354
+ },
16355
+ "gemini-3.1-pro": {
16356
+ low: "gemini-3.1-pro-low",
16357
+ medium: "gemini-pro-agent",
16358
+ high: "gemini-pro-agent"
16359
+ }
16360
+ };
16367
16361
  var buildModelFromSimple = (modelId, simple) => {
16368
16362
  const isClaude = modelId.startsWith("claude-");
16369
16363
  const isGpt = modelId.startsWith("gpt-");
16364
+ let variants = void 0;
16365
+ if (TIER_MAPPING[modelId]) {
16366
+ variants = {
16367
+ "low": { id: "low", name: "low", displayName: "low", title: "low", label: "low", options: { name: "low" }, headers: { "x-agy-tier": "low" } },
16368
+ "medium": { id: "medium", name: "medium", displayName: "medium", title: "medium", label: "medium", options: { name: "medium" }, headers: { "x-agy-tier": "medium" } },
16369
+ "high": { id: "high", name: "high", displayName: "high", title: "high", label: "high", options: { name: "high" }, headers: { "x-agy-tier": "high" } }
16370
+ };
16371
+ }
16370
16372
  return {
16371
16373
  id: modelId,
16372
16374
  providerID: AGY_PROVIDER_ID,
@@ -16376,6 +16378,7 @@ var buildModelFromSimple = (modelId, simple) => {
16376
16378
  npm: "@ai-sdk/google"
16377
16379
  },
16378
16380
  name: simple.name,
16381
+ family: modelId.includes("gemini") ? "gemini" : isClaude ? "claude" : isGpt ? "gpt" : "unknown",
16379
16382
  status: "active",
16380
16383
  release_date: "2026-05-26",
16381
16384
  capabilities: {
@@ -16414,13 +16417,91 @@ var buildModelFromSimple = (modelId, simple) => {
16414
16417
  options: {
16415
16418
  description: simple.description
16416
16419
  },
16417
- headers: {}
16420
+ headers: {},
16421
+ variants
16418
16422
  };
16419
16423
  };
16420
16424
  var STATIC_MODELS = {};
16421
16425
  for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
16422
16426
  STATIC_MODELS[modelId] = buildModelFromSimple(modelId, simple);
16423
16427
  }
16428
+ function getSafeHeader(headers, key) {
16429
+ if (!headers) {
16430
+ return void 0;
16431
+ }
16432
+ const targetKey = key.toLowerCase();
16433
+ if (typeof headers.get === "function") {
16434
+ try {
16435
+ return headers.get(targetKey) || void 0;
16436
+ } catch {
16437
+ }
16438
+ }
16439
+ if (Array.isArray(headers)) {
16440
+ const found = headers.find((item) => {
16441
+ if (Array.isArray(item) && typeof item[0] === "string") {
16442
+ return item[0].toLowerCase() === targetKey;
16443
+ }
16444
+ return false;
16445
+ });
16446
+ return found ? String(found[1]) : void 0;
16447
+ }
16448
+ if (typeof headers === "object") {
16449
+ const foundKey = Object.keys(headers).find((k) => k.toLowerCase() === targetKey);
16450
+ return foundKey ? headers[foundKey] !== void 0 ? String(headers[foundKey]) : void 0 : void 0;
16451
+ }
16452
+ return void 0;
16453
+ }
16454
+ function setSafeHeaders(initHeaders, newHeaders) {
16455
+ if (typeof globalThis.Headers !== "undefined") {
16456
+ const headers = new globalThis.Headers(initHeaders ?? {});
16457
+ for (const [k, v] of Object.entries(newHeaders)) {
16458
+ headers.set(k, v);
16459
+ }
16460
+ return headers;
16461
+ }
16462
+ if (Array.isArray(initHeaders)) {
16463
+ const nextHeaders2 = [...initHeaders];
16464
+ for (const [k, v] of Object.entries(newHeaders)) {
16465
+ const idx = nextHeaders2.findIndex((item) => Array.isArray(item) && typeof item[0] === "string" && item[0].toLowerCase() === k.toLowerCase());
16466
+ if (idx !== -1) {
16467
+ nextHeaders2[idx] = [k, v];
16468
+ } else {
16469
+ nextHeaders2.push([k, v]);
16470
+ }
16471
+ }
16472
+ return nextHeaders2;
16473
+ }
16474
+ const nextHeaders = {};
16475
+ if (initHeaders && typeof initHeaders === "object") {
16476
+ for (const [k, v] of Object.entries(initHeaders)) {
16477
+ nextHeaders[k] = String(v);
16478
+ }
16479
+ }
16480
+ for (const [k, v] of Object.entries(newHeaders)) {
16481
+ const existingKey = Object.keys(nextHeaders).find((key) => key.toLowerCase() === k.toLowerCase());
16482
+ if (existingKey) {
16483
+ nextHeaders[existingKey] = v;
16484
+ } else {
16485
+ nextHeaders[k] = v;
16486
+ }
16487
+ }
16488
+ return nextHeaders;
16489
+ }
16490
+ function resolveModelTier(baseModelId, init) {
16491
+ const parts = baseModelId.split("@");
16492
+ const base = parts[0] || "";
16493
+ const suffixTier = parts[1]?.toLowerCase();
16494
+ const mapping = TIER_MAPPING[base];
16495
+ if (!mapping) {
16496
+ return baseModelId;
16497
+ }
16498
+ const headerTier = getSafeHeader(init?.headers, "x-agy-tier")?.toLowerCase() || null;
16499
+ const requestedTier = headerTier || suffixTier;
16500
+ if (requestedTier && Object.prototype.hasOwnProperty.call(mapping, requestedTier)) {
16501
+ return mapping[requestedTier] || baseModelId;
16502
+ }
16503
+ return mapping["medium"];
16504
+ }
16424
16505
  var AgyCLIOAuthPlugin = async ({ client }) => {
16425
16506
  let latestConfig;
16426
16507
  const getModelsList = (provider) => {
@@ -16515,14 +16596,15 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
16515
16596
  }
16516
16597
  const configuredProjectId2 = await resolveLatestConfiguredProjectId(provider);
16517
16598
  if (isInternal) {
16518
- const headers = new Headers(init?.headers ?? {});
16519
- const hasAuth = headers.has("Authorization") || Object.keys(init?.headers ?? {}).some((k) => k.toLowerCase() === "authorization");
16599
+ const hasAuth = getSafeHeader(init?.headers, "Authorization") !== void 0;
16520
16600
  if (hasAuth) {
16521
16601
  return agyFetch(input, init);
16522
16602
  }
16523
- headers.set("Authorization", `Bearer ${authRecord.access}`);
16524
16603
  const userAgent = buildAgyCliUserAgent(latestAgyUserAgentModel);
16525
- headers.set("User-Agent", userAgent);
16604
+ const headers = setSafeHeaders(init?.headers, {
16605
+ "Authorization": `Bearer ${authRecord.access}`,
16606
+ "User-Agent": userAgent
16607
+ });
16526
16608
  if (configuredProjectId2) {
16527
16609
  simulateClientBackgroundTraffic(authRecord.access, configuredProjectId2, latestAgyUserAgentModel);
16528
16610
  }
@@ -16543,9 +16625,23 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
16543
16625
  requestUserAgentModel
16544
16626
  );
16545
16627
  await maybeShowAgyTestToast(client, projectContext.effectiveProjectId);
16628
+ const originalRequestedModel = parseGenerativeLanguageRequest(input)?.effectiveModel;
16629
+ let modifiedInput = input;
16630
+ if (isGL && originalRequestedModel) {
16631
+ const originalBase = originalRequestedModel.replace("google-agy/", "");
16632
+ const resolvedBase = resolveModelTier(originalBase, init);
16633
+ if (originalBase !== resolvedBase) {
16634
+ if (typeof modifiedInput === "string") {
16635
+ modifiedInput = modifiedInput.replace(`models/${originalBase}`, `models/${resolvedBase}`);
16636
+ } else if (typeof Request !== "undefined" && modifiedInput instanceof Request) {
16637
+ const newUrl = modifiedInput.url.replace(`models/${originalBase}`, `models/${resolvedBase}`);
16638
+ modifiedInput = new Request(newUrl, modifiedInput);
16639
+ }
16640
+ }
16641
+ }
16546
16642
  const parts = parseRefreshParts(authRecord.refresh);
16547
16643
  const transformed = prepareAgyRequest(
16548
- input,
16644
+ modifiedInput,
16549
16645
  init,
16550
16646
  authRecord.access,
16551
16647
  projectContext.effectiveProjectId,
@@ -16616,7 +16712,7 @@ var AgyCLIOAuthPlugin = async ({ client }) => {
16616
16712
  if (!auth || !isOAuthAuth(auth)) {
16617
16713
  return {
16618
16714
  "login-required": {
16619
- name: "\u6682\u65E0\u6A21\u578B\u5217\u8868"
16715
+ name: "No models available"
16620
16716
  }
16621
16717
  };
16622
16718
  }