@layer-ai/core 0.9.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,12 +5,16 @@
5
5
  * Priority: User's BYOK key → Platform key → Error
6
6
  */
7
7
  import type { Provider } from './provider-constants.js';
8
+ export interface ResolvedKey {
9
+ key: string;
10
+ usedPlatformKey: boolean;
11
+ }
8
12
  /**
9
13
  * Resolves the API key to use for a provider
10
14
  * @param provider - The provider name
11
15
  * @param userId - Optional user ID for BYOK lookup
12
16
  * @param platformKey - The platform's API key (fallback)
13
- * @returns The API key to use
17
+ * @returns The API key to use and whether platform key was used
14
18
  */
15
- export declare function resolveApiKey(provider: Provider, userId: string | undefined, platformKey: string | undefined): Promise<string>;
19
+ export declare function resolveApiKey(provider: Provider, userId: string | undefined, platformKey: string | undefined): Promise<ResolvedKey>;
16
20
  //# sourceMappingURL=key-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"key-resolver.d.ts","sourceRoot":"","sources":["../../src/lib/key-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGxD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAAC,MAAM,CAAC,CAoBjB"}
1
+ {"version":3,"file":"key-resolver.d.ts","sourceRoot":"","sources":["../../src/lib/key-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGxD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,OAAO,CAAC,WAAW,CAAC,CAoBtB"}
@@ -10,7 +10,7 @@ import { decrypt } from './encryption.js';
10
10
  * @param provider - The provider name
11
11
  * @param userId - Optional user ID for BYOK lookup
12
12
  * @param platformKey - The platform's API key (fallback)
13
- * @returns The API key to use
13
+ * @returns The API key to use and whether platform key was used
14
14
  */
15
15
  export async function resolveApiKey(provider, userId, platformKey) {
16
16
  // If userId is provided, check for BYOK key
@@ -18,7 +18,7 @@ export async function resolveApiKey(provider, userId, platformKey) {
18
18
  try {
19
19
  const byokKey = await getUserProviderKey(userId, provider);
20
20
  if (byokKey) {
21
- return byokKey;
21
+ return { key: byokKey, usedPlatformKey: false };
22
22
  }
23
23
  }
24
24
  catch (error) {
@@ -28,7 +28,7 @@ export async function resolveApiKey(provider, userId, platformKey) {
28
28
  }
29
29
  // Fallback to platform key
30
30
  if (platformKey) {
31
- return platformKey;
31
+ return { key: platformKey, usedPlatformKey: true };
32
32
  }
33
33
  throw new Error(`No API key available for provider: ${provider}`);
34
34
  }
@@ -327,7 +327,7 @@ router.post('/test', async (req, res) => {
327
327
  try {
328
328
  const request = {
329
329
  type: 'chat',
330
- gate: finalGate.name || 'test-gate',
330
+ gateId: finalGate.id,
331
331
  model: finalGate.model,
332
332
  data: {
333
333
  messages,
@@ -363,7 +363,7 @@ router.post('/test', async (req, res) => {
363
363
  try {
364
364
  const request = {
365
365
  type: 'chat',
366
- gate: finalGate.name || 'test-gate',
366
+ gateId: finalGate.id,
367
367
  model: fallbackModel,
368
368
  data: {
369
369
  messages,
@@ -1 +1 @@
1
- {"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/complete.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AASpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;AAqQpC,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/complete.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AASpD,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;AA+OpC,eAAe,MAAM,CAAC"}
@@ -1,6 +1,5 @@
1
1
  import { Router } from 'express';
2
2
  import { db } from '../../lib/db/postgres.js';
3
- import { cache } from '../../lib/db/redis.js';
4
3
  import { authenticate } from '../../middleware/auth.js';
5
4
  import { callAdapter, normalizeModelId } from '../../lib/provider-factory.js';
6
5
  import { OverrideField } from '@layer-ai/sdk';
@@ -13,29 +12,6 @@ function isOverrideAllowed(allowOverrides, field) {
13
12
  return false;
14
13
  return allowOverrides[field] ?? false;
15
14
  }
16
- async function getGateConfig(userId, gateIdentifier) {
17
- const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(gateIdentifier);
18
- let gateConfig = null;
19
- if (isUUID) {
20
- gateConfig = await cache.getGateById(userId, gateIdentifier);
21
- if (!gateConfig) {
22
- gateConfig = await db.getGateByUserAndId(userId, gateIdentifier);
23
- if (gateConfig) {
24
- await cache.setGate(userId, gateConfig.name, gateConfig);
25
- }
26
- }
27
- }
28
- else {
29
- gateConfig = await cache.getGate(userId, gateIdentifier);
30
- if (!gateConfig) {
31
- gateConfig = await db.getGateByUserAndName(userId, gateIdentifier);
32
- if (gateConfig) {
33
- await cache.setGate(userId, gateIdentifier, gateConfig);
34
- }
35
- }
36
- }
37
- return gateConfig;
38
- }
39
15
  function resolveFinalRequest(gateConfig, request) {
40
16
  const finalRequest = { ...request };
41
17
  let finalModel = gateConfig.model;
@@ -141,18 +117,23 @@ router.post('/', authenticate, async (req, res) => {
141
117
  let request = null;
142
118
  try {
143
119
  const rawRequest = req.body;
144
- if (!rawRequest.gate) {
145
- res.status(400).json({ error: 'bad_request', message: 'Missing required field: gate' });
120
+ if (!rawRequest.gateId) {
121
+ res.status(400).json({ error: 'bad_request', message: 'Missing required field: gateId' });
122
+ return;
123
+ }
124
+ const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(rawRequest.gateId);
125
+ if (!isUUID) {
126
+ res.status(400).json({ error: 'bad_request', message: 'gateId must be a valid UUID. Gate names are no longer supported.' });
146
127
  return;
147
128
  }
148
- gateConfig = await getGateConfig(userId, rawRequest.gate);
129
+ gateConfig = await db.getGateByUserAndId(userId, rawRequest.gateId);
149
130
  if (!gateConfig) {
150
- res.status(404).json({ error: 'not_found', message: `Gate "${rawRequest.gate}" not found` });
131
+ res.status(404).json({ error: 'not_found', message: `Gate with ID "${rawRequest.gateId}" not found` });
151
132
  return;
152
133
  }
153
134
  const requestType = rawRequest.type || gateConfig.taskType || 'chat';
154
135
  request = {
155
- gate: rawRequest.gate,
136
+ gateId: rawRequest.gateId,
156
137
  type: requestType,
157
138
  data: rawRequest.data,
158
139
  model: rawRequest.model,
@@ -171,7 +152,7 @@ router.post('/', authenticate, async (req, res) => {
171
152
  db.logRequest({
172
153
  userId,
173
154
  gateId: gateConfig.id,
174
- gateName: request.gate,
155
+ gateName: gateConfig.name,
175
156
  modelRequested: request.model || gateConfig.model,
176
157
  modelUsed: modelUsed,
177
158
  promptTokens: result.usage?.promptTokens || 0,
@@ -12,7 +12,7 @@ import { GoogleAdapter } from '../../../services/providers/google-adapter.js';
12
12
  // Test user ID from the database
13
13
  const TEST_USER_ID = 'ebd64998-465d-4211-ad67-87b4e01ad0da';
14
14
  const SIMPLE_REQUEST = {
15
- gate: 'byok-test',
15
+ gateId: 'byok-test',
16
16
  model: 'gpt-4o-mini',
17
17
  type: 'chat',
18
18
  data: {
@@ -3,7 +3,7 @@
3
3
  async function testBasicChat() {
4
4
  console.log('Test 1: Basic chat completion with Anthropic\n');
5
5
  const request = {
6
- gate: 'test-gate',
6
+ gateId: 'test-gate',
7
7
  model: 'claude-sonnet-4-5-20250929',
8
8
  type: 'chat',
9
9
  data: {
@@ -27,7 +27,7 @@ async function testBasicChat() {
27
27
  async function testVision() {
28
28
  console.log('\n\nTest 2: Vision with Anthropic (not supported in v1)\n');
29
29
  const request = {
30
- gate: 'test-gate',
30
+ gateId: 'test-gate',
31
31
  model: 'claude-sonnet-4-5-20250929',
32
32
  type: 'chat',
33
33
  data: {
@@ -49,7 +49,7 @@ async function testVision() {
49
49
  async function testToolCalls() {
50
50
  console.log('\n\nTest 3: Tool calls with Anthropic (not supported in v1)\n');
51
51
  const request = {
52
- gate: 'test-gate',
52
+ gateId: 'test-gate',
53
53
  model: 'claude-sonnet-4-5-20250929',
54
54
  type: 'chat',
55
55
  data: {
@@ -86,7 +86,7 @@ async function testToolCalls() {
86
86
  async function testSystemPrompt() {
87
87
  console.log('\n\nTest 4: System prompt and advanced params\n');
88
88
  const request = {
89
- gate: 'test-gate',
89
+ gateId: 'test-gate',
90
90
  model: 'claude-sonnet-4-5-20250929',
91
91
  type: 'chat',
92
92
  data: {
@@ -3,7 +3,7 @@
3
3
  async function testBasicChat() {
4
4
  console.log('Test 1: Basic chat completion with OpenAI\n');
5
5
  const request = {
6
- gate: 'test-gate',
6
+ gateId: 'test-gate',
7
7
  model: 'gpt-4o-mini',
8
8
  type: 'chat',
9
9
  data: {
@@ -26,7 +26,7 @@ async function testBasicChat() {
26
26
  async function testVision() {
27
27
  console.log('\n\nTest 2: Vision with GPT-4o\n');
28
28
  const request = {
29
- gate: 'test-gate',
29
+ gateId: 'test-gate',
30
30
  model: 'gpt-4o',
31
31
  type: 'chat',
32
32
  data: {
@@ -49,7 +49,7 @@ async function testVision() {
49
49
  async function testToolCalls() {
50
50
  console.log('\n\nTest 3: Tool calls with GPT-4\n');
51
51
  const request = {
52
- gate: 'test-gate',
52
+ gateId: 'test-gate',
53
53
  model: 'gpt-4o-mini',
54
54
  type: 'chat',
55
55
  data: {
@@ -85,7 +85,7 @@ async function testToolCalls() {
85
85
  async function testImageGeneration() {
86
86
  console.log('\n\nTest 4: Image generation with DALL-E\n');
87
87
  const request = {
88
- gate: 'test-gate',
88
+ gateId: 'test-gate',
89
89
  model: 'dall-e-3',
90
90
  type: 'image',
91
91
  data: {
@@ -102,7 +102,7 @@ async function testImageGeneration() {
102
102
  async function testEmbeddings() {
103
103
  console.log('\n\nTest 5: Text embeddings\n');
104
104
  const request = {
105
- gate: 'test-gate',
105
+ gateId: 'test-gate',
106
106
  model: 'text-embedding-3-small',
107
107
  type: 'embeddings',
108
108
  data: {
@@ -117,7 +117,7 @@ async function testEmbeddings() {
117
117
  async function testTextToSpeech() {
118
118
  console.log('\n\nTest 6: Text-to-speech\n');
119
119
  const request = {
120
- gate: 'test-gate',
120
+ gateId: 'test-gate',
121
121
  model: 'tts-1',
122
122
  type: 'tts',
123
123
  data: {
@@ -133,7 +133,7 @@ async function testTextToSpeech() {
133
133
  async function testResponseFormat() {
134
134
  console.log('\n\nTest 7: JSON response format\n');
135
135
  const request = {
136
- gate: 'test-gate',
136
+ gateId: 'test-gate',
137
137
  model: 'gpt-4o-mini',
138
138
  type: 'chat',
139
139
  data: {
@@ -3,7 +3,7 @@
3
3
  async function testFallbackRouting() {
4
4
  console.log('Test 1: Fallback routing (Anthropic -> OpenAI)\n');
5
5
  const request = {
6
- gate: 'test-gate-with-fallback',
6
+ gateId: 'test-gate-with-fallback',
7
7
  model: 'claude-sonnet-4-5-20250929', // Primary model
8
8
  type: 'chat',
9
9
  data: {
@@ -27,7 +27,7 @@ async function testFallbackRouting() {
27
27
  async function testRoundRobinRouting() {
28
28
  console.log('\n\nTest 2: Round-robin routing across providers\n');
29
29
  const request = {
30
- gate: 'test-gate-with-round-robin',
30
+ gateId: 'test-gate-with-round-robin',
31
31
  model: 'claude-sonnet-4-5-20250929',
32
32
  type: 'chat',
33
33
  data: {
@@ -50,7 +50,7 @@ async function testRoundRobinRouting() {
50
50
  async function testCrossProviderFallback() {
51
51
  console.log('\n\nTest 3: Cross-provider fallback with vision\n');
52
52
  const request = {
53
- gate: 'test-gate-vision-fallback',
53
+ gateId: 'test-gate-vision-fallback',
54
54
  model: 'claude-sonnet-4-5-20250929',
55
55
  type: 'chat',
56
56
  data: {
@@ -78,7 +78,7 @@ async function testCrossProviderFallback() {
78
78
  async function testToolCallsFallback() {
79
79
  console.log('\n\nTest 4: Fallback routing with tool calls\n');
80
80
  const request = {
81
- gate: 'test-gate-tools-fallback',
81
+ gateId: 'test-gate-tools-fallback',
82
82
  model: 'gpt-4o-mini',
83
83
  type: 'chat',
84
84
  data: {
@@ -117,7 +117,7 @@ async function testToolCallsFallback() {
117
117
  async function testCostOptimization() {
118
118
  console.log('\n\nTest 5: Cost optimization with round-robin\n');
119
119
  const request = {
120
- gate: 'test-gate-cost-optimization',
120
+ gateId: 'test-gate-cost-optimization',
121
121
  model: 'gpt-4o-mini',
122
122
  type: 'chat',
123
123
  data: {
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/anthropic-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAmB,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,YAAY,EACZ,UAAU,EACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAoB1E,qBAAa,gBAAiB,SAAQ,mBAAmB;IACvD,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAsB;IAElD,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAQ1C;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAI3D;IAEF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAM1D;IAEF,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS;IAalE,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAoB5D,UAAU;CA4JzB"}
1
+ {"version":3,"file":"anthropic-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/anthropic-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAmB,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,YAAY,EACZ,UAAU,EACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAoB1E,qBAAa,gBAAiB,SAAQ,mBAAmB;IACvD,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAsB;IAElD,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAQ1C;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAI3D;IAEF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAM1D;IAEF,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS;IAalE,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAoB5D,UAAU;CA6JzB"}
@@ -55,10 +55,10 @@ export class AnthropicAdapter extends BaseProviderAdapter {
55
55
  }
56
56
  async call(request, userId) {
57
57
  // Resolve API key (BYOK → Platform key)
58
- const apiKey = await resolveApiKey(this.provider, userId, process.env.ANTHROPIC_API_KEY);
58
+ const resolved = await resolveApiKey(this.provider, userId, process.env.ANTHROPIC_API_KEY);
59
59
  switch (request.type) {
60
60
  case 'chat':
61
- return this.handleChat(request, apiKey);
61
+ return this.handleChat(request, resolved.key, resolved.usedPlatformKey);
62
62
  case 'image':
63
63
  throw new Error('Image generation not yet supported by Anthropic');
64
64
  case 'embeddings':
@@ -71,7 +71,7 @@ export class AnthropicAdapter extends BaseProviderAdapter {
71
71
  throw new Error(`Unknown modality: ${request.type}`);
72
72
  }
73
73
  }
74
- async handleChat(request, apiKey) {
74
+ async handleChat(request, apiKey, usedPlatformKey) {
75
75
  const startTime = Date.now();
76
76
  const client = getAnthropicClient(apiKey);
77
77
  const { data: chat, model } = request;
@@ -211,6 +211,7 @@ export class AnthropicAdapter extends BaseProviderAdapter {
211
211
  },
212
212
  cost,
213
213
  latencyMs: Date.now() - startTime,
214
+ usedPlatformKey,
214
215
  raw: response,
215
216
  };
216
217
  }
@@ -1 +1 @@
1
- {"version":3,"file":"google-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/google-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,yBAAyB,EAI1B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,YAAY,EACZ,SAAS,EACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAkB1E,qBAAa,aAAc,SAAQ,mBAAmB;IACpD,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAmB;IAE/C,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAQ1C;IAGF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAO1D;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAIrE;IAGF,SAAS,CAAC,eAAe,EAAE,MAAM,CAC/B,SAAS,EACT;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAC5C,CAKC;IAEI,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAoB5D,UAAU;YAsLV,qBAAqB;YAmCrB,gBAAgB;YAoChB,qBAAqB;YAoHrB,kBAAkB;IAyChC,OAAO,CAAC,KAAK;CAGd"}
1
+ {"version":3,"file":"google-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/google-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,yBAAyB,EAI1B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,YAAY,EACZ,SAAS,EACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAkB1E,qBAAa,aAAc,SAAQ,mBAAmB;IACpD,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAmB;IAE/C,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAQ1C;IAGF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAO1D;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAIrE;IAGF,SAAS,CAAC,eAAe,EAAE,MAAM,CAC/B,SAAS,EACT;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAC5C,CAKC;IAEI,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAoB5D,UAAU;YAwLV,qBAAqB;YAqCrB,gBAAgB;YAsChB,qBAAqB;YAsHrB,kBAAkB;IA2ChC,OAAO,CAAC,KAAK;CAGd"}
@@ -52,23 +52,23 @@ export class GoogleAdapter extends BaseProviderAdapter {
52
52
  }
53
53
  async call(request, userId) {
54
54
  // Resolve API key (BYOK → Platform key)
55
- const apiKey = await resolveApiKey(this.provider, userId, process.env.GOOGLE_API_KEY);
55
+ const resolved = await resolveApiKey(this.provider, userId, process.env.GOOGLE_API_KEY);
56
56
  switch (request.type) {
57
57
  case 'chat':
58
- return this.handleChat(request, apiKey);
58
+ return this.handleChat(request, resolved.key, resolved.usedPlatformKey);
59
59
  case 'image':
60
- return this.handleImageGeneration(request, apiKey);
60
+ return this.handleImageGeneration(request, resolved.key, resolved.usedPlatformKey);
61
61
  case 'embeddings':
62
- return this.handleEmbeddings(request, apiKey);
62
+ return this.handleEmbeddings(request, resolved.key, resolved.usedPlatformKey);
63
63
  case 'tts':
64
- return this.handleTextToSpeech(request, apiKey);
64
+ return this.handleTextToSpeech(request, resolved.key, resolved.usedPlatformKey);
65
65
  case 'video':
66
- return this.handleVideoGeneration(request, apiKey);
66
+ return this.handleVideoGeneration(request, resolved.key, resolved.usedPlatformKey);
67
67
  default:
68
68
  throw new Error(`Unknown modality: ${request.type}`);
69
69
  }
70
70
  }
71
- async handleChat(request, apiKey) {
71
+ async handleChat(request, apiKey, usedPlatformKey) {
72
72
  const startTime = Date.now();
73
73
  const client = getGoogleClient(apiKey);
74
74
  const { data: chat, model } = request;
@@ -220,10 +220,11 @@ export class GoogleAdapter extends BaseProviderAdapter {
220
220
  },
221
221
  cost,
222
222
  latencyMs: Date.now() - startTime,
223
+ usedPlatformKey,
223
224
  raw: response,
224
225
  };
225
226
  }
226
- async handleImageGeneration(request, apiKey) {
227
+ async handleImageGeneration(request, apiKey, usedPlatformKey) {
227
228
  const startTime = Date.now();
228
229
  const client = getGoogleClient(apiKey);
229
230
  const { data: image, model } = request;
@@ -246,10 +247,11 @@ export class GoogleAdapter extends BaseProviderAdapter {
246
247
  images,
247
248
  model: model,
248
249
  latencyMs: Date.now() - startTime,
250
+ usedPlatformKey,
249
251
  raw: response,
250
252
  };
251
253
  }
252
- async handleEmbeddings(request, apiKey) {
254
+ async handleEmbeddings(request, apiKey, usedPlatformKey) {
253
255
  const startTime = Date.now();
254
256
  const client = getGoogleClient(apiKey);
255
257
  const { data: embedding, model } = request;
@@ -273,10 +275,11 @@ export class GoogleAdapter extends BaseProviderAdapter {
273
275
  totalTokens: 0,
274
276
  },
275
277
  latencyMs: Date.now() - startTime,
278
+ usedPlatformKey,
276
279
  raw: response,
277
280
  };
278
281
  }
279
- async handleVideoGeneration(request, apiKey) {
282
+ async handleVideoGeneration(request, apiKey, usedPlatformKey) {
280
283
  const startTime = Date.now();
281
284
  const client = getGoogleClient(apiKey);
282
285
  const { data: video, model } = request;
@@ -376,10 +379,11 @@ export class GoogleAdapter extends BaseProviderAdapter {
376
379
  videos: videos.filter((v) => v.url),
377
380
  model: model,
378
381
  latencyMs: Date.now() - startTime,
382
+ usedPlatformKey,
379
383
  raw: operation.response,
380
384
  };
381
385
  }
382
- async handleTextToSpeech(request, apiKey) {
386
+ async handleTextToSpeech(request, apiKey, usedPlatformKey) {
383
387
  const startTime = Date.now();
384
388
  const client = getGoogleClient(apiKey);
385
389
  const { data: tts, model } = request;
@@ -408,6 +412,7 @@ export class GoogleAdapter extends BaseProviderAdapter {
408
412
  },
409
413
  model: model,
410
414
  latencyMs: Date.now() - startTime,
415
+ usedPlatformKey,
411
416
  raw: response,
412
417
  };
413
418
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mistral-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/mistral-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,YAAY,EAEb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAoB1E,qBAAa,cAAe,SAAQ,mBAAmB;IACrD,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAoB;IAEhD,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAQ1C;IAGF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAM1D;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIlD;IAEI,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAsB5D,UAAU;YA+LV,gBAAgB;YAwChB,SAAS;CA4ExB"}
1
+ {"version":3,"file":"mistral-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/mistral-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,YAAY,EAEb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAoB1E,qBAAa,cAAe,SAAQ,mBAAmB;IACrD,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAoB;IAEhD,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAQ1C;IAGF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAM1D;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIlD;IAEI,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAsB5D,UAAU;YAiMV,gBAAgB;YA0ChB,SAAS;CA8ExB"}
@@ -46,14 +46,14 @@ export class MistralAdapter extends BaseProviderAdapter {
46
46
  }
47
47
  async call(request, userId) {
48
48
  // Resolve API key (BYOK → Platform key)
49
- const apiKey = await resolveApiKey(this.provider, userId, process.env.MISTRAL_API_KEY);
49
+ const resolved = await resolveApiKey(this.provider, userId, process.env.MISTRAL_API_KEY);
50
50
  switch (request.type) {
51
51
  case 'chat':
52
- return this.handleChat(request, apiKey);
52
+ return this.handleChat(request, resolved.key, resolved.usedPlatformKey);
53
53
  case 'embeddings':
54
- return this.handleEmbeddings(request, apiKey);
54
+ return this.handleEmbeddings(request, resolved.key, resolved.usedPlatformKey);
55
55
  case 'ocr':
56
- return this.handleOCR(request, apiKey);
56
+ return this.handleOCR(request, resolved.key, resolved.usedPlatformKey);
57
57
  case 'image':
58
58
  throw new Error('Image generation not supported by Mistral');
59
59
  case 'tts':
@@ -64,7 +64,7 @@ export class MistralAdapter extends BaseProviderAdapter {
64
64
  throw new Error(`Unknown modality: ${request.type}`);
65
65
  }
66
66
  }
67
- async handleChat(request, apiKey) {
67
+ async handleChat(request, apiKey, usedPlatformKey) {
68
68
  const startTime = Date.now();
69
69
  const mistral = getMistralClient(apiKey);
70
70
  const { data: chat, model } = request;
@@ -214,10 +214,11 @@ export class MistralAdapter extends BaseProviderAdapter {
214
214
  },
215
215
  cost,
216
216
  latencyMs: Date.now() - startTime,
217
+ usedPlatformKey,
217
218
  raw: response,
218
219
  };
219
220
  }
220
- async handleEmbeddings(request, apiKey) {
221
+ async handleEmbeddings(request, apiKey, usedPlatformKey) {
221
222
  const startTime = Date.now();
222
223
  const mistral = getMistralClient(apiKey);
223
224
  const { data: embedding, model } = request;
@@ -244,10 +245,11 @@ export class MistralAdapter extends BaseProviderAdapter {
244
245
  },
245
246
  cost,
246
247
  latencyMs: Date.now() - startTime,
248
+ usedPlatformKey,
247
249
  raw: response,
248
250
  };
249
251
  }
250
- async handleOCR(request, apiKey) {
252
+ async handleOCR(request, apiKey, usedPlatformKey) {
251
253
  const startTime = Date.now();
252
254
  const mistral = getMistralClient(apiKey);
253
255
  const { data: ocr, model } = request;
@@ -313,6 +315,7 @@ export class MistralAdapter extends BaseProviderAdapter {
313
315
  },
314
316
  model: response.model || ocrModel,
315
317
  latencyMs: Date.now() - startTime,
318
+ usedPlatformKey,
316
319
  raw: response,
317
320
  };
318
321
  }
@@ -1 +1 @@
1
- {"version":3,"file":"openai-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/openai-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,WAAW,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAoB1E,qBAAa,aAAc,SAAQ,mBAAmB;IACpD,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAmB;IAE/C,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAQ1C;IAEF,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAIxD;IAEF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAK1D;IAEF,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAQpD;IAEF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAG1D;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAGtD;IAEF,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAKpD;IAEF,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAOxD;IAEI,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAoB5D,UAAU;YA2GV,qBAAqB;YA6BrB,gBAAgB;YAiChB,kBAAkB;CA8BjC"}
1
+ {"version":3,"file":"openai-adapter.d.ts","sourceRoot":"","sources":["../../../src/services/providers/openai-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,WAAW,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAoB1E,qBAAa,aAAc,SAAQ,mBAAmB;IACpD,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAmB;IAE/C,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAQ1C;IAEF,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAIxD;IAEF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAK1D;IAEF,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAQpD;IAEF,SAAS,CAAC,oBAAoB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAG1D;IAEF,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAGtD;IAEF,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAKpD;IAEF,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAOxD;IAEI,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAoB5D,UAAU;YA4GV,qBAAqB;YA8BrB,gBAAgB;YAkChB,kBAAkB;CA+BjC"}
@@ -74,23 +74,23 @@ export class OpenAIAdapter extends BaseProviderAdapter {
74
74
  }
75
75
  async call(request, userId) {
76
76
  // Resolve API key (BYOK → Platform key)
77
- const apiKey = await resolveApiKey(this.provider, userId, process.env.OPENAI_API_KEY);
77
+ const resolved = await resolveApiKey(this.provider, userId, process.env.OPENAI_API_KEY);
78
78
  switch (request.type) {
79
79
  case 'chat':
80
- return this.handleChat(request, apiKey);
80
+ return this.handleChat(request, resolved.key, resolved.usedPlatformKey);
81
81
  case 'image':
82
- return this.handleImageGeneration(request, apiKey);
82
+ return this.handleImageGeneration(request, resolved.key, resolved.usedPlatformKey);
83
83
  case 'embeddings':
84
- return this.handleEmbeddings(request, apiKey);
84
+ return this.handleEmbeddings(request, resolved.key, resolved.usedPlatformKey);
85
85
  case 'tts':
86
- return this.handleTextToSpeech(request, apiKey);
86
+ return this.handleTextToSpeech(request, resolved.key, resolved.usedPlatformKey);
87
87
  case 'video':
88
88
  throw new Error('Video generation not yet supported by OpenAI');
89
89
  default:
90
90
  throw new Error(`Unknown modality: ${request.type}`);
91
91
  }
92
92
  }
93
- async handleChat(request, apiKey) {
93
+ async handleChat(request, apiKey, usedPlatformKey) {
94
94
  const startTime = Date.now();
95
95
  const client = getOpenAIClient(apiKey);
96
96
  const { data: chat, model } = request;
@@ -181,10 +181,11 @@ export class OpenAIAdapter extends BaseProviderAdapter {
181
181
  },
182
182
  cost,
183
183
  latencyMs: Date.now() - startTime,
184
+ usedPlatformKey,
184
185
  raw: response,
185
186
  };
186
187
  }
187
- async handleImageGeneration(request, apiKey) {
188
+ async handleImageGeneration(request, apiKey, usedPlatformKey) {
188
189
  const startTime = Date.now();
189
190
  const client = getOpenAIClient(apiKey);
190
191
  const { data: image, model } = request;
@@ -206,10 +207,11 @@ export class OpenAIAdapter extends BaseProviderAdapter {
206
207
  })),
207
208
  model: model,
208
209
  latencyMs: Date.now() - startTime,
210
+ usedPlatformKey,
209
211
  raw: response,
210
212
  };
211
213
  }
212
- async handleEmbeddings(request, apiKey) {
214
+ async handleEmbeddings(request, apiKey, usedPlatformKey) {
213
215
  const startTime = Date.now();
214
216
  const client = getOpenAIClient(apiKey);
215
217
  const { data: embedding, model } = request;
@@ -234,10 +236,11 @@ export class OpenAIAdapter extends BaseProviderAdapter {
234
236
  },
235
237
  cost,
236
238
  latencyMs: Date.now() - startTime,
239
+ usedPlatformKey,
237
240
  raw: response,
238
241
  };
239
242
  }
240
- async handleTextToSpeech(request, apiKey) {
243
+ async handleTextToSpeech(request, apiKey, usedPlatformKey) {
241
244
  const startTime = Date.now();
242
245
  const client = getOpenAIClient(apiKey);
243
246
  const { data: tts, model } = request;
@@ -260,6 +263,7 @@ export class OpenAIAdapter extends BaseProviderAdapter {
260
263
  },
261
264
  model: model,
262
265
  latencyMs: Date.now() - startTime,
266
+ usedPlatformKey,
263
267
  };
264
268
  }
265
269
  }
@@ -3,7 +3,7 @@ const adapter = new AnthropicAdapter();
3
3
  async function testChatCompletion() {
4
4
  console.log('Testing chat completion...');
5
5
  const request = {
6
- gate: 'test-gate',
6
+ gateId: 'test-gate',
7
7
  model: 'claude-sonnet-4-5-20250929',
8
8
  type: 'chat',
9
9
  data: {
@@ -25,7 +25,7 @@ async function testChatCompletion() {
25
25
  async function testChatWithVision() {
26
26
  console.log('Testing chat with vision...');
27
27
  const request = {
28
- gate: 'test-gate',
28
+ gateId: 'test-gate',
29
29
  model: 'claude-sonnet-4-5-20250929',
30
30
  type: 'chat',
31
31
  data: {
@@ -50,7 +50,7 @@ async function testToolCalls() {
50
50
  console.log('Testing tool calls...');
51
51
  // Step 1: Initial request with tool available
52
52
  const request = {
53
- gate: 'test-gate',
53
+ gateId: 'test-gate',
54
54
  model: 'claude-sonnet-4-5-20250929',
55
55
  type: 'chat',
56
56
  data: {
@@ -91,7 +91,7 @@ async function testToolCalls() {
91
91
  console.log('Function arguments:', toolCall.function.arguments);
92
92
  // Step 2: Send tool response back
93
93
  const toolResponseRequest = {
94
- gate: 'test-gate',
94
+ gateId: 'test-gate',
95
95
  model: 'claude-sonnet-4-5-20250929',
96
96
  type: 'chat',
97
97
  data: {
@@ -4,7 +4,7 @@ const adapter = new GoogleAdapter();
4
4
  async function testChatCompletion() {
5
5
  console.log('Testing chat completion...');
6
6
  const request = {
7
- gate: 'test-gate',
7
+ gateId: 'test-gate',
8
8
  model: 'gemini-2.5-flash',
9
9
  type: 'chat',
10
10
  data: {
@@ -26,7 +26,7 @@ async function testChatCompletion() {
26
26
  async function testChatWithVision() {
27
27
  console.log('Testing chat with vision...');
28
28
  const request = {
29
- gate: 'test-gate',
29
+ gateId: 'test-gate',
30
30
  model: 'gemini-2.5-flash',
31
31
  type: 'chat',
32
32
  data: {
@@ -52,7 +52,7 @@ async function testChatWithVision() {
52
52
  async function testImageGeneration() {
53
53
  console.log('Testing image generation...');
54
54
  const request = {
55
- gate: 'test-gate',
55
+ gateId: 'test-gate',
56
56
  model: 'imagen-4.0-generate-001',
57
57
  type: 'image',
58
58
  data: {
@@ -69,7 +69,7 @@ async function testImageGeneration() {
69
69
  async function testEmbeddings() {
70
70
  console.log('Testing embeddings...');
71
71
  const request = {
72
- gate: 'test-gate',
72
+ gateId: 'test-gate',
73
73
  model: 'text-embedding-004',
74
74
  type: 'embeddings',
75
75
  data: {
@@ -85,7 +85,7 @@ async function testToolCalling() {
85
85
  console.log('Testing tool calling...');
86
86
  // Step 1: Send message with tools available
87
87
  const request = {
88
- gate: 'test-gate',
88
+ gateId: 'test-gate',
89
89
  model: 'gemini-2.5-flash',
90
90
  type: 'chat',
91
91
  data: {
@@ -122,7 +122,7 @@ async function testToolCalling() {
122
122
  console.log('Function arguments:', toolCall.function.arguments);
123
123
  // Step 2: Send tool response back
124
124
  const toolResponseRequest = {
125
- gate: 'test-gate',
125
+ gateId: 'test-gate',
126
126
  model: 'gemini-2.5-flash',
127
127
  type: 'chat',
128
128
  data: {
@@ -149,7 +149,7 @@ async function testToolCalling() {
149
149
  async function testEmbeddingsMultiple() {
150
150
  console.log('Testing multiple embeddings...');
151
151
  const request = {
152
- gate: 'test-gate',
152
+ gateId: 'test-gate',
153
153
  model: 'text-embedding-004',
154
154
  type: 'embeddings',
155
155
  data: {
@@ -165,7 +165,7 @@ async function testEmbeddingsMultiple() {
165
165
  async function testTextToSpeech() {
166
166
  console.log('Testing text-to-speech...');
167
167
  const request = {
168
- gate: 'test-gate',
168
+ gateId: 'test-gate',
169
169
  model: 'gemini-2.5-flash-preview-tts',
170
170
  type: 'tts',
171
171
  data: {
@@ -182,7 +182,7 @@ async function testTextToSpeech() {
182
182
  async function testVideoGeneration() {
183
183
  console.log('Testing video generation (this may take a few minutes)...');
184
184
  const request = {
185
- gate: 'test-gate',
185
+ gateId: 'test-gate',
186
186
  model: 'veo-2.0-generate-001',
187
187
  type: 'video',
188
188
  data: {
@@ -6,7 +6,7 @@ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
6
6
  async function testChatCompletion() {
7
7
  console.log('--- Testing Chat Completion ---');
8
8
  const request = {
9
- gate: 'test-gate',
9
+ gateId: 'test-gate',
10
10
  type: 'chat',
11
11
  model: 'mistral-small-latest',
12
12
  data: {
@@ -31,7 +31,7 @@ async function testChatCompletion() {
31
31
  async function testChatWithSystemPrompt() {
32
32
  console.log('--- Testing Chat with System Prompt ---');
33
33
  const request = {
34
- gate: 'test-gate',
34
+ gateId: 'test-gate',
35
35
  type: 'chat',
36
36
  model: 'mistral-small-latest',
37
37
  data: {
@@ -54,7 +54,7 @@ async function testChatWithSystemPrompt() {
54
54
  async function testChatWithTools() {
55
55
  console.log('--- Testing Chat with Tools ---');
56
56
  const request = {
57
- gate: 'test-gate',
57
+ gateId: 'test-gate',
58
58
  type: 'chat',
59
59
  model: 'mistral-small-latest',
60
60
  data: {
@@ -102,7 +102,7 @@ async function testToolResponse() {
102
102
  console.log('--- Testing Tool Response Flow ---');
103
103
  // First, get the tool call
104
104
  const initialRequest = {
105
- gate: 'test-gate',
105
+ gateId: 'test-gate',
106
106
  type: 'chat',
107
107
  model: 'mistral-small-latest',
108
108
  data: {
@@ -143,7 +143,7 @@ async function testToolResponse() {
143
143
  const toolCall = initialResponse.toolCalls[0];
144
144
  await delay(2000);
145
145
  const followUpRequest = {
146
- gate: 'test-gate',
146
+ gateId: 'test-gate',
147
147
  type: 'chat',
148
148
  model: 'mistral-small-latest',
149
149
  data: {
@@ -175,7 +175,7 @@ async function testToolResponse() {
175
175
  async function testEmbeddings() {
176
176
  console.log('--- Testing Embeddings ---');
177
177
  const request = {
178
- gate: 'test-gate',
178
+ gateId: 'test-gate',
179
179
  type: 'embeddings',
180
180
  model: 'mistral-embed',
181
181
  data: {
@@ -193,7 +193,7 @@ async function testVisionCapability() {
193
193
  console.log('--- Testing Vision Capability (Pixtral) ---');
194
194
  // Use a public image URL for testing
195
195
  const request = {
196
- gate: 'test-gate',
196
+ gateId: 'test-gate',
197
197
  type: 'chat',
198
198
  model: 'pixtral-large-2411',
199
199
  data: {
@@ -224,7 +224,7 @@ async function testVisionCapability() {
224
224
  async function testResponseFormat() {
225
225
  console.log('--- Testing JSON Response Format ---');
226
226
  const request = {
227
- gate: 'test-gate',
227
+ gateId: 'test-gate',
228
228
  type: 'chat',
229
229
  model: 'mistral-small-latest',
230
230
  data: {
@@ -245,7 +245,7 @@ async function testResponseFormat() {
245
245
  async function testMultiTurn() {
246
246
  console.log('--- Testing Multi-turn Conversation ---');
247
247
  const request = {
248
- gate: 'test-gate',
248
+ gateId: 'test-gate',
249
249
  type: 'chat',
250
250
  model: 'mistral-small-latest',
251
251
  data: {
@@ -273,7 +273,7 @@ async function testMultiTurn() {
273
273
  async function testOCR() {
274
274
  console.log('--- Testing OCR Capability ---');
275
275
  const request = {
276
- gate: 'test-gate',
276
+ gateId: 'test-gate',
277
277
  type: 'ocr',
278
278
  model: 'mistral-ocr-latest',
279
279
  data: {
@@ -295,7 +295,7 @@ async function testOCR() {
295
295
  async function testUnsupportedModality() {
296
296
  console.log('--- Testing Unsupported Modality (Image Generation) ---');
297
297
  const request = {
298
- gate: 'test-gate',
298
+ gateId: 'test-gate',
299
299
  type: 'image',
300
300
  model: 'mistral-large-latest',
301
301
  data: {
@@ -3,7 +3,7 @@ const adapter = new OpenAIAdapter();
3
3
  async function testChatCompletion() {
4
4
  console.log('Testing chat completion...');
5
5
  const request = {
6
- gate: 'test-gate',
6
+ gateId: 'test-gate',
7
7
  model: 'gpt-4o-mini',
8
8
  type: 'chat',
9
9
  data: {
@@ -25,7 +25,7 @@ async function testChatCompletion() {
25
25
  async function testChatWithVision() {
26
26
  console.log('Testing chat with vision...');
27
27
  const request = {
28
- gate: 'test-gate',
28
+ gateId: 'test-gate',
29
29
  model: 'gpt-4o-mini',
30
30
  type: 'chat',
31
31
  data: {
@@ -50,7 +50,7 @@ async function testChatWithVision() {
50
50
  async function testImageGeneration() {
51
51
  console.log('Testing image generation...');
52
52
  const request = {
53
- gate: 'test-gate',
53
+ gateId: 'test-gate',
54
54
  model: 'dall-e-3',
55
55
  type: 'image',
56
56
  data: {
@@ -69,7 +69,7 @@ async function testImageGeneration() {
69
69
  async function testEmbeddings() {
70
70
  console.log('Testing embeddings...');
71
71
  const request = {
72
- gate: 'test-gate',
72
+ gateId: 'test-gate',
73
73
  model: 'text-embedding-3-small',
74
74
  type: 'embeddings',
75
75
  data: {
@@ -85,7 +85,7 @@ async function testEmbeddings() {
85
85
  async function testTextToSpeech() {
86
86
  console.log('Testing text-to-speech...');
87
87
  const request = {
88
- gate: 'test-gate',
88
+ gateId: 'test-gate',
89
89
  model: 'tts-1',
90
90
  type: 'tts',
91
91
  data: {
@@ -104,7 +104,7 @@ async function testToolCalling() {
104
104
  console.log('Testing tool calling...');
105
105
  // Step 1: Initial request with tool available
106
106
  const request = {
107
- gate: 'test-gate',
107
+ gateId: 'test-gate',
108
108
  model: 'gpt-4o-mini',
109
109
  type: 'chat',
110
110
  data: {
@@ -145,7 +145,7 @@ async function testToolCalling() {
145
145
  console.log('Function arguments:', toolCall.function.arguments);
146
146
  // Step 2: Send tool response back
147
147
  const toolResponseRequest = {
148
- gate: 'test-gate',
148
+ gateId: 'test-gate',
149
149
  model: 'gpt-4o-mini',
150
150
  type: 'chat',
151
151
  data: {
@@ -173,7 +173,7 @@ async function testContentAndToolCalls() {
173
173
  console.log('Testing content + tool calls in same message...');
174
174
  // This tests the fix we made - assistant messages can have BOTH content and toolCalls
175
175
  const request = {
176
- gate: 'test-gate',
176
+ gateId: 'test-gate',
177
177
  model: 'gpt-4o-mini',
178
178
  type: 'chat',
179
179
  data: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layer-ai/core",
3
- "version": "0.9.1",
3
+ "version": "1.0.0",
4
4
  "description": "Core API routes and services for Layer AI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -36,7 +36,7 @@
36
36
  "nanoid": "^5.0.4",
37
37
  "openai": "^4.24.0",
38
38
  "pg": "^8.11.3",
39
- "@layer-ai/sdk": "^1.0.2"
39
+ "@layer-ai/sdk": "^2.0.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/bcryptjs": "^2.4.6",