@congzhen/changewayguard 6.8.12

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 (329) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +270 -0
  3. package/dashboard-dist/api/104.index.js +1420 -0
  4. package/dashboard-dist/api/104.index.js.map +1 -0
  5. package/dashboard-dist/api/113.index.js +496 -0
  6. package/dashboard-dist/api/113.index.js.map +1 -0
  7. package/dashboard-dist/api/18.index.js +67 -0
  8. package/dashboard-dist/api/18.index.js.map +1 -0
  9. package/dashboard-dist/api/217.index.js +44 -0
  10. package/dashboard-dist/api/217.index.js.map +1 -0
  11. package/dashboard-dist/api/222.index.js +90 -0
  12. package/dashboard-dist/api/222.index.js.map +1 -0
  13. package/dashboard-dist/api/25.index.js +3562 -0
  14. package/dashboard-dist/api/25.index.js.map +1 -0
  15. package/dashboard-dist/api/280.index.js +206 -0
  16. package/dashboard-dist/api/280.index.js.map +1 -0
  17. package/dashboard-dist/api/369.index.js +115 -0
  18. package/dashboard-dist/api/369.index.js.map +1 -0
  19. package/dashboard-dist/api/377.index.js +1176 -0
  20. package/dashboard-dist/api/377.index.js.map +1 -0
  21. package/dashboard-dist/api/411.index.js +4250 -0
  22. package/dashboard-dist/api/411.index.js.map +1 -0
  23. package/dashboard-dist/api/424.index.js +135 -0
  24. package/dashboard-dist/api/424.index.js.map +1 -0
  25. package/dashboard-dist/api/573.index.js +806 -0
  26. package/dashboard-dist/api/573.index.js.map +1 -0
  27. package/dashboard-dist/api/598.index.js +328 -0
  28. package/dashboard-dist/api/598.index.js.map +1 -0
  29. package/dashboard-dist/api/62.index.js +4151 -0
  30. package/dashboard-dist/api/62.index.js.map +1 -0
  31. package/dashboard-dist/api/67.index.js +23383 -0
  32. package/dashboard-dist/api/67.index.js.map +1 -0
  33. package/dashboard-dist/api/678.index.js +2734 -0
  34. package/dashboard-dist/api/678.index.js.map +1 -0
  35. package/dashboard-dist/api/698.index.js +1896 -0
  36. package/dashboard-dist/api/698.index.js.map +1 -0
  37. package/dashboard-dist/api/720.index.js +98 -0
  38. package/dashboard-dist/api/720.index.js.map +1 -0
  39. package/dashboard-dist/api/830.index.js +95 -0
  40. package/dashboard-dist/api/830.index.js.map +1 -0
  41. package/dashboard-dist/api/831.index.js +99 -0
  42. package/dashboard-dist/api/831.index.js.map +1 -0
  43. package/dashboard-dist/api/84.index.js +64 -0
  44. package/dashboard-dist/api/84.index.js.map +1 -0
  45. package/dashboard-dist/api/900.index.js +65 -0
  46. package/dashboard-dist/api/900.index.js.map +1 -0
  47. package/dashboard-dist/api/917.index.js +88 -0
  48. package/dashboard-dist/api/917.index.js.map +1 -0
  49. package/dashboard-dist/api/948.index.js +64 -0
  50. package/dashboard-dist/api/948.index.js.map +1 -0
  51. package/dashboard-dist/api/953.index.js +67 -0
  52. package/dashboard-dist/api/953.index.js.map +1 -0
  53. package/dashboard-dist/api/975.index.js +374 -0
  54. package/dashboard-dist/api/975.index.js.map +1 -0
  55. package/dashboard-dist/api/drizzle/sqlite/0000_short_captain_stacy.sql +70 -0
  56. package/dashboard-dist/api/drizzle/sqlite/0001_closed_magus.sql +10 -0
  57. package/dashboard-dist/api/drizzle/sqlite/0002_agent_capability_observation.sql +38 -0
  58. package/dashboard-dist/api/drizzle/sqlite/0003_auth_magic_link.sql +28 -0
  59. package/dashboard-dist/api/drizzle/sqlite/0004_static_scan_fields.sql +8 -0
  60. package/dashboard-dist/api/drizzle/sqlite/0005_gateway_activity.sql +24 -0
  61. package/dashboard-dist/api/drizzle/sqlite/0006_sour_marauders.sql +41 -0
  62. package/dashboard-dist/api/drizzle/sqlite/meta/0000_snapshot.json +460 -0
  63. package/dashboard-dist/api/drizzle/sqlite/meta/0001_snapshot.json +536 -0
  64. package/dashboard-dist/api/drizzle/sqlite/meta/0006_snapshot.json +1249 -0
  65. package/dashboard-dist/api/drizzle/sqlite/meta/_journal.json +55 -0
  66. package/dashboard-dist/api/index.js +27340 -0
  67. package/dashboard-dist/api/index.js.map +1 -0
  68. package/dashboard-dist/api/package.json +16 -0
  69. package/dashboard-dist/api/sourcemap-register.cjs +1 -0
  70. package/dashboard-dist/web/assets/index-CqWIeBTD.js +158 -0
  71. package/dashboard-dist/web/assets/index-Dw7--9q4.css +1 -0
  72. package/dashboard-dist/web/changeway-logo.png +0 -0
  73. package/dashboard-dist/web/favicon.svg +29 -0
  74. package/dashboard-dist/web/index.html +14 -0
  75. package/dashboard-dist/web/logo.svg +16 -0
  76. package/dist/agent/auth.d.ts +37 -0
  77. package/dist/agent/auth.d.ts.map +1 -0
  78. package/dist/agent/auth.js +151 -0
  79. package/dist/agent/auth.js.map +1 -0
  80. package/dist/agent/behavior-detector.d.ts +150 -0
  81. package/dist/agent/behavior-detector.d.ts.map +1 -0
  82. package/dist/agent/behavior-detector.js +573 -0
  83. package/dist/agent/behavior-detector.js.map +1 -0
  84. package/dist/agent/business-reporter.d.ts +114 -0
  85. package/dist/agent/business-reporter.d.ts.map +1 -0
  86. package/dist/agent/business-reporter.js +359 -0
  87. package/dist/agent/business-reporter.js.map +1 -0
  88. package/dist/agent/config-sync.d.ts +70 -0
  89. package/dist/agent/config-sync.d.ts.map +1 -0
  90. package/dist/agent/config-sync.js +133 -0
  91. package/dist/agent/config-sync.js.map +1 -0
  92. package/dist/agent/config.d.ts +97 -0
  93. package/dist/agent/config.d.ts.map +1 -0
  94. package/dist/agent/config.js +359 -0
  95. package/dist/agent/config.js.map +1 -0
  96. package/dist/agent/content-injection-scanner.d.ts +35 -0
  97. package/dist/agent/content-injection-scanner.d.ts.map +1 -0
  98. package/dist/agent/content-injection-scanner.js +270 -0
  99. package/dist/agent/content-injection-scanner.js.map +1 -0
  100. package/dist/agent/engine-log-writer.d.ts +6 -0
  101. package/dist/agent/engine-log-writer.d.ts.map +1 -0
  102. package/dist/agent/engine-log-writer.js +18 -0
  103. package/dist/agent/engine-log-writer.js.map +1 -0
  104. package/dist/agent/env.d.ts +19 -0
  105. package/dist/agent/env.d.ts.map +1 -0
  106. package/dist/agent/env.js +43 -0
  107. package/dist/agent/env.js.map +1 -0
  108. package/dist/agent/event-reporter.d.ts +87 -0
  109. package/dist/agent/event-reporter.d.ts.map +1 -0
  110. package/dist/agent/event-reporter.js +315 -0
  111. package/dist/agent/event-reporter.js.map +1 -0
  112. package/dist/agent/file-watcher.d.ts +50 -0
  113. package/dist/agent/file-watcher.d.ts.map +1 -0
  114. package/dist/agent/file-watcher.js +135 -0
  115. package/dist/agent/file-watcher.js.map +1 -0
  116. package/dist/agent/fs-utils.d.ts +22 -0
  117. package/dist/agent/fs-utils.d.ts.map +1 -0
  118. package/dist/agent/fs-utils.js +41 -0
  119. package/dist/agent/fs-utils.js.map +1 -0
  120. package/dist/agent/gateway-manager.d.ts +59 -0
  121. package/dist/agent/gateway-manager.d.ts.map +1 -0
  122. package/dist/agent/gateway-manager.js +583 -0
  123. package/dist/agent/gateway-manager.js.map +1 -0
  124. package/dist/agent/hook-types.d.ts +276 -0
  125. package/dist/agent/hook-types.d.ts.map +1 -0
  126. package/dist/agent/hook-types.js +51 -0
  127. package/dist/agent/hook-types.js.map +1 -0
  128. package/dist/agent/index.d.ts +8 -0
  129. package/dist/agent/index.d.ts.map +1 -0
  130. package/dist/agent/index.js +8 -0
  131. package/dist/agent/index.js.map +1 -0
  132. package/dist/agent/prompt-gate.d.ts +13 -0
  133. package/dist/agent/prompt-gate.d.ts.map +1 -0
  134. package/dist/agent/prompt-gate.js +28 -0
  135. package/dist/agent/prompt-gate.js.map +1 -0
  136. package/dist/agent/prompt-input.d.ts +9 -0
  137. package/dist/agent/prompt-input.d.ts.map +1 -0
  138. package/dist/agent/prompt-input.js +158 -0
  139. package/dist/agent/prompt-input.js.map +1 -0
  140. package/dist/agent/prompt-output.d.ts +4 -0
  141. package/dist/agent/prompt-output.d.ts.map +1 -0
  142. package/dist/agent/prompt-output.js +19 -0
  143. package/dist/agent/prompt-output.js.map +1 -0
  144. package/dist/agent/runner.d.ts +23 -0
  145. package/dist/agent/runner.d.ts.map +1 -0
  146. package/dist/agent/runner.js +154 -0
  147. package/dist/agent/runner.js.map +1 -0
  148. package/dist/agent/sanitizer.d.ts +10 -0
  149. package/dist/agent/sanitizer.d.ts.map +1 -0
  150. package/dist/agent/sanitizer.js +175 -0
  151. package/dist/agent/sanitizer.js.map +1 -0
  152. package/dist/agent/scan-activity.d.ts +18 -0
  153. package/dist/agent/scan-activity.d.ts.map +1 -0
  154. package/dist/agent/scan-activity.js +32 -0
  155. package/dist/agent/scan-activity.js.map +1 -0
  156. package/dist/agent/types.d.ts +177 -0
  157. package/dist/agent/types.d.ts.map +1 -0
  158. package/dist/agent/types.js +5 -0
  159. package/dist/agent/types.js.map +1 -0
  160. package/dist/agent/workspace-scanner.d.ts +35 -0
  161. package/dist/agent/workspace-scanner.d.ts.map +1 -0
  162. package/dist/agent/workspace-scanner.js +137 -0
  163. package/dist/agent/workspace-scanner.js.map +1 -0
  164. package/dist/dashboard-launcher.d.ts +52 -0
  165. package/dist/dashboard-launcher.d.ts.map +1 -0
  166. package/dist/dashboard-launcher.js +363 -0
  167. package/dist/dashboard-launcher.js.map +1 -0
  168. package/dist/gateway/activity.d.ts +52 -0
  169. package/dist/gateway/activity.d.ts.map +1 -0
  170. package/dist/gateway/activity.js +111 -0
  171. package/dist/gateway/activity.js.map +1 -0
  172. package/dist/gateway/config.d.ts +50 -0
  173. package/dist/gateway/config.d.ts.map +1 -0
  174. package/dist/gateway/config.js +200 -0
  175. package/dist/gateway/config.js.map +1 -0
  176. package/dist/gateway/gateway/activity.d.ts +52 -0
  177. package/dist/gateway/gateway/activity.d.ts.map +1 -0
  178. package/dist/gateway/gateway/activity.js +111 -0
  179. package/dist/gateway/gateway/activity.js.map +1 -0
  180. package/dist/gateway/gateway/config.d.ts +50 -0
  181. package/dist/gateway/gateway/config.d.ts.map +1 -0
  182. package/dist/gateway/gateway/config.js +200 -0
  183. package/dist/gateway/gateway/config.js.map +1 -0
  184. package/dist/gateway/gateway/handlers/anthropic.d.ts +12 -0
  185. package/dist/gateway/gateway/handlers/anthropic.d.ts.map +1 -0
  186. package/dist/gateway/gateway/handlers/anthropic.js +254 -0
  187. package/dist/gateway/gateway/handlers/anthropic.js.map +1 -0
  188. package/dist/gateway/gateway/handlers/gemini.d.ts +12 -0
  189. package/dist/gateway/gateway/handlers/gemini.d.ts.map +1 -0
  190. package/dist/gateway/gateway/handlers/gemini.js +101 -0
  191. package/dist/gateway/gateway/handlers/gemini.js.map +1 -0
  192. package/dist/gateway/gateway/handlers/models.d.ts +4 -0
  193. package/dist/gateway/gateway/handlers/models.d.ts.map +1 -0
  194. package/dist/gateway/gateway/handlers/models.js +36 -0
  195. package/dist/gateway/gateway/handlers/models.js.map +1 -0
  196. package/dist/gateway/gateway/handlers/openai.d.ts +16 -0
  197. package/dist/gateway/gateway/handlers/openai.d.ts.map +1 -0
  198. package/dist/gateway/gateway/handlers/openai.js +254 -0
  199. package/dist/gateway/gateway/handlers/openai.js.map +1 -0
  200. package/dist/gateway/gateway/index.d.ts +27 -0
  201. package/dist/gateway/gateway/index.d.ts.map +1 -0
  202. package/dist/gateway/gateway/index.js +293 -0
  203. package/dist/gateway/gateway/index.js.map +1 -0
  204. package/dist/gateway/gateway/mapping-store.d.ts +38 -0
  205. package/dist/gateway/gateway/mapping-store.d.ts.map +1 -0
  206. package/dist/gateway/gateway/mapping-store.js +74 -0
  207. package/dist/gateway/gateway/mapping-store.js.map +1 -0
  208. package/dist/gateway/gateway/restorer.d.ts +63 -0
  209. package/dist/gateway/gateway/restorer.d.ts.map +1 -0
  210. package/dist/gateway/gateway/restorer.js +284 -0
  211. package/dist/gateway/gateway/restorer.js.map +1 -0
  212. package/dist/gateway/gateway/sanitizer.d.ts +17 -0
  213. package/dist/gateway/gateway/sanitizer.d.ts.map +1 -0
  214. package/dist/gateway/gateway/sanitizer.js +228 -0
  215. package/dist/gateway/gateway/sanitizer.js.map +1 -0
  216. package/dist/gateway/gateway/types.d.ts +53 -0
  217. package/dist/gateway/gateway/types.d.ts.map +1 -0
  218. package/dist/gateway/gateway/types.js +5 -0
  219. package/dist/gateway/gateway/types.js.map +1 -0
  220. package/dist/gateway/handlers/anthropic.d.ts +12 -0
  221. package/dist/gateway/handlers/anthropic.d.ts.map +1 -0
  222. package/dist/gateway/handlers/anthropic.js +254 -0
  223. package/dist/gateway/handlers/anthropic.js.map +1 -0
  224. package/dist/gateway/handlers/gemini.d.ts +12 -0
  225. package/dist/gateway/handlers/gemini.d.ts.map +1 -0
  226. package/dist/gateway/handlers/gemini.js +101 -0
  227. package/dist/gateway/handlers/gemini.js.map +1 -0
  228. package/dist/gateway/handlers/models.d.ts +4 -0
  229. package/dist/gateway/handlers/models.d.ts.map +1 -0
  230. package/dist/gateway/handlers/models.js +36 -0
  231. package/dist/gateway/handlers/models.js.map +1 -0
  232. package/dist/gateway/handlers/openai.d.ts +16 -0
  233. package/dist/gateway/handlers/openai.d.ts.map +1 -0
  234. package/dist/gateway/handlers/openai.js +254 -0
  235. package/dist/gateway/handlers/openai.js.map +1 -0
  236. package/dist/gateway/index.d.ts +27 -0
  237. package/dist/gateway/index.d.ts.map +1 -0
  238. package/dist/gateway/index.js +293 -0
  239. package/dist/gateway/index.js.map +1 -0
  240. package/dist/gateway/mapping-store.d.ts +38 -0
  241. package/dist/gateway/mapping-store.d.ts.map +1 -0
  242. package/dist/gateway/mapping-store.js +74 -0
  243. package/dist/gateway/mapping-store.js.map +1 -0
  244. package/dist/gateway/restorer.d.ts +63 -0
  245. package/dist/gateway/restorer.d.ts.map +1 -0
  246. package/dist/gateway/restorer.js +284 -0
  247. package/dist/gateway/restorer.js.map +1 -0
  248. package/dist/gateway/sanitizer.d.ts +17 -0
  249. package/dist/gateway/sanitizer.d.ts.map +1 -0
  250. package/dist/gateway/sanitizer.js +228 -0
  251. package/dist/gateway/sanitizer.js.map +1 -0
  252. package/dist/gateway/types.d.ts +53 -0
  253. package/dist/gateway/types.d.ts.map +1 -0
  254. package/dist/gateway/types.js +5 -0
  255. package/dist/gateway/types.js.map +1 -0
  256. package/dist/index.d.ts +19 -0
  257. package/dist/index.d.ts.map +1 -0
  258. package/dist/index.js +2084 -0
  259. package/dist/index.js.map +1 -0
  260. package/dist/memory/index.d.ts +5 -0
  261. package/dist/memory/index.d.ts.map +1 -0
  262. package/dist/memory/index.js +5 -0
  263. package/dist/memory/index.js.map +1 -0
  264. package/dist/memory/store.d.ts +82 -0
  265. package/dist/memory/store.d.ts.map +1 -0
  266. package/dist/memory/store.js +194 -0
  267. package/dist/memory/store.js.map +1 -0
  268. package/dist/platform-client/index.d.ts +63 -0
  269. package/dist/platform-client/index.d.ts.map +1 -0
  270. package/dist/platform-client/index.js +294 -0
  271. package/dist/platform-client/index.js.map +1 -0
  272. package/dist/platform-client/types.d.ts +109 -0
  273. package/dist/platform-client/types.d.ts.map +1 -0
  274. package/dist/platform-client/types.js +3 -0
  275. package/dist/platform-client/types.js.map +1 -0
  276. package/gateway/activity.d.ts +52 -0
  277. package/gateway/activity.d.ts.map +1 -0
  278. package/gateway/activity.js +111 -0
  279. package/gateway/activity.js.map +1 -0
  280. package/gateway/config.d.ts +50 -0
  281. package/gateway/config.d.ts.map +1 -0
  282. package/gateway/config.js +200 -0
  283. package/gateway/config.js.map +1 -0
  284. package/gateway/handlers/anthropic.d.ts +12 -0
  285. package/gateway/handlers/anthropic.d.ts.map +1 -0
  286. package/gateway/handlers/anthropic.js +254 -0
  287. package/gateway/handlers/anthropic.js.map +1 -0
  288. package/gateway/handlers/gemini.d.ts +12 -0
  289. package/gateway/handlers/gemini.d.ts.map +1 -0
  290. package/gateway/handlers/gemini.js +101 -0
  291. package/gateway/handlers/gemini.js.map +1 -0
  292. package/gateway/handlers/models.d.ts +4 -0
  293. package/gateway/handlers/models.d.ts.map +1 -0
  294. package/gateway/handlers/models.js +36 -0
  295. package/gateway/handlers/models.js.map +1 -0
  296. package/gateway/handlers/openai.d.ts +16 -0
  297. package/gateway/handlers/openai.d.ts.map +1 -0
  298. package/gateway/handlers/openai.js +254 -0
  299. package/gateway/handlers/openai.js.map +1 -0
  300. package/gateway/index.d.ts +27 -0
  301. package/gateway/index.d.ts.map +1 -0
  302. package/gateway/index.js +293 -0
  303. package/gateway/index.js.map +1 -0
  304. package/gateway/mapping-store.d.ts +38 -0
  305. package/gateway/mapping-store.d.ts.map +1 -0
  306. package/gateway/mapping-store.js +74 -0
  307. package/gateway/mapping-store.js.map +1 -0
  308. package/gateway/restorer.d.ts +63 -0
  309. package/gateway/restorer.d.ts.map +1 -0
  310. package/gateway/restorer.js +284 -0
  311. package/gateway/restorer.js.map +1 -0
  312. package/gateway/sanitizer.d.ts +17 -0
  313. package/gateway/sanitizer.d.ts.map +1 -0
  314. package/gateway/sanitizer.js +228 -0
  315. package/gateway/sanitizer.js.map +1 -0
  316. package/gateway/types.d.ts +53 -0
  317. package/gateway/types.d.ts.map +1 -0
  318. package/gateway/types.js +5 -0
  319. package/gateway/types.js.map +1 -0
  320. package/openclaw.plugin.json +86 -0
  321. package/package.json +74 -0
  322. package/samples/Untitled +1 -0
  323. package/samples/clean-email.txt +20 -0
  324. package/samples/test-document.md +53 -0
  325. package/samples/test-email-popup.txt +44 -0
  326. package/samples/test-email.txt +32 -0
  327. package/samples/test-webpage.html +51 -0
  328. package/scripts/enterprise-enroll.sh +89 -0
  329. package/scripts/enterprise-unenroll.sh +75 -0
@@ -0,0 +1,101 @@
1
+ /**
2
+ * AI Security Gateway - Google Gemini API handler
3
+ *
4
+ * Handles POST /v1/models/:model:generateContent requests in Gemini's format.
5
+ */
6
+ import { sanitize } from "../sanitizer.js";
7
+ import { restore } from "../restorer.js";
8
+ import { generateRequestId, logSanitizeEvent, logRestoreEvent } from "../activity.js";
9
+ /**
10
+ * Handle Gemini API request
11
+ */
12
+ export async function handleGeminiRequest(req, res, backend, modelName) {
13
+ try {
14
+ const requestId = generateRequestId();
15
+ const sanitizeStart = Date.now();
16
+ // 1. Parse request body
17
+ const body = await readBody(req);
18
+ const requestData = JSON.parse(body);
19
+ const { contents, tools, generationConfig, ...rest } = requestData;
20
+ // 2. Sanitize contents (Gemini uses "contents" instead of "messages")
21
+ const { sanitized: sanitizedContents, mappingTable, redactionCount } = sanitize(contents);
22
+ // Log sanitization event
23
+ if (redactionCount > 0) {
24
+ logSanitizeEvent({
25
+ requestId,
26
+ backend: "gemini",
27
+ endpoint: `/v1/models/${modelName}:generateContent`,
28
+ model: modelName,
29
+ mappingTable,
30
+ redactionCount,
31
+ durationMs: Date.now() - sanitizeStart,
32
+ });
33
+ }
34
+ // 3. Build sanitized request
35
+ const sanitizedRequest = {
36
+ contents: sanitizedContents,
37
+ ...(tools && { tools }),
38
+ ...(generationConfig && { generationConfig }),
39
+ ...rest,
40
+ };
41
+ // 4. Forward to Gemini API
42
+ const apiUrl = `${backend.baseUrl}/v1/models/${modelName}:generateContent`;
43
+ const response = await fetch(apiUrl, {
44
+ method: "POST",
45
+ headers: {
46
+ "Content-Type": "application/json",
47
+ "x-goog-api-key": backend.apiKey,
48
+ },
49
+ body: JSON.stringify(sanitizedRequest),
50
+ });
51
+ if (!response.ok) {
52
+ // Forward error response
53
+ res.writeHead(response.status, { "Content-Type": "application/json" });
54
+ const errorBody = await response.text();
55
+ res.end(errorBody);
56
+ return;
57
+ }
58
+ // 6. Handle response (Gemini typically doesn't stream in same way)
59
+ const restoreStart = Date.now();
60
+ const responseBody = await response.text();
61
+ const responseData = JSON.parse(responseBody);
62
+ // Restore placeholders in response
63
+ const restoredData = restore(responseData, mappingTable);
64
+ // Log restoration event
65
+ if (mappingTable.size > 0) {
66
+ logRestoreEvent({
67
+ requestId,
68
+ backend: "gemini",
69
+ endpoint: `/v1/models/${modelName}:generateContent`,
70
+ model: modelName,
71
+ mappingTable,
72
+ restorationCount: mappingTable.size,
73
+ durationMs: Date.now() - restoreStart,
74
+ });
75
+ }
76
+ res.writeHead(200, { "Content-Type": "application/json" });
77
+ res.end(JSON.stringify(restoredData));
78
+ }
79
+ catch (error) {
80
+ console.error("[ai-security-gateway] Gemini handler error:", error);
81
+ res.writeHead(500, { "Content-Type": "application/json" });
82
+ res.end(JSON.stringify({
83
+ error: "Internal gateway error",
84
+ message: error instanceof Error ? error.message : String(error),
85
+ }));
86
+ }
87
+ }
88
+ /**
89
+ * Read request body as string
90
+ */
91
+ function readBody(req) {
92
+ return new Promise((resolve, reject) => {
93
+ let body = "";
94
+ req.on("data", (chunk) => {
95
+ body += chunk.toString();
96
+ });
97
+ req.on("end", () => resolve(body));
98
+ req.on("error", reject);
99
+ });
100
+ }
101
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/handlers/gemini.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ServerResponse } from "node:http";
2
+ import type { GatewayConfig } from "../types.js";
3
+ export declare function handleModelsRequest(res: ServerResponse, config: GatewayConfig): Promise<void>;
4
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/handlers/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAqCf"}
@@ -0,0 +1,36 @@
1
+ import { findDefaultBackend } from "../config.js";
2
+ export async function handleModelsRequest(res, config) {
3
+ try {
4
+ // Find an OpenAI-compatible backend for models listing
5
+ const resolved = findDefaultBackend("openai", config);
6
+ if (!resolved) {
7
+ res.writeHead(500, { "Content-Type": "application/json" });
8
+ res.end(JSON.stringify({ error: "No OpenAI-compatible backend configured" }));
9
+ return;
10
+ }
11
+ const { backend } = resolved;
12
+ const modelsUrl = `${backend.baseUrl}/v1/models`;
13
+ const headers = {
14
+ "Authorization": `Bearer ${backend.apiKey}`,
15
+ };
16
+ if (backend.referer) {
17
+ headers["HTTP-Referer"] = backend.referer;
18
+ }
19
+ if (backend.title) {
20
+ headers["X-Title"] = backend.title;
21
+ }
22
+ const response = await fetch(modelsUrl, { headers });
23
+ const body = await response.text();
24
+ res.writeHead(response.status, { "Content-Type": "application/json" });
25
+ res.end(body);
26
+ }
27
+ catch (error) {
28
+ console.error("[ai-security-gateway] Models request error:", error);
29
+ res.writeHead(500, { "Content-Type": "application/json" });
30
+ res.end(JSON.stringify({
31
+ error: "Internal gateway error",
32
+ message: error instanceof Error ? error.message : String(error),
33
+ }));
34
+ }
35
+ }
36
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/handlers/models.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAqB,MAAM,cAAc,CAAC;AAErE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAmB,EACnB,MAAqB;IAErB,IAAI,CAAC;QACH,uDAAuD;QACvD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,yCAAyC,EAAE,CAAC,CAAC,CAAC;YAC9E,OAAO;QACT,CAAC;QAED,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;QAC7B,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,OAAO,YAAY,CAAC;QACjD,MAAM,OAAO,GAA2B;YACtC,eAAe,EAAE,UAAU,OAAO,CAAC,MAAM,EAAE;SAC5C,CAAC;QAEF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC5C,CAAC;QACD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;QACrC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACvE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;QACpE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CACL,IAAI,CAAC,SAAS,CAAC;YACb,KAAK,EAAE,wBAAwB;YAC/B,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CACH,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * AI Security Gateway - OpenAI Chat Completions API handler
3
+ *
4
+ * Handles POST /v1/chat/completions requests in OpenAI's format.
5
+ * Also compatible with OpenAI-compatible APIs (Kimi, DeepSeek, etc.)
6
+ */
7
+ import type { IncomingMessage, ServerResponse } from "node:http";
8
+ import type { BackendConfig } from "../types.js";
9
+ /**
10
+ * Handle OpenAI API request
11
+ *
12
+ * @param backend - Config for OpenAI-compatible backend
13
+ * @param extraHeaders - Optional additional headers (e.g., OpenRouter attribution)
14
+ */
15
+ export declare function handleOpenAIRequest(req: IncomingMessage, res: ServerResponse, backend: BackendConfig, extraHeaders?: Record<string, string>): Promise<void>;
16
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/handlers/openai.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAC;AAK/D;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,aAAa,EACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC,CAiGf"}
@@ -0,0 +1,254 @@
1
+ /**
2
+ * AI Security Gateway - OpenAI Chat Completions API handler
3
+ *
4
+ * Handles POST /v1/chat/completions requests in OpenAI's format.
5
+ * Also compatible with OpenAI-compatible APIs (Kimi, DeepSeek, etc.)
6
+ */
7
+ import { sanitize } from "../sanitizer.js";
8
+ import { restore, createStreamRestorer } from "../restorer.js";
9
+ import { generateRequestId, logSanitizeEvent, logRestoreEvent } from "../activity.js";
10
+ /**
11
+ * Handle OpenAI API request
12
+ *
13
+ * @param backend - Config for OpenAI-compatible backend
14
+ * @param extraHeaders - Optional additional headers (e.g., OpenRouter attribution)
15
+ */
16
+ export async function handleOpenAIRequest(req, res, backend, extraHeaders) {
17
+ try {
18
+ const requestId = generateRequestId();
19
+ const sanitizeStart = Date.now();
20
+ // 1. Parse request body
21
+ const body = await readBody(req);
22
+ const requestData = JSON.parse(body);
23
+ const { model, messages, tools, tool_choice, temperature, max_tokens, stream = false, ...rest } = requestData;
24
+ // 2. Sanitize messages
25
+ const { sanitized: sanitizedMessages, mappingTable, redactionCount } = sanitize(messages);
26
+ // Debug: log what was sanitized
27
+ console.log(`[ai-security-gateway] Sanitized ${redactionCount} items`);
28
+ if (mappingTable.size > 0) {
29
+ for (const [placeholder, original] of mappingTable.entries()) {
30
+ console.log(`[ai-security-gateway] ${placeholder} <- (${original.length} chars)`);
31
+ }
32
+ }
33
+ // Log sanitization event
34
+ if (redactionCount > 0) {
35
+ logSanitizeEvent({
36
+ requestId,
37
+ backend: "openai",
38
+ endpoint: "/v1/chat/completions",
39
+ model,
40
+ mappingTable,
41
+ redactionCount,
42
+ durationMs: Date.now() - sanitizeStart,
43
+ });
44
+ }
45
+ // 3. Build sanitized request
46
+ const sanitizedRequest = {
47
+ model,
48
+ messages: sanitizedMessages,
49
+ ...(tools && { tools }),
50
+ ...(tool_choice && { tool_choice }),
51
+ ...(temperature !== undefined && { temperature }),
52
+ ...(max_tokens && { max_tokens }),
53
+ stream,
54
+ ...rest,
55
+ };
56
+ // 4. Use provided backend config
57
+ // Note: baseUrl already includes the full path prefix (e.g., /v1 or /v1/coding)
58
+ const apiUrl = `${backend.baseUrl}/chat/completions`;
59
+ const headers = {
60
+ "Content-Type": "application/json",
61
+ "Authorization": `Bearer ${backend.apiKey}`,
62
+ };
63
+ // Merge extra headers (e.g., OpenRouter attribution headers)
64
+ if (extraHeaders) {
65
+ Object.assign(headers, extraHeaders);
66
+ }
67
+ const response = await fetch(apiUrl, {
68
+ method: "POST",
69
+ headers,
70
+ body: JSON.stringify(sanitizedRequest),
71
+ });
72
+ if (!response.ok) {
73
+ // Forward error response
74
+ res.writeHead(response.status, { "Content-Type": "application/json" });
75
+ const errorBody = await response.text();
76
+ res.end(errorBody);
77
+ return;
78
+ }
79
+ // 6. Handle streaming or non-streaming response
80
+ if (stream) {
81
+ await handleOpenAIStream(response, res, mappingTable, requestId, model);
82
+ }
83
+ else {
84
+ await handleOpenAINonStream(response, res, mappingTable, requestId, model);
85
+ }
86
+ }
87
+ catch (error) {
88
+ console.error("[ai-security-gateway] OpenAI handler error:", error);
89
+ res.writeHead(500, { "Content-Type": "application/json" });
90
+ res.end(JSON.stringify({
91
+ error: "Internal gateway error",
92
+ message: error instanceof Error ? error.message : String(error),
93
+ }));
94
+ }
95
+ }
96
+ /**
97
+ * Handle streaming response (SSE) with smart placeholder restoration
98
+ *
99
+ * Uses StreamRestorer to detect `__` and buffer potential placeholders.
100
+ * Only buffers when necessary, maintaining streaming UX.
101
+ */
102
+ async function handleOpenAIStream(response, res, mappingTable, requestId, model) {
103
+ const restoreStart = Date.now();
104
+ // Debug: log mapping table
105
+ if (mappingTable.size > 0) {
106
+ console.log(`[ai-security-gateway] Streaming with ${mappingTable.size} placeholders to restore`);
107
+ }
108
+ // Set SSE headers
109
+ res.writeHead(200, {
110
+ "Content-Type": "text/event-stream",
111
+ "Cache-Control": "no-cache",
112
+ "Connection": "keep-alive",
113
+ });
114
+ const reader = response.body?.getReader();
115
+ if (!reader) {
116
+ res.end();
117
+ return;
118
+ }
119
+ const decoder = new TextDecoder();
120
+ let lineBuffer = "";
121
+ // Create stream restorer for text content
122
+ const streamRestorer = createStreamRestorer(mappingTable);
123
+ // Buffer for SSE chunks waiting for restoration
124
+ const pendingChunks = [];
125
+ try {
126
+ while (true) {
127
+ const { done, value } = await reader.read();
128
+ if (done)
129
+ break;
130
+ // Decode chunk
131
+ lineBuffer += decoder.decode(value, { stream: true });
132
+ // Process complete lines
133
+ const lines = lineBuffer.split("\n");
134
+ lineBuffer = lines.pop() || ""; // Keep incomplete line in buffer
135
+ for (const line of lines) {
136
+ if (!line.trim()) {
137
+ // Flush pending chunks before empty line
138
+ flushPendingChunks(pendingChunks, streamRestorer, res);
139
+ res.write("\n");
140
+ continue;
141
+ }
142
+ if (!line.startsWith("data: ")) {
143
+ res.write(line + "\n");
144
+ continue;
145
+ }
146
+ const dataContent = line.slice(6);
147
+ if (dataContent === "[DONE]") {
148
+ // Finalize any pending content
149
+ flushPendingChunks(pendingChunks, streamRestorer, res);
150
+ res.write(line + "\n");
151
+ continue;
152
+ }
153
+ try {
154
+ const parsed = JSON.parse(dataContent);
155
+ const textContent = parsed.choices?.[0]?.delta?.content;
156
+ if (textContent !== undefined && mappingTable.size > 0) {
157
+ // Process text through stream restorer
158
+ const restored = streamRestorer.process(textContent);
159
+ if (restored.length > 0) {
160
+ // We have restorable content - flush it
161
+ const restoredChunk = { ...parsed };
162
+ restoredChunk.choices = parsed.choices.map((c, i) => i === 0 ? { ...c, delta: { ...c.delta, content: restored } } : c);
163
+ res.write(`data: ${JSON.stringify(restoredChunk)}\n`);
164
+ }
165
+ // If restorer is buffering, we don't output anything yet
166
+ // Content will be output when buffer is flushed
167
+ }
168
+ else {
169
+ // No text content or no mappings - pass through
170
+ res.write(line + "\n");
171
+ }
172
+ }
173
+ catch {
174
+ // Not valid JSON, pass through
175
+ res.write(line + "\n");
176
+ }
177
+ }
178
+ }
179
+ // Write any remaining line buffer
180
+ if (lineBuffer.trim()) {
181
+ res.write(lineBuffer + "\n");
182
+ }
183
+ // Finalize stream restorer - flush any remaining buffered content
184
+ const finalContent = streamRestorer.finalize();
185
+ if (finalContent.length > 0) {
186
+ // Create a final chunk with remaining content
187
+ const finalChunk = {
188
+ choices: [{ delta: { content: finalContent }, index: 0, finish_reason: null }],
189
+ };
190
+ res.write(`data: ${JSON.stringify(finalChunk)}\n`);
191
+ }
192
+ // Log restoration event
193
+ if (mappingTable.size > 0) {
194
+ logRestoreEvent({
195
+ requestId,
196
+ backend: "openai",
197
+ endpoint: "/v1/chat/completions",
198
+ model,
199
+ mappingTable,
200
+ restorationCount: mappingTable.size,
201
+ durationMs: Date.now() - restoreStart,
202
+ });
203
+ }
204
+ res.end();
205
+ }
206
+ catch (error) {
207
+ console.error("[ai-security-gateway] Stream error:", error);
208
+ res.end();
209
+ }
210
+ }
211
+ /**
212
+ * Flush pending chunks with restored content
213
+ */
214
+ function flushPendingChunks(_pendingChunks, _streamRestorer, _res) {
215
+ // Currently unused - StreamRestorer handles buffering internally
216
+ }
217
+ /**
218
+ * Handle non-streaming response
219
+ */
220
+ async function handleOpenAINonStream(response, res, mappingTable, requestId, model) {
221
+ const restoreStart = Date.now();
222
+ const responseBody = await response.text();
223
+ const responseData = JSON.parse(responseBody);
224
+ // Restore placeholders in response
225
+ const restoredData = restore(responseData, mappingTable);
226
+ // Log restoration event
227
+ if (mappingTable.size > 0) {
228
+ logRestoreEvent({
229
+ requestId,
230
+ backend: "openai",
231
+ endpoint: "/v1/chat/completions",
232
+ model,
233
+ mappingTable,
234
+ restorationCount: mappingTable.size,
235
+ durationMs: Date.now() - restoreStart,
236
+ });
237
+ }
238
+ res.writeHead(200, { "Content-Type": "application/json" });
239
+ res.end(JSON.stringify(restoredData));
240
+ }
241
+ /**
242
+ * Read request body as string
243
+ */
244
+ function readBody(req) {
245
+ return new Promise((resolve, reject) => {
246
+ let body = "";
247
+ req.on("data", (chunk) => {
248
+ body += chunk.toString();
249
+ });
250
+ req.on("end", () => resolve(body));
251
+ req.on("error", reject);
252
+ });
253
+ }
254
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/handlers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * OpenGuardrails AI Security Gateway
4
+ *
5
+ * Local HTTP proxy that intercepts LLM API calls, sanitizes sensitive data
6
+ * before sending to providers, and restores it in responses.
7
+ * Supports Anthropic, OpenAI, and Gemini protocols.
8
+ */
9
+ /**
10
+ * Stop the gateway server
11
+ */
12
+ export declare function stopGateway(): Promise<void>;
13
+ /**
14
+ * Check if gateway is running
15
+ */
16
+ export declare function isGatewayServerRunning(): boolean;
17
+ /**
18
+ * Start gateway server
19
+ * @param configPath - Path to config file
20
+ * @param embedded - If true, don't call process.exit on errors (for in-process use)
21
+ */
22
+ export declare function startGateway(configPath?: string, embedded?: boolean): void;
23
+ export { sanitize, sanitizeMessages } from "./sanitizer.js";
24
+ export { restore, restoreJSON, restoreSSELine } from "./restorer.js";
25
+ export { addActivityListener, removeActivityListener, clearActivityListeners, } from "./activity.js";
26
+ export type { GatewayConfig, MappingTable, SanitizeResult, EntityMatch, GatewayActivityEvent, ActivityListener, } from "./types.js";
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AAwMH;;GAEG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAY3C;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,UAAQ,GAAG,IAAI,CAmFxE;AAGD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}