aisubs 0.1.0 → 0.3.0
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/CHANGELOG.md +17 -0
- package/README.md +478 -427
- package/dist/auth.d.ts +2 -0
- package/dist/auth.js +23 -2
- package/dist/cli.js +10 -7
- package/dist/compatibility.d.ts +14 -0
- package/dist/compatibility.js +1521 -0
- package/dist/dashboard/assets/index-CEDww1hA.css +2 -0
- package/dist/dashboard/assets/index-DrnM3oWy.js +84 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/dashboard.d.ts +5 -2
- package/dist/dashboard.js +200 -75
- package/dist/http.d.ts +9 -6
- package/dist/http.js +258 -150
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/providers/chatgpt.js +2 -0
- package/dist/providers/claude.js +2 -0
- package/dist/providers/copilot.js +0 -2
- package/dist/realtime.d.ts +6 -0
- package/dist/realtime.js +163 -0
- package/dist/store.d.ts +6 -0
- package/dist/store.js +51 -2
- package/examples/direct.mjs +31 -8
- package/examples/server.mjs +17 -5
- package/package.json +9 -1
- package/public/aisubs-dashboard.png +0 -0
- package/dist/dashboard/assets/index-BMoILzPw.js +0 -64
- package/dist/dashboard/assets/index-DHqDdNVe.css +0 -2
package/dist/auth.d.ts
CHANGED
|
@@ -66,6 +66,8 @@ export declare class SubscriptionAuth {
|
|
|
66
66
|
details(provider: ProviderId, account?: string, signal?: AbortSignal): Promise<SubscriptionAccountDetails>;
|
|
67
67
|
fetch(provider: ProviderId, input: string | URL | Request, init?: RequestInit, account?: string): Promise<Response>;
|
|
68
68
|
proxy(provider: ProviderId, account: string, path: string, init?: RequestInit): Promise<Response>;
|
|
69
|
+
/** Build an authorized direct-provider request for transports such as WebSocket. */
|
|
70
|
+
authorizeProxyRequest(provider: ProviderId, account: string, path: string, init?: RequestInit): Promise<Request>;
|
|
69
71
|
getUsage(provider: ProviderId, account?: string, callerSignal?: AbortSignal): Promise<ProviderUsage | null>;
|
|
70
72
|
getModels(provider: ProviderId, account?: string, callerSignal?: AbortSignal): Promise<ProviderModels | null>;
|
|
71
73
|
account(provider: ProviderId, account: string): SubscriptionAccount;
|
package/dist/auth.js
CHANGED
|
@@ -19,6 +19,11 @@ function normalizeAccountKey(value) {
|
|
|
19
19
|
}
|
|
20
20
|
return account;
|
|
21
21
|
}
|
|
22
|
+
function createRequest(input, init) {
|
|
23
|
+
return new Request(input, init?.body instanceof ReadableStream
|
|
24
|
+
? { ...init, duplex: "half" }
|
|
25
|
+
: init);
|
|
26
|
+
}
|
|
22
27
|
function credentialKey(provider, accountKey) {
|
|
23
28
|
if (accountKey === DEFAULT_ACCOUNT)
|
|
24
29
|
return provider;
|
|
@@ -375,7 +380,7 @@ export class SubscriptionAuth {
|
|
|
375
380
|
}
|
|
376
381
|
async fetch(provider, input, init, account = DEFAULT_ACCOUNT) {
|
|
377
382
|
const adapter = this.adapter(provider);
|
|
378
|
-
const original =
|
|
383
|
+
const original = createRequest(input, init);
|
|
379
384
|
const accountKey = normalizeAccountKey(account);
|
|
380
385
|
const send = async (credential) => {
|
|
381
386
|
const authorized = await adapter.authorize(original.clone(), credential);
|
|
@@ -400,7 +405,7 @@ export class SubscriptionAuth {
|
|
|
400
405
|
const accountKey = normalizeAccountKey(account);
|
|
401
406
|
const credential = await this.credential(provider, accountKey);
|
|
402
407
|
if (adapter.proxy) {
|
|
403
|
-
const local =
|
|
408
|
+
const local = createRequest(`http://aisubs.local/${path.replace(/^\//, "")}`, init);
|
|
404
409
|
let response = await adapter.proxy(local.clone(), credential);
|
|
405
410
|
if (response.status === 401) {
|
|
406
411
|
await response.body?.cancel();
|
|
@@ -416,6 +421,22 @@ export class SubscriptionAuth {
|
|
|
416
421
|
const base = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
417
422
|
return this.fetch(provider, new URL(path, base), init, accountKey);
|
|
418
423
|
}
|
|
424
|
+
/** Build an authorized direct-provider request for transports such as WebSocket. */
|
|
425
|
+
async authorizeProxyRequest(provider, account, path, init) {
|
|
426
|
+
const adapter = this.adapter(provider);
|
|
427
|
+
const accountKey = normalizeAccountKey(account);
|
|
428
|
+
if (adapter.proxy) {
|
|
429
|
+
throw new Error(`${provider} does not expose a direct transport endpoint`);
|
|
430
|
+
}
|
|
431
|
+
const credential = await this.credential(provider, accountKey);
|
|
432
|
+
const baseUrl = typeof adapter.proxyBaseUrl === "function"
|
|
433
|
+
? adapter.proxyBaseUrl(credential)
|
|
434
|
+
: adapter.proxyBaseUrl;
|
|
435
|
+
if (!baseUrl)
|
|
436
|
+
throw new Error(`${provider} does not expose a direct API endpoint`);
|
|
437
|
+
const base = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
438
|
+
return adapter.authorize(createRequest(new URL(path, base), init), credential);
|
|
439
|
+
}
|
|
419
440
|
async getUsage(provider, account = DEFAULT_ACCOUNT, callerSignal) {
|
|
420
441
|
const adapter = this.adapter(provider);
|
|
421
442
|
if (!adapter.getUsage)
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import { claudeProvider } from "./providers/claude.js";
|
|
|
8
8
|
import { copilotProvider } from "./providers/copilot.js";
|
|
9
9
|
import { grokProvider } from "./providers/grok.js";
|
|
10
10
|
import { openCodeGoProvider, openCodeZenProvider } from "./providers/opencode.js";
|
|
11
|
-
import { defaultAiSubsDataDir, FileCredentialStore } from "./store.js";
|
|
11
|
+
import { defaultAiSubsDataDir, FileApiKeyStore, FileCredentialStore } from "./store.js";
|
|
12
12
|
const DEFAULT_DASHBOARD_PORT = 4319;
|
|
13
13
|
function usage() {
|
|
14
14
|
console.log(`AI Subs
|
|
@@ -62,6 +62,7 @@ async function main() {
|
|
|
62
62
|
if (!Number.isInteger(port) || port < 0 || port > 65535)
|
|
63
63
|
throw new Error("Invalid port");
|
|
64
64
|
const store = new FileCredentialStore(join(dataDirectory, "credentials.json"));
|
|
65
|
+
const apiKeys = new FileApiKeyStore(join(dataDirectory, "api-key"));
|
|
65
66
|
const auth = createSubscriptionAuth({
|
|
66
67
|
store,
|
|
67
68
|
providers: [
|
|
@@ -73,14 +74,16 @@ async function main() {
|
|
|
73
74
|
openCodeZenProvider(),
|
|
74
75
|
],
|
|
75
76
|
});
|
|
76
|
-
const dashboard = await createSubscriptionAuthDashboardServer({
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
const dashboard = await createSubscriptionAuthDashboardServer({
|
|
78
|
+
auth,
|
|
79
|
+
apiKey: await apiKeys.readOrCreate(),
|
|
80
|
+
regenerateApiKey: () => apiKeys.regenerate(),
|
|
81
|
+
port,
|
|
82
|
+
});
|
|
83
|
+
console.log(`AI Subs is running at \u001b]8;;${dashboard.url}\u0007${dashboard.url}\u001b]8;;\u0007`);
|
|
81
84
|
console.log("Press Ctrl+C to stop.");
|
|
82
85
|
if (shouldOpen)
|
|
83
|
-
openBrowser(dashboard.
|
|
86
|
+
openBrowser(dashboard.url);
|
|
84
87
|
let closing = false;
|
|
85
88
|
const close = async () => {
|
|
86
89
|
if (closing)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SubscriptionAuth } from "./auth.js";
|
|
2
|
+
import type { ProviderId } from "./types.js";
|
|
3
|
+
export type WireProtocol = "responses" | "chat/completions" | "messages" | "google";
|
|
4
|
+
export declare class CompatibilityError extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
readonly status: number;
|
|
7
|
+
constructor(message: string, code?: string, status?: number);
|
|
8
|
+
}
|
|
9
|
+
export declare function requestProtocol(path: string): {
|
|
10
|
+
protocol: WireProtocol;
|
|
11
|
+
model?: string;
|
|
12
|
+
stream?: boolean;
|
|
13
|
+
} | null;
|
|
14
|
+
export declare function proxyCompatible(auth: SubscriptionAuth, provider: ProviderId, account: string, path: string, body: Buffer, headers: Headers, signal?: AbortSignal): Promise<Response | null>;
|