@centerforagenticai/pi-multi-account 0.1.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.
Files changed (124) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +29 -0
  3. package/README.md +999 -0
  4. package/config/models/pi-multi-account.v1.json +32 -0
  5. package/config/subscription-plans.v1.json +122 -0
  6. package/package.json +76 -0
  7. package/packages/pi-anthropic-oauth/LICENSE +21 -0
  8. package/packages/pi-anthropic-oauth/package.json +54 -0
  9. package/packages/pi-anthropic-oauth/src/auth.ts +396 -0
  10. package/packages/pi-anthropic-oauth/src/context.ts +116 -0
  11. package/packages/pi-anthropic-oauth/src/convert.ts +303 -0
  12. package/packages/pi-anthropic-oauth/src/index.ts +37 -0
  13. package/packages/pi-anthropic-oauth/src/prompt.ts +137 -0
  14. package/packages/pi-anthropic-oauth/src/stream.ts +476 -0
  15. package/packages/pi-antigravity/LICENSE +21 -0
  16. package/packages/pi-antigravity/package.json +77 -0
  17. package/packages/pi-antigravity/src/auth/index.ts +14 -0
  18. package/packages/pi-antigravity/src/auth/oauth.ts +442 -0
  19. package/packages/pi-antigravity/src/client/client.ts +561 -0
  20. package/packages/pi-antigravity/src/client/index.ts +1 -0
  21. package/packages/pi-antigravity/src/context.ts +110 -0
  22. package/packages/pi-antigravity/src/diagnostics/diagnostics.ts +96 -0
  23. package/packages/pi-antigravity/src/diagnostics/index.ts +1 -0
  24. package/packages/pi-antigravity/src/image/image.ts +336 -0
  25. package/packages/pi-antigravity/src/image/index.ts +1 -0
  26. package/packages/pi-antigravity/src/index.ts +280 -0
  27. package/packages/pi-antigravity/src/models/discovery.ts +154 -0
  28. package/packages/pi-antigravity/src/models/grouping.ts +424 -0
  29. package/packages/pi-antigravity/src/models/index.ts +3 -0
  30. package/packages/pi-antigravity/src/models/models.ts +500 -0
  31. package/packages/pi-antigravity/src/stream/index.ts +1 -0
  32. package/packages/pi-antigravity/src/stream/stream.ts +1478 -0
  33. package/packages/pi-antigravity/src/types/enums.ts +42 -0
  34. package/packages/pi-antigravity/src/types/index.ts +2 -0
  35. package/packages/pi-antigravity/src/types/types.ts +292 -0
  36. package/packages/pi-antigravity/src/usage/index.ts +1 -0
  37. package/packages/pi-antigravity/src/usage/usage.ts +416 -0
  38. package/packages/pi-antigravity/src/utils/http.ts +91 -0
  39. package/packages/pi-antigravity/src/utils/index.ts +3 -0
  40. package/packages/pi-antigravity/src/utils/security.ts +73 -0
  41. package/packages/pi-antigravity/src/utils/util.ts +132 -0
  42. package/scripts/multi-account.mjs +44 -0
  43. package/src/account-labels.ts +223 -0
  44. package/src/account-plan-assignment.ts +340 -0
  45. package/src/account-rate-history.ts +372 -0
  46. package/src/anthropic-adaptive-stream.ts +531 -0
  47. package/src/anthropic-alias-stream.ts +140 -0
  48. package/src/anthropic-context-compat.ts +80 -0
  49. package/src/api-pricing.ts +579 -0
  50. package/src/bounded-file-lines.ts +97 -0
  51. package/src/catalog-rebinding.ts +177 -0
  52. package/src/catalog-registration-probe.ts +111 -0
  53. package/src/codex-adapter.ts +345 -0
  54. package/src/codex-model-defaults.ts +785 -0
  55. package/src/command-completions.ts +404 -0
  56. package/src/commands.ts +2000 -0
  57. package/src/compaction.ts +14 -0
  58. package/src/config.ts +1317 -0
  59. package/src/continuation.ts +569 -0
  60. package/src/cooldowns.ts +110 -0
  61. package/src/cost-digest-store.ts +332 -0
  62. package/src/cost-digest.ts +1044 -0
  63. package/src/cost-history.ts +251 -0
  64. package/src/cost-period-closer.ts +160 -0
  65. package/src/cost-report-json.ts +318 -0
  66. package/src/cost-report-reader.ts +368 -0
  67. package/src/cost-report-render.ts +207 -0
  68. package/src/cost-report.ts +1104 -0
  69. package/src/coverage-attestation.ts +397 -0
  70. package/src/credential-lifecycle.ts +169 -0
  71. package/src/credential-refresh.ts +248 -0
  72. package/src/declaration-notice-marker.ts +238 -0
  73. package/src/diagnostic-store.ts +276 -0
  74. package/src/diagnostics.ts +309 -0
  75. package/src/discovery.ts +471 -0
  76. package/src/duration.ts +13 -0
  77. package/src/error-classification.ts +256 -0
  78. package/src/fuzzy.ts +15 -0
  79. package/src/group-policy.ts +81 -0
  80. package/src/history-store.ts +897 -0
  81. package/src/index.ts +5572 -0
  82. package/src/lifecycle.ts +378 -0
  83. package/src/logical-dispatch.ts +279 -0
  84. package/src/logical-model-selector.ts +254 -0
  85. package/src/logical-model-switcher.ts +430 -0
  86. package/src/logical-provider-attribution.ts +544 -0
  87. package/src/logical-provider.ts +1237 -0
  88. package/src/logical-route-indicator.ts +215 -0
  89. package/src/machine-lease.ts +445 -0
  90. package/src/model-support.ts +66 -0
  91. package/src/models-declaration.ts +1091 -0
  92. package/src/openai-adapter.ts +117 -0
  93. package/src/openrouter-budget.ts +304 -0
  94. package/src/openrouter-fallback.ts +146 -0
  95. package/src/period-boundaries.ts +376 -0
  96. package/src/pi-anthropic-oauth.d.ts +6 -0
  97. package/src/preflight.ts +253 -0
  98. package/src/pricing-cache.ts +235 -0
  99. package/src/project-identity.ts +100 -0
  100. package/src/provider-registration.ts +942 -0
  101. package/src/rate-formula.ts +163 -0
  102. package/src/recovery-engine.ts +853 -0
  103. package/src/recovery-output.ts +837 -0
  104. package/src/recovery-plan.ts +239 -0
  105. package/src/report-range.ts +203 -0
  106. package/src/route-resolver.ts +789 -0
  107. package/src/routing-config-transaction.ts +232 -0
  108. package/src/routing.ts +1163 -0
  109. package/src/runtime-state.ts +630 -0
  110. package/src/session-account-groups.ts +284 -0
  111. package/src/session-restore.ts +287 -0
  112. package/src/shared-usage.ts +1392 -0
  113. package/src/standalone-cli.ts +720 -0
  114. package/src/status-view.ts +578 -0
  115. package/src/subscription-plan-catalog.ts +346 -0
  116. package/src/tier-model-resolver.ts +46 -0
  117. package/src/upstream-anthropic.ts +315 -0
  118. package/src/upstream-antigravity.ts +327 -0
  119. package/src/usage-fetch.ts +1634 -0
  120. package/src/usage.ts +1026 -0
  121. package/src/vendor.ts +87 -0
  122. package/src/warmer.ts +231 -0
  123. package/src/watchdog.ts +219 -0
  124. package/src/window-history.ts +270 -0
@@ -0,0 +1,476 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import type { MessageCreateParamsStreaming } from "@anthropic-ai/sdk/resources/messages.js";
3
+ import {
4
+ type Api,
5
+ type AssistantMessage,
6
+ type AssistantMessageEventStream,
7
+ calculateCost,
8
+ type Context,
9
+ createAssistantMessageEventStream,
10
+ type Model,
11
+ type SimpleStreamOptions,
12
+ type StopReason,
13
+ } from "@earendil-works/pi-ai";
14
+ import { isClaudeOAuthAccessToken, USER_AGENT } from "./auth.js";
15
+ import {
16
+ convertPiMessagesToAnthropic,
17
+ convertPiToolsToAnthropic,
18
+ fromClaudeCodeToolName,
19
+ type IndexedBlock,
20
+ } from "./convert.js";
21
+ import { projectContext } from "./context.js";
22
+ import { buildAnthropicSystemPrompt } from "./prompt.js";
23
+
24
+ const REQUIRED_BETAS = [
25
+ "claude-code-20250219",
26
+ "oauth-2025-04-20",
27
+ // fine-grained-tool-streaming removed: it ships the model's raw, unvalidated
28
+ // tool-input JSON. For large edits full of quotes/newlines the streamed
29
+ // string escaping breaks, so a field (e.g. edit.oldText) swallows the rest of
30
+ // the structure — surfacing as either a hard JSON.parse crash or a wrong-shape
31
+ // schema-validation failure. Default streaming has the server validate/buffer
32
+ // tool JSON, guaranteeing well-formed, correctly-structured input.
33
+ "interleaved-thinking-2025-05-14",
34
+ ] as const;
35
+
36
+ function mapStopReason(reason: string | null | undefined): StopReason {
37
+ switch (reason) {
38
+ case "end_turn":
39
+ case "pause_turn":
40
+ case "stop_sequence":
41
+ return "stop";
42
+ case "max_tokens":
43
+ return "length";
44
+ case "tool_use":
45
+ return "toolUse";
46
+ default:
47
+ return "error";
48
+ }
49
+ }
50
+
51
+ function headersToRecord(headers: Headers): Record<string, string> {
52
+ const record: Record<string, string> = {};
53
+ headers.forEach((value, key) => {
54
+ record[key] = value;
55
+ });
56
+ return record;
57
+ }
58
+
59
+ function makeDefaultHeaders(
60
+ isOAuth: boolean,
61
+ options?: SimpleStreamOptions,
62
+ ): Record<string, string> {
63
+ const headers: Record<string, string> = {
64
+ accept: "application/json",
65
+ "anthropic-dangerous-direct-browser-access": "true",
66
+ };
67
+
68
+ if (isOAuth) {
69
+ headers["anthropic-beta"] = REQUIRED_BETAS.join(",");
70
+ headers["user-agent"] = USER_AGENT;
71
+ headers["x-app"] = "cli";
72
+ } else {
73
+ headers["anthropic-beta"] = ["interleaved-thinking-2025-05-14"].join(",");
74
+ }
75
+
76
+ if (options?.headers) {
77
+ for (const [key, value] of Object.entries(options.headers)) {
78
+ const normalizedKey = key.toLowerCase();
79
+ if (
80
+ isOAuth &&
81
+ (normalizedKey === "x-api-key" || normalizedKey === "authorization")
82
+ ) {
83
+ continue;
84
+ }
85
+ const existingKey = Object.keys(headers).find(
86
+ (header) => header.toLowerCase() === normalizedKey,
87
+ );
88
+ if (existingKey) delete headers[existingKey];
89
+ if (value !== null) headers[key] = value;
90
+ }
91
+ }
92
+
93
+ return headers;
94
+ }
95
+
96
+ export function streamAnthropicOAuth(
97
+ model: Model<Api>,
98
+ context: Context,
99
+ options?: SimpleStreamOptions,
100
+ ): AssistantMessageEventStream {
101
+ const stream = createAssistantMessageEventStream();
102
+
103
+ void (async () => {
104
+ const output: AssistantMessage = {
105
+ role: "assistant",
106
+ content: [],
107
+ api: model.api,
108
+ provider: model.provider,
109
+ model: model.id,
110
+ usage: {
111
+ input: 0,
112
+ output: 0,
113
+ cacheRead: 0,
114
+ cacheWrite: 0,
115
+ totalTokens: 0,
116
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
117
+ },
118
+ stopReason: "stop",
119
+ timestamp: Date.now(),
120
+ };
121
+
122
+ try {
123
+ const apiKey = options?.apiKey;
124
+ if (!apiKey) {
125
+ throw new Error(
126
+ "No Anthropic auth available. Run /login and choose Claude Pro/Max.",
127
+ );
128
+ }
129
+
130
+ const isOAuth = isClaudeOAuthAccessToken(apiKey);
131
+ const defaultHeaders = makeDefaultHeaders(isOAuth, options);
132
+
133
+ if (isOAuth) defaultHeaders.authorization = `Bearer ${apiKey}`;
134
+
135
+ const client = new Anthropic({
136
+ baseURL: model.baseUrl,
137
+ apiKey: isOAuth ? null : apiKey,
138
+ authToken: isOAuth ? apiKey : null,
139
+ defaultHeaders,
140
+ dangerouslyAllowBrowser: true,
141
+ });
142
+
143
+ const maxTokens =
144
+ options?.maxTokens || Math.floor(model.maxTokens / 3);
145
+ const projectedContext = projectContext(context);
146
+
147
+ const params: MessageCreateParamsStreaming = {
148
+ model: model.id,
149
+ messages: convertPiMessagesToAnthropic(
150
+ projectedContext.messages,
151
+ isOAuth,
152
+ model,
153
+ ),
154
+ max_tokens: maxTokens,
155
+ stream: true,
156
+ };
157
+
158
+ const system = buildAnthropicSystemPrompt(
159
+ projectedContext.systemPrompt,
160
+ isOAuth,
161
+ );
162
+ if (system) params.system = system as never;
163
+ if (projectedContext.tools.length) {
164
+ params.tools = convertPiToolsToAnthropic(
165
+ projectedContext.tools,
166
+ isOAuth,
167
+ );
168
+ }
169
+ if (options?.reasoning && model.reasoning && maxTokens > 1) {
170
+ const defaultBudgets: Record<string, number> = {
171
+ minimal: 1024,
172
+ low: 4096,
173
+ medium: 10240,
174
+ high: 20480,
175
+ xhigh: 32000,
176
+ };
177
+ const customBudget =
178
+ options.thinkingBudgets?.[
179
+ options.reasoning as keyof typeof options.thinkingBudgets
180
+ ];
181
+ const requestedBudget =
182
+ customBudget ?? defaultBudgets[options.reasoning] ?? 10240;
183
+ const display = "summarized";
184
+ const forceAdaptive = (
185
+ model.compat as { forceAdaptiveThinking?: boolean } | undefined
186
+ )?.forceAdaptiveThinking;
187
+ const id = model.id.toLowerCase().replace(/\./g, "-");
188
+ const adaptive =
189
+ forceAdaptive === true ||
190
+ (forceAdaptive !== false &&
191
+ (/claude-(?:opus|sonnet|haiku|fable|mythos)-5(?:-|$)/.test(id) ||
192
+ /claude-(?:opus|sonnet|haiku|fable|mythos)-4-(?:[6-9]|\d{2,})(?:-|$)/.test(
193
+ id,
194
+ )));
195
+
196
+ if (adaptive) {
197
+ const mapped = model.thinkingLevelMap?.[options.reasoning];
198
+ const effort =
199
+ typeof mapped === "string"
200
+ ? mapped
201
+ : options.reasoning === "minimal" || options.reasoning === "low"
202
+ ? "low"
203
+ : options.reasoning === "medium"
204
+ ? "medium"
205
+ : options.reasoning === "high"
206
+ ? "high"
207
+ : "high";
208
+ params.thinking = { type: "adaptive", display } as never;
209
+ Object.assign(params, { output_config: { effort } });
210
+ } else {
211
+ params.thinking = {
212
+ type: "enabled",
213
+ budget_tokens: Math.min(requestedBudget, maxTokens - 1),
214
+ display,
215
+ } as never;
216
+ }
217
+ }
218
+
219
+ // Raw stream instead of the MessageStream helper: MessageStream
220
+ // accumulates tool_use input and JSON.parses it on content_block_stop,
221
+ // which throws under fine-grained-tool-streaming (input may be invalid
222
+ // mid-flight) and aborts the turn. The raw stream yields the same
223
+ // RawMessageStreamEvents; tool args are already parsed leniently below.
224
+ const { data: anthropicStream, response: httpResponse } =
225
+ await client.messages
226
+ .create(params, {
227
+ signal: options?.signal,
228
+ })
229
+ .withResponse();
230
+
231
+ if (options?.onResponse) {
232
+ try {
233
+ await options.onResponse(
234
+ {
235
+ status: httpResponse.status,
236
+ headers: headersToRecord(httpResponse.headers),
237
+ },
238
+ model,
239
+ );
240
+ } catch {
241
+ // Response hooks are best-effort and should not break streaming.
242
+ }
243
+ }
244
+
245
+ stream.push({ type: "start", partial: output });
246
+
247
+ const blocks = output.content as IndexedBlock[];
248
+
249
+ for await (const event of anthropicStream) {
250
+ if (event.type === "message_start") {
251
+ output.usage.input = event.message.usage.input_tokens || 0;
252
+ output.usage.output = event.message.usage.output_tokens || 0;
253
+ output.usage.cacheRead =
254
+ (event.message.usage as { cache_read_input_tokens?: number })
255
+ .cache_read_input_tokens || 0;
256
+ output.usage.cacheWrite =
257
+ (event.message.usage as { cache_creation_input_tokens?: number })
258
+ .cache_creation_input_tokens || 0;
259
+ output.usage.totalTokens =
260
+ output.usage.input +
261
+ output.usage.output +
262
+ output.usage.cacheRead +
263
+ output.usage.cacheWrite;
264
+ calculateCost(model, output.usage);
265
+ continue;
266
+ }
267
+
268
+ if (event.type === "content_block_start") {
269
+ if (event.content_block.type === "text") {
270
+ output.content.push({
271
+ type: "text",
272
+ text: "",
273
+ index: event.index,
274
+ } as IndexedBlock);
275
+ stream.push({
276
+ type: "text_start",
277
+ contentIndex: output.content.length - 1,
278
+ partial: output,
279
+ });
280
+ } else if (event.content_block.type === "thinking") {
281
+ output.content.push({
282
+ type: "thinking",
283
+ thinking: "",
284
+ thinkingSignature: "",
285
+ index: event.index,
286
+ } as IndexedBlock);
287
+ stream.push({
288
+ type: "thinking_start",
289
+ contentIndex: output.content.length - 1,
290
+ partial: output,
291
+ });
292
+ } else if (event.content_block.type === "redacted_thinking") {
293
+ output.content.push({
294
+ type: "thinking",
295
+ thinking: "[Reasoning redacted]",
296
+ thinkingSignature: event.content_block.data,
297
+ redacted: true,
298
+ index: event.index,
299
+ } as IndexedBlock);
300
+ stream.push({
301
+ type: "thinking_start",
302
+ contentIndex: output.content.length - 1,
303
+ partial: output,
304
+ });
305
+ } else if (event.content_block.type === "tool_use") {
306
+ output.content.push({
307
+ type: "toolCall",
308
+ id: event.content_block.id,
309
+ name: isOAuth
310
+ ? fromClaudeCodeToolName(
311
+ event.content_block.name,
312
+ projectedContext.tools,
313
+ )
314
+ : event.content_block.name,
315
+ arguments: {},
316
+ partialJson: "",
317
+ index: event.index,
318
+ } as IndexedBlock);
319
+ stream.push({
320
+ type: "toolcall_start",
321
+ contentIndex: output.content.length - 1,
322
+ partial: output,
323
+ });
324
+ }
325
+ continue;
326
+ }
327
+
328
+ if (event.type === "content_block_delta") {
329
+ const contentIndex = blocks.findIndex(
330
+ (block) => block.index === event.index,
331
+ );
332
+ const block = blocks[contentIndex];
333
+ if (!block) continue;
334
+
335
+ if (event.delta.type === "text_delta" && block.type === "text") {
336
+ block.text += event.delta.text;
337
+ stream.push({
338
+ type: "text_delta",
339
+ contentIndex,
340
+ delta: event.delta.text,
341
+ partial: output,
342
+ });
343
+ } else if (
344
+ event.delta.type === "thinking_delta" &&
345
+ block.type === "thinking"
346
+ ) {
347
+ block.thinking += event.delta.thinking;
348
+ stream.push({
349
+ type: "thinking_delta",
350
+ contentIndex,
351
+ delta: event.delta.thinking,
352
+ partial: output,
353
+ });
354
+ } else if (
355
+ event.delta.type === "signature_delta" &&
356
+ block.type === "thinking"
357
+ ) {
358
+ block.thinkingSignature =
359
+ (block.thinkingSignature || "") + event.delta.signature;
360
+ } else if (
361
+ event.delta.type === "input_json_delta" &&
362
+ block.type === "toolCall"
363
+ ) {
364
+ block.partialJson += event.delta.partial_json;
365
+ try {
366
+ block.arguments = JSON.parse(block.partialJson) as Record<
367
+ string,
368
+ unknown
369
+ >;
370
+ } catch {}
371
+ stream.push({
372
+ type: "toolcall_delta",
373
+ contentIndex,
374
+ delta: event.delta.partial_json,
375
+ partial: output,
376
+ });
377
+ }
378
+ continue;
379
+ }
380
+
381
+ if (event.type === "content_block_stop") {
382
+ const contentIndex = blocks.findIndex(
383
+ (block) => block.index === event.index,
384
+ );
385
+ const block = blocks[contentIndex];
386
+ if (!block) continue;
387
+
388
+ delete (block as { index?: number }).index;
389
+ if (block.type === "text") {
390
+ stream.push({
391
+ type: "text_end",
392
+ contentIndex,
393
+ content: block.text,
394
+ partial: output,
395
+ });
396
+ } else if (block.type === "thinking") {
397
+ stream.push({
398
+ type: "thinking_end",
399
+ contentIndex,
400
+ content: block.thinking,
401
+ partial: output,
402
+ });
403
+ } else if (block.type === "toolCall") {
404
+ try {
405
+ block.arguments = JSON.parse(block.partialJson) as Record<
406
+ string,
407
+ unknown
408
+ >;
409
+ } catch {}
410
+ delete (block as { partialJson?: string }).partialJson;
411
+ stream.push({
412
+ type: "toolcall_end",
413
+ contentIndex,
414
+ toolCall: block,
415
+ partial: output,
416
+ });
417
+ }
418
+ continue;
419
+ }
420
+
421
+ if (event.type === "message_delta") {
422
+ output.stopReason = mapStopReason(event.delta.stop_reason);
423
+ output.usage.input =
424
+ (event.usage as { input_tokens?: number }).input_tokens ||
425
+ output.usage.input;
426
+ output.usage.output =
427
+ (event.usage as { output_tokens?: number }).output_tokens ||
428
+ output.usage.output;
429
+ output.usage.cacheRead =
430
+ (event.usage as { cache_read_input_tokens?: number })
431
+ .cache_read_input_tokens || 0;
432
+ output.usage.cacheWrite =
433
+ (event.usage as { cache_creation_input_tokens?: number })
434
+ .cache_creation_input_tokens || 0;
435
+ const thinkingTokens = (
436
+ event.usage as {
437
+ output_tokens_details?: { thinking_tokens?: number };
438
+ }
439
+ ).output_tokens_details?.thinking_tokens;
440
+ if (thinkingTokens != null) {
441
+ output.usage.reasoning = thinkingTokens;
442
+ }
443
+ output.usage.totalTokens =
444
+ output.usage.input +
445
+ output.usage.output +
446
+ output.usage.cacheRead +
447
+ output.usage.cacheWrite;
448
+ calculateCost(model, output.usage);
449
+ }
450
+ }
451
+
452
+ if (options?.signal?.aborted) throw new Error("Request aborted");
453
+ stream.push({
454
+ type: "done",
455
+ reason: output.stopReason as "stop" | "length" | "toolUse",
456
+ message: output,
457
+ });
458
+ stream.end();
459
+ } catch (error) {
460
+ for (const block of output.content as Array<{
461
+ index?: number;
462
+ partialJson?: string;
463
+ }>) {
464
+ delete block.index;
465
+ delete block.partialJson;
466
+ }
467
+ output.stopReason = options?.signal?.aborted ? "aborted" : "error";
468
+ output.errorMessage =
469
+ error instanceof Error ? error.message : String(error);
470
+ stream.push({ type: "error", reason: output.stopReason, error: output });
471
+ stream.end();
472
+ }
473
+ })();
474
+
475
+ return stream;
476
+ }
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rahul Arya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "pi-antigravity",
3
+ "version": "0.7.2-intel.1",
4
+ "description": "Personal Antigravity / Cloud Code Assist provider for Pi Coding Agent",
5
+ "author": "Rahul Arya",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Rahularya01/pi-antigravity.git"
10
+ },
11
+ "homepage": "https://github.com/Rahularya01/pi-antigravity#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/Rahularya01/pi-antigravity/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./src/index.ts",
17
+ "keywords": [
18
+ "pi-package",
19
+ "pi-extension",
20
+ "antigravity",
21
+ "google",
22
+ "oauth",
23
+ "provider"
24
+ ],
25
+ "files": [
26
+ "LICENSE",
27
+ "README.md",
28
+ "UPSTREAM.json",
29
+ "src",
30
+ "tsconfig.json",
31
+ "UPSTREAM.md",
32
+ "SOURCE_MANIFEST.sha256"
33
+ ],
34
+ "packageManager": "bun@1.4.0",
35
+ "scripts": {
36
+ "build": "tsc -p tsconfig.json --noEmit",
37
+ "prepare": "npm run build",
38
+ "typecheck": "tsc --noEmit",
39
+ "lint": "eslint src",
40
+ "lint:fix": "eslint src --fix",
41
+ "format": "prettier --write .",
42
+ "format:check": "prettier --check .",
43
+ "security-check": "bun scripts/security-check.ts",
44
+ "test": "bun scripts/test-model-routing.ts && bun scripts/test-model-discovery.ts && bun scripts/test-usage-formatter.ts && bun scripts/test-stream-sse.ts && bun scripts/test-stream-header-deadline.ts && bun scripts/test-http-proxy.ts && bun scripts/test-image-gen.ts && bun run test:stream-primary-error && bun run test:usage-abort && bun run test:context-projection",
45
+ "test:stream-primary-error": "bun scripts/test-stream-primary-error.ts",
46
+ "test:usage-abort": "bun scripts/test-usage-abort.ts",
47
+ "smoke:tools": "bun scripts/smoke-tool-schema.ts",
48
+ "smoke:models": "bun scripts/smoke-all-models.mjs",
49
+ "check": "bun run typecheck && bun run lint && bun run format:check && bun run security-check && bun run test",
50
+ "test:context-projection": "bun scripts/test-context-projection.ts",
51
+ "test:context-projection:normalized": "bun scripts/test-context-projection.ts normalized"
52
+ },
53
+ "pi": {
54
+ "extensions": [
55
+ "./src/index.ts"
56
+ ]
57
+ },
58
+ "peerDependencies": {
59
+ "@earendil-works/pi-ai": ">=0.80.0",
60
+ "@earendil-works/pi-coding-agent": ">=0.80.0"
61
+ },
62
+ "devDependencies": {
63
+ "@earendil-works/pi-ai": "^0.84.2",
64
+ "@eslint/js": "^10.0.1",
65
+ "@types/node": "^26.1.1",
66
+ "eslint": "^10.7.0",
67
+ "eslint-config-prettier": "^10.1.8",
68
+ "globals": "^17.7.0",
69
+ "pi-ai-087": "npm:@earendil-works/pi-ai@0.87.1",
70
+ "prettier": "^3.9.5",
71
+ "typescript": "^6.0.3",
72
+ "typescript-eslint": "^8.64.0"
73
+ },
74
+ "dependencies": {
75
+ "undici": "^8.10.0"
76
+ }
77
+ }
@@ -0,0 +1,14 @@
1
+ export {
2
+ loginAntigravity,
3
+ refreshAntigravityToken,
4
+ getApiKey,
5
+ CLIENT_ID,
6
+ CLIENT_SECRET,
7
+ REDIRECT_URI,
8
+ AUTH_URL,
9
+ TOKEN_URL,
10
+ SCOPES,
11
+ CALLBACK_HOST,
12
+ OAUTH_CALLBACK_TIMEOUT_MS,
13
+ } from "./oauth.js";
14
+ export type { OAuthCredentials, OAuthLoginCallbacks } from "./oauth.js";