@anthonyhaussman/opencode-agy-auth 1.2.3-alpha.4 → 1.2.3-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/index.d.ts +5 -6
- package/dist/index.js +20 -609
- package/dist/index.js.map +1 -1
- package/dist/src/constants.d.ts +0 -2
- package/dist/src/plugin/oauth-authorize.d.ts +0 -4
- package/dist/src/plugin/types.d.ts +0 -33
- package/dist/src/plugin.d.ts +0 -23
- package/package.json +1 -1
- package/dist/src/plugin/v2.d.ts +0 -20
package/README.md
CHANGED
|
@@ -8,7 +8,6 @@ An [OpenCode](https://opencode.ai/) authentication plugin that enables seamless
|
|
|
8
8
|
- **Dynamic Model Retrieval**: Fetches available models based on user tier and current allocations.
|
|
9
9
|
- **Quota Tracking**: Injects the `agy_quota` tool into OpenCode to check usage limits directly.
|
|
10
10
|
- **Traffic Simulation**: Maintains background heartbeat with `agy` servers.
|
|
11
|
-
- **Dual OpenCode Compatibility**: Fully supports both OpenCode v1 (>= 1.18.29) and OpenCode v2 seamlessly without breaking changes.
|
|
12
11
|
|
|
13
12
|
## Installation
|
|
14
13
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { AgyCLIOAuthPlugin, GoogleOAuthPlugin } from "./src/plugin";
|
|
2
|
-
import { setupOpenCodeV2, v2PluginDefinition } from "./src/plugin/v2";
|
|
3
|
-
import type { DualOpenCodePlugin } from "./src/plugin/types";
|
|
4
2
|
export { AgyCLIOAuthPlugin, GoogleOAuthPlugin };
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
declare const _default: {
|
|
4
|
+
id: string;
|
|
5
|
+
server: typeof AgyCLIOAuthPlugin;
|
|
6
|
+
};
|
|
7
|
+
export default _default;
|
package/dist/index.js
CHANGED
|
@@ -104,8 +104,6 @@ function updateStaticModelsWithPricing(staticModels) {
|
|
|
104
104
|
|
|
105
105
|
// src/constants.ts
|
|
106
106
|
var AGY_PROVIDER_ID = "google-agy";
|
|
107
|
-
var AGY_AUTH_URL = "https://accounts.google.com/o/oauth2/auth";
|
|
108
|
-
var AGY_TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
109
107
|
var AGY_CLIENT_ID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com";
|
|
110
108
|
var AGY_CLIENT_SECRET = "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";
|
|
111
109
|
var AGY_SCOPES = [
|
|
@@ -581,12 +579,6 @@ async function resolveQuotaResetDelay(accessToken, projectId, model, userAgentMo
|
|
|
581
579
|
return null;
|
|
582
580
|
}
|
|
583
581
|
}
|
|
584
|
-
var retryInternals = {
|
|
585
|
-
parseRetryDelayValue,
|
|
586
|
-
parseRetryDelayFromMessage,
|
|
587
|
-
findResetTimeForModel,
|
|
588
|
-
resolveQuotaResetDelay
|
|
589
|
-
};
|
|
590
582
|
|
|
591
583
|
// src/sdk/retry/helpers.ts
|
|
592
584
|
var DEFAULT_MAX_ATTEMPTS = 3;
|
|
@@ -19603,6 +19595,23 @@ function normalizeToolSchemaTypes(tools, toolMapper) {
|
|
|
19603
19595
|
obj.type = t.toUpperCase();
|
|
19604
19596
|
}
|
|
19605
19597
|
}
|
|
19598
|
+
if (Array.isArray(obj.enum)) {
|
|
19599
|
+
const sanitizedEnum = Array.from(
|
|
19600
|
+
new Set(
|
|
19601
|
+
obj.enum.filter((v) => v !== null && v !== void 0).map((v) => String(v))
|
|
19602
|
+
)
|
|
19603
|
+
);
|
|
19604
|
+
if (sanitizedEnum.length > 0) {
|
|
19605
|
+
obj.enum = sanitizedEnum;
|
|
19606
|
+
if (obj.type === "BOOLEAN") {
|
|
19607
|
+
obj.type = "STRING";
|
|
19608
|
+
}
|
|
19609
|
+
} else {
|
|
19610
|
+
delete obj.enum;
|
|
19611
|
+
}
|
|
19612
|
+
} else if ("enum" in obj) {
|
|
19613
|
+
delete obj.enum;
|
|
19614
|
+
}
|
|
19606
19615
|
if (obj.properties && typeof obj.properties === "object") {
|
|
19607
19616
|
Object.values(obj.properties).forEach(sanitizeSchema);
|
|
19608
19617
|
}
|
|
@@ -20660,612 +20669,14 @@ function toUrlString(value) {
|
|
|
20660
20669
|
return value.toString();
|
|
20661
20670
|
}
|
|
20662
20671
|
|
|
20663
|
-
// src/plugin/types.ts
|
|
20664
|
-
function defineOpenCodeV2Plugin(def) {
|
|
20665
|
-
return def;
|
|
20666
|
-
}
|
|
20667
|
-
|
|
20668
|
-
// src/plugin/v2.ts
|
|
20669
|
-
import { homedir as homedir4 } from "os";
|
|
20670
|
-
import { join as join6 } from "path";
|
|
20671
|
-
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
20672
|
-
var AGY_V2_QUOTA_COMMAND = "agy-quota";
|
|
20673
|
-
var AGY_V2_QUOTA_SUMMARY_COMMAND = "agy-quota-summary";
|
|
20674
|
-
var AGY_V2_QUOTA_COMMAND_TEMPLATE = `Retrieve Agy Code Assist quota usage for the current authenticated account.
|
|
20675
|
-
|
|
20676
|
-
Immediately call \`${AGY_QUOTA_TOOL_NAME}\` with no arguments and return its output verbatim.
|
|
20677
|
-
Do not call other tools.
|
|
20678
|
-
`;
|
|
20679
|
-
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.
|
|
20680
|
-
|
|
20681
|
-
Immediately call \`${AGY_QUOTA_SUMMARY_TOOL_NAME}\` with no arguments and return its output verbatim.
|
|
20682
|
-
Do not call other tools.
|
|
20683
|
-
`;
|
|
20684
|
-
function getSafeHeader2(headers, key) {
|
|
20685
|
-
if (!headers) {
|
|
20686
|
-
return void 0;
|
|
20687
|
-
}
|
|
20688
|
-
const targetKey = key.toLowerCase();
|
|
20689
|
-
if (typeof headers.get === "function") {
|
|
20690
|
-
try {
|
|
20691
|
-
return headers.get(targetKey) || void 0;
|
|
20692
|
-
} catch {
|
|
20693
|
-
}
|
|
20694
|
-
}
|
|
20695
|
-
if (Array.isArray(headers)) {
|
|
20696
|
-
const found = headers.find((item) => {
|
|
20697
|
-
if (Array.isArray(item) && typeof item[0] === "string") {
|
|
20698
|
-
return item[0].toLowerCase() === targetKey;
|
|
20699
|
-
}
|
|
20700
|
-
return false;
|
|
20701
|
-
});
|
|
20702
|
-
return found ? String(found[1]) : void 0;
|
|
20703
|
-
}
|
|
20704
|
-
if (typeof headers === "object") {
|
|
20705
|
-
const foundKey = Object.keys(headers).find((k) => k.toLowerCase() === targetKey);
|
|
20706
|
-
return foundKey ? headers[foundKey] !== void 0 ? String(headers[foundKey]) : void 0 : void 0;
|
|
20707
|
-
}
|
|
20708
|
-
return void 0;
|
|
20709
|
-
}
|
|
20710
|
-
function setSafeHeaders2(initHeaders, newHeaders) {
|
|
20711
|
-
if (typeof globalThis.Headers !== "undefined") {
|
|
20712
|
-
const headers = new globalThis.Headers(initHeaders ?? {});
|
|
20713
|
-
for (const [k, v] of Object.entries(newHeaders)) {
|
|
20714
|
-
headers.set(k, v);
|
|
20715
|
-
}
|
|
20716
|
-
return headers;
|
|
20717
|
-
}
|
|
20718
|
-
if (Array.isArray(initHeaders)) {
|
|
20719
|
-
const nextHeaders2 = [...initHeaders];
|
|
20720
|
-
for (const [k, v] of Object.entries(newHeaders)) {
|
|
20721
|
-
const idx = nextHeaders2.findIndex((item) => Array.isArray(item) && typeof item[0] === "string" && item[0].toLowerCase() === k.toLowerCase());
|
|
20722
|
-
if (idx !== -1) {
|
|
20723
|
-
nextHeaders2[idx] = [k, v];
|
|
20724
|
-
} else {
|
|
20725
|
-
nextHeaders2.push([k, v]);
|
|
20726
|
-
}
|
|
20727
|
-
}
|
|
20728
|
-
return nextHeaders2;
|
|
20729
|
-
}
|
|
20730
|
-
const nextHeaders = {};
|
|
20731
|
-
if (initHeaders && typeof initHeaders === "object") {
|
|
20732
|
-
for (const [k, v] of Object.entries(initHeaders)) {
|
|
20733
|
-
nextHeaders[k] = String(v);
|
|
20734
|
-
}
|
|
20735
|
-
}
|
|
20736
|
-
for (const [k, v] of Object.entries(newHeaders)) {
|
|
20737
|
-
const existingKey = Object.keys(nextHeaders).find((key) => key.toLowerCase() === k.toLowerCase());
|
|
20738
|
-
if (existingKey) {
|
|
20739
|
-
nextHeaders[existingKey] = v;
|
|
20740
|
-
} else {
|
|
20741
|
-
nextHeaders[k] = v;
|
|
20742
|
-
}
|
|
20743
|
-
}
|
|
20744
|
-
return nextHeaders;
|
|
20745
|
-
}
|
|
20746
|
-
function toUrlString2(value) {
|
|
20747
|
-
if (typeof value === "string") {
|
|
20748
|
-
return value;
|
|
20749
|
-
}
|
|
20750
|
-
const candidate = value.url;
|
|
20751
|
-
if (candidate) {
|
|
20752
|
-
return candidate;
|
|
20753
|
-
}
|
|
20754
|
-
return value.toString();
|
|
20755
|
-
}
|
|
20756
|
-
function resolveModelTier2(baseModelId, init) {
|
|
20757
|
-
const parts = baseModelId.split("@");
|
|
20758
|
-
const base = parts[0] || "";
|
|
20759
|
-
const suffixTier = parts[1]?.toLowerCase();
|
|
20760
|
-
const mapping = TIER_MAPPING[base];
|
|
20761
|
-
if (!mapping) {
|
|
20762
|
-
return baseModelId;
|
|
20763
|
-
}
|
|
20764
|
-
const headerTier = getSafeHeader2(init?.headers, "x-agy-tier")?.toLowerCase() || null;
|
|
20765
|
-
const requestedTier = headerTier || suffixTier;
|
|
20766
|
-
if (requestedTier && Object.prototype.hasOwnProperty.call(mapping, requestedTier)) {
|
|
20767
|
-
return mapping[requestedTier] || baseModelId;
|
|
20768
|
-
}
|
|
20769
|
-
return mapping["medium"] ?? mapping["high"];
|
|
20770
|
-
}
|
|
20771
|
-
function loadStoredAuthFromJson() {
|
|
20772
|
-
const authPath = join6(homedir4(), ".local", "share", "opencode", "auth.json");
|
|
20773
|
-
try {
|
|
20774
|
-
if (existsSync6(authPath)) {
|
|
20775
|
-
const content = readFileSync5(authPath, "utf8");
|
|
20776
|
-
const data = JSON.parse(content);
|
|
20777
|
-
return data?.[AGY_PROVIDER_ID];
|
|
20778
|
-
}
|
|
20779
|
-
} catch {
|
|
20780
|
-
}
|
|
20781
|
-
return void 0;
|
|
20782
|
-
}
|
|
20783
|
-
function createV2FetchInterceptor(getAuthSnapshot) {
|
|
20784
|
-
return async function agyV2Fetch(input, init) {
|
|
20785
|
-
const isGL = isGenerativeLanguageRequest(input);
|
|
20786
|
-
const isInternal = toUrlString2(input).includes("cloudcode-pa.googleapis.com");
|
|
20787
|
-
if (!isGL && !isInternal) {
|
|
20788
|
-
return agyFetch(input, init);
|
|
20789
|
-
}
|
|
20790
|
-
let rawAuth = getAuthSnapshot ? await getAuthSnapshot() : void 0;
|
|
20791
|
-
if (!rawAuth) {
|
|
20792
|
-
rawAuth = loadStoredAuthFromJson();
|
|
20793
|
-
}
|
|
20794
|
-
if (!rawAuth || !isOAuthAuth(rawAuth)) {
|
|
20795
|
-
return agyFetch(input, init);
|
|
20796
|
-
}
|
|
20797
|
-
let authRecord = resolveCachedAuth(rawAuth);
|
|
20798
|
-
if (accessTokenExpired(authRecord)) {
|
|
20799
|
-
const refreshed = await refreshAccessToken(authRecord, { auth: { set: async () => {
|
|
20800
|
-
} } });
|
|
20801
|
-
if (refreshed) {
|
|
20802
|
-
authRecord = refreshed;
|
|
20803
|
-
}
|
|
20804
|
-
}
|
|
20805
|
-
if (!authRecord.access) {
|
|
20806
|
-
return agyFetch(input, init);
|
|
20807
|
-
}
|
|
20808
|
-
if (isInternal) {
|
|
20809
|
-
const hasAuth = getSafeHeader2(init?.headers, "Authorization") !== void 0;
|
|
20810
|
-
if (hasAuth) {
|
|
20811
|
-
return agyFetch(input, init);
|
|
20812
|
-
}
|
|
20813
|
-
const userAgent = buildAgyCliUserAgent();
|
|
20814
|
-
const headers = setSafeHeaders2(init?.headers, {
|
|
20815
|
-
Authorization: `Bearer ${authRecord.access}`,
|
|
20816
|
-
"User-Agent": userAgent
|
|
20817
|
-
});
|
|
20818
|
-
return agyFetch(input, {
|
|
20819
|
-
...init,
|
|
20820
|
-
headers
|
|
20821
|
-
});
|
|
20822
|
-
}
|
|
20823
|
-
const requestTarget = parseGenerativeLanguageRequest(input);
|
|
20824
|
-
const requestUserAgentModel = requestTarget?.effectiveModel;
|
|
20825
|
-
let projectContext;
|
|
20826
|
-
try {
|
|
20827
|
-
projectContext = await ensureProjectContext(
|
|
20828
|
-
authRecord,
|
|
20829
|
-
{ auth: { set: async () => {
|
|
20830
|
-
} } },
|
|
20831
|
-
void 0,
|
|
20832
|
-
requestUserAgentModel
|
|
20833
|
-
);
|
|
20834
|
-
} catch {
|
|
20835
|
-
projectContext = {
|
|
20836
|
-
effectiveProjectId: parseRefreshParts(authRecord.refresh).projectId || "antigravity",
|
|
20837
|
-
auth: authRecord
|
|
20838
|
-
};
|
|
20839
|
-
}
|
|
20840
|
-
const originalRequestedModel = parseGenerativeLanguageRequest(input)?.effectiveModel;
|
|
20841
|
-
let modifiedInput = input;
|
|
20842
|
-
if (isGL && originalRequestedModel) {
|
|
20843
|
-
const originalBase = originalRequestedModel.replace("google-agy/", "");
|
|
20844
|
-
const resolvedBase = resolveModelTier2(originalBase, init);
|
|
20845
|
-
if (originalBase !== resolvedBase) {
|
|
20846
|
-
if (typeof modifiedInput === "string") {
|
|
20847
|
-
modifiedInput = modifiedInput.replace(`models/${originalBase}`, `models/${resolvedBase}`);
|
|
20848
|
-
} else if (typeof Request !== "undefined" && modifiedInput instanceof Request) {
|
|
20849
|
-
const newUrl = modifiedInput.url.replace(`models/${originalBase}`, `models/${resolvedBase}`);
|
|
20850
|
-
modifiedInput = new Request(newUrl, modifiedInput);
|
|
20851
|
-
}
|
|
20852
|
-
}
|
|
20853
|
-
}
|
|
20854
|
-
const transformed = prepareAgyRequest(
|
|
20855
|
-
modifiedInput,
|
|
20856
|
-
init,
|
|
20857
|
-
authRecord.access,
|
|
20858
|
-
projectContext.effectiveProjectId,
|
|
20859
|
-
void 0
|
|
20860
|
-
);
|
|
20861
|
-
const chatLogger = createChatLogger();
|
|
20862
|
-
if (chatLogger) {
|
|
20863
|
-
chatLogger.logRequest(
|
|
20864
|
-
toUrlString2(transformed.request),
|
|
20865
|
-
transformed.init.method || "GET",
|
|
20866
|
-
transformed.init.headers,
|
|
20867
|
-
transformed.init.body
|
|
20868
|
-
);
|
|
20869
|
-
}
|
|
20870
|
-
const response = await fetchWithRetry(transformed.request, transformed.init);
|
|
20871
|
-
return transformAgyResponse(
|
|
20872
|
-
response,
|
|
20873
|
-
transformed.streaming,
|
|
20874
|
-
null,
|
|
20875
|
-
transformed.requestedModel,
|
|
20876
|
-
transformed.sessionId,
|
|
20877
|
-
chatLogger
|
|
20878
|
-
);
|
|
20879
|
-
};
|
|
20880
|
-
}
|
|
20881
|
-
async function setupOpenCodeV2(ctx) {
|
|
20882
|
-
ctx.catalog.transform(async (editor) => {
|
|
20883
|
-
if (!editor) return;
|
|
20884
|
-
const resolveVariants = (modelId) => {
|
|
20885
|
-
const mapping = TIER_MAPPING[modelId];
|
|
20886
|
-
if (!mapping) return void 0;
|
|
20887
|
-
const variants = [];
|
|
20888
|
-
if (mapping.minimal !== void 0) variants.push({ id: "minimal" });
|
|
20889
|
-
if (mapping.low !== void 0) variants.push({ id: "low" });
|
|
20890
|
-
if (mapping.medium !== void 0) variants.push({ id: "medium" });
|
|
20891
|
-
if (mapping.high !== void 0) variants.push({ id: "high" });
|
|
20892
|
-
return variants.length > 0 ? variants : void 0;
|
|
20893
|
-
};
|
|
20894
|
-
if (typeof editor?.provider?.update === "function") {
|
|
20895
|
-
editor.provider.update(AGY_PROVIDER_ID, (p) => {
|
|
20896
|
-
p.name = "Antigravity CLI";
|
|
20897
|
-
p.activation = "enabled";
|
|
20898
|
-
p.package = "aisdk:@ai-sdk/google";
|
|
20899
|
-
p.description = "Google Gemini Antigravity Code Assist OAuth provider";
|
|
20900
|
-
p.settings = { ...p.settings || {}, apiKey: "dummy" };
|
|
20901
|
-
p.integrationID = AGY_PROVIDER_ID;
|
|
20902
|
-
});
|
|
20903
|
-
if (typeof editor?.model?.update === "function") {
|
|
20904
|
-
for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
|
|
20905
|
-
editor.model.update(AGY_PROVIDER_ID, modelId, (m) => {
|
|
20906
|
-
m.name = simple.name;
|
|
20907
|
-
m.capabilities = {
|
|
20908
|
-
tools: true,
|
|
20909
|
-
input: ["text", "image"],
|
|
20910
|
-
output: ["text"]
|
|
20911
|
-
};
|
|
20912
|
-
m.limit = {
|
|
20913
|
-
context: simple.maxTokens,
|
|
20914
|
-
output: simple.maxOutputTokens
|
|
20915
|
-
};
|
|
20916
|
-
m.family = "gemini";
|
|
20917
|
-
if (simple.cost) {
|
|
20918
|
-
m.cost = simple.cost;
|
|
20919
|
-
}
|
|
20920
|
-
const variants = resolveVariants(modelId);
|
|
20921
|
-
if (variants) {
|
|
20922
|
-
m.variants = variants;
|
|
20923
|
-
}
|
|
20924
|
-
});
|
|
20925
|
-
}
|
|
20926
|
-
}
|
|
20927
|
-
return;
|
|
20928
|
-
}
|
|
20929
|
-
const catalog = editor;
|
|
20930
|
-
catalog.providers = catalog.providers || {};
|
|
20931
|
-
catalog.providers[AGY_PROVIDER_ID] = {
|
|
20932
|
-
id: AGY_PROVIDER_ID,
|
|
20933
|
-
name: "Antigravity CLI",
|
|
20934
|
-
npm: "aisdk:@ai-sdk/google",
|
|
20935
|
-
settings: { apiKey: "dummy" },
|
|
20936
|
-
integrationID: AGY_PROVIDER_ID,
|
|
20937
|
-
models: { ...catalog.providers[AGY_PROVIDER_ID]?.models || {} },
|
|
20938
|
-
...catalog.providers[AGY_PROVIDER_ID]
|
|
20939
|
-
};
|
|
20940
|
-
if (catalog.providers[AGY_PROVIDER_ID].settings) {
|
|
20941
|
-
catalog.providers[AGY_PROVIDER_ID].settings = {
|
|
20942
|
-
...catalog.providers[AGY_PROVIDER_ID].settings,
|
|
20943
|
-
apiKey: "dummy"
|
|
20944
|
-
};
|
|
20945
|
-
} else {
|
|
20946
|
-
catalog.providers[AGY_PROVIDER_ID].settings = { apiKey: "dummy" };
|
|
20947
|
-
}
|
|
20948
|
-
catalog.providers[AGY_PROVIDER_ID].integrationID = AGY_PROVIDER_ID;
|
|
20949
|
-
const targetModels = catalog.providers[AGY_PROVIDER_ID].models;
|
|
20950
|
-
for (const [modelId, simple] of Object.entries(STATIC_MODELS_SIMPLE)) {
|
|
20951
|
-
const isClaude = modelId.startsWith("claude-");
|
|
20952
|
-
const isGpt = modelId.startsWith("gpt-");
|
|
20953
|
-
const variants = resolveVariants(modelId);
|
|
20954
|
-
targetModels[modelId] = {
|
|
20955
|
-
id: modelId,
|
|
20956
|
-
providerID: AGY_PROVIDER_ID,
|
|
20957
|
-
name: simple.name,
|
|
20958
|
-
description: simple.description,
|
|
20959
|
-
family: modelId.includes("gemini") ? "gemini" : isClaude ? "claude" : isGpt ? "gpt" : "unknown",
|
|
20960
|
-
reasoning: simple.reasoning,
|
|
20961
|
-
attachment: simple.attachment,
|
|
20962
|
-
tool_call: simple.toolCall,
|
|
20963
|
-
limit: {
|
|
20964
|
-
context: simple.maxTokens,
|
|
20965
|
-
output: simple.maxOutputTokens
|
|
20966
|
-
},
|
|
20967
|
-
cost: simple.cost || { input: 0, output: 0 },
|
|
20968
|
-
...variants ? { variants } : {},
|
|
20969
|
-
...targetModels[modelId] || {}
|
|
20970
|
-
};
|
|
20971
|
-
}
|
|
20972
|
-
});
|
|
20973
|
-
ctx.tool.transform(async (editor) => {
|
|
20974
|
-
if (!editor) return;
|
|
20975
|
-
const quotaTool = createAgyQuotaTool({
|
|
20976
|
-
client: void 0,
|
|
20977
|
-
getAuthResolver: () => void 0,
|
|
20978
|
-
getConfiguredProjectId: () => void 0,
|
|
20979
|
-
getUserAgentModel: () => void 0
|
|
20980
|
-
});
|
|
20981
|
-
const quotaSummaryTool = createAgyQuotaSummaryTool({
|
|
20982
|
-
client: void 0,
|
|
20983
|
-
getAuthResolver: () => void 0,
|
|
20984
|
-
getConfiguredProjectId: () => void 0,
|
|
20985
|
-
getUserAgentModel: () => void 0
|
|
20986
|
-
});
|
|
20987
|
-
if (typeof editor.add === "function") {
|
|
20988
|
-
editor.add({
|
|
20989
|
-
name: AGY_QUOTA_TOOL_NAME,
|
|
20990
|
-
description: quotaTool.description,
|
|
20991
|
-
input: {},
|
|
20992
|
-
execute: async (args, context) => quotaTool.execute(args, context)
|
|
20993
|
-
});
|
|
20994
|
-
editor.add({
|
|
20995
|
-
name: AGY_QUOTA_SUMMARY_TOOL_NAME,
|
|
20996
|
-
description: quotaSummaryTool.description,
|
|
20997
|
-
input: {},
|
|
20998
|
-
execute: async (args, context) => quotaSummaryTool.execute(args, context)
|
|
20999
|
-
});
|
|
21000
|
-
} else if (typeof editor.set === "function") {
|
|
21001
|
-
editor.set(AGY_QUOTA_TOOL_NAME, quotaTool);
|
|
21002
|
-
editor.set(AGY_QUOTA_SUMMARY_TOOL_NAME, quotaSummaryTool);
|
|
21003
|
-
} else if (editor.tools && typeof editor.tools === "object") {
|
|
21004
|
-
editor.tools[AGY_QUOTA_TOOL_NAME] = quotaTool;
|
|
21005
|
-
editor.tools[AGY_QUOTA_SUMMARY_TOOL_NAME] = quotaSummaryTool;
|
|
21006
|
-
} else if (typeof editor === "object") {
|
|
21007
|
-
editor[AGY_QUOTA_TOOL_NAME] = quotaTool;
|
|
21008
|
-
editor[AGY_QUOTA_SUMMARY_TOOL_NAME] = quotaSummaryTool;
|
|
21009
|
-
}
|
|
21010
|
-
});
|
|
21011
|
-
ctx.command.transform(async (editor) => {
|
|
21012
|
-
if (!editor) return;
|
|
21013
|
-
const commands = {
|
|
21014
|
-
[AGY_V2_QUOTA_COMMAND]: {
|
|
21015
|
-
description: "Show Agy Code Assist quota usage",
|
|
21016
|
-
template: AGY_V2_QUOTA_COMMAND_TEMPLATE
|
|
21017
|
-
},
|
|
21018
|
-
[AGY_V2_QUOTA_SUMMARY_COMMAND]: {
|
|
21019
|
-
description: "Show Agy Code Assist quota summary with weekly and 5-hour limits",
|
|
21020
|
-
template: AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE
|
|
21021
|
-
}
|
|
21022
|
-
};
|
|
21023
|
-
if (typeof editor.add === "function") {
|
|
21024
|
-
editor.add({
|
|
21025
|
-
name: AGY_V2_QUOTA_COMMAND,
|
|
21026
|
-
description: "Display current Antigravity quota usage",
|
|
21027
|
-
template: AGY_V2_QUOTA_COMMAND_TEMPLATE
|
|
21028
|
-
});
|
|
21029
|
-
editor.add({
|
|
21030
|
-
name: AGY_V2_QUOTA_SUMMARY_COMMAND,
|
|
21031
|
-
description: "Display Antigravity quota summary grouped by model family",
|
|
21032
|
-
template: AGY_V2_QUOTA_SUMMARY_COMMAND_TEMPLATE
|
|
21033
|
-
});
|
|
21034
|
-
} else if (typeof editor.set === "function") {
|
|
21035
|
-
editor.set(AGY_V2_QUOTA_COMMAND, commands[AGY_V2_QUOTA_COMMAND]);
|
|
21036
|
-
editor.set(AGY_V2_QUOTA_SUMMARY_COMMAND, commands[AGY_V2_QUOTA_SUMMARY_COMMAND]);
|
|
21037
|
-
} else if (editor.commands && typeof editor.commands === "object") {
|
|
21038
|
-
editor.commands[AGY_V2_QUOTA_COMMAND] = commands[AGY_V2_QUOTA_COMMAND];
|
|
21039
|
-
editor.commands[AGY_V2_QUOTA_SUMMARY_COMMAND] = commands[AGY_V2_QUOTA_SUMMARY_COMMAND];
|
|
21040
|
-
} else if (typeof editor === "object") {
|
|
21041
|
-
editor[AGY_V2_QUOTA_COMMAND] = commands[AGY_V2_QUOTA_COMMAND];
|
|
21042
|
-
editor[AGY_V2_QUOTA_SUMMARY_COMMAND] = commands[AGY_V2_QUOTA_SUMMARY_COMMAND];
|
|
21043
|
-
}
|
|
21044
|
-
});
|
|
21045
|
-
ctx.integration?.transform?.((editor) => {
|
|
21046
|
-
if (!editor) return;
|
|
21047
|
-
editor.update?.(AGY_PROVIDER_ID, (integration) => {
|
|
21048
|
-
integration.name = "Antigravity CLI (plugin)";
|
|
21049
|
-
});
|
|
21050
|
-
editor.method?.update?.({
|
|
21051
|
-
integrationID: AGY_PROVIDER_ID,
|
|
21052
|
-
method: {
|
|
21053
|
-
id: "oauth",
|
|
21054
|
-
type: "oauth",
|
|
21055
|
-
label: "Antigravity CLI (OAuth)"
|
|
21056
|
-
},
|
|
21057
|
-
authorize: async () => {
|
|
21058
|
-
const authUrl = new URL(AGY_AUTH_URL);
|
|
21059
|
-
authUrl.searchParams.set("client_id", AGY_CLIENT_ID);
|
|
21060
|
-
authUrl.searchParams.set("response_type", "code");
|
|
21061
|
-
authUrl.searchParams.set("redirect_uri", "http://localhost");
|
|
21062
|
-
authUrl.searchParams.set("scope", AGY_SCOPES.join(" "));
|
|
21063
|
-
authUrl.searchParams.set("access_type", "offline");
|
|
21064
|
-
authUrl.searchParams.set("prompt", "consent");
|
|
21065
|
-
return {
|
|
21066
|
-
mode: "code",
|
|
21067
|
-
url: authUrl.toString(),
|
|
21068
|
-
instructions: "Please complete Google account authorization in your browser. After authorization, copy the full redirect URL or code and paste it below:",
|
|
21069
|
-
callback: async (code) => {
|
|
21070
|
-
const trimmed = code.trim();
|
|
21071
|
-
const parsed = parseOAuthCallbackInput(trimmed);
|
|
21072
|
-
const authCode = parsed.code || trimmed;
|
|
21073
|
-
if (!authCode) {
|
|
21074
|
-
return { type: "failed", error: "Missing authorization code in callback input" };
|
|
21075
|
-
}
|
|
21076
|
-
const tokenResponse = await agyFetch(AGY_TOKEN_URL, {
|
|
21077
|
-
method: "POST",
|
|
21078
|
-
headers: {
|
|
21079
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
21080
|
-
},
|
|
21081
|
-
body: new URLSearchParams({
|
|
21082
|
-
client_id: AGY_CLIENT_ID,
|
|
21083
|
-
client_secret: AGY_CLIENT_SECRET,
|
|
21084
|
-
code: authCode,
|
|
21085
|
-
grant_type: "authorization_code",
|
|
21086
|
-
redirect_uri: "http://localhost"
|
|
21087
|
-
})
|
|
21088
|
-
});
|
|
21089
|
-
if (!tokenResponse.ok) {
|
|
21090
|
-
const errorText = await tokenResponse.text();
|
|
21091
|
-
return { type: "failed", error: errorText };
|
|
21092
|
-
}
|
|
21093
|
-
const tokenPayload = await tokenResponse.json();
|
|
21094
|
-
if (!tokenPayload.refresh_token) {
|
|
21095
|
-
return { type: "failed", error: "Missing refresh token in response" };
|
|
21096
|
-
}
|
|
21097
|
-
const initialRefresh = formatRefreshParts({
|
|
21098
|
-
refreshToken: tokenPayload.refresh_token
|
|
21099
|
-
});
|
|
21100
|
-
let authRecord = {
|
|
21101
|
-
type: "oauth",
|
|
21102
|
-
refresh: initialRefresh,
|
|
21103
|
-
access: tokenPayload.access_token,
|
|
21104
|
-
expires: Date.now() + tokenPayload.expires_in * 1e3
|
|
21105
|
-
};
|
|
21106
|
-
try {
|
|
21107
|
-
const projectContext = await ensureProjectContext(
|
|
21108
|
-
authRecord,
|
|
21109
|
-
{ auth: { set: async () => {
|
|
21110
|
-
} } }
|
|
21111
|
-
);
|
|
21112
|
-
authRecord = {
|
|
21113
|
-
...authRecord,
|
|
21114
|
-
refresh: projectContext.auth.refresh
|
|
21115
|
-
};
|
|
21116
|
-
} catch {
|
|
21117
|
-
}
|
|
21118
|
-
return {
|
|
21119
|
-
type: "success",
|
|
21120
|
-
refresh: authRecord.refresh,
|
|
21121
|
-
access: authRecord.access,
|
|
21122
|
-
expires: authRecord.expires
|
|
21123
|
-
};
|
|
21124
|
-
}
|
|
21125
|
-
};
|
|
21126
|
-
}
|
|
21127
|
-
});
|
|
21128
|
-
});
|
|
21129
|
-
ctx.aisdk?.hook("sdk", async (event) => {
|
|
21130
|
-
if (!event) return;
|
|
21131
|
-
const isMatchingProvider = event.providerID === AGY_PROVIDER_ID || event.model?.providerID === AGY_PROVIDER_ID;
|
|
21132
|
-
if (!isMatchingProvider) return;
|
|
21133
|
-
event.options = event.options || {};
|
|
21134
|
-
event.options.apiKey = "dummy";
|
|
21135
|
-
event.options.fetch = createV2FetchInterceptor();
|
|
21136
|
-
});
|
|
21137
|
-
ctx.session.hook(
|
|
21138
|
-
"http.request",
|
|
21139
|
-
async (event) => {
|
|
21140
|
-
if (!event) return;
|
|
21141
|
-
const rawUrl = typeof event.url === "string" ? event.url : event.request?.url || "";
|
|
21142
|
-
const isGL = isGenerativeLanguageRequest(rawUrl);
|
|
21143
|
-
const isInternal = rawUrl.includes("cloudcode-pa.googleapis.com");
|
|
21144
|
-
if (!isGL && !isInternal) {
|
|
21145
|
-
return;
|
|
21146
|
-
}
|
|
21147
|
-
event.headers = event.headers || {};
|
|
21148
|
-
let modelName;
|
|
21149
|
-
if (isGL) {
|
|
21150
|
-
const parsed = parseGenerativeLanguageRequest(rawUrl);
|
|
21151
|
-
modelName = parsed?.effectiveModel;
|
|
21152
|
-
if (typeof event.headers.delete === "function") {
|
|
21153
|
-
event.headers.delete("x-goog-api-key");
|
|
21154
|
-
event.headers.delete("api-key");
|
|
21155
|
-
} else {
|
|
21156
|
-
for (const key of Object.keys(event.headers)) {
|
|
21157
|
-
const lower = key.toLowerCase();
|
|
21158
|
-
if (lower === "x-goog-api-key" || lower === "api-key") {
|
|
21159
|
-
delete event.headers[key];
|
|
21160
|
-
}
|
|
21161
|
-
}
|
|
21162
|
-
}
|
|
21163
|
-
try {
|
|
21164
|
-
const parsedUrl = new URL(rawUrl);
|
|
21165
|
-
let urlChanged = false;
|
|
21166
|
-
for (const param of ["key", "x-goog-api-key", "api-key"]) {
|
|
21167
|
-
if (parsedUrl.searchParams.has(param)) {
|
|
21168
|
-
parsedUrl.searchParams.delete(param);
|
|
21169
|
-
urlChanged = true;
|
|
21170
|
-
}
|
|
21171
|
-
}
|
|
21172
|
-
if (urlChanged) {
|
|
21173
|
-
const cleanedUrl = parsedUrl.toString();
|
|
21174
|
-
if (typeof event.url === "string") {
|
|
21175
|
-
event.url = cleanedUrl;
|
|
21176
|
-
}
|
|
21177
|
-
if (event.request && typeof event.request === "object") {
|
|
21178
|
-
if (typeof event.request.url === "string") {
|
|
21179
|
-
event.request.url = cleanedUrl;
|
|
21180
|
-
}
|
|
21181
|
-
}
|
|
21182
|
-
}
|
|
21183
|
-
} catch {
|
|
21184
|
-
}
|
|
21185
|
-
const hasAuth = typeof event.headers.get === "function" ? !!event.headers.get("Authorization") : Object.keys(event.headers).some((k) => k.toLowerCase() === "authorization");
|
|
21186
|
-
if (!hasAuth) {
|
|
21187
|
-
let token;
|
|
21188
|
-
if (typeof event.auth?.access === "string" && event.auth.access) {
|
|
21189
|
-
token = event.auth.access;
|
|
21190
|
-
} else if (typeof event.auth?.token === "string" && event.auth.token) {
|
|
21191
|
-
token = event.auth.token;
|
|
21192
|
-
}
|
|
21193
|
-
if (typeof event.headers.set === "function") {
|
|
21194
|
-
event.headers.set("Authorization", `Bearer ${token || "dummy"}`);
|
|
21195
|
-
} else {
|
|
21196
|
-
event.headers["Authorization"] = `Bearer ${token || "dummy"}`;
|
|
21197
|
-
}
|
|
21198
|
-
}
|
|
21199
|
-
}
|
|
21200
|
-
const userAgent = buildAgyCliUserAgent(modelName);
|
|
21201
|
-
if (typeof event.headers.set === "function") {
|
|
21202
|
-
if (!event.headers.get("User-Agent")) {
|
|
21203
|
-
event.headers.set("User-Agent", userAgent);
|
|
21204
|
-
}
|
|
21205
|
-
} else {
|
|
21206
|
-
if (!event.headers["User-Agent"] && !event.headers["user-agent"]) {
|
|
21207
|
-
event.headers["User-Agent"] = userAgent;
|
|
21208
|
-
}
|
|
21209
|
-
}
|
|
21210
|
-
},
|
|
21211
|
-
{ providerID: AGY_PROVIDER_ID }
|
|
21212
|
-
);
|
|
21213
|
-
ctx.session.hook(
|
|
21214
|
-
"http.response",
|
|
21215
|
-
async (event) => {
|
|
21216
|
-
if (!event) return;
|
|
21217
|
-
if (event.response?.status === 429) {
|
|
21218
|
-
return;
|
|
21219
|
-
}
|
|
21220
|
-
},
|
|
21221
|
-
{ providerID: AGY_PROVIDER_ID }
|
|
21222
|
-
);
|
|
21223
|
-
ctx.session.hook(
|
|
21224
|
-
"retry",
|
|
21225
|
-
async (event) => {
|
|
21226
|
-
if (!event) return;
|
|
21227
|
-
const response = event.response;
|
|
21228
|
-
if (response instanceof Response) {
|
|
21229
|
-
if (response.status === 429 || response.status === 503) {
|
|
21230
|
-
const quota = await classifyQuotaResponse(response);
|
|
21231
|
-
if (quota?.retryDelayMs) {
|
|
21232
|
-
event.retryDelayMs = quota.retryDelayMs;
|
|
21233
|
-
} else {
|
|
21234
|
-
event.retryDelayMs = await resolveRetryDelayMs(response, event.attempt || 1);
|
|
21235
|
-
}
|
|
21236
|
-
}
|
|
21237
|
-
} else if (event.details && Array.isArray(event.details)) {
|
|
21238
|
-
const retryInfo = event.details.find(
|
|
21239
|
-
(d) => d && d["@type"] === "type.googleapis.com/google.rpc.RetryInfo"
|
|
21240
|
-
);
|
|
21241
|
-
if (retryInfo?.retryDelay) {
|
|
21242
|
-
const delayMs = retryInternals.parseRetryDelayValue(retryInfo.retryDelay);
|
|
21243
|
-
if (delayMs !== null) {
|
|
21244
|
-
event.retryDelayMs = delayMs;
|
|
21245
|
-
}
|
|
21246
|
-
}
|
|
21247
|
-
}
|
|
21248
|
-
},
|
|
21249
|
-
{ providerID: AGY_PROVIDER_ID }
|
|
21250
|
-
);
|
|
21251
|
-
}
|
|
21252
|
-
var v2PluginDefinition = defineOpenCodeV2Plugin({
|
|
21253
|
-
id: AGY_PROVIDER_ID,
|
|
21254
|
-
setup: setupOpenCodeV2
|
|
21255
|
-
});
|
|
21256
|
-
|
|
21257
20672
|
// index.ts
|
|
21258
|
-
var
|
|
21259
|
-
|
|
20673
|
+
var index_default = {
|
|
20674
|
+
id: "@anthonyhaussman/opencode-agy-auth",
|
|
21260
20675
|
server: AgyCLIOAuthPlugin
|
|
21261
20676
|
};
|
|
21262
|
-
var index_default = dualPlugin;
|
|
21263
20677
|
export {
|
|
21264
20678
|
AgyCLIOAuthPlugin,
|
|
21265
20679
|
GoogleOAuthPlugin,
|
|
21266
|
-
index_default as default
|
|
21267
|
-
defineOpenCodeV2Plugin,
|
|
21268
|
-
setupOpenCodeV2,
|
|
21269
|
-
v2PluginDefinition
|
|
20680
|
+
index_default as default
|
|
21270
20681
|
};
|
|
21271
20682
|
//# sourceMappingURL=index.js.map
|