@hushhenry/ai-gateway 1.0.0 → 1.0.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.
- package/dist/cli.js +4 -3
- package/dist/core/auth.js +9 -2
- package/dist/core/gateway.js +4 -4
- package/dist/core/providers.js +2 -2
- package/dist/tui/settings.js +46 -0
- package/package.json +6 -1
package/dist/cli.js
CHANGED
|
@@ -23,8 +23,9 @@ program.command('serve')
|
|
|
23
23
|
});
|
|
24
24
|
program.command('login')
|
|
25
25
|
.description('Configure providers (TUI)')
|
|
26
|
-
.action(() => {
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
.action(async () => {
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
const { runLoginTui } = await import('./tui/settings.js');
|
|
29
|
+
await runLoginTui();
|
|
29
30
|
});
|
|
30
31
|
program.parse();
|
package/dist/core/auth.js
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.saveAuth = saveAuth;
|
|
3
4
|
exports.loadAuth = loadAuth;
|
|
4
5
|
exports.getCredentials = getCredentials;
|
|
5
6
|
const fs_1 = require("fs");
|
|
6
7
|
const path_1 = require("path");
|
|
7
8
|
const os_1 = require("os");
|
|
8
9
|
const DEFAULT_CONFIG_DIR = (0, path_1.join)((0, os_1.homedir)(), '.config', 'ai-gateway');
|
|
9
|
-
const PI_CONFIG_DIR = (0, path_1.join)((0, os_1.homedir)(), '.config', 'pi');
|
|
10
10
|
const AUTH_FILE = 'auth.json';
|
|
11
|
+
function saveAuth(auth, configPath) {
|
|
12
|
+
const p = configPath || (0, path_1.join)(DEFAULT_CONFIG_DIR, AUTH_FILE);
|
|
13
|
+
const dir = (0, path_1.dirname)(p);
|
|
14
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
15
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
(0, fs_1.writeFileSync)(p, JSON.stringify(auth, null, 2), 'utf-8');
|
|
18
|
+
}
|
|
11
19
|
function loadAuth(configPath) {
|
|
12
20
|
const pathsToCheck = [];
|
|
13
21
|
if (configPath)
|
|
14
22
|
pathsToCheck.push(configPath);
|
|
15
23
|
pathsToCheck.push((0, path_1.join)(DEFAULT_CONFIG_DIR, AUTH_FILE));
|
|
16
|
-
pathsToCheck.push((0, path_1.join)(PI_CONFIG_DIR, AUTH_FILE));
|
|
17
24
|
for (const p of pathsToCheck) {
|
|
18
25
|
if ((0, fs_1.existsSync)(p)) {
|
|
19
26
|
try {
|
package/dist/core/gateway.js
CHANGED
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AiGateway = void 0;
|
|
4
4
|
const hono_1 = require("hono");
|
|
5
5
|
const ai_1 = require("ai");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const providers_js_1 = require("./providers.js");
|
|
7
|
+
const auth_js_1 = require("./auth.js");
|
|
8
8
|
class AiGateway {
|
|
9
9
|
app;
|
|
10
10
|
configPath;
|
|
@@ -15,7 +15,7 @@ class AiGateway {
|
|
|
15
15
|
}
|
|
16
16
|
setupRoutes() {
|
|
17
17
|
this.app.get('/v1/models', async (c) => {
|
|
18
|
-
const auth = (0,
|
|
18
|
+
const auth = (0, auth_js_1.loadAuth)(this.configPath);
|
|
19
19
|
const models = Object.keys(auth).map(id => ({
|
|
20
20
|
id,
|
|
21
21
|
object: 'model',
|
|
@@ -28,7 +28,7 @@ class AiGateway {
|
|
|
28
28
|
const body = await c.req.json();
|
|
29
29
|
const modelId = body.model;
|
|
30
30
|
try {
|
|
31
|
-
const provider = await (0,
|
|
31
|
+
const provider = await (0, providers_js_1.getProvider)(modelId, this.configPath);
|
|
32
32
|
const result = await (0, ai_1.streamText)({
|
|
33
33
|
model: provider,
|
|
34
34
|
messages: body.messages,
|
package/dist/core/providers.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getProvider = getProvider;
|
|
4
|
-
const
|
|
4
|
+
const auth_js_1 = require("./auth.js");
|
|
5
5
|
async function getProvider(modelId, configPath) {
|
|
6
6
|
// Basic routing logic: provider:model
|
|
7
7
|
const [providerBrand, ...modelNameParts] = modelId.split(':');
|
|
8
8
|
const modelName = modelNameParts.join(':');
|
|
9
|
-
const creds = await (0,
|
|
9
|
+
const creds = await (0, auth_js_1.getCredentials)(providerBrand, configPath);
|
|
10
10
|
if (!creds)
|
|
11
11
|
throw new Error(`No credentials found for provider: ${providerBrand}`);
|
|
12
12
|
switch (providerBrand) {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runLoginTui = runLoginTui;
|
|
4
|
+
const auth_js_1 = require("../core/auth.js");
|
|
5
|
+
const readline_1 = require("readline");
|
|
6
|
+
const PROVIDERS = [
|
|
7
|
+
{ id: 'openai', name: 'OpenAI' },
|
|
8
|
+
{ id: 'anthropic', name: 'Anthropic' },
|
|
9
|
+
{ id: 'google', name: 'Google Gemini' },
|
|
10
|
+
{ id: 'github-copilot', name: 'GitHub Copilot (OAuth)' },
|
|
11
|
+
{ id: 'deepseek', name: 'DeepSeek' },
|
|
12
|
+
{ id: 'openrouter', name: 'OpenRouter' }
|
|
13
|
+
];
|
|
14
|
+
async function runLoginTui() {
|
|
15
|
+
const rl = (0, readline_1.createInterface)({
|
|
16
|
+
input: process.stdin,
|
|
17
|
+
output: process.stdout
|
|
18
|
+
});
|
|
19
|
+
console.log('\nSelect a Provider to configure:\n');
|
|
20
|
+
PROVIDERS.forEach((p, i) => {
|
|
21
|
+
console.log(`${i + 1}. ${p.name}`);
|
|
22
|
+
});
|
|
23
|
+
console.log('');
|
|
24
|
+
const ask = (query) => new Promise(resolve => rl.question(query, resolve));
|
|
25
|
+
const choice = await ask('Enter selection (1-' + PROVIDERS.length + '): ');
|
|
26
|
+
const index = parseInt(choice) - 1;
|
|
27
|
+
if (isNaN(index) || index < 0 || index >= PROVIDERS.length) {
|
|
28
|
+
console.log('Invalid selection.');
|
|
29
|
+
rl.close();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const provider = PROVIDERS[index];
|
|
33
|
+
if (provider.id === 'github-copilot') {
|
|
34
|
+
console.log('\nGitHub Copilot OAuth requires complex flow. Please use pi-ai login or manually add token for now.');
|
|
35
|
+
rl.close();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const apiKey = await ask(`Enter API Key for ${provider.name}: `);
|
|
39
|
+
if (apiKey) {
|
|
40
|
+
const auth = (0, auth_js_1.loadAuth)();
|
|
41
|
+
auth[provider.id] = { apiKey, type: 'key' };
|
|
42
|
+
(0, auth_js_1.saveAuth)(auth);
|
|
43
|
+
console.log(`\nSuccessfully saved credentials for ${provider.name}`);
|
|
44
|
+
}
|
|
45
|
+
rl.close();
|
|
46
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hushhenry/ai-gateway",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A TypeScript AI proxy supporting CLI and Library modes, built with Vercel AI SDK and pi-mono TUI/OAuth logic.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -31,13 +31,18 @@
|
|
|
31
31
|
"@ai-sdk/google": "^1.1.0",
|
|
32
32
|
"@ai-sdk/openai": "^1.1.0",
|
|
33
33
|
"@hono/node-server": "^1.19.9",
|
|
34
|
+
"@types/react": "^19.2.14",
|
|
34
35
|
"ai": "^4.1.0",
|
|
35
36
|
"commander": "^12.0.0",
|
|
36
37
|
"hono": "^4.0.0",
|
|
38
|
+
"ink": "^6.7.0",
|
|
39
|
+
"lucide-react": "^0.564.0",
|
|
40
|
+
"react": "^19.2.4",
|
|
37
41
|
"zod": "^3.23.0"
|
|
38
42
|
},
|
|
39
43
|
"devDependencies": {
|
|
40
44
|
"@types/node": "^20.19.33",
|
|
45
|
+
"@types/react-dom": "^19.2.3",
|
|
41
46
|
"typescript": "^5.0.0"
|
|
42
47
|
}
|
|
43
48
|
}
|