responses-proxy 0.1.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 +56 -0
- package/cli.js +118 -0
- package/dist/anthropic-messages.js +383 -0
- package/dist/anthropic-messages.test.js +209 -0
- package/dist/audit-log.js +138 -0
- package/dist/audit-log.test.js +480 -0
- package/dist/billing-expiration.js +70 -0
- package/dist/billing-expiration.test.js +114 -0
- package/dist/billing.js +716 -0
- package/dist/billing.test.js +228 -0
- package/dist/chatgpt-oauth-store.js +240 -0
- package/dist/chatgpt-oauth-store.test.js +88 -0
- package/dist/chatgpt-oauth.js +118 -0
- package/dist/chatgpt-oauth.test.js +63 -0
- package/dist/chatgpt-provider-auth.js +60 -0
- package/dist/chatgpt-provider-auth.test.js +101 -0
- package/dist/client/app-icon.svg +17 -0
- package/dist/client/assets/index-C7Vvhst8.js +14 -0
- package/dist/client/assets/index-DpqgYK3L.css +1 -0
- package/dist/client/favicon.svg +17 -0
- package/dist/client/index.html +31 -0
- package/dist/client-config-apply.js +345 -0
- package/dist/client-config-apply.test.js +185 -0
- package/dist/client-token-limits.js +111 -0
- package/dist/client-token-limits.test.js +129 -0
- package/dist/codex-config.js +47 -0
- package/dist/codex-setup.js +87 -0
- package/dist/codex-setup.test.js +30 -0
- package/dist/config.js +314 -0
- package/dist/cost-analytics.js +31 -0
- package/dist/cost-analytics.test.js +38 -0
- package/dist/customer-key-access.js +126 -0
- package/dist/customer-key-access.test.js +178 -0
- package/dist/customer-keys.js +209 -0
- package/dist/customer-keys.test.js +68 -0
- package/dist/customer-usage.js +18 -0
- package/dist/customer-usage.test.js +55 -0
- package/dist/dashboard-auth.js +318 -0
- package/dist/dashboard-auth.test.js +133 -0
- package/dist/dashboard-serving.test.js +235 -0
- package/dist/error-response.js +174 -0
- package/dist/error-response.test.js +88 -0
- package/dist/forward.js +357 -0
- package/dist/health-websocket-manager.js +174 -0
- package/dist/http-rate-limit.js +36 -0
- package/dist/http-rate-limit.test.js +62 -0
- package/dist/kiro-auth.js +136 -0
- package/dist/kiro-auth.test.js +234 -0
- package/dist/kiro-codewhisperer.js +646 -0
- package/dist/kiro-codewhisperer.test.js +219 -0
- package/dist/kiro-device-login.js +338 -0
- package/dist/kiro-eventstream.js +219 -0
- package/dist/kiro-eventstream.test.js +79 -0
- package/dist/kiro-forward.js +401 -0
- package/dist/kiro-import-cli.js +69 -0
- package/dist/kiro-import.js +94 -0
- package/dist/kiro-import.test.js +125 -0
- package/dist/kiro-token-store.js +196 -0
- package/dist/kiro-token-store.test.js +207 -0
- package/dist/krouter-usage.js +243 -0
- package/dist/model-combo-repository.js +147 -0
- package/dist/model-routing.js +69 -0
- package/dist/model-routing.test.js +41 -0
- package/dist/normalize-request.js +531 -0
- package/dist/normalize-request.test.js +277 -0
- package/dist/omv-public-firewall.test.js +11 -0
- package/dist/package.json +17 -0
- package/dist/prompt-cache-state.js +146 -0
- package/dist/prompt-cache-state.test.js +71 -0
- package/dist/prompt-cache.js +229 -0
- package/dist/provider-health-service.js +404 -0
- package/dist/provider-request-parameters.js +107 -0
- package/dist/provider-request-parameters.test.js +26 -0
- package/dist/provider-routing.js +114 -0
- package/dist/provider-routing.test.js +64 -0
- package/dist/provider-usage.js +314 -0
- package/dist/request-timeout-policy.js +61 -0
- package/dist/request-timeout-policy.test.js +40 -0
- package/dist/response-cache.js +69 -0
- package/dist/response-cache.test.js +28 -0
- package/dist/routing-combo-repository.js +300 -0
- package/dist/routing-engine.js +377 -0
- package/dist/routing-integration.js +155 -0
- package/dist/routing-simulation-engine.js +326 -0
- package/dist/rtk-layer.js +483 -0
- package/dist/rtk-layer.test.js +198 -0
- package/dist/runtime-provider-repository.js +1742 -0
- package/dist/runtime-provider-repository.test.js +1177 -0
- package/dist/schema.js +118 -0
- package/dist/schema.test.js +16 -0
- package/dist/sepay-webhook.js +87 -0
- package/dist/sepay-webhook.test.js +142 -0
- package/dist/server-body-limit.test.js +35 -0
- package/dist/server-client-token-limits.test.js +161 -0
- package/dist/server-codex-config-setup.test.js +76 -0
- package/dist/server-http-rate-limit.test.js +80 -0
- package/dist/server-response-cache.test.js +105 -0
- package/dist/server-routes-alias.test.js +39 -0
- package/dist/server-sepay-webhook-security.test.js +59 -0
- package/dist/server.js +5906 -0
- package/dist/session-log.js +178 -0
- package/dist/tailnet-funnel-script.test.js +33 -0
- package/dist/telegram-bot/actions.js +118 -0
- package/dist/telegram-bot/admin-actions.js +103 -0
- package/dist/telegram-bot/auth.js +46 -0
- package/dist/telegram-bot/auth.test.js +1 -0
- package/dist/telegram-bot/bot-identity-repository.js +189 -0
- package/dist/telegram-bot/bot-identity-repository.test.js +78 -0
- package/dist/telegram-bot/callbacks.js +30 -0
- package/dist/telegram-bot/codex-config-delivery.js +38 -0
- package/dist/telegram-bot/codex-config-delivery.test.js +75 -0
- package/dist/telegram-bot/commands/accounts.js +140 -0
- package/dist/telegram-bot/commands/apikey.js +737 -0
- package/dist/telegram-bot/commands/apply.js +265 -0
- package/dist/telegram-bot/commands/clients.js +13 -0
- package/dist/telegram-bot/commands/customer-billing.test.js +271 -0
- package/dist/telegram-bot/commands/grant.js +138 -0
- package/dist/telegram-bot/commands/grant.test.js +217 -0
- package/dist/telegram-bot/commands/help.js +52 -0
- package/dist/telegram-bot/commands/me.js +53 -0
- package/dist/telegram-bot/commands/models.js +6 -0
- package/dist/telegram-bot/commands/oauth.js +64 -0
- package/dist/telegram-bot/commands/plans.js +96 -0
- package/dist/telegram-bot/commands/providers.js +27 -0
- package/dist/telegram-bot/commands/quota.js +10 -0
- package/dist/telegram-bot/commands/renew-user.js +139 -0
- package/dist/telegram-bot/commands/renew-user.test.js +184 -0
- package/dist/telegram-bot/commands/renew.js +1369 -0
- package/dist/telegram-bot/commands/renew.test.js +1633 -0
- package/dist/telegram-bot/commands/start.js +212 -0
- package/dist/telegram-bot/commands/start.test.js +280 -0
- package/dist/telegram-bot/commands/status.js +6 -0
- package/dist/telegram-bot/commands/tailscale.js +15 -0
- package/dist/telegram-bot/commands/tailscale.test.js +76 -0
- package/dist/telegram-bot/commands/test.js +51 -0
- package/dist/telegram-bot/commands/test.test.js +14 -0
- package/dist/telegram-bot/commands/usage.js +10 -0
- package/dist/telegram-bot/config.js +98 -0
- package/dist/telegram-bot/config.test.js +42 -0
- package/dist/telegram-bot/customer-actions.js +160 -0
- package/dist/telegram-bot/customer-api-keys.js +68 -0
- package/dist/telegram-bot/customer-billing.js +72 -0
- package/dist/telegram-bot/customer-workspace-repository.js +134 -0
- package/dist/telegram-bot/customer-workspace-repository.test.js +47 -0
- package/dist/telegram-bot/dashboard-login.js +39 -0
- package/dist/telegram-bot/format.js +140 -0
- package/dist/telegram-bot/grants.js +370 -0
- package/dist/telegram-bot/grants.test.js +290 -0
- package/dist/telegram-bot/index.js +85 -0
- package/dist/telegram-bot/message-cleanup.js +55 -0
- package/dist/telegram-bot/message-cleanup.test.js +77 -0
- package/dist/telegram-bot/message-format.js +45 -0
- package/dist/telegram-bot/message-format.test.js +10 -0
- package/dist/telegram-bot/proxy-client.js +174 -0
- package/dist/telegram-bot/rate-limit.js +95 -0
- package/dist/telegram-bot/rate-limit.test.js +58 -0
- package/dist/telegram-bot/sessions.js +171 -0
- package/dist/telegram-bot/sessions.test.js +107 -0
- package/dist/telegram-bot/telegram-adapter.js +126 -0
- package/dist/telegram-bot/worker.js +63 -0
- package/package.json +39 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Bot } from "grammy";
|
|
2
|
+
import { createAllowlistMiddleware, createCustomerCommandMiddleware } from "./auth.js";
|
|
3
|
+
import { BotIdentityRepository } from "./bot-identity-repository.js";
|
|
4
|
+
import { CustomerWorkspaceRepository } from "./customer-workspace-repository.js";
|
|
5
|
+
import { CustomerKeyRepository } from "../customer-keys.js";
|
|
6
|
+
import { BillingRepository } from "../billing.js";
|
|
7
|
+
import { AuditLogRepository } from "../audit-log.js";
|
|
8
|
+
import { registerCustomerActionCallbacks } from "./customer-actions.js";
|
|
9
|
+
import { registerAccountsCommand } from "./commands/accounts.js";
|
|
10
|
+
import { registerApiKeyCommand } from "./commands/apikey.js";
|
|
11
|
+
import { registerApplyCommand } from "./commands/apply.js";
|
|
12
|
+
import { registerClientsCommand } from "./commands/clients.js";
|
|
13
|
+
import { registerGrantCommand } from "./commands/grant.js";
|
|
14
|
+
import { registerHelpCommand } from "./commands/help.js";
|
|
15
|
+
import { registerMeCommand } from "./commands/me.js";
|
|
16
|
+
import { registerModelsCommand } from "./commands/models.js";
|
|
17
|
+
import { registerOauthCommand } from "./commands/oauth.js";
|
|
18
|
+
import { registerPlansCommand } from "./commands/plans.js";
|
|
19
|
+
import { registerProvidersCommand } from "./commands/providers.js";
|
|
20
|
+
import { registerQuotaCommand } from "./commands/quota.js";
|
|
21
|
+
import { registerRenewCommand } from "./commands/renew.js";
|
|
22
|
+
import { registerRenewUserCommand } from "./commands/renew-user.js";
|
|
23
|
+
import { registerStartCommand } from "./commands/start.js";
|
|
24
|
+
import { registerStatusCommand } from "./commands/status.js";
|
|
25
|
+
import { registerTailscaleCommand } from "./commands/tailscale.js";
|
|
26
|
+
import { registerTestCommand } from "./commands/test.js";
|
|
27
|
+
import { registerUsageCommand } from "./commands/usage.js";
|
|
28
|
+
import { createRateLimitMiddleware, SqliteRateLimiter } from "./rate-limit.js";
|
|
29
|
+
import { SqliteSessionStore } from "./sessions.js";
|
|
30
|
+
import { createCustomerMessageCleanupMiddleware } from "./message-cleanup.js";
|
|
31
|
+
import { DashboardAuthRepository } from "../dashboard-auth.js";
|
|
32
|
+
import { registerDashboardLoginCallbacks } from "./dashboard-login.js";
|
|
33
|
+
export function createTelegramBot(deps) {
|
|
34
|
+
const bot = new Bot(deps.config.telegramBotToken);
|
|
35
|
+
const identities = BotIdentityRepository.create(deps.config.sessionDbPath);
|
|
36
|
+
const workspaces = CustomerWorkspaceRepository.create(deps.config.sessionDbPath);
|
|
37
|
+
const sessions = SqliteSessionStore.create(deps.config.sessionDbPath, deps.config.sessionTtlMs);
|
|
38
|
+
const customerKeys = CustomerKeyRepository.create(deps.config.sessionDbPath);
|
|
39
|
+
const billing = BillingRepository.create(deps.config.sessionDbPath);
|
|
40
|
+
const auditLog = AuditLogRepository.create(deps.config.sessionDbPath);
|
|
41
|
+
const dashboardAuth = DashboardAuthRepository.create(deps.config.sessionDbPath);
|
|
42
|
+
const rateLimiter = SqliteRateLimiter.create(deps.config.sessionDbPath, {
|
|
43
|
+
windowMs: deps.config.rateLimitWindowMs,
|
|
44
|
+
maxRequests: deps.config.rateLimitMaxRequests,
|
|
45
|
+
});
|
|
46
|
+
bot.use(createAllowlistMiddleware(deps.config));
|
|
47
|
+
bot.use(async (ctx, next) => {
|
|
48
|
+
const fromId = ctx.from?.id?.toString();
|
|
49
|
+
const chatId = ctx.chat?.id?.toString();
|
|
50
|
+
if (fromId) {
|
|
51
|
+
identities.upsertUser({
|
|
52
|
+
telegramUserId: fromId,
|
|
53
|
+
username: ctx.from?.username,
|
|
54
|
+
firstName: ctx.from?.first_name,
|
|
55
|
+
lastName: ctx.from?.last_name,
|
|
56
|
+
languageCode: ctx.from?.language_code,
|
|
57
|
+
defaultRole: deps.config.ownerUserIds.has(fromId) ? "owner" : "customer",
|
|
58
|
+
defaultStatus: deps.config.requireAdminApproval ? "pending_approval" : "active",
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (chatId && ctx.chat) {
|
|
62
|
+
identities.upsertChat({
|
|
63
|
+
telegramChatId: chatId,
|
|
64
|
+
chatType: ctx.chat.type,
|
|
65
|
+
title: "title" in ctx.chat ? ctx.chat.title : undefined,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (fromId && chatId) {
|
|
69
|
+
identities.upsertMembership({
|
|
70
|
+
telegramUserId: fromId,
|
|
71
|
+
telegramChatId: chatId,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
await next();
|
|
75
|
+
});
|
|
76
|
+
bot.use(createCustomerCommandMiddleware(deps.config));
|
|
77
|
+
bot.use(createRateLimitMiddleware(rateLimiter));
|
|
78
|
+
bot.use(createCustomerMessageCleanupMiddleware(deps.config));
|
|
79
|
+
registerStartCommand(bot, deps, identities, workspaces, customerKeys, billing);
|
|
80
|
+
registerCustomerActionCallbacks(bot, workspaces, customerKeys, billing, auditLog);
|
|
81
|
+
registerHelpCommand(bot, deps);
|
|
82
|
+
registerMeCommand(bot, identities, workspaces, customerKeys, auditLog);
|
|
83
|
+
registerPlansCommand(bot, deps, billing);
|
|
84
|
+
registerApiKeyCommand(bot, deps, customerKeys, workspaces, billing, auditLog);
|
|
85
|
+
registerTailscaleCommand(bot, deps);
|
|
86
|
+
registerUsageCommand(bot, workspaces, customerKeys, billing);
|
|
87
|
+
registerQuotaCommand(bot, workspaces, customerKeys, billing);
|
|
88
|
+
registerRenewCommand(bot, deps, sessions, identities, workspaces, customerKeys, billing, auditLog);
|
|
89
|
+
registerGrantCommand(bot, deps, identities, workspaces, customerKeys, billing, auditLog);
|
|
90
|
+
registerRenewUserCommand(bot, deps, identities, workspaces, customerKeys, billing, auditLog);
|
|
91
|
+
registerStatusCommand(bot, deps);
|
|
92
|
+
registerProvidersCommand(bot, deps);
|
|
93
|
+
registerClientsCommand(bot, deps);
|
|
94
|
+
registerModelsCommand(bot, deps);
|
|
95
|
+
registerApplyCommand(bot, deps, sessions);
|
|
96
|
+
registerOauthCommand(bot, deps, sessions);
|
|
97
|
+
registerAccountsCommand(bot, deps, sessions);
|
|
98
|
+
registerTestCommand(bot, deps, sessions);
|
|
99
|
+
registerDashboardLoginCallbacks(bot, deps.config, dashboardAuth);
|
|
100
|
+
bot.catch((error) => {
|
|
101
|
+
const ctx = error.ctx;
|
|
102
|
+
console.error("telegram bot error", {
|
|
103
|
+
error: error.error instanceof Error
|
|
104
|
+
? {
|
|
105
|
+
name: error.error.name,
|
|
106
|
+
message: error.error.message,
|
|
107
|
+
stack: error.error.stack,
|
|
108
|
+
}
|
|
109
|
+
: error.error,
|
|
110
|
+
updateType: resolveUpdateType(ctx.update),
|
|
111
|
+
chatId: ctx.chat?.id,
|
|
112
|
+
fromId: ctx.from?.id,
|
|
113
|
+
callbackData: ctx.callbackQuery?.data,
|
|
114
|
+
messageText: ctx.message && "text" in ctx.message ? ctx.message.text : undefined,
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
return bot;
|
|
118
|
+
}
|
|
119
|
+
function resolveUpdateType(update) {
|
|
120
|
+
for (const key of Object.keys(update)) {
|
|
121
|
+
if (key !== "update_id") {
|
|
122
|
+
return key;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return "unknown";
|
|
126
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Bot } from "grammy";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { AuditLogRepository } from "../audit-log.js";
|
|
4
|
+
import { runBillingExpiration } from "../billing-expiration.js";
|
|
5
|
+
import { BillingRepository } from "../billing.js";
|
|
6
|
+
import { CustomerKeyRepository } from "../customer-keys.js";
|
|
7
|
+
import { CustomerWorkspaceRepository } from "./customer-workspace-repository.js";
|
|
8
|
+
import { readTelegramBotConfig } from "./config.js";
|
|
9
|
+
const config = readTelegramBotConfig(process.env);
|
|
10
|
+
const dbFile = path.resolve(config.sessionDbPath);
|
|
11
|
+
const billing = BillingRepository.create(dbFile);
|
|
12
|
+
const customerKeys = CustomerKeyRepository.create(dbFile);
|
|
13
|
+
const workspaces = CustomerWorkspaceRepository.create(dbFile);
|
|
14
|
+
const auditLog = AuditLogRepository.create(dbFile);
|
|
15
|
+
const bot = new Bot(config.telegramBotToken);
|
|
16
|
+
const intervalMs = readPositiveInteger(process.env.BOT_WORKER_INTERVAL_MS) ?? 60_000;
|
|
17
|
+
const runOnceOnly = readEnvBoolean(process.env.BOT_WORKER_ONCE);
|
|
18
|
+
let stopping = false;
|
|
19
|
+
process.once("SIGINT", () => {
|
|
20
|
+
stopping = true;
|
|
21
|
+
});
|
|
22
|
+
process.once("SIGTERM", () => {
|
|
23
|
+
stopping = true;
|
|
24
|
+
});
|
|
25
|
+
while (!stopping) {
|
|
26
|
+
const startedAt = Date.now();
|
|
27
|
+
const summary = await runBillingExpiration({
|
|
28
|
+
billing,
|
|
29
|
+
customerKeys,
|
|
30
|
+
workspaces,
|
|
31
|
+
auditLog,
|
|
32
|
+
notifyCustomer: async ({ telegramUserId, text }) => {
|
|
33
|
+
await bot.api.sendMessage(Number(telegramUserId), text);
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
console.info("telegram billing worker cycle completed", {
|
|
37
|
+
expiredEntitlements: summary.expiredEntitlements,
|
|
38
|
+
suspendedWorkspaces: summary.suspendedWorkspaces,
|
|
39
|
+
suspendedKeys: summary.suspendedKeys,
|
|
40
|
+
notificationsSent: summary.notificationsSent,
|
|
41
|
+
notificationsFailed: summary.notificationsFailed,
|
|
42
|
+
totalMs: Date.now() - startedAt,
|
|
43
|
+
});
|
|
44
|
+
if (runOnceOnly || stopping) {
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
await sleep(intervalMs);
|
|
48
|
+
}
|
|
49
|
+
console.info("telegram billing worker stopped");
|
|
50
|
+
function sleep(ms) {
|
|
51
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
52
|
+
}
|
|
53
|
+
function readPositiveInteger(value) {
|
|
54
|
+
if (!value?.trim()) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const parsed = Number(value);
|
|
58
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
59
|
+
}
|
|
60
|
+
function readEnvBoolean(value) {
|
|
61
|
+
const normalized = value?.trim().toLowerCase();
|
|
62
|
+
return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
|
|
63
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "responses-proxy",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI routing proxy with multi-provider fallback, RTK token saver, and web dashboard",
|
|
5
|
+
"bin": {
|
|
6
|
+
"responses-proxy": "./cli.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"cli.js",
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "node scripts/build-cli.js",
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20.0.0"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"ai",
|
|
23
|
+
"proxy",
|
|
24
|
+
"router",
|
|
25
|
+
"openai",
|
|
26
|
+
"anthropic",
|
|
27
|
+
"claude",
|
|
28
|
+
"codex",
|
|
29
|
+
"rtk",
|
|
30
|
+
"token-saver",
|
|
31
|
+
"llm",
|
|
32
|
+
"fallback"
|
|
33
|
+
],
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/phamtuandat/responses-proxy"
|
|
38
|
+
}
|
|
39
|
+
}
|