@anthonyhaussman/opencode-agy-auth 1.2.14 → 1.2.16-alpha.1

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.js CHANGED
@@ -268,7 +268,7 @@ function createAgyActivityRequestId() {
268
268
  import os from "os";
269
269
 
270
270
  // src/sdk/agy-cli-version.ts
271
- var AGY_CLI_VERSION = "1.2.14";
271
+ var AGY_CLI_VERSION = "1.2.16";
272
272
 
273
273
  // src/sdk/user-agent.ts
274
274
  var cachedUserAgent = null;
@@ -579,6 +579,12 @@ async function resolveQuotaResetDelay(accessToken, projectId, model, userAgentMo
579
579
  return null;
580
580
  }
581
581
  }
582
+ var retryInternals = {
583
+ parseRetryDelayValue,
584
+ parseRetryDelayFromMessage,
585
+ findResetTimeForModel,
586
+ resolveQuotaResetDelay
587
+ };
582
588
 
583
589
  // src/sdk/retry/helpers.ts
584
590
  var DEFAULT_MAX_ATTEMPTS = 3;
@@ -1575,7 +1581,11 @@ function createOAuthAuthorizeMethod(options) {
1575
1581
  const isHeadless = !!(process.env.SSH_CONNECTION || process.env.SSH_CLIENT || process.env.SSH_TTY || process.env.OPENCODE_HEADLESS);
1576
1582
  const authorization = await authorizeAgy();
1577
1583
  if (!isHeadless) {
1578
- openBrowserUrl(authorization.url);
1584
+ if (options?.openBrowser) {
1585
+ options.openBrowser(authorization.url);
1586
+ } else {
1587
+ openBrowserUrl(authorization.url);
1588
+ }
1579
1589
  }
1580
1590
  return {
1581
1591
  url: authorization.url,
@@ -1629,16 +1639,23 @@ function parseOAuthCallbackInput(input) {
1629
1639
  }
1630
1640
  return { code: trimmed };
1631
1641
  }
1642
+ function defaultOpenBrowserLauncher(command, args) {
1643
+ const child = spawn(command, args, {
1644
+ stdio: "ignore",
1645
+ detached: true
1646
+ });
1647
+ child.unref?.();
1648
+ }
1649
+ var openBrowserLauncher = defaultOpenBrowserLauncher;
1632
1650
  function openBrowserUrl(url2) {
1651
+ if ((process.env.NODE_ENV === "test" || process.env.VITEST) && openBrowserLauncher === defaultOpenBrowserLauncher) {
1652
+ return;
1653
+ }
1633
1654
  try {
1634
1655
  const platform2 = process.platform;
1635
1656
  const command = platform2 === "darwin" ? "open" : platform2 === "win32" ? "rundll32" : "xdg-open";
1636
1657
  const args = platform2 === "win32" ? ["url.dll,FileProtocolHandler", url2] : [url2];
1637
- const child = spawn(command, args, {
1638
- stdio: "ignore",
1639
- detached: true
1640
- });
1641
- child.unref?.();
1658
+ openBrowserLauncher(command, args);
1642
1659
  } catch {
1643
1660
  }
1644
1661
  }
@@ -15320,6 +15337,12 @@ function formatRelativeResetTime(resetTime) {
15320
15337
 
15321
15338
  // src/plugin/quota.ts
15322
15339
  var AGY_QUOTA_TOOL_NAME = "agy_quota";
15340
+ var AGY_V2_QUOTA_COMMAND = "agy-quota";
15341
+ var AGY_V2_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
15342
+
15343
+ Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
15344
+ Do not call other tools.
15345
+ `;
15323
15346
  function createAgyQuotaTool({
15324
15347
  client,
15325
15348
  getAuthResolver,
@@ -15559,6 +15582,12 @@ function splitModelVariant(modelId) {
15559
15582
 
15560
15583
  // src/plugin/quota-summary.ts
15561
15584
  var AGY_QUOTA_SUMMARY_TOOL_NAME = "agy_quota_summary";
15585
+ var AGY_V2_QUOTA_SUMMARY_COMMAND = "agy-quota-summary";
15586
+ var AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota summary (weekly and 5-hour limits by model group) for the current authenticated account.
15587
+
15588
+ Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
15589
+ Do not call other tools.
15590
+ `;
15562
15591
  function createAgyQuotaSummaryTool({
15563
15592
  client,
15564
15593
  getAuthResolver,
@@ -16017,8 +16046,12 @@ var models_default = {
16017
16046
  "gemini-3.6-flash-low",
16018
16047
  "gemini-pro-agent",
16019
16048
  "gemini-3.1-pro-low",
16020
- "claude-sonnet-4-6",
16021
- "claude-opus-4-6-thinking",
16049
+ "claude-opus-5-5-low",
16050
+ "claude-opus-5-5-medium",
16051
+ "claude-opus-5-5-high",
16052
+ "claude-sonnet-5-5-low",
16053
+ "claude-sonnet-5-5-medium",
16054
+ "claude-sonnet-5-5-high",
16022
16055
  "gpt-oss-120b-medium"
16023
16056
  ]
16024
16057
  }
@@ -16043,9 +16076,8 @@ var models_default = {
16043
16076
  }
16044
16077
  },
16045
16078
  experimentIds: [
16046
- 106329237,
16079
+ 106560668,
16047
16080
  106760947,
16048
- 106519115,
16049
16081
  105979552,
16050
16082
  105979574,
16051
16083
  106015333,
@@ -16055,14 +16087,14 @@ var models_default = {
16055
16087
  106123599,
16056
16088
  106121401,
16057
16089
  106100625,
16090
+ 106754391,
16058
16091
  106143956,
16059
16092
  105856899,
16060
16093
  106064030,
16061
- 106106760,
16094
+ 106544525,
16062
16095
  106021688,
16063
16096
  105887299,
16064
16097
  106428370,
16065
- 106283618,
16066
16098
  106640126,
16067
16099
  106380926,
16068
16100
  106281951,
@@ -16071,6 +16103,7 @@ var models_default = {
16071
16103
  106032303,
16072
16104
  106228452,
16073
16105
  106121607,
16106
+ 106793059,
16074
16107
  105979531,
16075
16108
  105979553,
16076
16109
  106015328,
@@ -16081,11 +16114,11 @@ var models_default = {
16081
16114
  106100654,
16082
16115
  106064028,
16083
16116
  105906495,
16084
- 106283614,
16085
16117
  106640124,
16086
16118
  106038164,
16087
16119
  106032301,
16088
- 106121604
16120
+ 106121604,
16121
+ 106793057
16089
16122
  ],
16090
16123
  imageGenerationModelIds: [
16091
16124
  "gemini-3.1-flash-image"
@@ -16123,29 +16156,102 @@ var models_default = {
16123
16156
  supportsEstimateTokenCounter: true,
16124
16157
  toolFormatterType: "TOOL_FORMATTER_TYPE_XML"
16125
16158
  },
16126
- "claude-opus-4-6-thinking": {
16159
+ "claude-opus-5-5-high": {
16127
16160
  apiProvider: "API_PROVIDER_ANTHROPIC_VERTEX",
16128
- displayName: "Claude Opus 4.6 (Thinking)",
16129
- maxOutputTokens: 64e3,
16130
- maxTokens: 25e4,
16131
- model: "MODEL_PLACEHOLDER_M26",
16161
+ displayName: "Claude Opus 5.5 (High)",
16162
+ maxOutputTokens: 128e3,
16163
+ maxTokens: 1e6,
16164
+ model: "MODEL_PLACEHOLDER_M402",
16132
16165
  modelExperiments: {
16133
16166
  experiments: {
16134
16167
  CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16135
- stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_UNSPECIFIED",\n "max_token_limit": "160000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": false,\n "is_sync": false,\n "max_user_requests": 10,\n "include_last_user_message": false,\n "include_conversation_log": true,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 0,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n },\n "session_summary_prompt_override": ""\n}'
16168
+ stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SAME_MODEL",\n "max_token_limit": "256000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": true,\n "is_sync": true,\n "max_user_requests": 10,\n "include_last_user_message": true,\n "include_conversation_log": false,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 4,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n },\n "session_summary_prompt_override": ""\n}'
16136
16169
  },
16137
16170
  retry_model_capacity_exhausted: {
16138
16171
  boolValue: true
16172
+ }
16173
+ }
16174
+ },
16175
+ modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16176
+ quotaInfo: {
16177
+ remainingFraction: 1,
16178
+ resetTime: "2026-10-03T18:28:29Z"
16179
+ },
16180
+ recommended: true,
16181
+ supportedMimeTypes: {
16182
+ "image/heic": true,
16183
+ "image/heif": true,
16184
+ "image/jpeg": true,
16185
+ "image/png": true,
16186
+ "image/webp": true,
16187
+ "video/jpeg2000": true,
16188
+ "video/videoframe/jpeg2000": true
16189
+ },
16190
+ supportsAdaptiveThinking: true,
16191
+ supportsImages: true,
16192
+ supportsThinking: true,
16193
+ tagTitle: "New",
16194
+ thinkingLevel: 3,
16195
+ vertexModelId: "claude-opus-5-5@default"
16196
+ },
16197
+ "claude-opus-5-5-low": {
16198
+ apiProvider: "API_PROVIDER_ANTHROPIC_VERTEX",
16199
+ displayName: "Claude Opus 5.5 (Low)",
16200
+ maxOutputTokens: 128e3,
16201
+ maxTokens: 1e6,
16202
+ model: "MODEL_PLACEHOLDER_M400",
16203
+ modelExperiments: {
16204
+ experiments: {
16205
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16206
+ stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SAME_MODEL",\n "max_token_limit": "256000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": true,\n "is_sync": true,\n "max_user_requests": 10,\n "include_last_user_message": true,\n "include_conversation_log": false,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 4,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n },\n "session_summary_prompt_override": ""\n}'
16139
16207
  },
16140
- template__system_prompts__planning_mode_artifacts: {
16141
- stringValue: "When in planning mode, you will work with three special artifacts.\n\n# Tasks\nPath: {{ArtifactDirectoryPath}}/task.md\n\n**Purpose**: A TODO list to organize your work during execution. Create this artifact after receiving user approval on your implementation plan. Break down complex tasks into component-level items and track progress as a living document.\n\n**Format**:\n```markdown\n- `[ ]` uncompleted tasks\n- `[/]` in progress tasks (custom notation)\n- `[x]` completed tasks\n- Use indented lists for sub-items\n```\n\n**Updating task.md**: Mark items as `[/]` when starting work on them, and `[x]` when completed. Update task.md as you make progress through your checklist.\n\n# Implementation Plan\nPath: {{ArtifactDirectoryPath}}/implementation_plan.md\n\n**Purpose**: A detailed design document to present your technical implementation plan to the user for feedback and approval.\nAfter reading the document, the user should understand the key technical details of your plan, and be able to make an informed decision on whether to approve it.\n\n**Format**: Use the following format, omitting any irrelevant sections.\n```markdown\n# [Goal Description]\n\nProvide a brief description of the problem, any background context, and what the change accomplishes.\n\n## User Review Required\n\nDocument anything that requires user review or feedback, for example, breaking changes or significant design decisions. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Open Questions\n\nAny clarifying or design questions for the user that will impact the implementation plan. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Proposed Changes\n\nGroup files by component (e.g., package, feature area, dependency layer) and order logically (dependencies first). Separate components with horizontal rules for visual clarity.\n\n### [Component Name]\n\nSummary of what will change in this component, separated by files. For specific files, Use [NEW] and [DELETE] to demarcate new and deleted files, for example:\n\n#### [MODIFY] [file basename](file:///absolute/path/to/modifiedfile)\n#### [NEW] [file basename](file:///absolute/path/to/newfile)\n#### [DELETE] [file basename](file:///absolute/path/to/deletedfile)\n\n## Verification Plan\n\nSummary of how you will verify that your changes have the desired effects.\n\n### Automated Tests\n- The commands of any automated tests you'll run.\n\n### Manual Verification\n- Asking the user to deploy to staging and testing, verifying UI changes on an iOS app etc.\n```\n\n# Walkthrough\nPath: {{ArtifactDirectoryPath}}/walkthrough.md\n\n**Purpose**: After completing work, summarize what you accomplished. Update an existing walkthrough for related follow-up work rather than creating a new one.\n\n**Document**:\n- Changes made\n- What was tested\n- Validation results\n\nEmbed screenshots and recordings to visually demonstrate UI changes and user flows.\n"
16208
+ retry_model_capacity_exhausted: {
16209
+ boolValue: true
16210
+ }
16211
+ }
16212
+ },
16213
+ modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16214
+ quotaInfo: {
16215
+ remainingFraction: 1,
16216
+ resetTime: "2026-10-03T18:28:29Z"
16217
+ },
16218
+ recommended: true,
16219
+ supportedMimeTypes: {
16220
+ "image/heic": true,
16221
+ "image/heif": true,
16222
+ "image/jpeg": true,
16223
+ "image/png": true,
16224
+ "image/webp": true,
16225
+ "video/jpeg2000": true,
16226
+ "video/videoframe/jpeg2000": true
16227
+ },
16228
+ supportsAdaptiveThinking: true,
16229
+ supportsImages: true,
16230
+ supportsThinking: true,
16231
+ tagTitle: "New",
16232
+ thinkingLevel: 1,
16233
+ vertexModelId: "claude-opus-5-5@default"
16234
+ },
16235
+ "claude-opus-5-5-medium": {
16236
+ apiProvider: "API_PROVIDER_ANTHROPIC_VERTEX",
16237
+ displayName: "Claude Opus 5.5 (Medium)",
16238
+ maxOutputTokens: 128e3,
16239
+ maxTokens: 1e6,
16240
+ model: "MODEL_PLACEHOLDER_M401",
16241
+ modelExperiments: {
16242
+ experiments: {
16243
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16244
+ stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SAME_MODEL",\n "max_token_limit": "256000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": true,\n "is_sync": true,\n "max_user_requests": 10,\n "include_last_user_message": true,\n "include_conversation_log": false,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 4,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n },\n "session_summary_prompt_override": ""\n}'
16245
+ },
16246
+ retry_model_capacity_exhausted: {
16247
+ boolValue: true
16142
16248
  }
16143
16249
  }
16144
16250
  },
16145
16251
  modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16146
16252
  quotaInfo: {
16147
16253
  remainingFraction: 1,
16148
- resetTime: "2026-09-30T12:45:45Z"
16254
+ resetTime: "2026-10-03T18:28:29Z"
16149
16255
  },
16150
16256
  recommended: true,
16151
16257
  supportedMimeTypes: {
@@ -16157,34 +16263,109 @@ var models_default = {
16157
16263
  "video/jpeg2000": true,
16158
16264
  "video/videoframe/jpeg2000": true
16159
16265
  },
16266
+ supportsAdaptiveThinking: true,
16160
16267
  supportsImages: true,
16161
16268
  supportsThinking: true,
16162
- thinkingBudget: 1024,
16163
- vertexModelId: "claude-opus-4-6@default"
16269
+ tagTitle: "New",
16270
+ thinkingLevel: 2,
16271
+ vertexModelId: "claude-opus-5-5@default"
16164
16272
  },
16165
- "claude-sonnet-4-6": {
16273
+ "claude-sonnet-5-5-high": {
16166
16274
  apiProvider: "API_PROVIDER_ANTHROPIC_VERTEX",
16167
- displayName: "Claude Sonnet 4.6 (Thinking)",
16168
- maxOutputTokens: 64e3,
16169
- maxTokens: 25e4,
16170
- model: "MODEL_PLACEHOLDER_M35",
16275
+ displayName: "Claude Sonnet 5.5 (High)",
16276
+ maxOutputTokens: 128e3,
16277
+ maxTokens: 1e6,
16278
+ model: "MODEL_PLACEHOLDER_M405",
16171
16279
  modelExperiments: {
16172
16280
  experiments: {
16173
16281
  CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16174
- stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_UNSPECIFIED",\n "max_token_limit": "160000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": false,\n "is_sync": false,\n "max_user_requests": 10,\n "include_last_user_message": false,\n "include_conversation_log": true,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 0,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n },\n "session_summary_prompt_override": ""\n}'
16282
+ stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SAME_MODEL",\n "max_token_limit": "256000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": true,\n "is_sync": true,\n "max_user_requests": 10,\n "include_last_user_message": true,\n "include_conversation_log": false,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 4,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n },\n "session_summary_prompt_override": ""\n}'
16175
16283
  },
16176
16284
  retry_model_capacity_exhausted: {
16177
16285
  boolValue: true
16286
+ }
16287
+ }
16288
+ },
16289
+ modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16290
+ quotaInfo: {
16291
+ remainingFraction: 1,
16292
+ resetTime: "2026-10-03T18:28:29Z"
16293
+ },
16294
+ recommended: true,
16295
+ supportedMimeTypes: {
16296
+ "image/heic": true,
16297
+ "image/heif": true,
16298
+ "image/jpeg": true,
16299
+ "image/png": true,
16300
+ "image/webp": true,
16301
+ "video/jpeg2000": true,
16302
+ "video/videoframe/jpeg2000": true
16303
+ },
16304
+ supportsAdaptiveThinking: true,
16305
+ supportsImages: true,
16306
+ supportsThinking: true,
16307
+ tagTitle: "New",
16308
+ thinkingLevel: 3,
16309
+ vertexModelId: "claude-sonnet-5-5@default"
16310
+ },
16311
+ "claude-sonnet-5-5-low": {
16312
+ apiProvider: "API_PROVIDER_ANTHROPIC_VERTEX",
16313
+ displayName: "Claude Sonnet 5.5 (Low)",
16314
+ maxOutputTokens: 128e3,
16315
+ maxTokens: 1e6,
16316
+ model: "MODEL_PLACEHOLDER_M403",
16317
+ modelExperiments: {
16318
+ experiments: {
16319
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16320
+ stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SAME_MODEL",\n "max_token_limit": "256000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": true,\n "is_sync": true,\n "max_user_requests": 10,\n "include_last_user_message": true,\n "include_conversation_log": false,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 4,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n },\n "session_summary_prompt_override": ""\n}'
16178
16321
  },
16179
- template__system_prompts__planning_mode_artifacts: {
16180
- stringValue: "When in planning mode, you will work with three special artifacts.\n\n# Tasks\nPath: {{ArtifactDirectoryPath}}/task.md\n\n**Purpose**: A TODO list to organize your work during execution. Create this artifact after receiving user approval on your implementation plan. Break down complex tasks into component-level items and track progress as a living document.\n\n**Format**:\n```markdown\n- `[ ]` uncompleted tasks\n- `[/]` in progress tasks (custom notation)\n- `[x]` completed tasks\n- Use indented lists for sub-items\n```\n\n**Updating task.md**: Mark items as `[/]` when starting work on them, and `[x]` when completed. Update task.md as you make progress through your checklist.\n\n# Implementation Plan\nPath: {{ArtifactDirectoryPath}}/implementation_plan.md\n\n**Purpose**: A detailed design document to present your technical implementation plan to the user for feedback and approval.\nAfter reading the document, the user should understand the key technical details of your plan, and be able to make an informed decision on whether to approve it.\n\n**Format**: Use the following format, omitting any irrelevant sections.\n```markdown\n# [Goal Description]\n\nProvide a brief description of the problem, any background context, and what the change accomplishes.\n\n## User Review Required\n\nDocument anything that requires user review or feedback, for example, breaking changes or significant design decisions. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Open Questions\n\nAny clarifying or design questions for the user that will impact the implementation plan. Use GitHub alerts (IMPORTANT/WARNING/CAUTION) to highlight critical items.\n\n## Proposed Changes\n\nGroup files by component (e.g., package, feature area, dependency layer) and order logically (dependencies first). Separate components with horizontal rules for visual clarity.\n\n### [Component Name]\n\nSummary of what will change in this component, separated by files. For specific files, Use [NEW] and [DELETE] to demarcate new and deleted files, for example:\n\n#### [MODIFY] [file basename](file:///absolute/path/to/modifiedfile)\n#### [NEW] [file basename](file:///absolute/path/to/newfile)\n#### [DELETE] [file basename](file:///absolute/path/to/deletedfile)\n\n## Verification Plan\n\nSummary of how you will verify that your changes have the desired effects.\n\n### Automated Tests\n- The commands of any automated tests you'll run.\n\n### Manual Verification\n- Asking the user to deploy to staging and testing, verifying UI changes on an iOS app etc.\n```\n\n# Walkthrough\nPath: {{ArtifactDirectoryPath}}/walkthrough.md\n\n**Purpose**: After completing work, summarize what you accomplished. Update an existing walkthrough for related follow-up work rather than creating a new one.\n\n**Document**:\n- Changes made\n- What was tested\n- Validation results\n\nEmbed screenshots and recordings to visually demonstrate UI changes and user flows.\n"
16322
+ retry_model_capacity_exhausted: {
16323
+ boolValue: true
16324
+ }
16325
+ }
16326
+ },
16327
+ modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16328
+ quotaInfo: {
16329
+ remainingFraction: 1,
16330
+ resetTime: "2026-10-03T18:28:29Z"
16331
+ },
16332
+ recommended: true,
16333
+ supportedMimeTypes: {
16334
+ "image/heic": true,
16335
+ "image/heif": true,
16336
+ "image/jpeg": true,
16337
+ "image/png": true,
16338
+ "image/webp": true,
16339
+ "video/jpeg2000": true,
16340
+ "video/videoframe/jpeg2000": true
16341
+ },
16342
+ supportsAdaptiveThinking: true,
16343
+ supportsImages: true,
16344
+ supportsThinking: true,
16345
+ tagTitle: "New",
16346
+ thinkingLevel: 1,
16347
+ vertexModelId: "claude-sonnet-5-5@default"
16348
+ },
16349
+ "claude-sonnet-5-5-medium": {
16350
+ apiProvider: "API_PROVIDER_ANTHROPIC_VERTEX",
16351
+ displayName: "Claude Sonnet 5.5 (Medium)",
16352
+ maxOutputTokens: 128e3,
16353
+ maxTokens: 1e6,
16354
+ model: "MODEL_PLACEHOLDER_M404",
16355
+ modelExperiments: {
16356
+ experiments: {
16357
+ CASCADE_USE_EXPERIMENT_CHECKPOINTER: {
16358
+ stringValue: '{\n "strategy": "CHECKPOINT_STRATEGY_SAME_MODEL",\n "max_token_limit": "256000",\n "token_threshold": "50000",\n "max_overhead_ratio": "0.15",\n "moving_window_size": "1",\n "enabled": true,\n "max_output_tokens": "16384",\n "checkpoint_model": "MODEL_PLACEHOLDER_M50",\n "use_last_planner_model": true,\n "is_sync": true,\n "max_user_requests": 10,\n "include_last_user_message": true,\n "include_conversation_log": false,\n "include_running_task_snapshots": true,\n "include_subagent_snapshots": true,\n "include_artifact_snapshots": true,\n "retry_config": {\n "max_retries": 4,\n "initial_sleep_duration_ms": 1000,\n "exponential_multiplier": 2,\n "include_error_feedback": false\n },\n "session_summary_prompt_override": ""\n}'
16359
+ },
16360
+ retry_model_capacity_exhausted: {
16361
+ boolValue: true
16181
16362
  }
16182
16363
  }
16183
16364
  },
16184
16365
  modelProvider: "MODEL_PROVIDER_ANTHROPIC",
16185
16366
  quotaInfo: {
16186
16367
  remainingFraction: 1,
16187
- resetTime: "2026-09-30T12:45:45Z"
16368
+ resetTime: "2026-10-03T18:28:29Z"
16188
16369
  },
16189
16370
  recommended: true,
16190
16371
  supportedMimeTypes: {
@@ -16196,10 +16377,12 @@ var models_default = {
16196
16377
  "video/jpeg2000": true,
16197
16378
  "video/videoframe/jpeg2000": true
16198
16379
  },
16380
+ supportsAdaptiveThinking: true,
16199
16381
  supportsImages: true,
16200
16382
  supportsThinking: true,
16201
- thinkingBudget: 1024,
16202
- vertexModelId: "claude-sonnet-4-6@default"
16383
+ tagTitle: "New",
16384
+ thinkingLevel: 2,
16385
+ vertexModelId: "claude-sonnet-5-5@default"
16203
16386
  },
16204
16387
  "gemini-2.5-flash": {
16205
16388
  apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
@@ -16220,8 +16403,8 @@ var models_default = {
16220
16403
  },
16221
16404
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16222
16405
  quotaInfo: {
16223
- remainingFraction: 0.9673149,
16224
- resetTime: "2026-09-30T12:41:07Z"
16406
+ remainingFraction: 0.9911344,
16407
+ resetTime: "2026-10-03T16:28:30Z"
16225
16408
  },
16226
16409
  recommended: true,
16227
16410
  supportedMimeTypes: {
@@ -16282,7 +16465,7 @@ var models_default = {
16282
16465
  supportsVideo: true,
16283
16466
  tagDescription: "gemini-3.5-flash-lite",
16284
16467
  thinkingBudget: -1,
16285
- thinkingLevel: 3
16468
+ thinkingLevel: 1
16286
16469
  },
16287
16470
  "gemini-2.5-flash-lite": {
16288
16471
  apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
@@ -16303,8 +16486,8 @@ var models_default = {
16303
16486
  },
16304
16487
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16305
16488
  quotaInfo: {
16306
- remainingFraction: 0.9673149,
16307
- resetTime: "2026-09-30T12:41:07Z"
16489
+ remainingFraction: 0.9911344,
16490
+ resetTime: "2026-10-03T16:28:30Z"
16308
16491
  },
16309
16492
  recommended: true,
16310
16493
  supportedMimeTypes: {
@@ -16365,7 +16548,7 @@ var models_default = {
16365
16548
  supportsVideo: true,
16366
16549
  tagDescription: "gemini-3.5-flash-lite",
16367
16550
  thinkingBudget: -1,
16368
- thinkingLevel: 3
16551
+ thinkingLevel: 1
16369
16552
  },
16370
16553
  "gemini-2.5-flash-thinking": {
16371
16554
  apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
@@ -16386,8 +16569,8 @@ var models_default = {
16386
16569
  },
16387
16570
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16388
16571
  quotaInfo: {
16389
- remainingFraction: 0.9673149,
16390
- resetTime: "2026-09-30T12:41:07Z"
16572
+ remainingFraction: 0.9911344,
16573
+ resetTime: "2026-10-03T16:28:30Z"
16391
16574
  },
16392
16575
  recommended: true,
16393
16576
  supportedMimeTypes: {
@@ -16448,7 +16631,7 @@ var models_default = {
16448
16631
  supportsVideo: true,
16449
16632
  tagDescription: "gemini-3.5-flash-lite",
16450
16633
  thinkingBudget: -1,
16451
- thinkingLevel: 3
16634
+ thinkingLevel: 1
16452
16635
  },
16453
16636
  "gemini-2.5-pro": {
16454
16637
  apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
@@ -16466,8 +16649,8 @@ var models_default = {
16466
16649
  },
16467
16650
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16468
16651
  quotaInfo: {
16469
- remainingFraction: 0.9673149,
16470
- resetTime: "2026-09-30T12:41:07Z"
16652
+ remainingFraction: 0.9911344,
16653
+ resetTime: "2026-10-03T16:28:30Z"
16471
16654
  },
16472
16655
  recommended: true,
16473
16656
  requiresImageOutputOutsideFunctionResponses: true,
@@ -16547,8 +16730,8 @@ var models_default = {
16547
16730
  },
16548
16731
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16549
16732
  quotaInfo: {
16550
- remainingFraction: 0.9673149,
16551
- resetTime: "2026-09-30T12:41:07Z"
16733
+ remainingFraction: 0.9911344,
16734
+ resetTime: "2026-10-03T16:28:30Z"
16552
16735
  },
16553
16736
  recommended: true,
16554
16737
  supportedMimeTypes: {
@@ -16652,8 +16835,8 @@ var models_default = {
16652
16835
  },
16653
16836
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16654
16837
  quotaInfo: {
16655
- remainingFraction: 0.9673149,
16656
- resetTime: "2026-09-30T12:41:07Z"
16838
+ remainingFraction: 0.9911344,
16839
+ resetTime: "2026-10-03T16:28:30Z"
16657
16840
  },
16658
16841
  recommended: true,
16659
16842
  supportedMimeTypes: {
@@ -16722,8 +16905,8 @@ var models_default = {
16722
16905
  model: "MODEL_PLACEHOLDER_M21",
16723
16906
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16724
16907
  quotaInfo: {
16725
- remainingFraction: 0.9673149,
16726
- resetTime: "2026-09-30T12:41:07Z"
16908
+ remainingFraction: 0.9911344,
16909
+ resetTime: "2026-10-03T16:28:30Z"
16727
16910
  }
16728
16911
  },
16729
16912
  "gemini-3.1-flash-lite": {
@@ -16741,8 +16924,8 @@ var models_default = {
16741
16924
  },
16742
16925
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16743
16926
  quotaInfo: {
16744
- remainingFraction: 0.9673149,
16745
- resetTime: "2026-09-30T12:41:07Z"
16927
+ remainingFraction: 0.9911344,
16928
+ resetTime: "2026-10-03T16:28:30Z"
16746
16929
  }
16747
16930
  },
16748
16931
  "gemini-3.1-pro-high": {
@@ -16773,8 +16956,8 @@ var models_default = {
16773
16956
  },
16774
16957
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16775
16958
  quotaInfo: {
16776
- remainingFraction: 0.9673149,
16777
- resetTime: "2026-09-30T12:41:07Z"
16959
+ remainingFraction: 0.9911344,
16960
+ resetTime: "2026-10-03T16:28:30Z"
16778
16961
  },
16779
16962
  recommended: true,
16780
16963
  supportedMimeTypes: {
@@ -16864,8 +17047,8 @@ var models_default = {
16864
17047
  },
16865
17048
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16866
17049
  quotaInfo: {
16867
- remainingFraction: 0.9673149,
16868
- resetTime: "2026-09-30T12:41:07Z"
17050
+ remainingFraction: 0.9911344,
17051
+ resetTime: "2026-10-03T16:28:30Z"
16869
17052
  },
16870
17053
  recommended: true,
16871
17054
  supportedMimeTypes: {
@@ -16969,8 +17152,8 @@ var models_default = {
16969
17152
  },
16970
17153
  modelProvider: "MODEL_PROVIDER_GOOGLE",
16971
17154
  quotaInfo: {
16972
- remainingFraction: 0.9673149,
16973
- resetTime: "2026-09-30T12:41:07Z"
17155
+ remainingFraction: 0.9911344,
17156
+ resetTime: "2026-10-03T16:28:30Z"
16974
17157
  },
16975
17158
  recommended: true,
16976
17159
  supportedMimeTypes: {
@@ -17052,8 +17235,8 @@ var models_default = {
17052
17235
  },
17053
17236
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17054
17237
  quotaInfo: {
17055
- remainingFraction: 0.9673149,
17056
- resetTime: "2026-09-30T12:41:07Z"
17238
+ remainingFraction: 0.9911344,
17239
+ resetTime: "2026-10-03T16:28:30Z"
17057
17240
  },
17058
17241
  recommended: true,
17059
17242
  supportedMimeTypes: {
@@ -17114,7 +17297,7 @@ var models_default = {
17114
17297
  supportsVideo: true,
17115
17298
  tagDescription: "gemini-3.5-flash-lite",
17116
17299
  thinkingBudget: -1,
17117
- thinkingLevel: 3
17300
+ thinkingLevel: 1
17118
17301
  },
17119
17302
  "gemini-3.5-flash-low": {
17120
17303
  apiProvider: "API_PROVIDER_GOOGLE_GEMINI",
@@ -17159,8 +17342,8 @@ var models_default = {
17159
17342
  },
17160
17343
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17161
17344
  quotaInfo: {
17162
- remainingFraction: 0.9673149,
17163
- resetTime: "2026-09-30T12:41:07Z"
17345
+ remainingFraction: 0.9911344,
17346
+ resetTime: "2026-10-03T16:28:30Z"
17164
17347
  },
17165
17348
  recommended: true,
17166
17349
  supportedMimeTypes: {
@@ -17278,8 +17461,8 @@ var models_default = {
17278
17461
  },
17279
17462
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17280
17463
  quotaInfo: {
17281
- remainingFraction: 0.9673149,
17282
- resetTime: "2026-09-30T12:41:07Z"
17464
+ remainingFraction: 0.9911344,
17465
+ resetTime: "2026-10-03T16:28:30Z"
17283
17466
  },
17284
17467
  recommended: true,
17285
17468
  supportedMimeTypes: {
@@ -17397,8 +17580,8 @@ var models_default = {
17397
17580
  },
17398
17581
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17399
17582
  quotaInfo: {
17400
- remainingFraction: 0.9673149,
17401
- resetTime: "2026-09-30T12:41:07Z"
17583
+ remainingFraction: 0.9911344,
17584
+ resetTime: "2026-10-03T16:28:30Z"
17402
17585
  },
17403
17586
  recommended: true,
17404
17587
  supportedMimeTypes: {
@@ -17516,8 +17699,8 @@ var models_default = {
17516
17699
  },
17517
17700
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17518
17701
  quotaInfo: {
17519
- remainingFraction: 0.9673149,
17520
- resetTime: "2026-09-30T12:41:07Z"
17702
+ remainingFraction: 0.9911344,
17703
+ resetTime: "2026-10-03T16:28:30Z"
17521
17704
  },
17522
17705
  recommended: true,
17523
17706
  supportedMimeTypes: {
@@ -17634,8 +17817,8 @@ var models_default = {
17634
17817
  },
17635
17818
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17636
17819
  quotaInfo: {
17637
- remainingFraction: 0.9673149,
17638
- resetTime: "2026-09-30T12:41:07Z"
17820
+ remainingFraction: 0.9911344,
17821
+ resetTime: "2026-10-03T16:28:30Z"
17639
17822
  },
17640
17823
  recommended: true,
17641
17824
  supportedMimeTypes: {
@@ -17745,8 +17928,8 @@ var models_default = {
17745
17928
  },
17746
17929
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17747
17930
  quotaInfo: {
17748
- remainingFraction: 0.9673149,
17749
- resetTime: "2026-09-30T12:41:07Z"
17931
+ remainingFraction: 0.9911344,
17932
+ resetTime: "2026-10-03T16:28:30Z"
17750
17933
  },
17751
17934
  recommended: true,
17752
17935
  supportedMimeTypes: {
@@ -17858,8 +18041,8 @@ var models_default = {
17858
18041
  },
17859
18042
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17860
18043
  quotaInfo: {
17861
- remainingFraction: 0.9673149,
17862
- resetTime: "2026-09-30T12:41:07Z"
18044
+ remainingFraction: 0.9911344,
18045
+ resetTime: "2026-10-03T16:28:30Z"
17863
18046
  },
17864
18047
  recommended: true,
17865
18048
  supportedMimeTypes: {
@@ -17971,8 +18154,8 @@ var models_default = {
17971
18154
  },
17972
18155
  modelProvider: "MODEL_PROVIDER_GOOGLE",
17973
18156
  quotaInfo: {
17974
- remainingFraction: 0.9673149,
17975
- resetTime: "2026-09-30T12:41:07Z"
18157
+ remainingFraction: 0.9911344,
18158
+ resetTime: "2026-10-03T16:28:30Z"
17976
18159
  },
17977
18160
  recommended: true,
17978
18161
  supportedMimeTypes: {
@@ -18083,8 +18266,8 @@ var models_default = {
18083
18266
  },
18084
18267
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18085
18268
  quotaInfo: {
18086
- remainingFraction: 0.9673149,
18087
- resetTime: "2026-09-30T12:41:07Z"
18269
+ remainingFraction: 0.9911344,
18270
+ resetTime: "2026-10-03T16:28:30Z"
18088
18271
  },
18089
18272
  recommended: true,
18090
18273
  supportedMimeTypes: {
@@ -18194,8 +18377,8 @@ var models_default = {
18194
18377
  },
18195
18378
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18196
18379
  quotaInfo: {
18197
- remainingFraction: 0.9673149,
18198
- resetTime: "2026-09-30T12:41:07Z"
18380
+ remainingFraction: 0.9911344,
18381
+ resetTime: "2026-10-03T16:28:30Z"
18199
18382
  },
18200
18383
  recommended: true,
18201
18384
  supportedMimeTypes: {
@@ -18307,8 +18490,8 @@ var models_default = {
18307
18490
  },
18308
18491
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18309
18492
  quotaInfo: {
18310
- remainingFraction: 0.9673149,
18311
- resetTime: "2026-09-30T12:41:07Z"
18493
+ remainingFraction: 0.9911344,
18494
+ resetTime: "2026-10-03T16:28:30Z"
18312
18495
  },
18313
18496
  recommended: true,
18314
18497
  supportedMimeTypes: {
@@ -18420,8 +18603,8 @@ var models_default = {
18420
18603
  },
18421
18604
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18422
18605
  quotaInfo: {
18423
- remainingFraction: 0.9673149,
18424
- resetTime: "2026-09-30T12:41:07Z"
18606
+ remainingFraction: 0.9911344,
18607
+ resetTime: "2026-10-03T16:28:30Z"
18425
18608
  },
18426
18609
  recommended: true,
18427
18610
  supportedMimeTypes: {
@@ -18532,8 +18715,8 @@ var models_default = {
18532
18715
  },
18533
18716
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18534
18717
  quotaInfo: {
18535
- remainingFraction: 0.9673149,
18536
- resetTime: "2026-09-30T12:41:07Z"
18718
+ remainingFraction: 0.9911344,
18719
+ resetTime: "2026-10-03T16:28:30Z"
18537
18720
  },
18538
18721
  recommended: true,
18539
18722
  supportedMimeTypes: {
@@ -18622,8 +18805,8 @@ var models_default = {
18622
18805
  },
18623
18806
  modelProvider: "MODEL_PROVIDER_GOOGLE",
18624
18807
  quotaInfo: {
18625
- remainingFraction: 0.9673149,
18626
- resetTime: "2026-09-30T12:41:07Z"
18808
+ remainingFraction: 0.9911344,
18809
+ resetTime: "2026-10-03T16:28:30Z"
18627
18810
  },
18628
18811
  recommended: true,
18629
18812
  supportedMimeTypes: {
@@ -18700,10 +18883,12 @@ var models_default = {
18700
18883
  modelProvider: "MODEL_PROVIDER_OPENAI",
18701
18884
  quotaInfo: {
18702
18885
  remainingFraction: 1,
18703
- resetTime: "2026-09-30T12:45:45Z"
18886
+ resetTime: "2026-10-03T18:28:29Z"
18704
18887
  },
18705
18888
  recommended: true,
18706
18889
  supportsThinking: true,
18890
+ tagDescription: "GPT-OSS will be removed from Antigravity on November 2, 2026.",
18891
+ tagTitle: "Notice",
18707
18892
  thinkingBudget: 8192,
18708
18893
  vertexModelId: "openai/gpt-oss-120b-maas"
18709
18894
  },
@@ -19772,9 +19957,14 @@ function normalizeToolSchemaTypes(tools, toolMapper) {
19772
19957
  fn.name = toolMapper ? toolMapper.toGemini(fn.name) : sanitizeToolName(fn.name);
19773
19958
  }
19774
19959
  if (fn) {
19960
+ if (!fn.parameters) {
19961
+ fn.parameters = fn.parameters_json_schema ?? fn.parametersJsonSchema;
19962
+ }
19775
19963
  if (!fn.parameters) {
19776
19964
  fn.parameters = { type: "OBJECT", properties: {} };
19777
19965
  }
19966
+ delete fn.parameters_json_schema;
19967
+ delete fn.parametersJsonSchema;
19778
19968
  sanitizeSchema(fn.parameters);
19779
19969
  }
19780
19970
  }
@@ -20199,22 +20389,81 @@ var ChatLoggerImpl = class {
20199
20389
  }
20200
20390
  };
20201
20391
 
20202
- // src/plugin.ts
20203
- var AGY_QUOTA_COMMAND = "agyquota";
20204
- var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
20205
-
20206
- Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
20207
- Do not call other tools.
20208
- `;
20209
- var AGY_QUOTA_SUMMARY_COMMAND = "agyquotasummary";
20210
- var AGY_QUOTA_SUMMARY_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota summary (weekly and 5-hour limits by model group) for the current authenticated account.
20392
+ // src/plugin/headers.ts
20393
+ function getSafeHeader(headers, key) {
20394
+ if (!headers) {
20395
+ return void 0;
20396
+ }
20397
+ const targetKey = key.toLowerCase();
20398
+ if (typeof headers.get === "function") {
20399
+ try {
20400
+ return headers.get(targetKey) || void 0;
20401
+ } catch {
20402
+ }
20403
+ }
20404
+ if (Array.isArray(headers)) {
20405
+ const found = headers.find((item) => {
20406
+ if (Array.isArray(item) && typeof item[0] === "string") {
20407
+ return item[0].toLowerCase() === targetKey;
20408
+ }
20409
+ return false;
20410
+ });
20411
+ return found ? String(found[1]) : void 0;
20412
+ }
20413
+ if (typeof headers === "object") {
20414
+ const foundKey = Object.keys(headers).find((k) => k.toLowerCase() === targetKey);
20415
+ return foundKey ? headers[foundKey] !== void 0 ? String(headers[foundKey]) : void 0 : void 0;
20416
+ }
20417
+ return void 0;
20418
+ }
20419
+ function setSafeHeaders(initHeaders, newHeaders) {
20420
+ if (typeof globalThis.Headers !== "undefined") {
20421
+ const headers = new globalThis.Headers(initHeaders ?? {});
20422
+ for (const [k, v] of Object.entries(newHeaders)) {
20423
+ headers.set(k, v);
20424
+ }
20425
+ return headers;
20426
+ }
20427
+ if (Array.isArray(initHeaders)) {
20428
+ const nextHeaders2 = [...initHeaders];
20429
+ for (const [k, v] of Object.entries(newHeaders)) {
20430
+ const idx = nextHeaders2.findIndex((item) => Array.isArray(item) && typeof item[0] === "string" && item[0].toLowerCase() === k.toLowerCase());
20431
+ if (idx !== -1) {
20432
+ nextHeaders2[idx] = [k, v];
20433
+ } else {
20434
+ nextHeaders2.push([k, v]);
20435
+ }
20436
+ }
20437
+ return nextHeaders2;
20438
+ }
20439
+ const nextHeaders = {};
20440
+ if (initHeaders && typeof initHeaders === "object") {
20441
+ for (const [k, v] of Object.entries(initHeaders)) {
20442
+ nextHeaders[k] = String(v);
20443
+ }
20444
+ }
20445
+ for (const [k, v] of Object.entries(newHeaders)) {
20446
+ const existingKey = Object.keys(nextHeaders).find((key) => key.toLowerCase() === k.toLowerCase());
20447
+ if (existingKey) {
20448
+ nextHeaders[existingKey] = v;
20449
+ } else {
20450
+ nextHeaders[k] = v;
20451
+ }
20452
+ }
20453
+ return nextHeaders;
20454
+ }
20455
+ function toUrlString(value) {
20456
+ if (typeof value === "string") {
20457
+ return value;
20458
+ }
20459
+ const candidate = value.url;
20460
+ if (candidate) {
20461
+ return candidate;
20462
+ }
20463
+ return value.toString();
20464
+ }
20211
20465
 
20212
- Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
20213
- Do not call other tools.
20214
- `;
20215
- var latestAgyAuthResolver;
20216
- var latestAgyConfiguredProjectId;
20217
- var latestAgyUserAgentModel;
20466
+ // src/plugin/tier.ts
20218
20467
  var STATIC_MODELS_SIMPLE = {
20219
20468
  "gemini-3.8-flash": {
20220
20469
  name: "Gemini 3.8 Flash",
@@ -20252,20 +20501,20 @@ var STATIC_MODELS_SIMPLE = {
20252
20501
  reasoning: true,
20253
20502
  attachment: true
20254
20503
  },
20255
- "claude-sonnet-4-6": {
20256
- name: "Claude Sonnet 4.6 (Thinking)",
20257
- description: "Claude Sonnet 4.6 deep reasoning model, perfectly balancing thinking process, processing speed, and output quality.",
20258
- maxTokens: 25e4,
20259
- maxOutputTokens: 64e3,
20504
+ "claude-opus-5-5": {
20505
+ name: "Claude Opus 5.5",
20506
+ description: "Claude Opus 5.5 deep reasoning model. Select tier at runtime.",
20507
+ maxTokens: 1e6,
20508
+ maxOutputTokens: 128e3,
20260
20509
  toolCall: true,
20261
20510
  reasoning: true,
20262
20511
  attachment: true
20263
20512
  },
20264
- "claude-opus-4-6-thinking": {
20265
- name: "Claude Opus 4.6 (Thinking)",
20266
- description: "Claude Opus 4.6 deep reasoning model, built-in chain of thought, highly suitable for top-tier algorithm and logic puzzles.",
20267
- maxTokens: 25e4,
20268
- maxOutputTokens: 64e3,
20513
+ "claude-sonnet-5-5": {
20514
+ name: "Claude Sonnet 5.5",
20515
+ description: "Claude Sonnet 5.5 deep reasoning model. Select tier at runtime.",
20516
+ maxTokens: 1e6,
20517
+ maxOutputTokens: 128e3,
20269
20518
  toolCall: true,
20270
20519
  reasoning: true,
20271
20520
  attachment: true
@@ -20300,8 +20549,51 @@ var TIER_MAPPING = {
20300
20549
  "gemini-3.1-pro": {
20301
20550
  low: "gemini-3.1-pro-low",
20302
20551
  high: "gemini-3.1-pro-high"
20552
+ },
20553
+ "claude-opus-5-5": {
20554
+ low: "claude-opus-5-5-low",
20555
+ medium: "claude-opus-5-5-medium",
20556
+ high: "claude-opus-5-5-high"
20557
+ },
20558
+ "claude-sonnet-5-5": {
20559
+ low: "claude-sonnet-5-5-low",
20560
+ medium: "claude-sonnet-5-5-medium",
20561
+ high: "claude-sonnet-5-5-high"
20303
20562
  }
20304
20563
  };
20564
+ function resolveModelTier(baseModelId, headersOrInit) {
20565
+ const parts = baseModelId.split("@");
20566
+ const base = parts[0] || "";
20567
+ const suffixTier = parts[1]?.toLowerCase();
20568
+ const mapping = TIER_MAPPING[base];
20569
+ if (!mapping) {
20570
+ return baseModelId;
20571
+ }
20572
+ const rawHeaders = headersOrInit && typeof headersOrInit === "object" && "headers" in headersOrInit ? headersOrInit.headers : headersOrInit;
20573
+ const headerTier = getSafeHeader(rawHeaders, "x-agy-tier")?.toLowerCase() || null;
20574
+ const requestedTier = headerTier || suffixTier;
20575
+ if (requestedTier && Object.prototype.hasOwnProperty.call(mapping, requestedTier)) {
20576
+ return mapping[requestedTier] || baseModelId;
20577
+ }
20578
+ return mapping["medium"] ?? mapping["high"] ?? baseModelId;
20579
+ }
20580
+
20581
+ // src/plugin.ts
20582
+ var AGY_QUOTA_COMMAND = "agyquota";
20583
+ var AGY_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
20584
+
20585
+ Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
20586
+ Do not call other tools.
20587
+ `;
20588
+ var AGY_QUOTA_SUMMARY_COMMAND = "agyquotasummary";
20589
+ var AGY_QUOTA_SUMMARY_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota summary (weekly and 5-hour limits by model group) for the current authenticated account.
20590
+
20591
+ Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
20592
+ Do not call other tools.
20593
+ `;
20594
+ var latestAgyAuthResolver;
20595
+ var latestAgyConfiguredProjectId;
20596
+ var latestAgyUserAgentModel;
20305
20597
  var buildModelFromSimple = (modelId, simple) => {
20306
20598
  const isClaude = modelId.startsWith("claude-");
20307
20599
  const isGpt = modelId.startsWith("gpt-");
@@ -20395,83 +20687,6 @@ var STATIC_MODELS = {};
20395
20687
  for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
20396
20688
  STATIC_MODELS[modelId] = buildModelFromSimple(modelId, simple);
20397
20689
  }
20398
- function getSafeHeader(headers, key) {
20399
- if (!headers) {
20400
- return void 0;
20401
- }
20402
- const targetKey = key.toLowerCase();
20403
- if (typeof headers.get === "function") {
20404
- try {
20405
- return headers.get(targetKey) || void 0;
20406
- } catch {
20407
- }
20408
- }
20409
- if (Array.isArray(headers)) {
20410
- const found = headers.find((item) => {
20411
- if (Array.isArray(item) && typeof item[0] === "string") {
20412
- return item[0].toLowerCase() === targetKey;
20413
- }
20414
- return false;
20415
- });
20416
- return found ? String(found[1]) : void 0;
20417
- }
20418
- if (typeof headers === "object") {
20419
- const foundKey = Object.keys(headers).find((k) => k.toLowerCase() === targetKey);
20420
- return foundKey ? headers[foundKey] !== void 0 ? String(headers[foundKey]) : void 0 : void 0;
20421
- }
20422
- return void 0;
20423
- }
20424
- function setSafeHeaders(initHeaders, newHeaders) {
20425
- if (typeof globalThis.Headers !== "undefined") {
20426
- const headers = new globalThis.Headers(initHeaders ?? {});
20427
- for (const [k, v] of Object.entries(newHeaders)) {
20428
- headers.set(k, v);
20429
- }
20430
- return headers;
20431
- }
20432
- if (Array.isArray(initHeaders)) {
20433
- const nextHeaders2 = [...initHeaders];
20434
- for (const [k, v] of Object.entries(newHeaders)) {
20435
- const idx = nextHeaders2.findIndex((item) => Array.isArray(item) && typeof item[0] === "string" && item[0].toLowerCase() === k.toLowerCase());
20436
- if (idx !== -1) {
20437
- nextHeaders2[idx] = [k, v];
20438
- } else {
20439
- nextHeaders2.push([k, v]);
20440
- }
20441
- }
20442
- return nextHeaders2;
20443
- }
20444
- const nextHeaders = {};
20445
- if (initHeaders && typeof initHeaders === "object") {
20446
- for (const [k, v] of Object.entries(initHeaders)) {
20447
- nextHeaders[k] = String(v);
20448
- }
20449
- }
20450
- for (const [k, v] of Object.entries(newHeaders)) {
20451
- const existingKey = Object.keys(nextHeaders).find((key) => key.toLowerCase() === k.toLowerCase());
20452
- if (existingKey) {
20453
- nextHeaders[existingKey] = v;
20454
- } else {
20455
- nextHeaders[k] = v;
20456
- }
20457
- }
20458
- return nextHeaders;
20459
- }
20460
- function resolveModelTier(baseModelId, init) {
20461
- const parts = baseModelId.split("@");
20462
- const base = parts[0] || "";
20463
- const suffixTier = parts[1]?.toLowerCase();
20464
- const mapping = TIER_MAPPING[base];
20465
- if (!mapping) {
20466
- return baseModelId;
20467
- }
20468
- const headerTier = getSafeHeader(init?.headers, "x-agy-tier")?.toLowerCase() || null;
20469
- const requestedTier = headerTier || suffixTier;
20470
- if (requestedTier && Object.prototype.hasOwnProperty.call(mapping, requestedTier)) {
20471
- return mapping[requestedTier] || baseModelId;
20472
- }
20473
- return mapping["medium"] ?? mapping["high"];
20474
- }
20475
20690
  var AgyCLIOAuthPlugin = async ({ client }) => {
20476
20691
  let latestConfig;
20477
20692
  updateStaticModelsWithPricing(STATIC_MODELS);
@@ -20799,25 +21014,782 @@ async function ensureProjectContextOrThrow(authRecord, client, configuredProject
20799
21014
  throw error45;
20800
21015
  }
20801
21016
  }
20802
- function toUrlString(value) {
20803
- if (typeof value === "string") {
20804
- return value;
21017
+
21018
+ // src/plugin/types.ts
21019
+ function defineOpenCodeV2Plugin(def) {
21020
+ return def;
21021
+ }
21022
+
21023
+ // src/plugin/v2-storage.ts
21024
+ import { closeSync, existsSync as existsSync6, mkdirSync as mkdirSync5, openSync, readFileSync as readFileSync5, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync5 } from "fs";
21025
+ import { randomUUID as randomUUID4 } from "crypto";
21026
+ import { homedir as homedir4 } from "os";
21027
+ import { join as join6 } from "path";
21028
+ var storedAuthOverrideForTesting = void 0;
21029
+ function loadStoredAuthFromJson() {
21030
+ if (storedAuthOverrideForTesting !== void 0) {
21031
+ return storedAuthOverrideForTesting;
21032
+ }
21033
+ const authPath = join6(homedir4(), ".local", "share", "opencode", "auth.json");
21034
+ try {
21035
+ if (existsSync6(authPath)) {
21036
+ const content = readFileSync5(authPath, "utf8");
21037
+ const data = JSON.parse(content);
21038
+ return data?.[AGY_PROVIDER_ID];
21039
+ }
21040
+ } catch {
20805
21041
  }
20806
- const candidate = value.url;
20807
- if (candidate) {
20808
- return candidate;
21042
+ return void 0;
21043
+ }
21044
+ function saveStoredAuthToJson(authRecord) {
21045
+ if (process.env.NODE_ENV === "test" || process.env.VITEST || storedAuthOverrideForTesting !== void 0) {
21046
+ return;
20809
21047
  }
20810
- return value.toString();
21048
+ const dirPath = join6(homedir4(), ".local", "share", "opencode");
21049
+ if (!existsSync6(dirPath)) {
21050
+ mkdirSync5(dirPath, { recursive: true });
21051
+ }
21052
+ const authPath = join6(dirPath, "auth.json");
21053
+ const data = existsSync6(authPath) ? JSON.parse(readFileSync5(authPath, "utf8")) : {};
21054
+ data[AGY_PROVIDER_ID] = {
21055
+ type: "oauth",
21056
+ refresh: authRecord.refresh,
21057
+ access: authRecord.access,
21058
+ expires: authRecord.expires
21059
+ };
21060
+ const tempPath = `${authPath}.${process.pid}.${randomUUID4()}.tmp`;
21061
+ let tempFileDescriptor;
21062
+ let ownsTempFile = false;
21063
+ try {
21064
+ tempFileDescriptor = openSync(tempPath, "wx", 384);
21065
+ ownsTempFile = true;
21066
+ writeFileSync5(tempFileDescriptor, JSON.stringify(data, null, 2), {
21067
+ encoding: "utf8"
21068
+ });
21069
+ closeSync(tempFileDescriptor);
21070
+ tempFileDescriptor = void 0;
21071
+ renameSync4(tempPath, authPath);
21072
+ } catch (error45) {
21073
+ if (tempFileDescriptor !== void 0) {
21074
+ try {
21075
+ closeSync(tempFileDescriptor);
21076
+ } catch {
21077
+ }
21078
+ }
21079
+ if (ownsTempFile) {
21080
+ try {
21081
+ unlinkSync4(tempPath);
21082
+ } catch {
21083
+ }
21084
+ }
21085
+ throw error45;
21086
+ }
21087
+ }
21088
+
21089
+ // src/plugin/v2-fetch.ts
21090
+ function createV2FetchInterceptor(getAuthSnapshot) {
21091
+ return async function agyV2Fetch(input, init) {
21092
+ const isGL = isGenerativeLanguageRequest(input);
21093
+ const isInternal = toUrlString(input).includes("cloudcode-pa.googleapis.com");
21094
+ if (!isGL && !isInternal) {
21095
+ return (globalThis.fetch || fetch)(input, init);
21096
+ }
21097
+ let rawAuth = getAuthSnapshot ? await getAuthSnapshot() : void 0;
21098
+ if (!rawAuth) {
21099
+ rawAuth = loadStoredAuthFromJson();
21100
+ }
21101
+ if (!rawAuth || !isOAuthAuth(rawAuth)) {
21102
+ return (globalThis.fetch || fetch)(input, init);
21103
+ }
21104
+ let authRecord = resolveCachedAuth(rawAuth);
21105
+ if (accessTokenExpired(authRecord)) {
21106
+ const refreshed = await refreshAccessToken(authRecord, { auth: { set: async () => {
21107
+ } } });
21108
+ if (refreshed) {
21109
+ authRecord = refreshed;
21110
+ }
21111
+ }
21112
+ if (!authRecord.access) {
21113
+ return (globalThis.fetch || fetch)(input, init);
21114
+ }
21115
+ if (isInternal) {
21116
+ const hasAuth = getSafeHeader(init?.headers, "Authorization") !== void 0;
21117
+ if (hasAuth) {
21118
+ return (globalThis.fetch || fetch)(input, init);
21119
+ }
21120
+ const userAgent = buildAgyCliUserAgent();
21121
+ const headers = setSafeHeaders(init?.headers, {
21122
+ Authorization: `Bearer ${authRecord.access}`,
21123
+ "User-Agent": userAgent
21124
+ });
21125
+ return (globalThis.fetch || fetch)(input, {
21126
+ ...init,
21127
+ headers
21128
+ });
21129
+ }
21130
+ const requestTarget = parseGenerativeLanguageRequest(input);
21131
+ const requestUserAgentModel = requestTarget?.effectiveModel;
21132
+ let projectContext;
21133
+ try {
21134
+ projectContext = await ensureProjectContext(
21135
+ authRecord,
21136
+ { auth: { set: async () => {
21137
+ } } },
21138
+ void 0,
21139
+ requestUserAgentModel
21140
+ );
21141
+ } catch {
21142
+ projectContext = {
21143
+ effectiveProjectId: parseRefreshParts(authRecord.refresh).projectId || "antigravity",
21144
+ auth: authRecord
21145
+ };
21146
+ }
21147
+ const originalRequestedModel = parseGenerativeLanguageRequest(input)?.effectiveModel;
21148
+ let modifiedInput = input;
21149
+ if (isGL && originalRequestedModel) {
21150
+ const originalBase = originalRequestedModel.replace("google-agy/", "");
21151
+ const resolvedBase = resolveModelTier(originalBase, init);
21152
+ if (originalBase !== resolvedBase) {
21153
+ if (typeof modifiedInput === "string") {
21154
+ modifiedInput = modifiedInput.replace(`models/${originalBase}`, `models/${resolvedBase}`);
21155
+ } else if (typeof Request !== "undefined" && modifiedInput instanceof Request) {
21156
+ const newUrl = modifiedInput.url.replace(`models/${originalBase}`, `models/${resolvedBase}`);
21157
+ modifiedInput = new Request(newUrl, modifiedInput);
21158
+ }
21159
+ }
21160
+ }
21161
+ const transformed = prepareAgyRequest(
21162
+ modifiedInput,
21163
+ init,
21164
+ authRecord.access,
21165
+ projectContext.effectiveProjectId,
21166
+ void 0
21167
+ );
21168
+ const chatLogger = createChatLogger();
21169
+ if (chatLogger) {
21170
+ chatLogger.logRequest(
21171
+ toUrlString(transformed.request),
21172
+ transformed.init.method || "GET",
21173
+ transformed.init.headers,
21174
+ transformed.init.body
21175
+ );
21176
+ }
21177
+ const response = await fetchWithRetry(transformed.request, transformed.init);
21178
+ return transformAgyResponse(
21179
+ response,
21180
+ transformed.streaming,
21181
+ null,
21182
+ transformed.requestedModel,
21183
+ transformed.sessionId,
21184
+ chatLogger
21185
+ );
21186
+ };
21187
+ }
21188
+
21189
+ // src/plugin/v2-session.ts
21190
+ function createV2HttpRequestHook(state = {}) {
21191
+ return async (event) => {
21192
+ if (!event) return;
21193
+ const rawUrl = typeof event.url === "string" ? event.url : event.request?.url || "";
21194
+ const isGL = isGenerativeLanguageRequest(rawUrl);
21195
+ const isInternal = rawUrl.includes("cloudcode-pa.googleapis.com");
21196
+ if (!isGL && !isInternal) {
21197
+ return;
21198
+ }
21199
+ event.headers = event.headers || {};
21200
+ let modelName;
21201
+ let rawAuth = event.auth;
21202
+ if (rawAuth && !rawAuth.type) {
21203
+ const tokenVal = rawAuth.access || rawAuth.token;
21204
+ if (tokenVal || rawAuth.refresh) {
21205
+ rawAuth = { type: "oauth", access: tokenVal, ...rawAuth };
21206
+ }
21207
+ }
21208
+ if (!rawAuth || !isOAuthAuth(rawAuth)) {
21209
+ rawAuth = loadStoredAuthFromJson();
21210
+ }
21211
+ let authRecord = rawAuth && isOAuthAuth(rawAuth) ? resolveCachedAuth(rawAuth) : void 0;
21212
+ if (authRecord && accessTokenExpired(authRecord)) {
21213
+ const refreshed = await refreshAccessToken(authRecord, { auth: { set: async () => {
21214
+ } } });
21215
+ if (refreshed) {
21216
+ authRecord = refreshed;
21217
+ try {
21218
+ saveStoredAuthToJson(refreshed);
21219
+ } catch {
21220
+ console.warn("[Agy Auth] Refreshed credentials could not be persisted; the current request will continue.");
21221
+ }
21222
+ }
21223
+ }
21224
+ if (isGL) {
21225
+ const parsed = parseGenerativeLanguageRequest(rawUrl);
21226
+ modelName = parsed?.effectiveModel;
21227
+ if (modelName) {
21228
+ state.lastInterceptedModel = modelName;
21229
+ }
21230
+ if (typeof event.headers.delete === "function") {
21231
+ event.headers.delete("x-goog-api-key");
21232
+ event.headers.delete("api-key");
21233
+ } else {
21234
+ for (const key of Object.keys(event.headers)) {
21235
+ const lower = key.toLowerCase();
21236
+ if (lower === "x-goog-api-key" || lower === "api-key") {
21237
+ delete event.headers[key];
21238
+ }
21239
+ }
21240
+ }
21241
+ if (event.request?.headers) {
21242
+ if (typeof event.request.headers.delete === "function") {
21243
+ event.request.headers.delete("x-goog-api-key");
21244
+ event.request.headers.delete("api-key");
21245
+ } else {
21246
+ for (const key of Object.keys(event.request.headers)) {
21247
+ const lower = key.toLowerCase();
21248
+ if (lower === "x-goog-api-key" || lower === "api-key") {
21249
+ delete event.request.headers[key];
21250
+ }
21251
+ }
21252
+ }
21253
+ }
21254
+ let cleanUrl = rawUrl;
21255
+ try {
21256
+ const parsedUrl = new URL(rawUrl);
21257
+ let urlChanged = false;
21258
+ for (const param of ["key", "x-goog-api-key", "api-key"]) {
21259
+ if (parsedUrl.searchParams.has(param)) {
21260
+ parsedUrl.searchParams.delete(param);
21261
+ urlChanged = true;
21262
+ }
21263
+ }
21264
+ if (urlChanged) {
21265
+ cleanUrl = parsedUrl.toString();
21266
+ }
21267
+ } catch {
21268
+ }
21269
+ if (authRecord && authRecord.access) {
21270
+ let projectContext;
21271
+ try {
21272
+ projectContext = await ensureProjectContext(
21273
+ authRecord,
21274
+ { auth: { set: async () => {
21275
+ } } },
21276
+ void 0,
21277
+ modelName
21278
+ );
21279
+ } catch {
21280
+ projectContext = {
21281
+ effectiveProjectId: parseRefreshParts(authRecord.refresh).projectId || "antigravity",
21282
+ auth: authRecord
21283
+ };
21284
+ }
21285
+ const originalRequestedModel = modelName;
21286
+ let modifiedUrl = cleanUrl;
21287
+ if (originalRequestedModel) {
21288
+ const originalBase = originalRequestedModel.replace("google-agy/", "");
21289
+ const initHeaders = event.headers instanceof Headers ? event.headers : event.request?.headers;
21290
+ const resolvedBase = resolveModelTier(originalBase, { headers: initHeaders });
21291
+ if (originalBase !== resolvedBase) {
21292
+ modifiedUrl = modifiedUrl.replace(`models/${originalBase}`, `models/${resolvedBase}`);
21293
+ }
21294
+ }
21295
+ let bodyPayload = event.body;
21296
+ if (bodyPayload === void 0 && event.request) {
21297
+ if (typeof event.request.clone === "function") {
21298
+ try {
21299
+ bodyPayload = await event.request.clone().text();
21300
+ } catch {
21301
+ }
21302
+ } else if (event.request.body !== void 0) {
21303
+ bodyPayload = event.request.body;
21304
+ }
21305
+ }
21306
+ let preExistingUserAgent;
21307
+ if (typeof event.headers?.get === "function") {
21308
+ preExistingUserAgent = event.headers.get("user-agent") || event.headers.get("User-Agent") || void 0;
21309
+ } else if (event.headers && typeof event.headers === "object") {
21310
+ preExistingUserAgent = event.headers["user-agent"] || event.headers["User-Agent"] || void 0;
21311
+ }
21312
+ if (!preExistingUserAgent && typeof event.request?.headers?.get === "function") {
21313
+ preExistingUserAgent = event.request.headers.get("user-agent") || event.request.headers.get("User-Agent") || void 0;
21314
+ } else if (!preExistingUserAgent && event.request?.headers && typeof event.request.headers === "object") {
21315
+ preExistingUserAgent = event.request.headers["user-agent"] || event.request.headers["User-Agent"] || void 0;
21316
+ }
21317
+ const method = event.method || event.request?.method || "POST";
21318
+ const requestHeaders = event.headers || event.request?.headers;
21319
+ const transformed = prepareAgyRequest(
21320
+ modifiedUrl,
21321
+ {
21322
+ method,
21323
+ headers: requestHeaders,
21324
+ body: bodyPayload
21325
+ },
21326
+ authRecord.access,
21327
+ projectContext.effectiveProjectId
21328
+ );
21329
+ const targetUrl = toUrlString(transformed.request);
21330
+ if (typeof event.url === "string") {
21331
+ event.url = targetUrl;
21332
+ }
21333
+ if (event.request && typeof event.request === "object") {
21334
+ if (typeof Request !== "undefined" && event.request instanceof Request) {
21335
+ event.request = new Request(targetUrl, {
21336
+ method: transformed.init.method,
21337
+ headers: transformed.init.headers,
21338
+ body: transformed.init.body
21339
+ });
21340
+ } else if (typeof event.request.url === "string") {
21341
+ try {
21342
+ event.request.url = targetUrl;
21343
+ } catch {
21344
+ }
21345
+ }
21346
+ }
21347
+ const headerEntries = transformed.init.headers instanceof Headers ? Array.from(transformed.init.headers.entries()) : Object.entries(transformed.init.headers || {});
21348
+ for (const [k, v] of headerEntries) {
21349
+ const lowerK = k.toLowerCase();
21350
+ if (lowerK === "user-agent") {
21351
+ if (preExistingUserAgent) {
21352
+ continue;
21353
+ }
21354
+ if (typeof event.headers?.set === "function") {
21355
+ event.headers.set("User-Agent", v);
21356
+ } else if (event.headers) {
21357
+ event.headers["User-Agent"] = v;
21358
+ }
21359
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21360
+ event.request.headers.set("User-Agent", v);
21361
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21362
+ event.request.headers["User-Agent"] = v;
21363
+ }
21364
+ continue;
21365
+ }
21366
+ if (typeof event.headers?.set === "function") {
21367
+ event.headers.set(k, v);
21368
+ } else if (event.headers) {
21369
+ event.headers[k] = v;
21370
+ }
21371
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21372
+ event.request.headers.set(k, v);
21373
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21374
+ event.request.headers[k] = v;
21375
+ }
21376
+ }
21377
+ if (transformed.init.body !== void 0) {
21378
+ event.body = transformed.init.body;
21379
+ if (event.request && typeof event.request === "object" && !(event.request instanceof Request)) {
21380
+ event.request.body = transformed.init.body;
21381
+ }
21382
+ }
21383
+ } else {
21384
+ if (typeof event.url === "string") {
21385
+ event.url = cleanUrl;
21386
+ }
21387
+ if (event.request && typeof event.request === "object") {
21388
+ if (typeof Request !== "undefined" && event.request instanceof Request) {
21389
+ event.request = new Request(cleanUrl, event.request);
21390
+ } else if (typeof event.request.url === "string") {
21391
+ try {
21392
+ event.request.url = cleanUrl;
21393
+ } catch {
21394
+ }
21395
+ }
21396
+ }
21397
+ }
21398
+ }
21399
+ if (authRecord && authRecord.access) {
21400
+ if (typeof event.headers?.set === "function") {
21401
+ event.headers.set("Authorization", `Bearer ${authRecord.access}`);
21402
+ } else if (event.headers) {
21403
+ event.headers["Authorization"] = `Bearer ${authRecord.access}`;
21404
+ }
21405
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21406
+ event.request.headers.set("Authorization", `Bearer ${authRecord.access}`);
21407
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21408
+ event.request.headers["Authorization"] = `Bearer ${authRecord.access}`;
21409
+ }
21410
+ }
21411
+ const userAgent = buildAgyCliUserAgent(modelName);
21412
+ if (typeof event.headers?.set === "function") {
21413
+ if (!event.headers.get("User-Agent") && !event.headers.get("user-agent")) {
21414
+ event.headers.set("User-Agent", userAgent);
21415
+ }
21416
+ } else if (event.headers) {
21417
+ if (!event.headers["User-Agent"] && !event.headers["user-agent"]) {
21418
+ event.headers["User-Agent"] = userAgent;
21419
+ }
21420
+ }
21421
+ if (event.request?.headers && typeof event.request.headers.set === "function") {
21422
+ if (!event.request.headers.get("User-Agent") && !event.request.headers.get("user-agent")) {
21423
+ event.request.headers.set("User-Agent", userAgent);
21424
+ }
21425
+ } else if (event.request?.headers && typeof event.request.headers === "object") {
21426
+ if (!event.request.headers["User-Agent"] && !event.request.headers["user-agent"]) {
21427
+ event.request.headers["User-Agent"] = userAgent;
21428
+ }
21429
+ }
21430
+ };
21431
+ }
21432
+ function createV2HttpResponseHook(state = {}) {
21433
+ return async (event) => {
21434
+ if (!event || !event.response) return;
21435
+ const rawUrl = typeof event.url === "string" ? event.url : event.request?.url || "";
21436
+ const isInternal = rawUrl.includes("cloudcode-pa.googleapis.com");
21437
+ if (isInternal && event.response instanceof Response) {
21438
+ const isStreaming = rawUrl.includes(":streamGenerateCode") || event.response.headers.get("content-type")?.includes("text/event-stream");
21439
+ const parsedModel = parseGenerativeLanguageRequest(rawUrl)?.effectiveModel || state.lastInterceptedModel;
21440
+ const transformed = await transformAgyResponse(
21441
+ event.response,
21442
+ !!isStreaming,
21443
+ null,
21444
+ parsedModel,
21445
+ void 0,
21446
+ void 0
21447
+ );
21448
+ event.response = transformed;
21449
+ }
21450
+ };
21451
+ }
21452
+ function createV2RetryHook() {
21453
+ return async (event) => {
21454
+ if (!event) return;
21455
+ const response = event.response;
21456
+ if (response instanceof Response) {
21457
+ if (response.status === 429 || response.status === 503) {
21458
+ const quota = await classifyQuotaResponse(response);
21459
+ if (quota?.retryDelayMs) {
21460
+ event.retryDelayMs = quota.retryDelayMs;
21461
+ } else {
21462
+ event.retryDelayMs = await resolveRetryDelayMs(response, event.attempt || 1);
21463
+ }
21464
+ }
21465
+ } else if (event.details && Array.isArray(event.details)) {
21466
+ const retryInfo = event.details.find(
21467
+ (d) => d && d["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
21468
+ );
21469
+ if (retryInfo?.retryDelay) {
21470
+ const delayMs = retryInternals.parseRetryDelayValue(retryInfo.retryDelay);
21471
+ if (delayMs !== null) {
21472
+ event.retryDelayMs = delayMs;
21473
+ }
21474
+ }
21475
+ }
21476
+ };
21477
+ }
21478
+ function registerV2SessionHooks(ctx) {
21479
+ const state = {};
21480
+ ctx.session.hook("http.request", createV2HttpRequestHook(state), { providerID: AGY_PROVIDER_ID });
21481
+ ctx.session.hook("http.response", createV2HttpResponseHook(state), { providerID: AGY_PROVIDER_ID });
21482
+ ctx.session.hook("retry", createV2RetryHook(), { providerID: AGY_PROVIDER_ID });
21483
+ }
21484
+
21485
+ // src/plugin/v2.ts
21486
+ async function setupOpenCodeV2(ctx) {
21487
+ const resolveVariants = (modelId) => {
21488
+ const mapping = TIER_MAPPING[modelId];
21489
+ if (!mapping) return void 0;
21490
+ const variants = [];
21491
+ if (mapping.minimal !== void 0) variants.push({ id: "minimal" });
21492
+ if (mapping.low !== void 0) variants.push({ id: "low" });
21493
+ if (mapping.medium !== void 0) variants.push({ id: "medium" });
21494
+ if (mapping.high !== void 0) variants.push({ id: "high" });
21495
+ return variants.length > 0 ? variants : void 0;
21496
+ };
21497
+ const updateProviderRecord = (p) => {
21498
+ p.name = "Antigravity CLI";
21499
+ p.activation = "enabled";
21500
+ p.package = "aisdk:@ai-sdk/google";
21501
+ p.description = "Google Gemini Antigravity Code Assist OAuth provider";
21502
+ p.settings = { ...p.settings || {}, apiKey: "dummy" };
21503
+ p.integrationID = AGY_PROVIDER_ID;
21504
+ };
21505
+ const buildModelRecord = (modelId, simple, existingModel) => {
21506
+ const isClaude = modelId.startsWith("claude-");
21507
+ const isGpt = modelId.startsWith("gpt-");
21508
+ const variants = resolveVariants(modelId);
21509
+ return {
21510
+ id: modelId,
21511
+ providerID: AGY_PROVIDER_ID,
21512
+ name: simple.name,
21513
+ description: simple.description,
21514
+ family: modelId.includes("gemini") ? "gemini" : isClaude ? "claude" : isGpt ? "gpt" : "unknown",
21515
+ reasoning: simple.reasoning,
21516
+ attachment: simple.attachment,
21517
+ tool_call: simple.toolCall,
21518
+ limit: {
21519
+ context: simple.maxTokens,
21520
+ output: simple.maxOutputTokens
21521
+ },
21522
+ cost: simple.cost || { input: 0, output: 0 },
21523
+ ...variants ? { variants } : {},
21524
+ ...existingModel || {}
21525
+ };
21526
+ };
21527
+ const updateModelRecord = (m, modelId, simple) => {
21528
+ m.name = simple.name;
21529
+ m.capabilities = {
21530
+ tools: true,
21531
+ input: ["text", "image"],
21532
+ output: ["text"]
21533
+ };
21534
+ m.limit = {
21535
+ context: simple.maxTokens,
21536
+ output: simple.maxOutputTokens
21537
+ };
21538
+ m.family = "gemini";
21539
+ if (simple.cost) {
21540
+ m.cost = simple.cost;
21541
+ }
21542
+ const variants = resolveVariants(modelId);
21543
+ if (variants) {
21544
+ m.variants = variants;
21545
+ }
21546
+ };
21547
+ if (ctx.provider?.transform) {
21548
+ ctx.provider.transform(async (editor) => {
21549
+ if (!editor) return;
21550
+ if (typeof editor.update === "function") {
21551
+ editor.update(AGY_PROVIDER_ID, updateProviderRecord);
21552
+ } else if (typeof editor.set === "function") {
21553
+ const p = { id: AGY_PROVIDER_ID };
21554
+ updateProviderRecord(p);
21555
+ editor.set(AGY_PROVIDER_ID, p);
21556
+ } else if (typeof editor === "object") {
21557
+ const p = editor[AGY_PROVIDER_ID] || { id: AGY_PROVIDER_ID };
21558
+ updateProviderRecord(p);
21559
+ editor[AGY_PROVIDER_ID] = p;
21560
+ }
21561
+ });
21562
+ }
21563
+ if (ctx.model?.transform) {
21564
+ ctx.model.transform(async (editor) => {
21565
+ if (!editor) return;
21566
+ if (typeof editor.update === "function") {
21567
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21568
+ editor.update(AGY_PROVIDER_ID, modelId, (m) => updateModelRecord(m, modelId, simple));
21569
+ }
21570
+ } else if (typeof editor.set === "function") {
21571
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21572
+ const m = buildModelRecord(modelId, simple);
21573
+ editor.set(`${AGY_PROVIDER_ID}:${modelId}`, m);
21574
+ }
21575
+ } else if (typeof editor === "object") {
21576
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21577
+ const key = `${AGY_PROVIDER_ID}:${modelId}`;
21578
+ editor[key] = buildModelRecord(modelId, simple, editor[key]);
21579
+ }
21580
+ }
21581
+ });
21582
+ }
21583
+ if (ctx.catalog?.transform) {
21584
+ ctx.catalog.transform(async (editor) => {
21585
+ if (!editor) return;
21586
+ if (typeof editor?.provider?.update === "function") {
21587
+ editor.provider.update(AGY_PROVIDER_ID, updateProviderRecord);
21588
+ if (typeof editor?.model?.update === "function") {
21589
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21590
+ editor.model.update(AGY_PROVIDER_ID, modelId, (m) => updateModelRecord(m, modelId, simple));
21591
+ }
21592
+ }
21593
+ return;
21594
+ }
21595
+ const catalog = editor;
21596
+ catalog.providers = catalog.providers || {};
21597
+ catalog.providers[AGY_PROVIDER_ID] = {
21598
+ id: AGY_PROVIDER_ID,
21599
+ name: "Antigravity CLI",
21600
+ npm: "aisdk:@ai-sdk/google",
21601
+ settings: { apiKey: "dummy" },
21602
+ integrationID: AGY_PROVIDER_ID,
21603
+ models: { ...catalog.providers[AGY_PROVIDER_ID]?.models || {} },
21604
+ ...catalog.providers[AGY_PROVIDER_ID]
21605
+ };
21606
+ if (catalog.providers[AGY_PROVIDER_ID].settings) {
21607
+ catalog.providers[AGY_PROVIDER_ID].settings = {
21608
+ ...catalog.providers[AGY_PROVIDER_ID].settings,
21609
+ apiKey: "dummy"
21610
+ };
21611
+ } else {
21612
+ catalog.providers[AGY_PROVIDER_ID].settings = { apiKey: "dummy" };
21613
+ }
21614
+ catalog.providers[AGY_PROVIDER_ID].integrationID = AGY_PROVIDER_ID;
21615
+ const targetModels = catalog.providers[AGY_PROVIDER_ID].models;
21616
+ for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
21617
+ targetModels[modelId] = buildModelRecord(modelId, simple, targetModels[modelId]);
21618
+ }
21619
+ });
21620
+ }
21621
+ ctx.tool.transform(async (editor) => {
21622
+ if (!editor) return;
21623
+ const quotaTool = createAgyQuotaTool({
21624
+ client: void 0,
21625
+ getAuthResolver: () => void 0,
21626
+ getConfiguredProjectId: () => void 0,
21627
+ getUserAgentModel: () => void 0
21628
+ });
21629
+ const quotaSummaryTool = createAgyQuotaSummaryTool({
21630
+ client: void 0,
21631
+ getAuthResolver: () => void 0,
21632
+ getConfiguredProjectId: () => void 0,
21633
+ getUserAgentModel: () => void 0
21634
+ });
21635
+ if (typeof editor.add === "function") {
21636
+ editor.add({
21637
+ name: AGY_QUOTA_TOOL_NAME,
21638
+ description: quotaTool.description,
21639
+ input: {},
21640
+ execute: async (args, context) => quotaTool.execute(args, context)
21641
+ });
21642
+ editor.add({
21643
+ name: AGY_QUOTA_SUMMARY_TOOL_NAME,
21644
+ description: quotaSummaryTool.description,
21645
+ input: {},
21646
+ execute: async (args, context) => quotaSummaryTool.execute(args, context)
21647
+ });
21648
+ } else if (typeof editor.set === "function") {
21649
+ editor.set(AGY_QUOTA_TOOL_NAME, quotaTool);
21650
+ editor.set(AGY_QUOTA_SUMMARY_TOOL_NAME, quotaSummaryTool);
21651
+ } else if (editor.tools && typeof editor.tools === "object") {
21652
+ editor.tools[AGY_QUOTA_TOOL_NAME] = quotaTool;
21653
+ editor.tools[AGY_QUOTA_SUMMARY_TOOL_NAME] = quotaSummaryTool;
21654
+ } else if (typeof editor === "object") {
21655
+ editor[AGY_QUOTA_TOOL_NAME] = quotaTool;
21656
+ editor[AGY_QUOTA_SUMMARY_TOOL_NAME] = quotaSummaryTool;
21657
+ }
21658
+ });
21659
+ ctx.command.transform(async (editor) => {
21660
+ if (!editor) return;
21661
+ const commands = {
21662
+ [AGY_V2_QUOTA_COMMAND]: {
21663
+ description: "Show Agy Code Assist quota usage",
21664
+ template: AGY_V2_QUOTA_COMMAND_TEMPLATE
21665
+ },
21666
+ [AGY_V2_QUOTA_SUMMARY_COMMAND]: {
21667
+ description: "Show Agy Code Assist quota summary with weekly and 5-hour limits",
21668
+ template: AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE
21669
+ }
21670
+ };
21671
+ if (typeof editor.add === "function") {
21672
+ editor.add({
21673
+ name: AGY_V2_QUOTA_COMMAND,
21674
+ description: "Display current Antigravity quota usage",
21675
+ template: AGY_V2_QUOTA_COMMAND_TEMPLATE
21676
+ });
21677
+ editor.add({
21678
+ name: AGY_V2_QUOTA_SUMMARY_COMMAND,
21679
+ description: "Display Antigravity quota summary grouped by model family",
21680
+ template: AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE
21681
+ });
21682
+ } else if (typeof editor.set === "function") {
21683
+ editor.set(AGY_V2_QUOTA_COMMAND, commands[AGY_V2_QUOTA_COMMAND]);
21684
+ editor.set(AGY_V2_QUOTA_SUMMARY_COMMAND, commands[AGY_V2_QUOTA_SUMMARY_COMMAND]);
21685
+ } else if (editor.commands && typeof editor.commands === "object") {
21686
+ editor.commands[AGY_V2_QUOTA_COMMAND] = commands[AGY_V2_QUOTA_COMMAND];
21687
+ editor.commands[AGY_V2_QUOTA_SUMMARY_COMMAND] = commands[AGY_V2_QUOTA_SUMMARY_COMMAND];
21688
+ } else if (typeof editor === "object") {
21689
+ editor[AGY_V2_QUOTA_COMMAND] = commands[AGY_V2_QUOTA_COMMAND];
21690
+ editor[AGY_V2_QUOTA_SUMMARY_COMMAND] = commands[AGY_V2_QUOTA_SUMMARY_COMMAND];
21691
+ }
21692
+ });
21693
+ ctx.integration?.transform?.((editor) => {
21694
+ if (!editor) return;
21695
+ editor.update?.(AGY_PROVIDER_ID, (integration) => {
21696
+ integration.name = "Antigravity CLI (plugin)";
21697
+ });
21698
+ editor.method?.update?.({
21699
+ integrationID: AGY_PROVIDER_ID,
21700
+ method: {
21701
+ id: "oauth",
21702
+ type: "oauth",
21703
+ label: "Antigravity CLI (OAuth)"
21704
+ },
21705
+ authorize: async () => {
21706
+ const authorization = await authorizeAgy();
21707
+ return {
21708
+ mode: "code",
21709
+ url: authorization.url,
21710
+ instructions: "Please complete Google account authorization in your browser. After authorization, copy the full redirect URL or code and paste it below:",
21711
+ callback: async (code) => {
21712
+ const trimmed = code.trim();
21713
+ const parsed = parseOAuthCallbackInput(trimmed);
21714
+ const authCode = parsed.code || trimmed;
21715
+ if (!authCode) {
21716
+ return { type: "failed", error: "Missing authorization code in callback input" };
21717
+ }
21718
+ if (parsed.state && parsed.state !== authorization.state) {
21719
+ return { type: "failed", error: "State mismatch in callback input (possible CSRF attempt)" };
21720
+ }
21721
+ const exchangeResult = await exchangeAgyWithVerifier(authCode, authorization.verifier);
21722
+ if (exchangeResult.type !== "success") {
21723
+ return exchangeResult;
21724
+ }
21725
+ const initialRefresh = formatRefreshParts({
21726
+ refreshToken: exchangeResult.refresh
21727
+ });
21728
+ let authRecord = {
21729
+ type: "oauth",
21730
+ refresh: initialRefresh,
21731
+ access: exchangeResult.access,
21732
+ expires: exchangeResult.expires
21733
+ };
21734
+ try {
21735
+ const projectContext = await ensureProjectContext(
21736
+ authRecord,
21737
+ { auth: { set: async () => {
21738
+ } } }
21739
+ );
21740
+ authRecord = {
21741
+ ...authRecord,
21742
+ refresh: projectContext.auth.refresh
21743
+ };
21744
+ } catch {
21745
+ }
21746
+ try {
21747
+ saveStoredAuthToJson(authRecord);
21748
+ } catch {
21749
+ return {
21750
+ type: "failed",
21751
+ error: "Google authentication succeeded but AGY credentials could not be stored. Check filesystem access and retry."
21752
+ };
21753
+ }
21754
+ return {
21755
+ type: "oauth",
21756
+ methodID: "oauth",
21757
+ refresh: authRecord.refresh,
21758
+ access: authRecord.access,
21759
+ expires: authRecord.expires
21760
+ };
21761
+ }
21762
+ };
21763
+ }
21764
+ });
21765
+ });
21766
+ ctx.aisdk?.hook("sdk", async (event) => {
21767
+ if (!event) return;
21768
+ const isMatchingProvider = event.providerID === AGY_PROVIDER_ID || event.model?.providerID === AGY_PROVIDER_ID;
21769
+ if (!isMatchingProvider) return;
21770
+ event.options = event.options || {};
21771
+ event.options.apiKey = "dummy";
21772
+ event.options.fetch = createV2FetchInterceptor();
21773
+ });
21774
+ registerV2SessionHooks(ctx);
20811
21775
  }
21776
+ var v2PluginDefinition = defineOpenCodeV2Plugin({
21777
+ id: AGY_PROVIDER_ID,
21778
+ setup: setupOpenCodeV2
21779
+ });
20812
21780
 
20813
21781
  // index.ts
20814
- var index_default = {
20815
- id: "@anthonyhaussman/opencode-agy-auth",
21782
+ var dualPlugin = {
21783
+ ...v2PluginDefinition,
20816
21784
  server: AgyCLIOAuthPlugin
20817
21785
  };
21786
+ var index_default = dualPlugin;
20818
21787
  export {
20819
21788
  AgyCLIOAuthPlugin,
20820
21789
  GoogleOAuthPlugin,
20821
- index_default as default
21790
+ index_default as default,
21791
+ defineOpenCodeV2Plugin,
21792
+ setupOpenCodeV2,
21793
+ v2PluginDefinition
20822
21794
  };
20823
21795
  //# sourceMappingURL=index.js.map