@kontextmind/kxm 0.7.15 → 0.7.16
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/.claude-plugin/marketplace.json +1 -1
- package/docs/configuration.md +1 -2
- package/docs/operator-pi-packages.md +5 -2
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +4 -0
- package/plugins/kxm/dist/core.js +4 -0
- package/plugins/kxm/dist/extension.js +3066 -2
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/runtime.js +4 -0
- package/plugins/kxm/dist/server.js +4 -0
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/src/extension.ts +9 -0
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/providers/antigravity/LICENSE +21 -0
- package/plugins/kxm/src/providers/antigravity/README.md +19 -0
- package/plugins/kxm/src/providers/antigravity/auth/index.ts +17 -0
- package/plugins/kxm/src/providers/antigravity/auth/oauth.ts +449 -0
- package/plugins/kxm/src/providers/antigravity/client/client.ts +562 -0
- package/plugins/kxm/src/providers/antigravity/client/index.ts +1 -0
- package/plugins/kxm/src/providers/antigravity/diagnostics/diagnostics.ts +97 -0
- package/plugins/kxm/src/providers/antigravity/diagnostics/index.ts +1 -0
- package/plugins/kxm/src/providers/antigravity/index.ts +24 -0
- package/plugins/kxm/src/providers/antigravity/models/discovery.ts +155 -0
- package/plugins/kxm/src/providers/antigravity/models/grouping.ts +425 -0
- package/plugins/kxm/src/providers/antigravity/models/index.ts +3 -0
- package/plugins/kxm/src/providers/antigravity/models/models.ts +501 -0
- package/plugins/kxm/src/providers/antigravity/pi-compat.ts +279 -0
- package/plugins/kxm/src/providers/antigravity/register.ts +123 -0
- package/plugins/kxm/src/providers/antigravity/stream/index.ts +1 -0
- package/plugins/kxm/src/providers/antigravity/stream/stream.ts +1461 -0
- package/plugins/kxm/src/providers/antigravity/types/enums.ts +50 -0
- package/plugins/kxm/src/providers/antigravity/types/index.ts +2 -0
- package/plugins/kxm/src/providers/antigravity/types/types.ts +293 -0
- package/plugins/kxm/src/providers/antigravity/usage/index.ts +1 -0
- package/plugins/kxm/src/providers/antigravity/usage/usage.ts +361 -0
- package/plugins/kxm/src/providers/antigravity/utils/http.ts +32 -0
- package/plugins/kxm/src/providers/antigravity/utils/index.ts +3 -0
- package/plugins/kxm/src/providers/antigravity/utils/security.ts +75 -0
- package/plugins/kxm/src/providers/antigravity/utils/util.ts +133 -0
- package/plugins/kxm/src/redact.ts +4 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural Pi stream/auth types used by the vendored Antigravity provider.
|
|
3
|
+
* No @earendil-works/pi-ai import (nested copy is forbidden).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type Api = string;
|
|
7
|
+
export type ProviderId = string;
|
|
8
|
+
export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
9
|
+
export type ModelThinkingLevel = "off" | ThinkingLevel;
|
|
10
|
+
export type ThinkingLevelMap = Partial<Record<ModelThinkingLevel, string | null>>;
|
|
11
|
+
export type ToolChoiceSimple = "auto" | "none";
|
|
12
|
+
|
|
13
|
+
export type ModelCostRates = {
|
|
14
|
+
input: number;
|
|
15
|
+
output: number;
|
|
16
|
+
cacheRead: number;
|
|
17
|
+
cacheWrite: number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type ModelCost = ModelCostRates & {
|
|
21
|
+
tiers?: Array<ModelCostRates & { inputTokensAbove: number }>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type ProviderModelConfig = {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
api?: Api;
|
|
28
|
+
baseUrl?: string;
|
|
29
|
+
reasoning: boolean;
|
|
30
|
+
thinkingLevelMap?: ThinkingLevelMap;
|
|
31
|
+
input: Array<"text" | "image">;
|
|
32
|
+
cost: ModelCost;
|
|
33
|
+
contextWindow: number;
|
|
34
|
+
maxTokens: number;
|
|
35
|
+
headers?: Record<string, string>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type Model<TApi extends Api = Api> = ProviderModelConfig & {
|
|
39
|
+
api: TApi;
|
|
40
|
+
provider: ProviderId;
|
|
41
|
+
baseUrl: string;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type TextContent = {
|
|
45
|
+
type: "text";
|
|
46
|
+
text: string;
|
|
47
|
+
textSignature?: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type ThinkingContent = {
|
|
51
|
+
type: "thinking";
|
|
52
|
+
thinking: string;
|
|
53
|
+
thinkingSignature?: string;
|
|
54
|
+
redacted?: boolean;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export type ImageContent = {
|
|
58
|
+
type: "image";
|
|
59
|
+
data: string;
|
|
60
|
+
mimeType: string;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type ToolCall = {
|
|
64
|
+
type: "toolCall";
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
arguments: Record<string, unknown>;
|
|
68
|
+
thoughtSignature?: string;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export type Usage = {
|
|
72
|
+
input: number;
|
|
73
|
+
output: number;
|
|
74
|
+
cacheRead: number;
|
|
75
|
+
cacheWrite: number;
|
|
76
|
+
cacheWrite1h?: number;
|
|
77
|
+
reasoning?: number;
|
|
78
|
+
totalTokens: number;
|
|
79
|
+
cost: {
|
|
80
|
+
input: number;
|
|
81
|
+
output: number;
|
|
82
|
+
cacheRead: number;
|
|
83
|
+
cacheWrite: number;
|
|
84
|
+
total: number;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export type StopReason = "pending" | "stop" | "length" | "toolUse" | "error" | "aborted" | "deferred";
|
|
89
|
+
|
|
90
|
+
export type UserMessage = {
|
|
91
|
+
role: "user";
|
|
92
|
+
content: string | Array<TextContent | ImageContent>;
|
|
93
|
+
timestamp: number;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type AssistantMessage = {
|
|
97
|
+
role: "assistant";
|
|
98
|
+
content: Array<TextContent | ThinkingContent | ToolCall>;
|
|
99
|
+
api: Api;
|
|
100
|
+
provider: ProviderId;
|
|
101
|
+
model: string;
|
|
102
|
+
usage: Usage;
|
|
103
|
+
stopReason: StopReason;
|
|
104
|
+
errorMessage?: string;
|
|
105
|
+
rawStopReason?: string;
|
|
106
|
+
timestamp: number;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export type ToolResultMessage = {
|
|
110
|
+
role: "toolResult";
|
|
111
|
+
toolCallId: string;
|
|
112
|
+
toolName: string;
|
|
113
|
+
content: Array<TextContent | ImageContent>;
|
|
114
|
+
isError: boolean;
|
|
115
|
+
timestamp: number;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export type Message = UserMessage | AssistantMessage | ToolResultMessage;
|
|
119
|
+
|
|
120
|
+
export type Tool = {
|
|
121
|
+
name: string;
|
|
122
|
+
description: string;
|
|
123
|
+
parameters: unknown;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export type Context = {
|
|
127
|
+
systemPrompt?: string;
|
|
128
|
+
messages: Message[];
|
|
129
|
+
tools?: Tool[];
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export type AssistantMessageEvent =
|
|
133
|
+
| { type: "start"; partial: AssistantMessage }
|
|
134
|
+
| { type: "text_start"; contentIndex: number; partial: AssistantMessage }
|
|
135
|
+
| { type: "text_delta"; contentIndex: number; delta: string; partial: AssistantMessage }
|
|
136
|
+
| { type: "text_end"; contentIndex: number; content: string; partial: AssistantMessage }
|
|
137
|
+
| { type: "thinking_start"; contentIndex: number; partial: AssistantMessage }
|
|
138
|
+
| { type: "thinking_delta"; contentIndex: number; delta: string; partial: AssistantMessage }
|
|
139
|
+
| { type: "thinking_end"; contentIndex: number; content: string; partial: AssistantMessage }
|
|
140
|
+
| { type: "toolcall_start"; contentIndex: number; partial: AssistantMessage }
|
|
141
|
+
| { type: "toolcall_delta"; contentIndex: number; delta: string; partial: AssistantMessage }
|
|
142
|
+
| { type: "toolcall_end"; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage }
|
|
143
|
+
| { type: "done"; reason: StopReason; message: AssistantMessage }
|
|
144
|
+
| { type: "error"; reason: StopReason; error: AssistantMessage };
|
|
145
|
+
|
|
146
|
+
export class AssistantMessageEventStream {
|
|
147
|
+
queue: AssistantMessageEvent[] = [];
|
|
148
|
+
waiting: Array<(result: { value?: AssistantMessageEvent; done: boolean }) => void> = [];
|
|
149
|
+
done = false;
|
|
150
|
+
finalResultPromise: Promise<AssistantMessage>;
|
|
151
|
+
private resolveFinalResult!: (message: AssistantMessage) => void;
|
|
152
|
+
|
|
153
|
+
constructor() {
|
|
154
|
+
this.finalResultPromise = new Promise((resolve) => {
|
|
155
|
+
this.resolveFinalResult = resolve;
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
push(event: AssistantMessageEvent): void {
|
|
160
|
+
if (this.done) return;
|
|
161
|
+
if (event.type === "done") {
|
|
162
|
+
this.done = true;
|
|
163
|
+
this.resolveFinalResult(event.message);
|
|
164
|
+
} else if (event.type === "error") {
|
|
165
|
+
this.done = true;
|
|
166
|
+
this.resolveFinalResult(event.error);
|
|
167
|
+
}
|
|
168
|
+
const waiter = this.waiting.shift();
|
|
169
|
+
if (waiter) waiter({ value: event, done: false });
|
|
170
|
+
else this.queue.push(event);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
end(result?: AssistantMessage): void {
|
|
174
|
+
this.done = true;
|
|
175
|
+
if (result !== undefined) this.resolveFinalResult(result);
|
|
176
|
+
while (this.waiting.length > 0) {
|
|
177
|
+
this.waiting.shift()?.({ done: true });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async *[Symbol.asyncIterator](): AsyncGenerator<AssistantMessageEvent> {
|
|
182
|
+
while (true) {
|
|
183
|
+
if (this.queue.length > 0) {
|
|
184
|
+
yield this.queue.shift()!;
|
|
185
|
+
} else if (this.done) {
|
|
186
|
+
return;
|
|
187
|
+
} else {
|
|
188
|
+
const next = await new Promise<{ value?: AssistantMessageEvent; done: boolean }>((resolve) => {
|
|
189
|
+
this.waiting.push(resolve);
|
|
190
|
+
});
|
|
191
|
+
if (next.done) return;
|
|
192
|
+
if (next.value) yield next.value;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
result(): Promise<AssistantMessage> {
|
|
198
|
+
return this.finalResultPromise;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export function createAssistantMessageEventStream(): AssistantMessageEventStream {
|
|
203
|
+
return new AssistantMessageEventStream();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export function calculateCost(model: { cost?: ModelCost }, usage: Usage): Usage["cost"] {
|
|
207
|
+
const rates = model.cost;
|
|
208
|
+
if (!rates) {
|
|
209
|
+
usage.cost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 };
|
|
210
|
+
return usage.cost;
|
|
211
|
+
}
|
|
212
|
+
const inputTokens = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
213
|
+
let applied: ModelCostRates = rates;
|
|
214
|
+
let matchedThreshold = -1;
|
|
215
|
+
for (const tier of rates.tiers ?? []) {
|
|
216
|
+
if (inputTokens > tier.inputTokensAbove && tier.inputTokensAbove > matchedThreshold) {
|
|
217
|
+
applied = tier;
|
|
218
|
+
matchedThreshold = tier.inputTokensAbove;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const longWrite = usage.cacheWrite1h ?? 0;
|
|
222
|
+
const shortWrite = usage.cacheWrite - longWrite;
|
|
223
|
+
usage.cost.input = (applied.input / 1_000_000) * usage.input;
|
|
224
|
+
usage.cost.output = (applied.output / 1_000_000) * usage.output;
|
|
225
|
+
usage.cost.cacheRead = (applied.cacheRead / 1_000_000) * usage.cacheRead;
|
|
226
|
+
usage.cost.cacheWrite = (applied.cacheWrite * shortWrite + applied.input * 2 * longWrite) / 1_000_000;
|
|
227
|
+
usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
|
|
228
|
+
return usage.cost;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export type OAuthCredentials = {
|
|
232
|
+
refresh: string;
|
|
233
|
+
access: string;
|
|
234
|
+
expires: number;
|
|
235
|
+
[key: string]: unknown;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export type OAuthLoginCallbacks = {
|
|
239
|
+
onAuth(info: { url: string; instructions?: string }): void;
|
|
240
|
+
onDeviceCode?(info: { userCode: string; verificationUri: string }): void;
|
|
241
|
+
onPrompt?(prompt: { message: string; placeholder?: string }): Promise<string>;
|
|
242
|
+
onProgress?(message: string): void;
|
|
243
|
+
onSelect?(prompt: { message: string; options: Array<{ id: string; label: string }> }): Promise<string | undefined>;
|
|
244
|
+
signal?: AbortSignal;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
export type ApiKeyCredential = {
|
|
248
|
+
type: "api_key";
|
|
249
|
+
key?: string;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
export type OAuthCredential = OAuthCredentials & {
|
|
253
|
+
type: "oauth";
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
export type Credential = ApiKeyCredential | OAuthCredential;
|
|
257
|
+
|
|
258
|
+
export type ModelsStoreEntry = Record<string, unknown>;
|
|
259
|
+
|
|
260
|
+
export type RefreshModelsContext = {
|
|
261
|
+
credential?: Credential;
|
|
262
|
+
stored?: Readonly<ModelsStoreEntry>;
|
|
263
|
+
publish(publication: { persist?: ModelsStoreEntry | null }): Promise<boolean>;
|
|
264
|
+
allowNetwork: boolean;
|
|
265
|
+
force?: boolean;
|
|
266
|
+
signal: AbortSignal;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
export type SimpleStreamOptions = {
|
|
270
|
+
signal?: AbortSignal;
|
|
271
|
+
apiKey?: string;
|
|
272
|
+
temperature?: number;
|
|
273
|
+
maxTokens?: number;
|
|
274
|
+
sessionId?: string;
|
|
275
|
+
reasoning?: ThinkingLevel;
|
|
276
|
+
toolChoice?: ToolChoiceSimple | string;
|
|
277
|
+
onPayload?: (payload: unknown, model: Model<Api>) => unknown | undefined | Promise<unknown | undefined>;
|
|
278
|
+
onResponse?: (response: { status: number; headers: Record<string, string> }, model: Model<Api>) => void | Promise<void>;
|
|
279
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register the Antigravity provider on a Pi extension host.
|
|
3
|
+
* Provider id stays `antigravity` so existing auth-store logins carry over.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
7
|
+
import { getApiKey, loginAntigravity, refreshAntigravityToken } from "./auth/index.ts";
|
|
8
|
+
import { DEFAULT_ENDPOINT, endpointCandidates } from "./client/index.ts";
|
|
9
|
+
import {
|
|
10
|
+
getCurrentAntigravityCatalog,
|
|
11
|
+
PROVIDER_ID,
|
|
12
|
+
PROVIDER_NAME,
|
|
13
|
+
refreshAntigravityModels,
|
|
14
|
+
} from "./models/index.ts";
|
|
15
|
+
import { ANTIGRAVITY_API, streamAntigravity } from "./stream/index.ts";
|
|
16
|
+
import { prewarmConnection } from "./utils/index.ts";
|
|
17
|
+
|
|
18
|
+
export const ANTIGRAVITY_DOUBLE_REGISTRATION_WARNING =
|
|
19
|
+
"kxm: standalone pi-antigravity is still installed. Remove that extension and reload. KXM will not double-register provider id antigravity.";
|
|
20
|
+
|
|
21
|
+
/** Slash commands that only the standalone extension registers. */
|
|
22
|
+
export const STANDALONE_ANTIGRAVITY_COMMANDS = Object.freeze([
|
|
23
|
+
"antigravity.image",
|
|
24
|
+
"antigravity.models",
|
|
25
|
+
"antigravity.doctor",
|
|
26
|
+
"antigravity.usage",
|
|
27
|
+
"antigravity.refresh",
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
export type AntigravityRegistration = {
|
|
31
|
+
registered: boolean;
|
|
32
|
+
conflict: boolean;
|
|
33
|
+
warning?: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type ProviderProbe = {
|
|
37
|
+
getRegisteredProviderIds?: () => readonly string[];
|
|
38
|
+
getCommands?: () => ReadonlyArray<{ name?: string }>;
|
|
39
|
+
modelRegistry?: {
|
|
40
|
+
getRegisteredProviderIds?: () => readonly string[];
|
|
41
|
+
getProvider?: (id: string) => unknown;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
function asProbe(pi: object): ProviderProbe {
|
|
46
|
+
return pi as ProviderProbe;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function registeredProviderIds(probe: ProviderProbe): string[] {
|
|
50
|
+
return [
|
|
51
|
+
...(probe.getRegisteredProviderIds?.() ?? []),
|
|
52
|
+
...(probe.modelRegistry?.getRegisteredProviderIds?.() ?? []),
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function antigravityStandaloneCommandsPresent(pi: object): boolean {
|
|
57
|
+
const probe = asProbe(pi);
|
|
58
|
+
let names: string[] = [];
|
|
59
|
+
try {
|
|
60
|
+
names = (probe.getCommands?.() ?? [])
|
|
61
|
+
.map((command) => command.name)
|
|
62
|
+
.filter((name): name is string => typeof name === "string");
|
|
63
|
+
} catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return STANDALONE_ANTIGRAVITY_COMMANDS.some((name) => names.includes(name));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function antigravityProviderRegistered(pi: object): boolean {
|
|
70
|
+
const probe = asProbe(pi);
|
|
71
|
+
const ids = registeredProviderIds(probe);
|
|
72
|
+
if (ids.includes(PROVIDER_ID)) return true;
|
|
73
|
+
if (probe.modelRegistry?.getProvider?.(PROVIDER_ID)) return true;
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function shouldSkipAntigravityRegistration(pi: object): boolean {
|
|
78
|
+
return antigravityProviderRegistered(pi) || antigravityStandaloneCommandsPresent(pi);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function antigravityRegistrationNotice(
|
|
82
|
+
report: AntigravityRegistration | undefined,
|
|
83
|
+
pi?: object,
|
|
84
|
+
): { message: string; type: "warning" } | undefined {
|
|
85
|
+
const conflict = Boolean(report?.conflict) || (pi ? antigravityStandaloneCommandsPresent(pi) : false);
|
|
86
|
+
if (!conflict) return undefined;
|
|
87
|
+
const warning = (report?.warning ?? ANTIGRAVITY_DOUBLE_REGISTRATION_WARNING).slice(0, 400);
|
|
88
|
+
return { message: warning, type: "warning" };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function registerAntigravityProvider(pi: ExtensionAPI): AntigravityRegistration {
|
|
92
|
+
if (shouldSkipAntigravityRegistration(pi)) {
|
|
93
|
+
return {
|
|
94
|
+
registered: false,
|
|
95
|
+
conflict: true,
|
|
96
|
+
warning: ANTIGRAVITY_DOUBLE_REGISTRATION_WARNING,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
if (typeof pi.registerProvider !== "function") {
|
|
100
|
+
return { registered: false, conflict: false };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const primaryEndpoint = endpointCandidates()[0];
|
|
104
|
+
if (primaryEndpoint) prewarmConnection(primaryEndpoint);
|
|
105
|
+
|
|
106
|
+
pi.registerProvider(PROVIDER_ID, {
|
|
107
|
+
name: PROVIDER_NAME,
|
|
108
|
+
baseUrl: DEFAULT_ENDPOINT,
|
|
109
|
+
api: ANTIGRAVITY_API,
|
|
110
|
+
models: getCurrentAntigravityCatalog().models,
|
|
111
|
+
refreshModels: refreshAntigravityModels,
|
|
112
|
+
oauth: {
|
|
113
|
+
name: PROVIDER_NAME,
|
|
114
|
+
isSubscription: true,
|
|
115
|
+
login: loginAntigravity,
|
|
116
|
+
refreshToken: refreshAntigravityToken,
|
|
117
|
+
getApiKey,
|
|
118
|
+
},
|
|
119
|
+
streamSimple: streamAntigravity,
|
|
120
|
+
} as unknown as Parameters<ExtensionAPI["registerProvider"]>[1]);
|
|
121
|
+
|
|
122
|
+
return { registered: true, conflict: false };
|
|
123
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./stream.ts";
|