@lenylvt/pi-ai 0.64.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/README.md +203 -0
- package/dist/api-registry.d.ts +20 -0
- package/dist/api-registry.d.ts.map +1 -0
- package/dist/api-registry.js +44 -0
- package/dist/api-registry.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +119 -0
- package/dist/cli.js.map +1 -0
- package/dist/env-api-keys.d.ts +7 -0
- package/dist/env-api-keys.d.ts.map +1 -0
- package/dist/env-api-keys.js +13 -0
- package/dist/env-api-keys.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/models.d.ts +24 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.generated.d.ts +2332 -0
- package/dist/models.generated.d.ts.map +1 -0
- package/dist/models.generated.js +2186 -0
- package/dist/models.generated.js.map +1 -0
- package/dist/models.js +60 -0
- package/dist/models.js.map +1 -0
- package/dist/oauth.d.ts +2 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +2 -0
- package/dist/oauth.js.map +1 -0
- package/dist/providers/anthropic.d.ts +40 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +749 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/faux.d.ts +56 -0
- package/dist/providers/faux.d.ts.map +1 -0
- package/dist/providers/faux.js +367 -0
- package/dist/providers/faux.js.map +1 -0
- package/dist/providers/github-copilot-headers.d.ts +8 -0
- package/dist/providers/github-copilot-headers.d.ts.map +1 -0
- package/dist/providers/github-copilot-headers.js +29 -0
- package/dist/providers/github-copilot-headers.js.map +1 -0
- package/dist/providers/openai-codex-responses.d.ts +9 -0
- package/dist/providers/openai-codex-responses.d.ts.map +1 -0
- package/dist/providers/openai-codex-responses.js +741 -0
- package/dist/providers/openai-codex-responses.js.map +1 -0
- package/dist/providers/openai-completions.d.ts +15 -0
- package/dist/providers/openai-completions.d.ts.map +1 -0
- package/dist/providers/openai-completions.js +687 -0
- package/dist/providers/openai-completions.js.map +1 -0
- package/dist/providers/openai-responses-shared.d.ts +17 -0
- package/dist/providers/openai-responses-shared.d.ts.map +1 -0
- package/dist/providers/openai-responses-shared.js +458 -0
- package/dist/providers/openai-responses-shared.js.map +1 -0
- package/dist/providers/openai-responses.d.ts +13 -0
- package/dist/providers/openai-responses.d.ts.map +1 -0
- package/dist/providers/openai-responses.js +190 -0
- package/dist/providers/openai-responses.js.map +1 -0
- package/dist/providers/register-builtins.d.ts +16 -0
- package/dist/providers/register-builtins.d.ts.map +1 -0
- package/dist/providers/register-builtins.js +140 -0
- package/dist/providers/register-builtins.js.map +1 -0
- package/dist/providers/simple-options.d.ts +8 -0
- package/dist/providers/simple-options.d.ts.map +1 -0
- package/dist/providers/simple-options.js +35 -0
- package/dist/providers/simple-options.js.map +1 -0
- package/dist/providers/transform-messages.d.ts +8 -0
- package/dist/providers/transform-messages.d.ts.map +1 -0
- package/dist/providers/transform-messages.js +155 -0
- package/dist/providers/transform-messages.js.map +1 -0
- package/dist/stream.d.ts +8 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +27 -0
- package/dist/stream.js.map +1 -0
- package/dist/types.d.ts +283 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/event-stream.d.ts +21 -0
- package/dist/utils/event-stream.d.ts.map +1 -0
- package/dist/utils/event-stream.js +81 -0
- package/dist/utils/event-stream.js.map +1 -0
- package/dist/utils/hash.d.ts +3 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +14 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/json-parse.d.ts +9 -0
- package/dist/utils/json-parse.d.ts.map +1 -0
- package/dist/utils/json-parse.js +29 -0
- package/dist/utils/json-parse.js.map +1 -0
- package/dist/utils/oauth/anthropic.d.ts +25 -0
- package/dist/utils/oauth/anthropic.d.ts.map +1 -0
- package/dist/utils/oauth/anthropic.js +335 -0
- package/dist/utils/oauth/anthropic.js.map +1 -0
- package/dist/utils/oauth/github-copilot.d.ts +30 -0
- package/dist/utils/oauth/github-copilot.d.ts.map +1 -0
- package/dist/utils/oauth/github-copilot.js +292 -0
- package/dist/utils/oauth/github-copilot.js.map +1 -0
- package/dist/utils/oauth/index.d.ts +36 -0
- package/dist/utils/oauth/index.d.ts.map +1 -0
- package/dist/utils/oauth/index.js +92 -0
- package/dist/utils/oauth/index.js.map +1 -0
- package/dist/utils/oauth/oauth-page.d.ts +3 -0
- package/dist/utils/oauth/oauth-page.d.ts.map +1 -0
- package/dist/utils/oauth/oauth-page.js +105 -0
- package/dist/utils/oauth/oauth-page.js.map +1 -0
- package/dist/utils/oauth/openai-codex.d.ts +34 -0
- package/dist/utils/oauth/openai-codex.d.ts.map +1 -0
- package/dist/utils/oauth/openai-codex.js +373 -0
- package/dist/utils/oauth/openai-codex.js.map +1 -0
- package/dist/utils/oauth/pkce.d.ts +13 -0
- package/dist/utils/oauth/pkce.d.ts.map +1 -0
- package/dist/utils/oauth/pkce.js +31 -0
- package/dist/utils/oauth/pkce.js.map +1 -0
- package/dist/utils/oauth/types.d.ts +47 -0
- package/dist/utils/oauth/types.d.ts.map +1 -0
- package/dist/utils/oauth/types.js +2 -0
- package/dist/utils/oauth/types.js.map +1 -0
- package/dist/utils/overflow.d.ts +53 -0
- package/dist/utils/overflow.d.ts.map +1 -0
- package/dist/utils/overflow.js +119 -0
- package/dist/utils/overflow.js.map +1 -0
- package/dist/utils/sanitize-unicode.d.ts +22 -0
- package/dist/utils/sanitize-unicode.d.ts.map +1 -0
- package/dist/utils/sanitize-unicode.js +26 -0
- package/dist/utils/sanitize-unicode.js.map +1 -0
- package/dist/utils/typebox-helpers.d.ts +17 -0
- package/dist/utils/typebox-helpers.d.ts.map +1 -0
- package/dist/utils/typebox-helpers.js +21 -0
- package/dist/utils/typebox-helpers.js.map +1 -0
- package/dist/utils/validation.d.ts +18 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +80 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +89 -0
- package/src/api-registry.ts +98 -0
- package/src/cli.ts +136 -0
- package/src/env-api-keys.ts +22 -0
- package/src/index.ts +29 -0
- package/src/models.generated.ts +2188 -0
- package/src/models.ts +82 -0
- package/src/oauth.ts +1 -0
- package/src/providers/anthropic.ts +905 -0
- package/src/providers/faux.ts +498 -0
- package/src/providers/github-copilot-headers.ts +37 -0
- package/src/providers/openai-codex-responses.ts +929 -0
- package/src/providers/openai-completions.ts +811 -0
- package/src/providers/openai-responses-shared.ts +513 -0
- package/src/providers/openai-responses.ts +251 -0
- package/src/providers/register-builtins.ts +232 -0
- package/src/providers/simple-options.ts +46 -0
- package/src/providers/transform-messages.ts +172 -0
- package/src/stream.ts +59 -0
- package/src/types.ts +294 -0
- package/src/utils/event-stream.ts +87 -0
- package/src/utils/hash.ts +13 -0
- package/src/utils/json-parse.ts +28 -0
- package/src/utils/oauth/anthropic.ts +402 -0
- package/src/utils/oauth/github-copilot.ts +396 -0
- package/src/utils/oauth/index.ts +123 -0
- package/src/utils/oauth/oauth-page.ts +109 -0
- package/src/utils/oauth/openai-codex.ts +450 -0
- package/src/utils/oauth/pkce.ts +34 -0
- package/src/utils/oauth/types.ts +59 -0
- package/src/utils/overflow.ts +125 -0
- package/src/utils/sanitize-unicode.ts +25 -0
- package/src/utils/typebox-helpers.ts +24 -0
- package/src/utils/validation.ts +93 -0
package/package.json
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lenylvt/pi-ai",
|
|
3
|
+
"version": "0.64.0",
|
|
4
|
+
"description": "Unified LLM API for Anthropic, GitHub Copilot, OpenAI Codex, and OpenRouter",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"bun": "./src/index.ts",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./anthropic": {
|
|
15
|
+
"bun": "./src/providers/anthropic.ts",
|
|
16
|
+
"types": "./dist/providers/anthropic.d.ts",
|
|
17
|
+
"import": "./dist/providers/anthropic.js"
|
|
18
|
+
},
|
|
19
|
+
"./openai-codex-responses": {
|
|
20
|
+
"bun": "./src/providers/openai-codex-responses.ts",
|
|
21
|
+
"types": "./dist/providers/openai-codex-responses.d.ts",
|
|
22
|
+
"import": "./dist/providers/openai-codex-responses.js"
|
|
23
|
+
},
|
|
24
|
+
"./openai-completions": {
|
|
25
|
+
"bun": "./src/providers/openai-completions.ts",
|
|
26
|
+
"types": "./dist/providers/openai-completions.d.ts",
|
|
27
|
+
"import": "./dist/providers/openai-completions.js"
|
|
28
|
+
},
|
|
29
|
+
"./openai-responses": {
|
|
30
|
+
"bun": "./src/providers/openai-responses.ts",
|
|
31
|
+
"types": "./dist/providers/openai-responses.d.ts",
|
|
32
|
+
"import": "./dist/providers/openai-responses.js"
|
|
33
|
+
},
|
|
34
|
+
"./oauth": {
|
|
35
|
+
"bun": "./src/oauth.ts",
|
|
36
|
+
"types": "./dist/oauth.d.ts",
|
|
37
|
+
"import": "./dist/oauth.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"bin": {
|
|
41
|
+
"pi-ai": "./dist/cli.js"
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"src",
|
|
46
|
+
"README.md"
|
|
47
|
+
],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"clean": "shx rm -rf dist",
|
|
50
|
+
"generate-models": "bun ./scripts/generate-models.ts",
|
|
51
|
+
"build": "bun run generate-models && tsgo -p tsconfig.build.json",
|
|
52
|
+
"dev": "tsgo -p tsconfig.build.json --watch --preserveWatchOutput",
|
|
53
|
+
"dev:tsc": "tsgo -p tsconfig.build.json --watch --preserveWatchOutput",
|
|
54
|
+
"test": "vitest --run",
|
|
55
|
+
"prepublishOnly": "bun run clean && bun run build"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@anthropic-ai/sdk": "^0.73.0",
|
|
59
|
+
"@sinclair/typebox": "^0.34.41",
|
|
60
|
+
"ajv": "^8.17.1",
|
|
61
|
+
"ajv-formats": "^3.0.1",
|
|
62
|
+
"chalk": "^5.6.2",
|
|
63
|
+
"openai": "6.26.0",
|
|
64
|
+
"partial-json": "^0.1.7",
|
|
65
|
+
"proxy-agent": "^6.5.0",
|
|
66
|
+
"undici": "^7.19.1",
|
|
67
|
+
"zod-to-json-schema": "^3.24.6"
|
|
68
|
+
},
|
|
69
|
+
"keywords": [
|
|
70
|
+
"ai",
|
|
71
|
+
"llm",
|
|
72
|
+
"anthropic",
|
|
73
|
+
"codex",
|
|
74
|
+
"copilot",
|
|
75
|
+
"openrouter",
|
|
76
|
+
"unified",
|
|
77
|
+
"api"
|
|
78
|
+
],
|
|
79
|
+
"author": "Mario Zechner",
|
|
80
|
+
"license": "MIT",
|
|
81
|
+
"engines": {
|
|
82
|
+
"node": ">=20.0.0"
|
|
83
|
+
},
|
|
84
|
+
"devDependencies": {
|
|
85
|
+
"@types/node": "^24.3.0",
|
|
86
|
+
"canvas": "^3.2.0",
|
|
87
|
+
"vitest": "^3.2.4"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Api,
|
|
3
|
+
AssistantMessageEventStream,
|
|
4
|
+
Context,
|
|
5
|
+
Model,
|
|
6
|
+
SimpleStreamOptions,
|
|
7
|
+
StreamFunction,
|
|
8
|
+
StreamOptions,
|
|
9
|
+
} from "./types.js";
|
|
10
|
+
|
|
11
|
+
export type ApiStreamFunction = (
|
|
12
|
+
model: Model<Api>,
|
|
13
|
+
context: Context,
|
|
14
|
+
options?: StreamOptions,
|
|
15
|
+
) => AssistantMessageEventStream;
|
|
16
|
+
|
|
17
|
+
export type ApiStreamSimpleFunction = (
|
|
18
|
+
model: Model<Api>,
|
|
19
|
+
context: Context,
|
|
20
|
+
options?: SimpleStreamOptions,
|
|
21
|
+
) => AssistantMessageEventStream;
|
|
22
|
+
|
|
23
|
+
export interface ApiProvider<TApi extends Api = Api, TOptions extends StreamOptions = StreamOptions> {
|
|
24
|
+
api: TApi;
|
|
25
|
+
stream: StreamFunction<TApi, TOptions>;
|
|
26
|
+
streamSimple: StreamFunction<TApi, SimpleStreamOptions>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface ApiProviderInternal {
|
|
30
|
+
api: Api;
|
|
31
|
+
stream: ApiStreamFunction;
|
|
32
|
+
streamSimple: ApiStreamSimpleFunction;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type RegisteredApiProvider = {
|
|
36
|
+
provider: ApiProviderInternal;
|
|
37
|
+
sourceId?: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const apiProviderRegistry = new Map<string, RegisteredApiProvider>();
|
|
41
|
+
|
|
42
|
+
function wrapStream<TApi extends Api, TOptions extends StreamOptions>(
|
|
43
|
+
api: TApi,
|
|
44
|
+
stream: StreamFunction<TApi, TOptions>,
|
|
45
|
+
): ApiStreamFunction {
|
|
46
|
+
return (model, context, options) => {
|
|
47
|
+
if (model.api !== api) {
|
|
48
|
+
throw new Error(`Mismatched api: ${model.api} expected ${api}`);
|
|
49
|
+
}
|
|
50
|
+
return stream(model as Model<TApi>, context, options as TOptions);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function wrapStreamSimple<TApi extends Api>(
|
|
55
|
+
api: TApi,
|
|
56
|
+
streamSimple: StreamFunction<TApi, SimpleStreamOptions>,
|
|
57
|
+
): ApiStreamSimpleFunction {
|
|
58
|
+
return (model, context, options) => {
|
|
59
|
+
if (model.api !== api) {
|
|
60
|
+
throw new Error(`Mismatched api: ${model.api} expected ${api}`);
|
|
61
|
+
}
|
|
62
|
+
return streamSimple(model as Model<TApi>, context, options);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function registerApiProvider<TApi extends Api, TOptions extends StreamOptions>(
|
|
67
|
+
provider: ApiProvider<TApi, TOptions>,
|
|
68
|
+
sourceId?: string,
|
|
69
|
+
): void {
|
|
70
|
+
apiProviderRegistry.set(provider.api, {
|
|
71
|
+
provider: {
|
|
72
|
+
api: provider.api,
|
|
73
|
+
stream: wrapStream(provider.api, provider.stream),
|
|
74
|
+
streamSimple: wrapStreamSimple(provider.api, provider.streamSimple),
|
|
75
|
+
},
|
|
76
|
+
sourceId,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function getApiProvider(api: Api): ApiProviderInternal | undefined {
|
|
81
|
+
return apiProviderRegistry.get(api)?.provider;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function getApiProviders(): ApiProviderInternal[] {
|
|
85
|
+
return Array.from(apiProviderRegistry.values(), (entry) => entry.provider);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function unregisterApiProviders(sourceId: string): void {
|
|
89
|
+
for (const [api, entry] of apiProviderRegistry.entries()) {
|
|
90
|
+
if (entry.sourceId === sourceId) {
|
|
91
|
+
apiProviderRegistry.delete(api);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function clearApiProviders(): void {
|
|
97
|
+
apiProviderRegistry.clear();
|
|
98
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
4
|
+
import { createInterface } from "readline";
|
|
5
|
+
import { getOAuthProvider, getOAuthProviders } from "./utils/oauth/index.js";
|
|
6
|
+
import type { OAuthCredentials, OAuthProviderId } from "./utils/oauth/types.js";
|
|
7
|
+
|
|
8
|
+
const AUTH_FILE = "auth.json";
|
|
9
|
+
const PROVIDERS = getOAuthProviders();
|
|
10
|
+
|
|
11
|
+
function prompt(rl: ReturnType<typeof createInterface>, question: string): Promise<string> {
|
|
12
|
+
return new Promise((resolve) => rl.question(question, resolve));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function loadAuth(): Record<string, { type: "oauth" } & OAuthCredentials> {
|
|
16
|
+
if (!existsSync(AUTH_FILE)) return {};
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(readFileSync(AUTH_FILE, "utf-8"));
|
|
19
|
+
} catch {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function saveAuth(auth: Record<string, { type: "oauth" } & OAuthCredentials>): void {
|
|
25
|
+
writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), "utf-8");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function login(providerId: OAuthProviderId): Promise<void> {
|
|
29
|
+
const provider = getOAuthProvider(providerId);
|
|
30
|
+
if (!provider) {
|
|
31
|
+
console.error(`Unknown provider: ${providerId}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
36
|
+
const promptFn = (msg: string) => prompt(rl, `${msg} `);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const credentials = await provider.login({
|
|
40
|
+
onAuth: (info) => {
|
|
41
|
+
console.log(`\nOpen this URL in your browser:\n${info.url}`);
|
|
42
|
+
if (info.instructions) console.log(info.instructions);
|
|
43
|
+
console.log();
|
|
44
|
+
},
|
|
45
|
+
onPrompt: async (p) => {
|
|
46
|
+
return await promptFn(`${p.message}${p.placeholder ? ` (${p.placeholder})` : ""}:`);
|
|
47
|
+
},
|
|
48
|
+
onProgress: (msg) => console.log(msg),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const auth = loadAuth();
|
|
52
|
+
auth[providerId] = { type: "oauth", ...credentials };
|
|
53
|
+
saveAuth(auth);
|
|
54
|
+
|
|
55
|
+
console.log(`\nCredentials saved to ${AUTH_FILE}`);
|
|
56
|
+
} finally {
|
|
57
|
+
rl.close();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function main(): Promise<void> {
|
|
62
|
+
const args = process.argv.slice(2);
|
|
63
|
+
const command = args[0];
|
|
64
|
+
|
|
65
|
+
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
66
|
+
const providerList = PROVIDERS.map((p) => ` ${p.id.padEnd(20)} ${p.name}`).join("\n");
|
|
67
|
+
console.log(`Usage: bunx @lenylvt/pi-ai <command> [provider]
|
|
68
|
+
|
|
69
|
+
Commands:
|
|
70
|
+
login [provider] Login to an OAuth provider
|
|
71
|
+
list List available providers
|
|
72
|
+
|
|
73
|
+
Providers:
|
|
74
|
+
${providerList}
|
|
75
|
+
|
|
76
|
+
Examples:
|
|
77
|
+
bunx @lenylvt/pi-ai login # interactive provider selection
|
|
78
|
+
bunx @lenylvt/pi-ai login anthropic # login to specific provider
|
|
79
|
+
bunx @lenylvt/pi-ai list # list providers
|
|
80
|
+
`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (command === "list") {
|
|
85
|
+
console.log("Available OAuth providers:\n");
|
|
86
|
+
for (const p of PROVIDERS) {
|
|
87
|
+
console.log(` ${p.id.padEnd(20)} ${p.name}`);
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (command === "login") {
|
|
93
|
+
let provider = args[1] as OAuthProviderId | undefined;
|
|
94
|
+
|
|
95
|
+
if (!provider) {
|
|
96
|
+
const rl = createInterface({
|
|
97
|
+
input: process.stdin,
|
|
98
|
+
output: process.stdout,
|
|
99
|
+
});
|
|
100
|
+
console.log("Select a provider:\n");
|
|
101
|
+
for (let i = 0; i < PROVIDERS.length; i++) {
|
|
102
|
+
console.log(` ${i + 1}. ${PROVIDERS[i].name}`);
|
|
103
|
+
}
|
|
104
|
+
console.log();
|
|
105
|
+
|
|
106
|
+
const choice = await prompt(rl, `Enter number (1-${PROVIDERS.length}): `);
|
|
107
|
+
rl.close();
|
|
108
|
+
|
|
109
|
+
const index = parseInt(choice, 10) - 1;
|
|
110
|
+
if (index < 0 || index >= PROVIDERS.length) {
|
|
111
|
+
console.error("Invalid selection");
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
provider = PROVIDERS[index].id;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!PROVIDERS.some((p) => p.id === provider)) {
|
|
118
|
+
console.error(`Unknown provider: ${provider}`);
|
|
119
|
+
console.error(`Use 'bunx @lenylvt/pi-ai list' to see available providers`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.log(`Logging in to ${provider}...`);
|
|
124
|
+
await login(provider);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
console.error(`Unknown command: ${command}`);
|
|
129
|
+
console.error(`Use 'bunx @lenylvt/pi-ai --help' for usage`);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
main().catch((err) => {
|
|
134
|
+
console.error("Error:", err.message);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { KnownProvider } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get API key for a supported built-in provider from environment variables.
|
|
5
|
+
*/
|
|
6
|
+
export function getEnvApiKey(provider: KnownProvider): string | undefined;
|
|
7
|
+
export function getEnvApiKey(provider: string): string | undefined;
|
|
8
|
+
export function getEnvApiKey(provider: string): string | undefined {
|
|
9
|
+
if (provider === "anthropic") {
|
|
10
|
+
return process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (provider === "github-copilot") {
|
|
14
|
+
return process.env.COPILOT_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (provider === "openrouter") {
|
|
18
|
+
return process.env.OPENROUTER_API_KEY;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type { Static, TSchema } from "@sinclair/typebox";
|
|
2
|
+
export { Type } from "@sinclair/typebox";
|
|
3
|
+
|
|
4
|
+
export * from "./api-registry.js";
|
|
5
|
+
export * from "./env-api-keys.js";
|
|
6
|
+
export * from "./models.js";
|
|
7
|
+
export type { AnthropicOptions } from "./providers/anthropic.js";
|
|
8
|
+
export * from "./providers/faux.js";
|
|
9
|
+
export type { OpenAICodexResponsesOptions } from "./providers/openai-codex-responses.js";
|
|
10
|
+
export type { OpenAICompletionsOptions } from "./providers/openai-completions.js";
|
|
11
|
+
export type { OpenAIResponsesOptions } from "./providers/openai-responses.js";
|
|
12
|
+
export * from "./providers/register-builtins.js";
|
|
13
|
+
export * from "./stream.js";
|
|
14
|
+
export * from "./types.js";
|
|
15
|
+
export * from "./utils/event-stream.js";
|
|
16
|
+
export * from "./utils/json-parse.js";
|
|
17
|
+
export type {
|
|
18
|
+
OAuthAuthInfo,
|
|
19
|
+
OAuthCredentials,
|
|
20
|
+
OAuthLoginCallbacks,
|
|
21
|
+
OAuthPrompt,
|
|
22
|
+
OAuthProvider,
|
|
23
|
+
OAuthProviderId,
|
|
24
|
+
OAuthProviderInfo,
|
|
25
|
+
OAuthProviderInterface,
|
|
26
|
+
} from "./utils/oauth/types.js";
|
|
27
|
+
export * from "./utils/overflow.js";
|
|
28
|
+
export * from "./utils/typebox-helpers.js";
|
|
29
|
+
export * from "./utils/validation.js";
|