@amodalai/runtime 0.1.16 → 0.1.17

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 (70) hide show
  1. package/dist/src/agent/feedback-store.d.ts +39 -0
  2. package/dist/src/agent/feedback-store.js +98 -0
  3. package/dist/src/agent/feedback-store.js.map +1 -0
  4. package/dist/src/agent/local-server.js +9 -2
  5. package/dist/src/agent/local-server.js.map +1 -1
  6. package/dist/src/agent/routes/admin-chat.d.ts +1 -0
  7. package/dist/src/agent/routes/admin-chat.js +1 -1
  8. package/dist/src/agent/routes/admin-chat.js.map +1 -1
  9. package/dist/src/agent/routes/evals.js +34 -47
  10. package/dist/src/agent/routes/evals.js.map +1 -1
  11. package/dist/src/agent/routes/feedback.d.ts +11 -0
  12. package/dist/src/agent/routes/feedback.js +72 -0
  13. package/dist/src/agent/routes/feedback.js.map +1 -0
  14. package/dist/src/agent/routes/files.js +118 -12
  15. package/dist/src/agent/routes/files.js.map +1 -1
  16. package/dist/src/agent/routes/inspect.js +33 -0
  17. package/dist/src/agent/routes/inspect.js.map +1 -1
  18. package/dist/src/cron/heartbeat-runner.d.ts +3 -6
  19. package/dist/src/cron/heartbeat-runner.js +1 -10
  20. package/dist/src/cron/heartbeat-runner.js.map +1 -1
  21. package/dist/src/index.d.ts +4 -5
  22. package/dist/src/index.js +3 -10
  23. package/dist/src/index.js.map +1 -1
  24. package/dist/src/middleware/auth.d.ts +3 -19
  25. package/dist/src/middleware/auth.js +0 -118
  26. package/dist/src/middleware/auth.js.map +1 -1
  27. package/dist/src/routes/ai-stream.d.ts +8 -7
  28. package/dist/src/routes/ai-stream.js +3 -16
  29. package/dist/src/routes/ai-stream.js.map +1 -1
  30. package/dist/src/routes/chat-stream.d.ts +4 -3
  31. package/dist/src/routes/chat-stream.js +3 -16
  32. package/dist/src/routes/chat-stream.js.map +1 -1
  33. package/dist/src/routes/chat.d.ts +4 -2
  34. package/dist/src/routes/chat.js +2 -14
  35. package/dist/src/routes/chat.js.map +1 -1
  36. package/dist/src/routes/chat.test.js +2 -2
  37. package/dist/src/routes/chat.test.js.map +1 -1
  38. package/dist/src/server.d.ts +16 -3
  39. package/dist/src/server.js +24 -25
  40. package/dist/src/server.js.map +1 -1
  41. package/dist/src/session/admin-file-tools.d.ts +136 -0
  42. package/dist/src/session/admin-file-tools.js +240 -0
  43. package/dist/src/session/admin-file-tools.js.map +1 -0
  44. package/dist/src/session/session-manager.d.ts +37 -3
  45. package/dist/src/session/session-manager.js +174 -44
  46. package/dist/src/session/session-manager.js.map +1 -1
  47. package/dist/src/session/session-manager.test.js +30 -52
  48. package/dist/src/session/session-manager.test.js.map +1 -1
  49. package/dist/src/session/session-runner.d.ts +29 -13
  50. package/dist/src/session/session-runner.js +28 -91
  51. package/dist/src/session/session-runner.js.map +1 -1
  52. package/dist/src/session/session-runner.test.js +70 -80
  53. package/dist/src/session/session-runner.test.js.map +1 -1
  54. package/dist/tsconfig.tsbuildinfo +1 -1
  55. package/package.json +2 -2
  56. package/dist/src/audit/audit-client.d.ts +0 -46
  57. package/dist/src/audit/audit-client.js +0 -83
  58. package/dist/src/audit/audit-client.js.map +0 -1
  59. package/dist/src/middleware/auth.test.d.ts +0 -6
  60. package/dist/src/middleware/auth.test.js +0 -260
  61. package/dist/src/middleware/auth.test.js.map +0 -1
  62. package/dist/src/routes/sessions.d.ts +0 -14
  63. package/dist/src/routes/sessions.js +0 -82
  64. package/dist/src/routes/sessions.js.map +0 -1
  65. package/dist/src/utils/jwt-verify.d.ts +0 -19
  66. package/dist/src/utils/jwt-verify.js +0 -32
  67. package/dist/src/utils/jwt-verify.js.map +0 -1
  68. package/dist/src/utils/jwt-verify.test.d.ts +0 -6
  69. package/dist/src/utils/jwt-verify.test.js +0 -150
  70. package/dist/src/utils/jwt-verify.test.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amodalai/runtime",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "Agent Runtime Platform — HTTP server for repo and platform modes",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -26,7 +26,7 @@
26
26
  "node-cron": "^3.0.3",
27
27
  "zod": "^3.25.0",
28
28
  "express-rate-limit": "^7.5.0",
29
- "@amodalai/core": "0.1.16"
29
+ "@amodalai/core": "0.1.17"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/express": "^4.17.21",
@@ -1,46 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- /**
7
- * Batching HTTP client that posts audit entries to the platform API.
8
- * Fire-and-forget — never blocks chat processing.
9
- */
10
- export interface AuditEntry {
11
- event: string;
12
- resource_name: string;
13
- author?: string;
14
- details?: Record<string, unknown>;
15
- timestamp?: string;
16
- }
17
- export interface AuditClientOptions {
18
- /** Platform API base URL */
19
- platformApiUrl: string;
20
- /** Flush interval in ms (default 2000) */
21
- flushIntervalMs?: number;
22
- /** Max batch size before auto-flush (default 20) */
23
- maxBatchSize?: number;
24
- }
25
- export declare class AuditClient {
26
- private readonly platformApiUrl;
27
- private readonly flushIntervalMs;
28
- private readonly maxBatchSize;
29
- private readonly pending;
30
- private flushTimer;
31
- constructor(options: AuditClientOptions);
32
- /**
33
- * Queue an audit entry for batched delivery.
34
- * Fire-and-forget — never throws.
35
- */
36
- log(appId: string, token: string, entry: AuditEntry): void;
37
- /**
38
- * Flush all pending batches immediately.
39
- */
40
- flush(): Promise<void>;
41
- /**
42
- * Stop the flush timer and drain remaining entries.
43
- */
44
- shutdown(): Promise<void>;
45
- private send;
46
- }
@@ -1,83 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- const DEFAULT_FLUSH_INTERVAL_MS = 2000;
7
- const DEFAULT_MAX_BATCH_SIZE = 20;
8
- export class AuditClient {
9
- platformApiUrl;
10
- flushIntervalMs;
11
- maxBatchSize;
12
- pending = new Map();
13
- flushTimer = null;
14
- constructor(options) {
15
- this.platformApiUrl = options.platformApiUrl;
16
- this.flushIntervalMs = options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;
17
- this.maxBatchSize = options.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;
18
- this.flushTimer = setInterval(() => {
19
- void this.flush();
20
- }, this.flushIntervalMs);
21
- this.flushTimer.unref();
22
- }
23
- /**
24
- * Queue an audit entry for batched delivery.
25
- * Fire-and-forget — never throws.
26
- */
27
- log(appId, token, entry) {
28
- const key = `${appId}:${token}`;
29
- let batch = this.pending.get(key);
30
- if (!batch) {
31
- batch = { appId, token, entries: [] };
32
- this.pending.set(key, batch);
33
- }
34
- batch.entries.push({
35
- ...entry,
36
- timestamp: entry.timestamp ?? new Date().toISOString(),
37
- });
38
- if (batch.entries.length >= this.maxBatchSize) {
39
- const toSend = batch;
40
- this.pending.delete(key);
41
- void this.send(toSend);
42
- }
43
- }
44
- /**
45
- * Flush all pending batches immediately.
46
- */
47
- async flush() {
48
- const batches = [...this.pending.values()];
49
- this.pending.clear();
50
- await Promise.all(batches.map((b) => this.send(b)));
51
- }
52
- /**
53
- * Stop the flush timer and drain remaining entries.
54
- */
55
- async shutdown() {
56
- if (this.flushTimer) {
57
- clearInterval(this.flushTimer);
58
- this.flushTimer = null;
59
- }
60
- await this.flush();
61
- }
62
- async send(batch) {
63
- try {
64
- const controller = new AbortController();
65
- const timer = setTimeout(() => controller.abort(), 10000);
66
- await fetch(`${this.platformApiUrl}/api/applications/${batch.appId}/audit-logs`, {
67
- method: 'POST',
68
- signal: controller.signal,
69
- headers: {
70
- 'Content-Type': 'application/json',
71
- Authorization: `Bearer ${batch.token}`,
72
- },
73
- body: JSON.stringify({ entries: batch.entries }),
74
- });
75
- clearTimeout(timer);
76
- }
77
- catch (err) {
78
- // Fire-and-forget — log but don't throw
79
- process.stderr.write(`[WARN] Failed to send audit batch: ${err instanceof Error ? err.message : String(err)}\n`);
80
- }
81
- }
82
- }
83
- //# sourceMappingURL=audit-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"audit-client.js","sourceRoot":"","sources":["../../../src/audit/audit-client.ts"],"names":[],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- export {};
@@ -1,260 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- import { describe, it, expect, vi, beforeEach, afterEach, beforeAll } from 'vitest';
7
- import express from 'express';
8
- import request from 'supertest';
9
- import { generateKeyPair, SignJWT, exportJWK, calculateJwkThumbprint } from 'jose';
10
- import { createAuthMiddleware, getAuthContext } from './auth.js';
11
- import { errorHandler } from './error-handler.js';
12
- // Mock fetch globally
13
- const mockFetch = vi.fn();
14
- vi.stubGlobal('fetch', mockFetch);
15
- function meResponse(orgId = 'org-123', appId = 'app-456') {
16
- return {
17
- ok: true,
18
- json: async () => ({
19
- org: { id: orgId },
20
- app: { id: appId },
21
- apps: [{ id: appId }],
22
- user: null,
23
- }),
24
- };
25
- }
26
- function createTestApp(platformApiUrl = 'http://localhost:4000', jwksUrl) {
27
- const app = express();
28
- app.use(express.json());
29
- const authMiddleware = createAuthMiddleware({ platformApiUrl, jwksUrl });
30
- app.get('/test', authMiddleware, (_req, res) => {
31
- const ctx = getAuthContext(res);
32
- res.json({
33
- authenticated: true,
34
- token: ctx?.token,
35
- orgId: ctx?.orgId,
36
- applicationId: ctx?.applicationId,
37
- authMethod: ctx?.authMethod,
38
- actor: ctx?.actor,
39
- });
40
- });
41
- app.use(errorHandler);
42
- return app;
43
- }
44
- describe('auth middleware', () => {
45
- beforeEach(() => {
46
- vi.clearAllMocks();
47
- });
48
- afterEach(() => {
49
- vi.restoreAllMocks();
50
- });
51
- it('rejects requests without Authorization header', async () => {
52
- const app = createTestApp();
53
- const res = await request(app).get('/test');
54
- expect(res.status).toBe(401);
55
- expect(res.body.error.code).toBe('UNAUTHORIZED');
56
- expect(res.body.error.message).toContain('Missing Authorization');
57
- });
58
- it('rejects non-Bearer auth schemes', async () => {
59
- const app = createTestApp();
60
- const res = await request(app)
61
- .get('/test')
62
- .set('Authorization', 'Basic abc123');
63
- expect(res.status).toBe(401);
64
- expect(res.body.error.message).toContain('Bearer scheme');
65
- });
66
- it('rejects tokens without ak_ prefix when no JWKS configured', async () => {
67
- // Create app without JWKS URL — will fail createJWTVerifier
68
- const app = express();
69
- app.use(express.json());
70
- const authMiddleware = createAuthMiddleware({
71
- platformApiUrl: 'http://localhost:4000',
72
- jwksUrl: 'not-a-valid-url',
73
- });
74
- app.get('/test', authMiddleware, (_req, res) => {
75
- res.json({ authenticated: true });
76
- });
77
- app.use(errorHandler);
78
- const res = await request(app)
79
- .get('/test')
80
- .set('Authorization', 'Bearer some-jwt-token');
81
- expect(res.status).toBe(401);
82
- });
83
- it('validates ak_ keys against platform API and returns full context', async () => {
84
- mockFetch.mockResolvedValueOnce(meResponse('org-123', 'app-456'));
85
- const app = createTestApp();
86
- const res = await request(app)
87
- .get('/test')
88
- .set('Authorization', 'Bearer ak_test-key');
89
- expect(res.status).toBe(200);
90
- expect(res.body.authenticated).toBe(true);
91
- expect(res.body.token).toBe('ak_test-key');
92
- expect(res.body.orgId).toBe('org-123');
93
- expect(res.body.applicationId).toBe('app-456');
94
- expect(res.body.authMethod).toBe('api_key');
95
- // Verify fetch was called with correct args
96
- expect(mockFetch).toHaveBeenCalledWith('http://localhost:4000/api/me', expect.objectContaining({
97
- headers: expect.objectContaining({
98
- Authorization: 'Bearer ak_test-key',
99
- }),
100
- }));
101
- });
102
- it('rejects invalid ak_ keys (platform returns non-ok)', async () => {
103
- mockFetch.mockResolvedValueOnce({
104
- ok: false,
105
- status: 401,
106
- });
107
- const app = createTestApp();
108
- const res = await request(app)
109
- .get('/test')
110
- .set('Authorization', 'Bearer ak_bad-key');
111
- expect(res.status).toBe(401);
112
- expect(res.body.error.code).toBe('UNAUTHORIZED');
113
- });
114
- it('caches validated keys', async () => {
115
- mockFetch.mockResolvedValue(meResponse());
116
- const app = createTestApp();
117
- // First request — validates against platform API
118
- await request(app)
119
- .get('/test')
120
- .set('Authorization', 'Bearer ak_cached-key');
121
- expect(mockFetch).toHaveBeenCalledTimes(1);
122
- // Second request — should use cache
123
- const res = await request(app)
124
- .get('/test')
125
- .set('Authorization', 'Bearer ak_cached-key');
126
- expect(res.status).toBe(200);
127
- expect(mockFetch).toHaveBeenCalledTimes(1); // No additional fetch
128
- });
129
- it('returns 502 when platform API is unreachable', async () => {
130
- mockFetch.mockRejectedValueOnce(new Error('Connection refused'));
131
- const app = createTestApp();
132
- const res = await request(app)
133
- .get('/test')
134
- .set('Authorization', 'Bearer ak_test-key');
135
- expect(res.status).toBe(502);
136
- expect(res.body.error.code).toBe('AUTH_UPSTREAM_ERROR');
137
- });
138
- describe('JWT verification', () => {
139
- let privateKey;
140
- let kid;
141
- let jwksJson;
142
- const jwksUrl = 'http://127.0.0.1:9999/.well-known/jwks.json';
143
- beforeAll(async () => {
144
- const pair = await generateKeyPair('ES256', { extractable: true });
145
- privateKey = pair.privateKey;
146
- const publicJwk = await exportJWK(pair.publicKey);
147
- kid = await calculateJwkThumbprint(publicJwk);
148
- jwksJson = {
149
- keys: [{ ...publicJwk, kid, alg: 'ES256', use: 'sig' }],
150
- };
151
- });
152
- it('validates platform JWTs locally without /api/me calls', async () => {
153
- // Mock fetch to serve JWKS
154
- mockFetch.mockImplementation(async (url) => {
155
- if (url.includes('.well-known/jwks.json')) {
156
- return { ok: true, status: 200, json: async () => jwksJson };
157
- }
158
- throw new Error(`Unexpected fetch: ${url}`);
159
- });
160
- const token = await new SignJWT({
161
- org_id: 'org-jwt',
162
- app_id: 'app-jwt',
163
- })
164
- .setProtectedHeader({ alg: 'ES256', kid })
165
- .setIssuer('aitize-platform')
166
- .setSubject('app-jwt')
167
- .setIssuedAt()
168
- .setExpirationTime('1h')
169
- .sign(privateKey);
170
- const app = createTestApp('http://localhost:4000', jwksUrl);
171
- const res = await request(app)
172
- .get('/test')
173
- .set('Authorization', `Bearer ${token}`);
174
- expect(res.status).toBe(200);
175
- expect(res.body.token).toBe(token);
176
- expect(res.body.orgId).toBe('org-jwt');
177
- expect(res.body.applicationId).toBe('app-jwt');
178
- expect(res.body.applicationId).toBe('app-jwt');
179
- expect(res.body.authMethod).toBe('platform_jwt');
180
- // Only JWKS fetch should have been made, not /api/me
181
- for (const call of mockFetch.mock.calls) {
182
- expect(String(call[0])).not.toContain('/api/me');
183
- }
184
- });
185
- it('includes actor in AuthContext when JWT has actor claim', async () => {
186
- mockFetch.mockImplementation(async (url) => {
187
- if (url.includes('.well-known/jwks.json')) {
188
- return { ok: true, status: 200, json: async () => jwksJson };
189
- }
190
- throw new Error(`Unexpected fetch: ${url}`);
191
- });
192
- const token = await new SignJWT({
193
- org_id: 'org-jwt',
194
- app_id: 'app-jwt',
195
- actor: 'bob@example.com',
196
- })
197
- .setProtectedHeader({ alg: 'ES256', kid })
198
- .setIssuer('aitize-platform')
199
- .setSubject('app-jwt')
200
- .setIssuedAt()
201
- .setExpirationTime('1h')
202
- .sign(privateKey);
203
- const app = createTestApp('http://localhost:4000', jwksUrl);
204
- const res = await request(app)
205
- .get('/test')
206
- .set('Authorization', `Bearer ${token}`);
207
- expect(res.status).toBe(200);
208
- expect(res.body.actor).toBe('bob@example.com');
209
- expect(res.body.authMethod).toBe('platform_jwt');
210
- });
211
- it('omits actor from AuthContext when JWT has no actor claim', async () => {
212
- mockFetch.mockImplementation(async (url) => {
213
- if (url.includes('.well-known/jwks.json')) {
214
- return { ok: true, status: 200, json: async () => jwksJson };
215
- }
216
- throw new Error(`Unexpected fetch: ${url}`);
217
- });
218
- const token = await new SignJWT({
219
- org_id: 'org-jwt',
220
- app_id: 'app-jwt',
221
- })
222
- .setProtectedHeader({ alg: 'ES256', kid })
223
- .setIssuer('aitize-platform')
224
- .setSubject('app-jwt')
225
- .setIssuedAt()
226
- .setExpirationTime('1h')
227
- .sign(privateKey);
228
- const app = createTestApp('http://localhost:4000', jwksUrl);
229
- const res = await request(app)
230
- .get('/test')
231
- .set('Authorization', `Bearer ${token}`);
232
- expect(res.status).toBe(200);
233
- expect(res.body.actor).toBeUndefined();
234
- });
235
- it('rejects expired JWTs', async () => {
236
- mockFetch.mockImplementation(async (url) => {
237
- if (url.includes('.well-known/jwks.json')) {
238
- return { ok: true, status: 200, json: async () => jwksJson };
239
- }
240
- throw new Error(`Unexpected fetch: ${url}`);
241
- });
242
- const token = await new SignJWT({
243
- org_id: 'org-1',
244
- app_id: 'app-1',
245
- })
246
- .setProtectedHeader({ alg: 'ES256', kid })
247
- .setIssuer('aitize-platform')
248
- .setSubject('app-1')
249
- .setIssuedAt(Math.floor(Date.now() / 1000) - 7200)
250
- .setExpirationTime(Math.floor(Date.now() / 1000) - 3600)
251
- .sign(privateKey);
252
- const app = createTestApp('http://localhost:4000', jwksUrl);
253
- const res = await request(app)
254
- .get('/test')
255
- .set('Authorization', `Bearer ${token}`);
256
- expect(res.status).toBe(401);
257
- });
258
- });
259
- });
260
- //# sourceMappingURL=auth.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.test.js","sourceRoot":"","sources":["../../../src/middleware/auth.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACpF,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,OAAO,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,MAAM,CAAC;AAEnF,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,sBAAsB;AACtB,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAC1B,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAElC,SAAS,UAAU,CAAC,KAAK,GAAG,SAAS,EAAE,KAAK,GAAG,SAAS;IACtD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;YACjB,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE;YAClB,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE;YAClB,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;YACrB,IAAI,EAAE,IAAI;SACX,CAAC;KACH,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,cAAc,GAAG,uBAAuB,EAAE,OAAgB;IAC/E,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAExB,MAAM,cAAc,GAAG,oBAAoB,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC;IAEzE,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC7C,MAAM,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC;YACP,aAAa,EAAE,IAAI;YACnB,KAAK,EAAE,GAAG,EAAE,KAAK;YACjB,KAAK,EAAE,GAAG,EAAE,KAAK;YACjB,aAAa,EAAE,GAAG,EAAE,aAAa;YACjC,UAAU,EAAE,GAAG,EAAE,UAAU;YAC3B,KAAK,EAAE,GAAG,EAAE,KAAK;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACtB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE5C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACjD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;aAC3B,GAAG,CAAC,OAAO,CAAC;aACZ,GAAG,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;QAExC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,4DAA4D;QAC5D,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxB,MAAM,cAAc,GAAG,oBAAoB,CAAC;YAC1C,cAAc,EAAE,uBAAuB;YACvC,OAAO,EAAE,iBAAiB;SAC3B,CAAC,CAAC;QACH,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC7C,GAAG,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEtB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;aAC3B,GAAG,CAAC,OAAO,CAAC;aACZ,GAAG,CAAC,eAAe,EAAE,uBAAuB,CAAC,CAAC;QAEjD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,SAAS,CAAC,qBAAqB,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;QAElE,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;aAC3B,GAAG,CAAC,OAAO,CAAC;aACZ,GAAG,CAAC,eAAe,EAAE,oBAAoB,CAAC,CAAC;QAE9C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE5C,4CAA4C;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,oBAAoB,CACpC,8BAA8B,EAC9B,MAAM,CAAC,gBAAgB,CAAC;YACtB,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC;gBAC/B,aAAa,EAAE,oBAAoB;aACpC,CAAC;SACH,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,SAAS,CAAC,qBAAqB,CAAC;YAC9B,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,GAAG;SACZ,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;aAC3B,GAAG,CAAC,OAAO,CAAC;aACZ,GAAG,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;QAE7C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,SAAS,CAAC,iBAAiB,CAAC,UAAU,EAAE,CAAC,CAAC;QAE1C,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAE5B,iDAAiD;QACjD,MAAM,OAAO,CAAC,GAAG,CAAC;aACf,GAAG,CAAC,OAAO,CAAC;aACZ,GAAG,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC;QAEhD,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE3C,oCAAoC;QACpC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;aAC3B,GAAG,CAAC,OAAO,CAAC;aACZ,GAAG,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC;QAEhD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,SAAS,CAAC,qBAAqB,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAEjE,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;aAC3B,GAAG,CAAC,OAAO,CAAC;aACZ,GAAG,CAAC,eAAe,EAAE,oBAAoB,CAAC,CAAC;QAE9C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,IAAI,UAAqB,CAAC;QAC1B,IAAI,GAAW,CAAC;QAChB,IAAI,QAAkD,CAAC;QACvD,MAAM,OAAO,GAAG,6CAA6C,CAAC;QAE9D,SAAS,CAAC,KAAK,IAAI,EAAE;YACnB,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;YACnE,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;YAC7B,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAClD,GAAG,GAAG,MAAM,sBAAsB,CAAC,SAAS,CAAC,CAAC;YAC9C,QAAQ,GAAG;gBACT,IAAI,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;aACxD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACrE,2BAA2B;YAC3B,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;gBACjD,IAAI,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;oBAC1C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;gBAC/D,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC;gBAC9B,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;aAElB,CAAC;iBACC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;iBACzC,SAAS,CAAC,iBAAiB,CAAC;iBAC5B,UAAU,CAAC,SAAS,CAAC;iBACrB,WAAW,EAAE;iBACb,iBAAiB,CAAC,IAAI,CAAC;iBACvB,IAAI,CAAC,UAAU,CAAC,CAAC;YAEpB,MAAM,GAAG,GAAG,aAAa,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAC3B,GAAG,CAAC,OAAO,CAAC;iBACZ,GAAG,CAAC,eAAe,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC;YAE3C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAEjD,qDAAqD;YACrD,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACnD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;gBACjD,IAAI,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;oBAC1C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;gBAC/D,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC;gBAC9B,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;gBAEjB,KAAK,EAAE,iBAAiB;aACzB,CAAC;iBACC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;iBACzC,SAAS,CAAC,iBAAiB,CAAC;iBAC5B,UAAU,CAAC,SAAS,CAAC;iBACrB,WAAW,EAAE;iBACb,iBAAiB,CAAC,IAAI,CAAC;iBACvB,IAAI,CAAC,UAAU,CAAC,CAAC;YAEpB,MAAM,GAAG,GAAG,aAAa,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAC3B,GAAG,CAAC,OAAO,CAAC;iBACZ,GAAG,CAAC,eAAe,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC;YAE3C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;YACxE,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;gBACjD,IAAI,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;oBAC1C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;gBAC/D,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC;gBAC9B,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;aAElB,CAAC;iBACC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;iBACzC,SAAS,CAAC,iBAAiB,CAAC;iBAC5B,UAAU,CAAC,SAAS,CAAC;iBACrB,WAAW,EAAE;iBACb,iBAAiB,CAAC,IAAI,CAAC;iBACvB,IAAI,CAAC,UAAU,CAAC,CAAC;YAEpB,MAAM,GAAG,GAAG,aAAa,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAC3B,GAAG,CAAC,OAAO,CAAC;iBACZ,GAAG,CAAC,eAAe,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC;YAE3C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;YACpC,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;gBACjD,IAAI,GAAG,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;oBAC1C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;gBAC/D,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,MAAM,IAAI,OAAO,CAAC;gBAC9B,MAAM,EAAE,OAAO;gBACf,MAAM,EAAE,OAAO;aAChB,CAAC;iBACC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;iBACzC,SAAS,CAAC,iBAAiB,CAAC;iBAC5B,UAAU,CAAC,OAAO,CAAC;iBACnB,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;iBACjD,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;iBACvD,IAAI,CAAC,UAAU,CAAC,CAAC;YAEpB,MAAM,GAAG,GAAG,aAAa,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;iBAC3B,GAAG,CAAC,OAAO,CAAC;iBACZ,GAAG,CAAC,eAAe,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC;YAE3C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,14 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- import { Router } from 'express';
7
- export interface SessionsRouterOptions {
8
- platformApiUrl: string;
9
- }
10
- /**
11
- * Proxy routes for session history.
12
- * Forwards to platform-api /api/applications/{applicationId}/sessions endpoints.
13
- */
14
- export declare function createSessionsRouter(options: SessionsRouterOptions): Router;
@@ -1,82 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- import { Router } from 'express';
7
- import { getAuthContext } from '../middleware/auth.js';
8
- /**
9
- * Proxy routes for session history.
10
- * Forwards to platform-api /api/applications/{applicationId}/sessions endpoints.
11
- */
12
- export function createSessionsRouter(options) {
13
- const router = Router();
14
- // List sessions for the authenticated application
15
- router.get('/sessions/history', async (req, res, next) => {
16
- try {
17
- const auth = getAuthContext(res);
18
- if (!auth?.applicationId || !auth.token) {
19
- res.status(401).json({ error: { code: 'UNAUTHORIZED', message: 'Missing auth context' } });
20
- return;
21
- }
22
- const tagsParam = req.query['tags'];
23
- const qs = tagsParam ? `?tags=${String(tagsParam)}` : '';
24
- const url = `${options.platformApiUrl}/api/applications/${auth.applicationId}/sessions${qs}`;
25
- const response = await fetch(url, {
26
- headers: { Authorization: `Bearer ${auth.token}` },
27
- });
28
- const data = await response.json();
29
- res.status(response.status).json(data);
30
- }
31
- catch (err) {
32
- next(err);
33
- }
34
- });
35
- // Get a single session with full messages
36
- router.get('/sessions/history/:id', async (req, res, next) => {
37
- try {
38
- const auth = getAuthContext(res);
39
- if (!auth?.applicationId || !auth.token) {
40
- res.status(401).json({ error: { code: 'UNAUTHORIZED', message: 'Missing auth context' } });
41
- return;
42
- }
43
- const sessionId = req.params['id'];
44
- const url = `${options.platformApiUrl}/api/applications/${auth.applicationId}/sessions/${sessionId}`;
45
- const response = await fetch(url, {
46
- headers: { Authorization: `Bearer ${auth.token}` },
47
- });
48
- const data = await response.json();
49
- res.status(response.status).json(data);
50
- }
51
- catch (err) {
52
- next(err);
53
- }
54
- });
55
- // Update session tags/title
56
- router.patch('/sessions/history/:id', async (req, res, next) => {
57
- try {
58
- const auth = getAuthContext(res);
59
- if (!auth?.applicationId || !auth.token) {
60
- res.status(401).json({ error: { code: 'UNAUTHORIZED', message: 'Missing auth context' } });
61
- return;
62
- }
63
- const sessionId = req.params['id'];
64
- const url = `${options.platformApiUrl}/api/applications/${auth.applicationId}/sessions/${sessionId}`;
65
- const response = await fetch(url, {
66
- method: 'PATCH',
67
- headers: {
68
- 'Content-Type': 'application/json',
69
- Authorization: `Bearer ${auth.token}`,
70
- },
71
- body: JSON.stringify(req.body),
72
- });
73
- const data = await response.json();
74
- res.status(response.status).json(data);
75
- }
76
- catch (err) {
77
- next(err);
78
- }
79
- });
80
- return router;
81
- }
82
- //# sourceMappingURL=sessions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../src/routes/sessions.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- export interface JWTVerifierOptions {
7
- jwksUrl: string;
8
- issuer?: string;
9
- }
10
- export interface PlatformJWTClaims {
11
- org_id: string;
12
- app_id: string;
13
- actor?: string;
14
- }
15
- /**
16
- * Create a JWT verifier that validates tokens against a remote JWKS endpoint.
17
- * The JWKS is auto-fetched and cached by the `jose` library.
18
- */
19
- export declare function createJWTVerifier(options: JWTVerifierOptions): (token: string) => Promise<PlatformJWTClaims | null>;
@@ -1,32 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- import { createRemoteJWKSet, jwtVerify } from 'jose';
7
- /**
8
- * Create a JWT verifier that validates tokens against a remote JWKS endpoint.
9
- * The JWKS is auto-fetched and cached by the `jose` library.
10
- */
11
- export function createJWTVerifier(options) {
12
- const jwks = createRemoteJWKSet(new URL(options.jwksUrl));
13
- const issuer = options.issuer ?? 'aitize-platform';
14
- return async (token) => {
15
- try {
16
- const { payload } = await jwtVerify(token, jwks, { issuer });
17
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
18
- const actor = payload['actor'];
19
- return {
20
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
21
- org_id: payload['org_id'] ?? '',
22
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
23
- app_id: payload['app_id'] ?? '',
24
- ...(actor ? { actor } : {}),
25
- };
26
- }
27
- catch {
28
- return null;
29
- }
30
- };
31
- }
32
- //# sourceMappingURL=jwt-verify.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jwt-verify.js","sourceRoot":"","sources":["../../../src/utils/jwt-verify.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAcrD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA2B;IAE3B,MAAM,IAAI,GAAoB,kBAAkB,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,iBAAiB,CAAC;IAEnD,OAAO,KAAK,EAAE,KAAa,EAAqC,EAAE;QAChE,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAC7D,uEAAuE;YACvE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAuB,CAAC;YACrD,OAAO;gBACL,uEAAuE;gBACvE,MAAM,EAAG,OAAO,CAAC,QAAQ,CAAY,IAAI,EAAE;gBAC3C,uEAAuE;gBACvE,MAAM,EAAG,OAAO,CAAC,QAAQ,CAAY,IAAI,EAAE;gBAC3C,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5B,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -1,6 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Amodal Labs, Inc.
4
- * SPDX-License-Identifier: MIT
5
- */
6
- export {};