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.
Files changed (161) hide show
  1. package/README.md +56 -0
  2. package/cli.js +118 -0
  3. package/dist/anthropic-messages.js +383 -0
  4. package/dist/anthropic-messages.test.js +209 -0
  5. package/dist/audit-log.js +138 -0
  6. package/dist/audit-log.test.js +480 -0
  7. package/dist/billing-expiration.js +70 -0
  8. package/dist/billing-expiration.test.js +114 -0
  9. package/dist/billing.js +716 -0
  10. package/dist/billing.test.js +228 -0
  11. package/dist/chatgpt-oauth-store.js +240 -0
  12. package/dist/chatgpt-oauth-store.test.js +88 -0
  13. package/dist/chatgpt-oauth.js +118 -0
  14. package/dist/chatgpt-oauth.test.js +63 -0
  15. package/dist/chatgpt-provider-auth.js +60 -0
  16. package/dist/chatgpt-provider-auth.test.js +101 -0
  17. package/dist/client/app-icon.svg +17 -0
  18. package/dist/client/assets/index-C7Vvhst8.js +14 -0
  19. package/dist/client/assets/index-DpqgYK3L.css +1 -0
  20. package/dist/client/favicon.svg +17 -0
  21. package/dist/client/index.html +31 -0
  22. package/dist/client-config-apply.js +345 -0
  23. package/dist/client-config-apply.test.js +185 -0
  24. package/dist/client-token-limits.js +111 -0
  25. package/dist/client-token-limits.test.js +129 -0
  26. package/dist/codex-config.js +47 -0
  27. package/dist/codex-setup.js +87 -0
  28. package/dist/codex-setup.test.js +30 -0
  29. package/dist/config.js +314 -0
  30. package/dist/cost-analytics.js +31 -0
  31. package/dist/cost-analytics.test.js +38 -0
  32. package/dist/customer-key-access.js +126 -0
  33. package/dist/customer-key-access.test.js +178 -0
  34. package/dist/customer-keys.js +209 -0
  35. package/dist/customer-keys.test.js +68 -0
  36. package/dist/customer-usage.js +18 -0
  37. package/dist/customer-usage.test.js +55 -0
  38. package/dist/dashboard-auth.js +318 -0
  39. package/dist/dashboard-auth.test.js +133 -0
  40. package/dist/dashboard-serving.test.js +235 -0
  41. package/dist/error-response.js +174 -0
  42. package/dist/error-response.test.js +88 -0
  43. package/dist/forward.js +357 -0
  44. package/dist/health-websocket-manager.js +174 -0
  45. package/dist/http-rate-limit.js +36 -0
  46. package/dist/http-rate-limit.test.js +62 -0
  47. package/dist/kiro-auth.js +136 -0
  48. package/dist/kiro-auth.test.js +234 -0
  49. package/dist/kiro-codewhisperer.js +646 -0
  50. package/dist/kiro-codewhisperer.test.js +219 -0
  51. package/dist/kiro-device-login.js +338 -0
  52. package/dist/kiro-eventstream.js +219 -0
  53. package/dist/kiro-eventstream.test.js +79 -0
  54. package/dist/kiro-forward.js +401 -0
  55. package/dist/kiro-import-cli.js +69 -0
  56. package/dist/kiro-import.js +94 -0
  57. package/dist/kiro-import.test.js +125 -0
  58. package/dist/kiro-token-store.js +196 -0
  59. package/dist/kiro-token-store.test.js +207 -0
  60. package/dist/krouter-usage.js +243 -0
  61. package/dist/model-combo-repository.js +147 -0
  62. package/dist/model-routing.js +69 -0
  63. package/dist/model-routing.test.js +41 -0
  64. package/dist/normalize-request.js +531 -0
  65. package/dist/normalize-request.test.js +277 -0
  66. package/dist/omv-public-firewall.test.js +11 -0
  67. package/dist/package.json +17 -0
  68. package/dist/prompt-cache-state.js +146 -0
  69. package/dist/prompt-cache-state.test.js +71 -0
  70. package/dist/prompt-cache.js +229 -0
  71. package/dist/provider-health-service.js +404 -0
  72. package/dist/provider-request-parameters.js +107 -0
  73. package/dist/provider-request-parameters.test.js +26 -0
  74. package/dist/provider-routing.js +114 -0
  75. package/dist/provider-routing.test.js +64 -0
  76. package/dist/provider-usage.js +314 -0
  77. package/dist/request-timeout-policy.js +61 -0
  78. package/dist/request-timeout-policy.test.js +40 -0
  79. package/dist/response-cache.js +69 -0
  80. package/dist/response-cache.test.js +28 -0
  81. package/dist/routing-combo-repository.js +300 -0
  82. package/dist/routing-engine.js +377 -0
  83. package/dist/routing-integration.js +155 -0
  84. package/dist/routing-simulation-engine.js +326 -0
  85. package/dist/rtk-layer.js +483 -0
  86. package/dist/rtk-layer.test.js +198 -0
  87. package/dist/runtime-provider-repository.js +1742 -0
  88. package/dist/runtime-provider-repository.test.js +1177 -0
  89. package/dist/schema.js +118 -0
  90. package/dist/schema.test.js +16 -0
  91. package/dist/sepay-webhook.js +87 -0
  92. package/dist/sepay-webhook.test.js +142 -0
  93. package/dist/server-body-limit.test.js +35 -0
  94. package/dist/server-client-token-limits.test.js +161 -0
  95. package/dist/server-codex-config-setup.test.js +76 -0
  96. package/dist/server-http-rate-limit.test.js +80 -0
  97. package/dist/server-response-cache.test.js +105 -0
  98. package/dist/server-routes-alias.test.js +39 -0
  99. package/dist/server-sepay-webhook-security.test.js +59 -0
  100. package/dist/server.js +5906 -0
  101. package/dist/session-log.js +178 -0
  102. package/dist/tailnet-funnel-script.test.js +33 -0
  103. package/dist/telegram-bot/actions.js +118 -0
  104. package/dist/telegram-bot/admin-actions.js +103 -0
  105. package/dist/telegram-bot/auth.js +46 -0
  106. package/dist/telegram-bot/auth.test.js +1 -0
  107. package/dist/telegram-bot/bot-identity-repository.js +189 -0
  108. package/dist/telegram-bot/bot-identity-repository.test.js +78 -0
  109. package/dist/telegram-bot/callbacks.js +30 -0
  110. package/dist/telegram-bot/codex-config-delivery.js +38 -0
  111. package/dist/telegram-bot/codex-config-delivery.test.js +75 -0
  112. package/dist/telegram-bot/commands/accounts.js +140 -0
  113. package/dist/telegram-bot/commands/apikey.js +737 -0
  114. package/dist/telegram-bot/commands/apply.js +265 -0
  115. package/dist/telegram-bot/commands/clients.js +13 -0
  116. package/dist/telegram-bot/commands/customer-billing.test.js +271 -0
  117. package/dist/telegram-bot/commands/grant.js +138 -0
  118. package/dist/telegram-bot/commands/grant.test.js +217 -0
  119. package/dist/telegram-bot/commands/help.js +52 -0
  120. package/dist/telegram-bot/commands/me.js +53 -0
  121. package/dist/telegram-bot/commands/models.js +6 -0
  122. package/dist/telegram-bot/commands/oauth.js +64 -0
  123. package/dist/telegram-bot/commands/plans.js +96 -0
  124. package/dist/telegram-bot/commands/providers.js +27 -0
  125. package/dist/telegram-bot/commands/quota.js +10 -0
  126. package/dist/telegram-bot/commands/renew-user.js +139 -0
  127. package/dist/telegram-bot/commands/renew-user.test.js +184 -0
  128. package/dist/telegram-bot/commands/renew.js +1369 -0
  129. package/dist/telegram-bot/commands/renew.test.js +1633 -0
  130. package/dist/telegram-bot/commands/start.js +212 -0
  131. package/dist/telegram-bot/commands/start.test.js +280 -0
  132. package/dist/telegram-bot/commands/status.js +6 -0
  133. package/dist/telegram-bot/commands/tailscale.js +15 -0
  134. package/dist/telegram-bot/commands/tailscale.test.js +76 -0
  135. package/dist/telegram-bot/commands/test.js +51 -0
  136. package/dist/telegram-bot/commands/test.test.js +14 -0
  137. package/dist/telegram-bot/commands/usage.js +10 -0
  138. package/dist/telegram-bot/config.js +98 -0
  139. package/dist/telegram-bot/config.test.js +42 -0
  140. package/dist/telegram-bot/customer-actions.js +160 -0
  141. package/dist/telegram-bot/customer-api-keys.js +68 -0
  142. package/dist/telegram-bot/customer-billing.js +72 -0
  143. package/dist/telegram-bot/customer-workspace-repository.js +134 -0
  144. package/dist/telegram-bot/customer-workspace-repository.test.js +47 -0
  145. package/dist/telegram-bot/dashboard-login.js +39 -0
  146. package/dist/telegram-bot/format.js +140 -0
  147. package/dist/telegram-bot/grants.js +370 -0
  148. package/dist/telegram-bot/grants.test.js +290 -0
  149. package/dist/telegram-bot/index.js +85 -0
  150. package/dist/telegram-bot/message-cleanup.js +55 -0
  151. package/dist/telegram-bot/message-cleanup.test.js +77 -0
  152. package/dist/telegram-bot/message-format.js +45 -0
  153. package/dist/telegram-bot/message-format.test.js +10 -0
  154. package/dist/telegram-bot/proxy-client.js +174 -0
  155. package/dist/telegram-bot/rate-limit.js +95 -0
  156. package/dist/telegram-bot/rate-limit.test.js +58 -0
  157. package/dist/telegram-bot/sessions.js +171 -0
  158. package/dist/telegram-bot/sessions.test.js +107 -0
  159. package/dist/telegram-bot/telegram-adapter.js +126 -0
  160. package/dist/telegram-bot/worker.js +63 -0
  161. package/package.json +39 -0
@@ -0,0 +1,184 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtempSync, rmSync } from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+ import { BillingRepository } from "../../billing.js";
7
+ import { CustomerKeyRepository } from "../../customer-keys.js";
8
+ import { AuditLogRepository } from "../../audit-log.js";
9
+ import { BotIdentityRepository } from "../bot-identity-repository.js";
10
+ import { registerRenewUserCommand } from "./renew-user.js";
11
+ import { CustomerWorkspaceRepository } from "../customer-workspace-repository.js";
12
+ import { grantCustomerAccess } from "../grants.js";
13
+ function createConfig(overrides = {}) {
14
+ return {
15
+ telegramBotToken: "token",
16
+ allowedUserIds: new Set(),
17
+ allowedChatIds: new Set(),
18
+ ownerUserIds: new Set(["1"]),
19
+ adminUserIds: new Set(),
20
+ botMode: "polling",
21
+ proxyAdminBaseUrl: "http://127.0.0.1:8318",
22
+ defaultModel: "gpt-5.5",
23
+ publicSignupEnabled: true,
24
+ requireAdminApproval: false,
25
+ defaultCustomerRoute: "customers",
26
+ publicResponsesBaseUrl: "http://127.0.0.1:8318/v1",
27
+ proxyRequestTimeoutMs: 30_000,
28
+ sessionDbPath: ":memory:",
29
+ sessionTtlMs: 900_000,
30
+ rateLimitWindowMs: 60_000,
31
+ rateLimitMaxRequests: 12,
32
+ logLevel: "info",
33
+ ...overrides,
34
+ };
35
+ }
36
+ function createMockProxyClient() {
37
+ let routeKeys = [];
38
+ return {
39
+ client: {
40
+ async getClientConfigs() {
41
+ return {
42
+ clientRoutes: [{ key: "customers", apiKeys: [...routeKeys] }],
43
+ };
44
+ },
45
+ async setClientRouteApiKeys(input) {
46
+ if (input.client === "customers") {
47
+ routeKeys = [...input.apiKeys];
48
+ }
49
+ return { ok: true };
50
+ },
51
+ },
52
+ };
53
+ }
54
+ function createBotHarness() {
55
+ const handlers = new Map();
56
+ return {
57
+ bot: {
58
+ command(name, handler) {
59
+ handlers.set(name, handler);
60
+ },
61
+ },
62
+ handler(name) {
63
+ const handler = handlers.get(name);
64
+ assert.ok(handler);
65
+ return handler;
66
+ },
67
+ };
68
+ }
69
+ function createContext(input) {
70
+ const replies = [];
71
+ const sentMessages = [];
72
+ const sentDocuments = [];
73
+ const ctx = {
74
+ from: { id: input.fromId, is_bot: false, first_name: "User" },
75
+ chat: input.chatType === "private"
76
+ ? { id: input.chatId, type: "private", first_name: "User" }
77
+ : { id: input.chatId, type: "group", title: "Ops" },
78
+ message: {
79
+ message_id: 1,
80
+ date: 0,
81
+ chat: input.chatType === "private"
82
+ ? { id: input.chatId, type: "private", first_name: "User" }
83
+ : { id: input.chatId, type: "group", title: "Ops" },
84
+ text: `/renewuser ${input.match}`.trim(),
85
+ },
86
+ match: input.match,
87
+ replies,
88
+ sentMessages,
89
+ sentDocuments,
90
+ reply(text) {
91
+ replies.push(text);
92
+ return Promise.resolve({});
93
+ },
94
+ api: {
95
+ async sendMessage(chatId, text) {
96
+ sentMessages.push({ chatId, text });
97
+ if (input.sendMessageImpl) {
98
+ await input.sendMessageImpl(chatId, text);
99
+ }
100
+ return {};
101
+ },
102
+ async sendDocument(chatId, document) {
103
+ sentDocuments.push({
104
+ chatId,
105
+ filename: document.filename,
106
+ content: document.fileData ? Buffer.from(document.fileData).toString("utf8") : "",
107
+ });
108
+ return {};
109
+ },
110
+ },
111
+ };
112
+ return ctx;
113
+ }
114
+ async function withRepos(fn) {
115
+ const dir = mkdtempSync(path.join(os.tmpdir(), "renew-user-command-"));
116
+ try {
117
+ const dbFile = path.join(dir, "bot.sqlite");
118
+ const proxy = createMockProxyClient();
119
+ await fn({
120
+ identities: BotIdentityRepository.create(dbFile),
121
+ workspaces: CustomerWorkspaceRepository.create(dbFile),
122
+ customerKeys: CustomerKeyRepository.create(dbFile),
123
+ billing: BillingRepository.create(dbFile),
124
+ auditLog: AuditLogRepository.create(dbFile),
125
+ deps: {
126
+ config: createConfig({ sessionDbPath: dbFile }),
127
+ proxyClient: proxy.client,
128
+ },
129
+ });
130
+ }
131
+ finally {
132
+ rmSync(dir, { recursive: true, force: true });
133
+ }
134
+ }
135
+ test("renewuser is admin-only", async () => {
136
+ await withRepos(async ({ identities, workspaces, customerKeys, billing, auditLog, deps }) => {
137
+ const harness = createBotHarness();
138
+ registerRenewUserCommand(harness.bot, deps, identities, workspaces, customerKeys, billing, auditLog);
139
+ const ctx = createContext({
140
+ fromId: 2,
141
+ chatId: 2,
142
+ chatType: "private",
143
+ match: "1283361952 basic 30",
144
+ });
145
+ await harness.handler("renewuser")(ctx);
146
+ assert.equal(ctx.replies[0], "Only admins can renew customer access.");
147
+ });
148
+ });
149
+ test("renewuser replace-key does not print the new key into a group chat", async () => {
150
+ await withRepos(async ({ identities, workspaces, customerKeys, billing, auditLog, deps }) => {
151
+ await grantCustomerAccess({
152
+ telegramUserId: "1283361952",
153
+ planId: "basic",
154
+ days: 30,
155
+ defaultClientRoute: deps.config.defaultCustomerRoute,
156
+ identities,
157
+ workspaces,
158
+ customerKeys,
159
+ billing,
160
+ proxyClient: deps.proxyClient,
161
+ auditLog,
162
+ actor: { type: "admin", id: "1" },
163
+ });
164
+ const harness = createBotHarness();
165
+ registerRenewUserCommand(harness.bot, deps, identities, workspaces, customerKeys, billing, auditLog);
166
+ const ctx = createContext({
167
+ fromId: 1,
168
+ chatId: -1001,
169
+ chatType: "group",
170
+ match: "1283361952 basic 30 replace-key",
171
+ });
172
+ await harness.handler("renewuser")(ctx);
173
+ assert.equal(ctx.replies.length >= 1, true);
174
+ assert.equal(ctx.replies[0].includes("api_key:"), false);
175
+ assert.equal(ctx.replies[0].includes("Full key: replacement key is shown only in private chat"), true);
176
+ assert.equal(ctx.sentMessages.length, 1);
177
+ assert.equal(ctx.sentMessages[0]?.chatId, 1283361952);
178
+ assert.equal(ctx.sentMessages[0]?.text.includes("api_key:"), false);
179
+ assert.deepEqual(ctx.sentDocuments.map((document) => document.filename), ["config.toml", "auth.json"]);
180
+ assert.match(ctx.sentDocuments[0]?.content ?? "", /base_url = "http:\/\/127\.0\.0\.1:8318\/v1"/);
181
+ assert.match(ctx.sentDocuments[0]?.content ?? "", /api_key = "sk-/);
182
+ assert.match(ctx.sentDocuments[1]?.content ?? "", /"OPENAI_API_KEY": "sk-/);
183
+ });
184
+ });