@agentxv2/gateway 0.1.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.
Files changed (175) hide show
  1. package/.env.example +53 -0
  2. package/db/migrations/001_init.sql +117 -0
  3. package/db/migrations/002_agents.sql +20 -0
  4. package/db/migrations/003_a2a_results.sql +23 -0
  5. package/deploy/.env.deploy.example +23 -0
  6. package/deploy/add_swap_build.py +45 -0
  7. package/deploy/build_and_deploy.py +110 -0
  8. package/deploy/build_deploy_a2a.py +190 -0
  9. package/deploy/build_no_lint.py +52 -0
  10. package/deploy/build_on_fe.py +86 -0
  11. package/deploy/build_on_gw.py +98 -0
  12. package/deploy/build_prod.py +54 -0
  13. package/deploy/check_bal.py +31 -0
  14. package/deploy/check_code.py +47 -0
  15. package/deploy/check_deploy.sh +20 -0
  16. package/deploy/check_docs.py +16 -0
  17. package/deploy/check_frontend.py +42 -0
  18. package/deploy/check_frontend2.py +35 -0
  19. package/deploy/check_pks.py +34 -0
  20. package/deploy/check_status.py +32 -0
  21. package/deploy/check_v2.py +8 -0
  22. package/deploy/clean_install.py +28 -0
  23. package/deploy/deploy_a2a.py +58 -0
  24. package/deploy/deploy_a2a.sh +33 -0
  25. package/deploy/deploy_a2a_bg.sh +40 -0
  26. package/deploy/deploy_a2a_v2.py +151 -0
  27. package/deploy/deploy_a2a_v2.sh +36 -0
  28. package/deploy/deploy_bin.py +64 -0
  29. package/deploy/deploy_config.py +34 -0
  30. package/deploy/deploy_final.py +42 -0
  31. package/deploy/deploy_frontend.py +108 -0
  32. package/deploy/deploy_mcp.py +108 -0
  33. package/deploy/deploy_now.py +49 -0
  34. package/deploy/deploy_push_all.py +128 -0
  35. package/deploy/deploy_script.py +64 -0
  36. package/deploy/deploy_sep_a2a.sh +18 -0
  37. package/deploy/dev_mode.py +51 -0
  38. package/deploy/diag.py +12 -0
  39. package/deploy/diff_test.py +22 -0
  40. package/deploy/final_check.py +33 -0
  41. package/deploy/final_deploy.py +50 -0
  42. package/deploy/final_fix.py +54 -0
  43. package/deploy/final_push.py +114 -0
  44. package/deploy/find_frontend.py +38 -0
  45. package/deploy/fix_a2a.py +43 -0
  46. package/deploy/fix_and_build.py +77 -0
  47. package/deploy/fix_and_verify.py +56 -0
  48. package/deploy/fix_build.py +51 -0
  49. package/deploy/forge_deploy.py +67 -0
  50. package/deploy/full_push.py +101 -0
  51. package/deploy/full_push2.py +106 -0
  52. package/deploy/go_prod.py +59 -0
  53. package/deploy/gw_deploy.py +133 -0
  54. package/deploy/gw_final.py +206 -0
  55. package/deploy/gw_restart.py +28 -0
  56. package/deploy/gw_status.py +18 -0
  57. package/deploy/inline_build.py +99 -0
  58. package/deploy/one_shot.py +84 -0
  59. package/deploy/ox_deploy.py +32 -0
  60. package/deploy/pg_setup.py +36 -0
  61. package/deploy/prod_deploy.py +126 -0
  62. package/deploy/prod_final.py +140 -0
  63. package/deploy/prod_go.py +61 -0
  64. package/deploy/prod_one_shot.py +139 -0
  65. package/deploy/prod_setup.sh +62 -0
  66. package/deploy/prod_v2.py +91 -0
  67. package/deploy/prod_v3.py +103 -0
  68. package/deploy/push_docs.py +93 -0
  69. package/deploy/push_mcp.py +66 -0
  70. package/deploy/push_mcp_doc.py +28 -0
  71. package/deploy/push_v063.py +80 -0
  72. package/deploy/push_v2.py +71 -0
  73. package/deploy/qcheck.py +13 -0
  74. package/deploy/qcheck2.py +18 -0
  75. package/deploy/quick_check.py +8 -0
  76. package/deploy/rebuild.py +47 -0
  77. package/deploy/rebuild_frontend.py +44 -0
  78. package/deploy/restart.py +28 -0
  79. package/deploy/restore_frontend.py +42 -0
  80. package/deploy/restore_frontend2.py +41 -0
  81. package/deploy/restore_gateway.py +34 -0
  82. package/deploy/restore_quick.py +33 -0
  83. package/deploy/run_bash.py +19 -0
  84. package/deploy/run_sep.py +20 -0
  85. package/deploy/sdk_upgrade.py +50 -0
  86. package/deploy/server_prepare.py +41 -0
  87. package/deploy/server_setup.py +41 -0
  88. package/deploy/ssh_check.py +14 -0
  89. package/deploy/ssh_push.py +24 -0
  90. package/deploy/start_deploy.py +35 -0
  91. package/deploy/start_frontend.py +12 -0
  92. package/deploy/start_v2.py +29 -0
  93. package/deploy/stat.py +18 -0
  94. package/deploy/tail_log.py +11 -0
  95. package/deploy/update_env.py +32 -0
  96. package/deploy/upload_and_start.py +107 -0
  97. package/deploy/verify_a2a.py +13 -0
  98. package/deploy/verify_mcp.py +37 -0
  99. package/deploy/verify_sdk.py +21 -0
  100. package/dist/config.d.ts +26 -0
  101. package/dist/config.js +41 -0
  102. package/dist/config.js.map +1 -0
  103. package/dist/index.d.ts +1 -0
  104. package/dist/index.js +149 -0
  105. package/dist/index.js.map +1 -0
  106. package/dist/lib/crypto.d.ts +2 -0
  107. package/dist/lib/crypto.js +43 -0
  108. package/dist/lib/crypto.js.map +1 -0
  109. package/dist/lib/db.d.ts +3 -0
  110. package/dist/lib/db.js +26 -0
  111. package/dist/lib/db.js.map +1 -0
  112. package/dist/lib/ethers-utils.d.ts +60 -0
  113. package/dist/lib/ethers-utils.js +186 -0
  114. package/dist/lib/ethers-utils.js.map +1 -0
  115. package/dist/middleware/adminAuth.d.ts +2 -0
  116. package/dist/middleware/adminAuth.js +31 -0
  117. package/dist/middleware/adminAuth.js.map +1 -0
  118. package/dist/middleware/auth.d.ts +22 -0
  119. package/dist/middleware/auth.js +192 -0
  120. package/dist/middleware/auth.js.map +1 -0
  121. package/dist/middleware/error-handler.d.ts +36 -0
  122. package/dist/middleware/error-handler.js +100 -0
  123. package/dist/middleware/error-handler.js.map +1 -0
  124. package/dist/middleware/rate-limiter.d.ts +5 -0
  125. package/dist/middleware/rate-limiter.js +107 -0
  126. package/dist/middleware/rate-limiter.js.map +1 -0
  127. package/dist/routes/a2a.d.ts +2 -0
  128. package/dist/routes/a2a.js +84 -0
  129. package/dist/routes/a2a.js.map +1 -0
  130. package/dist/routes/admin.d.ts +2 -0
  131. package/dist/routes/admin.js +180 -0
  132. package/dist/routes/admin.js.map +1 -0
  133. package/dist/routes/agents.d.ts +2 -0
  134. package/dist/routes/agents.js +43 -0
  135. package/dist/routes/agents.js.map +1 -0
  136. package/dist/routes/chat.d.ts +2 -0
  137. package/dist/routes/chat.js +183 -0
  138. package/dist/routes/chat.js.map +1 -0
  139. package/dist/routes/history.d.ts +2 -0
  140. package/dist/routes/history.js +92 -0
  141. package/dist/routes/history.js.map +1 -0
  142. package/dist/routes/mcp.d.ts +13 -0
  143. package/dist/routes/mcp.js +513 -0
  144. package/dist/routes/mcp.js.map +1 -0
  145. package/dist/routes/tenant.d.ts +2 -0
  146. package/dist/routes/tenant.js +154 -0
  147. package/dist/routes/tenant.js.map +1 -0
  148. package/dist/services/a2a-worker.d.ts +7 -0
  149. package/dist/services/a2a-worker.js +406 -0
  150. package/dist/services/a2a-worker.js.map +1 -0
  151. package/dist/services/agent-indexer.d.ts +4 -0
  152. package/dist/services/agent-indexer.js +124 -0
  153. package/dist/services/agent-indexer.js.map +1 -0
  154. package/e2e_wallet.js +175 -0
  155. package/ecosystem.config.js +17 -0
  156. package/package.json +33 -0
  157. package/src/config.ts +47 -0
  158. package/src/index.ts +143 -0
  159. package/src/lib/crypto.ts +44 -0
  160. package/src/lib/db.ts +25 -0
  161. package/src/lib/ethers-utils.ts +229 -0
  162. package/src/middleware/adminAuth.ts +34 -0
  163. package/src/middleware/auth.ts +244 -0
  164. package/src/middleware/error-handler.ts +109 -0
  165. package/src/middleware/rate-limiter.ts +115 -0
  166. package/src/routes/a2a.ts +97 -0
  167. package/src/routes/admin.ts +219 -0
  168. package/src/routes/agents.ts +52 -0
  169. package/src/routes/chat.ts +219 -0
  170. package/src/routes/history.ts +114 -0
  171. package/src/routes/mcp.ts +567 -0
  172. package/src/routes/tenant.ts +196 -0
  173. package/src/services/a2a-worker.ts +486 -0
  174. package/src/services/agent-indexer.ts +127 -0
  175. package/tsconfig.json +18 -0
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // AgentX Gateway — Admin Routes
4
+ // ---------------------------------------------------------------------------
5
+ // POST /api/v1/admin/platform-keys — Add platform API key
6
+ // GET /api/v1/admin/platform-keys — List platform API keys
7
+ // DELETE /api/v1/admin/platform-keys/:id — Delete platform API key
8
+ // GET /api/v1/admin/plans — List plans
9
+ // GET /api/v1/admin/tenants — List tenants (paginated)
10
+ // PATCH /api/v1/admin/tenants/:id — Update tenant plan/status
11
+ // GET /api/v1/admin/usage — Usage stats
12
+ // ---------------------------------------------------------------------------
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const express_1 = require("express");
15
+ const db_1 = require("../lib/db");
16
+ const adminAuth_1 = require("../middleware/adminAuth");
17
+ const crypto_1 = require("../lib/crypto");
18
+ const config_1 = require("../config");
19
+ const router = (0, express_1.Router)();
20
+ // All admin routes require admin auth
21
+ router.use(adminAuth_1.adminAuth);
22
+ // ── Platform API Keys ─────────────────────────────────────────────────────
23
+ // List all platform keys (masked)
24
+ router.get('/platform-keys', async (_req, res) => {
25
+ try {
26
+ const pool = (0, db_1.getPool)();
27
+ const result = await pool.query(`SELECT pk.id, pk.provider, pk.endpoint, pk.models, pk.plan_ids, pk.weight, pk.is_active,
28
+ pk.created_at,
29
+ array_agg(p.slug) as plan_slugs
30
+ FROM platform_api_keys pk
31
+ LEFT JOIN plans p ON p.id = ANY(pk.plan_ids)
32
+ GROUP BY pk.id
33
+ ORDER BY pk.created_at DESC`);
34
+ res.json({ keys: result.rows });
35
+ }
36
+ catch (err) {
37
+ res.status(500).json({ error: err.message });
38
+ }
39
+ });
40
+ // Add platform API key
41
+ router.post('/platform-keys', async (req, res) => {
42
+ try {
43
+ const { provider, endpoint, api_key, models, plan_slugs } = req.body;
44
+ if (!provider || !endpoint || !api_key) {
45
+ res.status(400).json({ error: 'provider, endpoint, and api_key are required' });
46
+ return;
47
+ }
48
+ const pool = (0, db_1.getPool)();
49
+ // Resolve plan slugs to IDs
50
+ const slugs = plan_slugs || ['pro', 'enterprise'];
51
+ const planResult = await pool.query(`SELECT id FROM plans WHERE slug = ANY($1)`, [slugs]);
52
+ const planIds = planResult.rows.map((r) => r.id);
53
+ const encrypted = (0, crypto_1.encryptApiKey)(api_key, config_1.config.masterEncryptionKey);
54
+ const modelList = models || [provider === 'deepseek' ? 'deepseek-chat' : 'gpt-4o'];
55
+ await pool.query(`INSERT INTO platform_api_keys (provider, endpoint, api_key, plan_ids, models, weight, is_active)
56
+ VALUES ($1, $2, $3, $4, $5, 1, true)`, [provider, endpoint, encrypted, planIds, modelList]);
57
+ res.status(201).json({ success: true, provider, endpoint, models: modelList });
58
+ }
59
+ catch (err) {
60
+ res.status(500).json({ error: err.message });
61
+ }
62
+ });
63
+ // Delete platform API key
64
+ router.delete('/platform-keys/:id', async (req, res) => {
65
+ try {
66
+ const pool = (0, db_1.getPool)();
67
+ const result = await pool.query(`DELETE FROM platform_api_keys WHERE id = $1 RETURNING id, provider`, [req.params.id]);
68
+ if (result.rows.length === 0) {
69
+ res.status(404).json({ error: 'Key not found' });
70
+ return;
71
+ }
72
+ res.json({ success: true, deleted: result.rows[0] });
73
+ }
74
+ catch (err) {
75
+ res.status(500).json({ error: err.message });
76
+ }
77
+ });
78
+ // ── Plans ──────────────────────────────────────────────────────────────────
79
+ router.get('/plans', async (_req, res) => {
80
+ try {
81
+ const pool = (0, db_1.getPool)();
82
+ const result = await pool.query(`SELECT id, name, slug, price_monthly, quota_daily, quota_monthly,
83
+ byok_enabled, rate_limit_rpm, max_concurrent, platform_models, is_active
84
+ FROM plans ORDER BY price_monthly ASC`);
85
+ res.json({ plans: result.rows });
86
+ }
87
+ catch (err) {
88
+ res.status(500).json({ error: err.message });
89
+ }
90
+ });
91
+ // ── Tenants ────────────────────────────────────────────────────────────────
92
+ router.get('/tenants', async (req, res) => {
93
+ try {
94
+ const page = parseInt(req.query.page) || 1;
95
+ const limit = Math.min(parseInt(req.query.limit) || 20, 100);
96
+ const offset = (page - 1) * limit;
97
+ const pool = (0, db_1.getPool)();
98
+ const [countResult, tenantResult] = await Promise.all([
99
+ pool.query(`SELECT COUNT(*) FROM tenants`),
100
+ pool.query(`SELECT t.id, t.wallet_address, t.status,
101
+ t.quota_daily, t.quota_used, t.rate_limit_rpm, t.max_concurrent,
102
+ t.created_at, t.updated_at,
103
+ p.slug as plan_slug, p.name as plan_name
104
+ FROM tenants t
105
+ LEFT JOIN plans p ON t.plan_id = p.id
106
+ ORDER BY t.created_at DESC
107
+ LIMIT $1 OFFSET $2`, [limit, offset]),
108
+ ]);
109
+ res.json({
110
+ tenants: tenantResult.rows,
111
+ total: parseInt(countResult.rows[0].count),
112
+ page,
113
+ limit,
114
+ });
115
+ }
116
+ catch (err) {
117
+ res.status(500).json({ error: err.message });
118
+ }
119
+ });
120
+ router.patch('/tenants/:id', async (req, res) => {
121
+ try {
122
+ const { plan_slug, status } = req.body;
123
+ const pool = (0, db_1.getPool)();
124
+ if (plan_slug) {
125
+ const planResult = await pool.query(`SELECT id FROM plans WHERE slug = $1`, [plan_slug]);
126
+ if (planResult.rows.length === 0) {
127
+ res.status(400).json({ error: 'Invalid plan slug' });
128
+ return;
129
+ }
130
+ const plan = planResult.rows[0];
131
+ await pool.query(`UPDATE tenants SET plan_id = $1, updated_at = NOW() WHERE id = $2`, [plan.id, req.params.id]);
132
+ }
133
+ if (status) {
134
+ await pool.query(`UPDATE tenants SET status = $1, updated_at = NOW() WHERE id = $2`, [status, req.params.id]);
135
+ }
136
+ res.json({ success: true });
137
+ }
138
+ catch (err) {
139
+ res.status(500).json({ error: err.message });
140
+ }
141
+ });
142
+ // ── Usage Stats ────────────────────────────────────────────────────────────
143
+ router.get('/usage', async (_req, res) => {
144
+ try {
145
+ const pool = (0, db_1.getPool)();
146
+ const [total, recent, topTenants] = await Promise.all([
147
+ pool.query(`SELECT COUNT(*) as total_requests,
148
+ COALESCE(SUM(tokens_total), 0) as total_tokens
149
+ FROM usage_logs`),
150
+ pool.query(`SELECT DATE(created_at) as date,
151
+ COUNT(*) as requests,
152
+ SUM(tokens_total) as tokens
153
+ FROM usage_logs
154
+ WHERE created_at > NOW() - INTERVAL '30 days'
155
+ GROUP BY DATE(created_at)
156
+ ORDER BY date DESC
157
+ LIMIT 30`),
158
+ pool.query(`SELECT t.wallet_address, p.slug as plan,
159
+ COUNT(ul.*) as requests,
160
+ COALESCE(SUM(ul.tokens_total), 0) as tokens
161
+ FROM tenants t
162
+ LEFT JOIN usage_logs ul ON ul.tenant_id = t.id
163
+ LEFT JOIN plans p ON t.plan_id = p.id
164
+ WHERE ul.created_at > NOW() - INTERVAL '30 days' OR ul.id IS NULL
165
+ GROUP BY t.id, t.wallet_address, p.slug
166
+ ORDER BY tokens DESC
167
+ LIMIT 20`),
168
+ ]);
169
+ res.json({
170
+ summary: total.rows[0],
171
+ daily: recent.rows,
172
+ topTenants: topTenants.rows,
173
+ });
174
+ }
175
+ catch (err) {
176
+ res.status(500).json({ error: err.message });
177
+ }
178
+ });
179
+ exports.default = router;
180
+ //# sourceMappingURL=admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/routes/admin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // ── Agents API (public, read-only)
4
+ // ---------------------------------------------------------------------------
5
+ // GET /api/v1/agents → list all agents
6
+ // GET /api/v1/agents/:id → single agent detail
7
+ // ---------------------------------------------------------------------------
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const express_1 = require("express");
10
+ const db_1 = require("../lib/db");
11
+ const router = (0, express_1.Router)();
12
+ // ── List all agents ─────────────────────────────────────────────────────────
13
+ router.get('/', async (_req, res) => {
14
+ try {
15
+ const pool = (0, db_1.getPool)();
16
+ const { rows } = await pool.query(`SELECT id, owner, name, description, tags, capabilities, synced_at, created_at
17
+ FROM agents
18
+ ORDER BY id DESC`);
19
+ res.json({ agents: rows, total: rows.length });
20
+ }
21
+ catch (err) {
22
+ console.error('[agents] list error:', err.message);
23
+ res.status(500).json({ error: 'Failed to fetch agents' });
24
+ }
25
+ });
26
+ // ── Single agent detail ─────────────────────────────────────────────────────
27
+ router.get('/:id', async (req, res) => {
28
+ try {
29
+ const pool = (0, db_1.getPool)();
30
+ const { rows } = await pool.query(`SELECT id, owner, name, description, tags, capabilities, token_uri, metadata_json, synced_at, created_at, updated_at
31
+ FROM agents WHERE id = $1`, [parseInt(req.params.id)]);
32
+ if (rows.length === 0) {
33
+ return res.status(404).json({ error: 'Agent not found' });
34
+ }
35
+ res.json(rows[0]);
36
+ }
37
+ catch (err) {
38
+ console.error('[agents] detail error:', err.message);
39
+ res.status(500).json({ error: 'Failed to fetch agent' });
40
+ }
41
+ });
42
+ exports.default = router;
43
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/routes/agents.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAC9E,+CAA+C;AAC/C,mDAAmD;AACnD,8EAA8E;;AAE9E,qCAAmD;AACnD,kCAAmC;AAEnC,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAA;AAEvB,+EAA+E;AAE/E,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,IAAa,EAAE,GAAa,EAAE,EAAE;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,YAAO,GAAE,CAAA;QACtB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B;;wBAEkB,CACnB,CAAA;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IAChD,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;QAClD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAA;IAC3D,CAAC;AACH,CAAC,CAAC,CAAA;AAEF,+EAA+E;AAE/E,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IACvD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAA,YAAO,GAAE,CAAA;QACtB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B;iCAC2B,EAC3B,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAC1B,CAAA;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAA;QAC3D,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;QACpD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAA;IAC1D,CAAC;AACH,CAAC,CAAC,CAAA;AAEF,kBAAe,MAAM,CAAA"}
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // AgentX Gateway — Chat Completions Proxy
4
+ // ---------------------------------------------------------------------------
5
+ // POST /api/v1/chat/completions
6
+ // Resolves tenant API key, proxies to LLM, streams back, records usage.
7
+ // ---------------------------------------------------------------------------
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const express_1 = require("express");
10
+ const db_1 = require("../lib/db");
11
+ const crypto_1 = require("../lib/crypto");
12
+ const config_1 = require("../config");
13
+ const rate_limiter_1 = require("../middleware/rate-limiter");
14
+ const router = (0, express_1.Router)();
15
+ router.post('/chat/completions', async (req, res) => {
16
+ const tenant = req.tenant;
17
+ if (!tenant) {
18
+ res.status(401).json({ error: 'Unauthorized' });
19
+ return;
20
+ }
21
+ const { model, messages, tools, stream, key_source, tenant_key_id, temperature, max_tokens, } = req.body;
22
+ let apiKey;
23
+ let endpoint;
24
+ let keySource;
25
+ let platformKeyId = null;
26
+ let tenantKeyId = null;
27
+ let resolvedModel = model || 'gpt-4o';
28
+ const pool = (0, db_1.getPool)();
29
+ try {
30
+ if (key_source === 'tenant_owned' && tenant_key_id) {
31
+ // ── BYOK Mode ──
32
+ const keyRow = await pool.query(`SELECT * FROM tenant_api_keys WHERE id = $1 AND tenant_id = $2 AND is_active = true`, [tenant_key_id, tenant.id]);
33
+ if (keyRow.rows.length === 0) {
34
+ res.status(400).json({ error: 'Tenant API key not found or inactive' });
35
+ return;
36
+ }
37
+ const tk = keyRow.rows[0];
38
+ apiKey = (0, crypto_1.decryptApiKey)(tk.api_key, config_1.config.masterEncryptionKey);
39
+ endpoint = tk.endpoint;
40
+ resolvedModel = model || tk.model;
41
+ keySource = 'tenant_owned';
42
+ tenantKeyId = tk.id;
43
+ }
44
+ else if (tenant.quotaDaily > 0) {
45
+ // ── Platform Mode ──
46
+ if (tenant.quotaUsed >= tenant.quotaDaily) {
47
+ res.status(429).json({
48
+ error: 'Platform quota exhausted',
49
+ hint: 'Switch to BYOK mode or upgrade your plan',
50
+ });
51
+ return;
52
+ }
53
+ const planRow = await pool.query(`SELECT platform_models FROM plans WHERE id = $1`, [tenant.planId]);
54
+ const planModels = planRow.rows[0]?.platform_models || [];
55
+ let matchedModel = null;
56
+ if (resolvedModel) {
57
+ matchedModel = planModels.find((m) => m.model === resolvedModel) || planModels[0];
58
+ }
59
+ else {
60
+ matchedModel = planModels[0];
61
+ }
62
+ if (!matchedModel) {
63
+ res.status(400).json({
64
+ error: 'No platform models available on current plan',
65
+ available_models: planModels.map((m) => m.model),
66
+ });
67
+ return;
68
+ }
69
+ const keyRow = await pool.query(`SELECT * FROM platform_api_keys
70
+ WHERE provider = $1 AND $2 = ANY(plan_ids) AND is_active = true
71
+ ORDER BY random() LIMIT 1`, [matchedModel.provider, tenant.planId]);
72
+ if (keyRow.rows.length === 0) {
73
+ res.status(500).json({ error: 'No platform API key available' });
74
+ return;
75
+ }
76
+ const pk = keyRow.rows[0];
77
+ apiKey = (0, crypto_1.decryptApiKey)(pk.api_key, config_1.config.masterEncryptionKey);
78
+ endpoint = pk.endpoint;
79
+ resolvedModel = matchedModel.model;
80
+ keySource = 'platform';
81
+ platformKeyId = pk.id;
82
+ }
83
+ else {
84
+ res.status(400).json({
85
+ error: 'No LLM access configured',
86
+ hint: 'Add a BYOK API key in tenant settings or upgrade to a paid plan',
87
+ });
88
+ return;
89
+ }
90
+ // ── Proxy to LLM ──
91
+ const llmBody = {
92
+ model: resolvedModel,
93
+ messages,
94
+ stream: true,
95
+ };
96
+ if (tools)
97
+ llmBody.tools = tools;
98
+ if (temperature !== undefined)
99
+ llmBody.temperature = temperature;
100
+ if (max_tokens)
101
+ llmBody.max_tokens = max_tokens;
102
+ const llmResponse = await fetch(`${endpoint}/chat/completions`, {
103
+ method: 'POST',
104
+ headers: {
105
+ 'Content-Type': 'application/json',
106
+ 'Authorization': `Bearer ${apiKey}`,
107
+ },
108
+ body: JSON.stringify(llmBody),
109
+ });
110
+ if (!llmResponse.ok) {
111
+ const errText = await llmResponse.text();
112
+ res.status(llmResponse.status).json({ error: `LLM error: ${errText}` });
113
+ return;
114
+ }
115
+ // ── SSE Stream Pipe ──
116
+ res.setHeader('Content-Type', 'text/event-stream');
117
+ res.setHeader('Cache-Control', 'no-cache');
118
+ res.setHeader('Connection', 'keep-alive');
119
+ const reader = llmResponse.body?.getReader();
120
+ if (!reader) {
121
+ res.status(500).json({ error: 'No response from LLM' });
122
+ return;
123
+ }
124
+ const decoder = new TextDecoder();
125
+ let buffer = '';
126
+ let totalPrompt = 0;
127
+ let totalCompletion = 0;
128
+ let totalTokens = 0;
129
+ try {
130
+ while (true) {
131
+ const { done, value } = await reader.read();
132
+ if (done)
133
+ break;
134
+ buffer += decoder.decode(value, { stream: true });
135
+ const lines = buffer.split('\n');
136
+ buffer = lines.pop() ?? '';
137
+ for (const line of lines) {
138
+ res.write(line + '\n');
139
+ if (line.startsWith('data: ') && !line.includes('[DONE]')) {
140
+ try {
141
+ const data = JSON.parse(line.slice(6));
142
+ if (data.usage) {
143
+ totalPrompt = data.usage.prompt_tokens || 0;
144
+ totalCompletion = data.usage.completion_tokens || 0;
145
+ totalTokens = data.usage.total_tokens || 0;
146
+ }
147
+ }
148
+ catch { /* skip parse errors */ }
149
+ }
150
+ }
151
+ }
152
+ if (buffer) {
153
+ res.write(buffer + '\n');
154
+ }
155
+ }
156
+ finally {
157
+ reader.releaseLock();
158
+ }
159
+ try {
160
+ await pool.query(`INSERT INTO usage_logs (tenant_id, key_source, platform_key_id, tenant_key_id, provider, model, tokens_prompt, tokens_completion, tokens_total, tool_calls, agent_id)
161
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)`, [
162
+ tenant.id, keySource, platformKeyId, tenantKeyId,
163
+ keySource === 'platform' ? 'openai' : 'unknown',
164
+ resolvedModel,
165
+ totalPrompt, totalCompletion, totalTokens,
166
+ Array.isArray(tools) ? tools.length : 0,
167
+ null,
168
+ ]);
169
+ }
170
+ catch { /* usage logging is non-critical */ }
171
+ if (keySource === 'platform' && totalTokens > 0) {
172
+ (0, rate_limiter_1.updateQuota)(tenant.id, totalTokens).catch(() => { });
173
+ }
174
+ res.end();
175
+ }
176
+ catch (err) {
177
+ if (!res.headersSent) {
178
+ res.status(500).json({ error: 'Internal proxy error' });
179
+ }
180
+ }
181
+ });
182
+ exports.default = router;
183
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/routes/chat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // AgentX Gateway — Chat History Routes
4
+ // ---------------------------------------------------------------------------
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const express_1 = require("express");
7
+ const db_1 = require("../lib/db");
8
+ const router = (0, express_1.Router)();
9
+ // GET /api/v1/chat/history/:agentId
10
+ router.get('/history/:agentId', async (req, res) => {
11
+ const agentId = parseInt(req.params.agentId, 10);
12
+ if (isNaN(agentId)) {
13
+ res.status(400).json({ error: 'Invalid agentId' });
14
+ return;
15
+ }
16
+ const limit = Math.min(parseInt(req.query.limit || '100', 10), 500);
17
+ const before = req.query.before;
18
+ const pool = (0, db_1.getPool)();
19
+ let result;
20
+ if (before) {
21
+ result = await pool.query(`SELECT id, agent_id, role, content, tool_name, tool_input, tool_output, created_at
22
+ FROM chat_messages
23
+ WHERE tenant_id = $1 AND agent_id = $2 AND id < $3
24
+ ORDER BY id DESC
25
+ LIMIT $4`, [req.tenant.id, agentId, before, limit]);
26
+ }
27
+ else {
28
+ result = await pool.query(`SELECT id, agent_id, role, content, tool_name, tool_input, tool_output, created_at
29
+ FROM chat_messages
30
+ WHERE tenant_id = $1 AND agent_id = $2
31
+ ORDER BY id DESC
32
+ LIMIT $3`, [req.tenant.id, agentId, limit]);
33
+ }
34
+ res.json({
35
+ messages: result.rows.reverse(),
36
+ agent_id: agentId,
37
+ has_more: result.rows.length >= limit,
38
+ });
39
+ });
40
+ // POST /api/v1/chat/history/:agentId
41
+ router.post('/history/:agentId', async (req, res) => {
42
+ const agentId = parseInt(req.params.agentId, 10);
43
+ if (isNaN(agentId)) {
44
+ res.status(400).json({ error: 'Invalid agentId' });
45
+ return;
46
+ }
47
+ const { messages } = req.body;
48
+ if (!Array.isArray(messages) || messages.length === 0) {
49
+ res.status(400).json({ error: 'messages array is required' });
50
+ return;
51
+ }
52
+ const pool = (0, db_1.getPool)();
53
+ const client = await pool.connect();
54
+ try {
55
+ await client.query('BEGIN');
56
+ await client.query(`DELETE FROM chat_messages WHERE tenant_id = $1 AND agent_id = $2`, [req.tenant.id, agentId]);
57
+ for (const msg of messages) {
58
+ await client.query(`INSERT INTO chat_messages (tenant_id, agent_id, role, content, tool_name, tool_input, tool_output)
59
+ VALUES ($1, $2, $3, $4, $5, $6, $7)`, [
60
+ req.tenant.id,
61
+ agentId,
62
+ msg.role,
63
+ msg.content || '',
64
+ msg.tool_name || null,
65
+ msg.tool_input ? JSON.stringify(msg.tool_input) : null,
66
+ msg.tool_output ? JSON.stringify(msg.tool_output) : null,
67
+ ]);
68
+ }
69
+ await client.query('COMMIT');
70
+ res.json({ saved: messages.length, agent_id: agentId });
71
+ }
72
+ catch (err) {
73
+ await client.query('ROLLBACK');
74
+ throw err;
75
+ }
76
+ finally {
77
+ client.release();
78
+ }
79
+ });
80
+ // DELETE /api/v1/chat/history/:agentId
81
+ router.delete('/history/:agentId', async (req, res) => {
82
+ const agentId = parseInt(req.params.agentId, 10);
83
+ if (isNaN(agentId)) {
84
+ res.status(400).json({ error: 'Invalid agentId' });
85
+ return;
86
+ }
87
+ const pool = (0, db_1.getPool)();
88
+ await pool.query(`DELETE FROM chat_messages WHERE tenant_id = $1 AND agent_id = $2`, [req.tenant.id, agentId]);
89
+ res.json({ cleared: true, agent_id: agentId });
90
+ });
91
+ exports.default = router;
92
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/routes/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ interface MCPTool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: 'object';
7
+ properties: Record<string, unknown>;
8
+ required?: string[];
9
+ };
10
+ }
11
+ declare const MCP_TOOLS: MCPTool[];
12
+ export default router;
13
+ export { MCP_TOOLS };