@insforge/sdk 1.1.2-edge.0 → 1.1.2-edge.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.
package/dist/index.d.mts CHANGED
@@ -166,19 +166,11 @@ declare class TokenManager {
166
166
  declare class Auth {
167
167
  private http;
168
168
  private tokenManager;
169
- /**
170
- * Promise that resolves when OAuth callback handling is complete.
171
- * Resolves immediately if no OAuth callback is detected in the URL.
172
- */
173
- private authCallbackHandled;
174
169
  constructor(http: HttpClient, tokenManager: TokenManager);
175
170
  /**
176
171
  * Automatically detect and handle OAuth callback parameters in the URL
177
172
  * This runs after initialization to seamlessly complete the OAuth flow
178
- *
179
- * Supports two flows:
180
- * - PKCE flow (new): Backend returns `insforge_code` param, exchanged for tokens
181
- * - Legacy flow: Backend returns tokens directly in URL (backward compatible)
173
+ * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
182
174
  */
183
175
  private detectAuthCallback;
184
176
  /**
@@ -197,7 +189,6 @@ declare class Auth {
197
189
  }>;
198
190
  /**
199
191
  * Sign in with OAuth provider
200
- * Uses PKCE (Proof Key for Code Exchange) for enhanced security
201
192
  */
202
193
  signInWithOAuth(options: {
203
194
  provider: OAuthProvidersSchema;
@@ -207,45 +198,9 @@ declare class Auth {
207
198
  data: {
208
199
  url?: string;
209
200
  provider?: string;
210
- codeVerifier?: string;
211
201
  };
212
202
  error: InsForgeError | null;
213
203
  }>;
214
- /**
215
- * Exchange OAuth authorization code for tokens (PKCE flow)
216
- *
217
- * After OAuth callback redirects with an `insforge_code` parameter, call this method
218
- * to exchange it for access tokens. The code verifier is automatically
219
- * retrieved from sessionStorage if available.
220
- *
221
- * Note: This is called automatically by the SDK on initialization. You typically
222
- * don't need to call this directly unless using `skipBrowserRedirect: true`.
223
- *
224
- * @param code - The authorization code from OAuth callback URL
225
- * @param codeVerifier - Optional code verifier (auto-retrieved from sessionStorage if not provided)
226
- * @returns Session data with access token and user info
227
- *
228
- * @example
229
- * ```ts
230
- * // Automatic verifier retrieval (recommended for browser)
231
- * const params = new URLSearchParams(window.location.search);
232
- * const code = params.get('insforge_code');
233
- * if (code) {
234
- * const { data, error } = await insforge.auth.exchangeOAuthCode(code);
235
- * }
236
- *
237
- * // Manual verifier (for custom flows)
238
- * const { data, error } = await insforge.auth.exchangeOAuthCode(code, codeVerifier);
239
- * ```
240
- */
241
- exchangeOAuthCode(code: string, codeVerifier?: string): Promise<{
242
- data: {
243
- accessToken: string;
244
- user: UserSchema;
245
- redirectTo?: string;
246
- } | null;
247
- error: InsForgeError | null;
248
- }>;
249
204
  /**
250
205
  * Sign out the current user
251
206
  */
@@ -283,7 +238,6 @@ declare class Auth {
283
238
  /**
284
239
  * Get the current session (only session data, no API call)
285
240
  * Returns the stored JWT token and basic user info from local storage
286
- * Automatically waits for any pending OAuth callback to complete first
287
241
  */
288
242
  getCurrentSession(): Promise<{
289
243
  data: {
@@ -579,16 +533,46 @@ declare class ChatCompletions {
579
533
  * });
580
534
  * console.log(completion.choices[0].message.content);
581
535
  *
582
- * // With images
536
+ * // With images (OpenAI-compatible format)
583
537
  * const response = await client.ai.chat.completions.create({
584
538
  * model: 'gpt-4-vision',
585
539
  * messages: [{
586
540
  * role: 'user',
587
- * content: 'What is in this image?',
588
- * images: [{ url: 'https://example.com/image.jpg' }]
541
+ * content: [
542
+ * { type: 'text', text: 'What is in this image?' },
543
+ * { type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } }
544
+ * ]
589
545
  * }]
590
546
  * });
591
547
  *
548
+ * // With PDF files
549
+ * const pdfResponse = await client.ai.chat.completions.create({
550
+ * model: 'anthropic/claude-3.5-sonnet',
551
+ * messages: [{
552
+ * role: 'user',
553
+ * content: [
554
+ * { type: 'text', text: 'Summarize this document' },
555
+ * { type: 'file', file: { filename: 'doc.pdf', file_data: 'https://example.com/doc.pdf' } }
556
+ * ]
557
+ * }],
558
+ * fileParser: { enabled: true, pdf: { engine: 'mistral-ocr' } }
559
+ * });
560
+ *
561
+ * // With web search
562
+ * const searchResponse = await client.ai.chat.completions.create({
563
+ * model: 'openai/gpt-4',
564
+ * messages: [{ role: 'user', content: 'What are the latest news about AI?' }],
565
+ * webSearch: { enabled: true, maxResults: 5 }
566
+ * });
567
+ * // Access citations from response.choices[0].message.annotations
568
+ *
569
+ * // With thinking/reasoning mode (Anthropic models)
570
+ * const thinkingResponse = await client.ai.chat.completions.create({
571
+ * model: 'anthropic/claude-3.5-sonnet',
572
+ * messages: [{ role: 'user', content: 'Solve this complex math problem...' }],
573
+ * thinking: true
574
+ * });
575
+ *
592
576
  * // Streaming - returns async iterable
593
577
  * const stream = await client.ai.chat.completions.create({
594
578
  * model: 'gpt-4',
package/dist/index.d.ts CHANGED
@@ -166,19 +166,11 @@ declare class TokenManager {
166
166
  declare class Auth {
167
167
  private http;
168
168
  private tokenManager;
169
- /**
170
- * Promise that resolves when OAuth callback handling is complete.
171
- * Resolves immediately if no OAuth callback is detected in the URL.
172
- */
173
- private authCallbackHandled;
174
169
  constructor(http: HttpClient, tokenManager: TokenManager);
175
170
  /**
176
171
  * Automatically detect and handle OAuth callback parameters in the URL
177
172
  * This runs after initialization to seamlessly complete the OAuth flow
178
- *
179
- * Supports two flows:
180
- * - PKCE flow (new): Backend returns `insforge_code` param, exchanged for tokens
181
- * - Legacy flow: Backend returns tokens directly in URL (backward compatible)
173
+ * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
182
174
  */
183
175
  private detectAuthCallback;
184
176
  /**
@@ -197,7 +189,6 @@ declare class Auth {
197
189
  }>;
198
190
  /**
199
191
  * Sign in with OAuth provider
200
- * Uses PKCE (Proof Key for Code Exchange) for enhanced security
201
192
  */
202
193
  signInWithOAuth(options: {
203
194
  provider: OAuthProvidersSchema;
@@ -207,45 +198,9 @@ declare class Auth {
207
198
  data: {
208
199
  url?: string;
209
200
  provider?: string;
210
- codeVerifier?: string;
211
201
  };
212
202
  error: InsForgeError | null;
213
203
  }>;
214
- /**
215
- * Exchange OAuth authorization code for tokens (PKCE flow)
216
- *
217
- * After OAuth callback redirects with an `insforge_code` parameter, call this method
218
- * to exchange it for access tokens. The code verifier is automatically
219
- * retrieved from sessionStorage if available.
220
- *
221
- * Note: This is called automatically by the SDK on initialization. You typically
222
- * don't need to call this directly unless using `skipBrowserRedirect: true`.
223
- *
224
- * @param code - The authorization code from OAuth callback URL
225
- * @param codeVerifier - Optional code verifier (auto-retrieved from sessionStorage if not provided)
226
- * @returns Session data with access token and user info
227
- *
228
- * @example
229
- * ```ts
230
- * // Automatic verifier retrieval (recommended for browser)
231
- * const params = new URLSearchParams(window.location.search);
232
- * const code = params.get('insforge_code');
233
- * if (code) {
234
- * const { data, error } = await insforge.auth.exchangeOAuthCode(code);
235
- * }
236
- *
237
- * // Manual verifier (for custom flows)
238
- * const { data, error } = await insforge.auth.exchangeOAuthCode(code, codeVerifier);
239
- * ```
240
- */
241
- exchangeOAuthCode(code: string, codeVerifier?: string): Promise<{
242
- data: {
243
- accessToken: string;
244
- user: UserSchema;
245
- redirectTo?: string;
246
- } | null;
247
- error: InsForgeError | null;
248
- }>;
249
204
  /**
250
205
  * Sign out the current user
251
206
  */
@@ -283,7 +238,6 @@ declare class Auth {
283
238
  /**
284
239
  * Get the current session (only session data, no API call)
285
240
  * Returns the stored JWT token and basic user info from local storage
286
- * Automatically waits for any pending OAuth callback to complete first
287
241
  */
288
242
  getCurrentSession(): Promise<{
289
243
  data: {
@@ -579,16 +533,46 @@ declare class ChatCompletions {
579
533
  * });
580
534
  * console.log(completion.choices[0].message.content);
581
535
  *
582
- * // With images
536
+ * // With images (OpenAI-compatible format)
583
537
  * const response = await client.ai.chat.completions.create({
584
538
  * model: 'gpt-4-vision',
585
539
  * messages: [{
586
540
  * role: 'user',
587
- * content: 'What is in this image?',
588
- * images: [{ url: 'https://example.com/image.jpg' }]
541
+ * content: [
542
+ * { type: 'text', text: 'What is in this image?' },
543
+ * { type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } }
544
+ * ]
589
545
  * }]
590
546
  * });
591
547
  *
548
+ * // With PDF files
549
+ * const pdfResponse = await client.ai.chat.completions.create({
550
+ * model: 'anthropic/claude-3.5-sonnet',
551
+ * messages: [{
552
+ * role: 'user',
553
+ * content: [
554
+ * { type: 'text', text: 'Summarize this document' },
555
+ * { type: 'file', file: { filename: 'doc.pdf', file_data: 'https://example.com/doc.pdf' } }
556
+ * ]
557
+ * }],
558
+ * fileParser: { enabled: true, pdf: { engine: 'mistral-ocr' } }
559
+ * });
560
+ *
561
+ * // With web search
562
+ * const searchResponse = await client.ai.chat.completions.create({
563
+ * model: 'openai/gpt-4',
564
+ * messages: [{ role: 'user', content: 'What are the latest news about AI?' }],
565
+ * webSearch: { enabled: true, maxResults: 5 }
566
+ * });
567
+ * // Access citations from response.choices[0].message.annotations
568
+ *
569
+ * // With thinking/reasoning mode (Anthropic models)
570
+ * const thinkingResponse = await client.ai.chat.completions.create({
571
+ * model: 'anthropic/claude-3.5-sonnet',
572
+ * messages: [{ role: 'user', content: 'Solve this complex math problem...' }],
573
+ * thinking: true
574
+ * });
575
+ *
592
576
  * // Streaming - returns async iterable
593
577
  * const stream = await client.ai.chat.completions.create({
594
578
  * model: 'gpt-4',
package/dist/index.js CHANGED
@@ -357,74 +357,21 @@ function isHostedAuthEnvironment() {
357
357
  }
358
358
  return false;
359
359
  }
360
- var PKCE_VERIFIER_KEY = "insforge_pkce_verifier";
361
- function generateCodeVerifier() {
362
- const array = new Uint8Array(32);
363
- crypto.getRandomValues(array);
364
- return base64UrlEncode(array);
365
- }
366
- async function generateCodeChallenge(verifier) {
367
- const encoder = new TextEncoder();
368
- const data = encoder.encode(verifier);
369
- const hash = await crypto.subtle.digest("SHA-256", data);
370
- return base64UrlEncode(new Uint8Array(hash));
371
- }
372
- function base64UrlEncode(buffer) {
373
- const base64 = btoa(String.fromCharCode(...buffer));
374
- return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
375
- }
376
- function storePkceVerifier(verifier) {
377
- if (typeof sessionStorage !== "undefined") {
378
- sessionStorage.setItem(PKCE_VERIFIER_KEY, verifier);
379
- }
380
- }
381
- function retrievePkceVerifier() {
382
- if (typeof sessionStorage === "undefined") {
383
- return null;
384
- }
385
- const verifier = sessionStorage.getItem(PKCE_VERIFIER_KEY);
386
- if (verifier) {
387
- sessionStorage.removeItem(PKCE_VERIFIER_KEY);
388
- }
389
- return verifier;
390
- }
391
360
  var Auth = class {
392
361
  constructor(http, tokenManager) {
393
362
  this.http = http;
394
363
  this.tokenManager = tokenManager;
395
- this.authCallbackHandled = this.detectAuthCallback();
364
+ this.detectAuthCallback();
396
365
  }
397
366
  /**
398
367
  * Automatically detect and handle OAuth callback parameters in the URL
399
368
  * This runs after initialization to seamlessly complete the OAuth flow
400
- *
401
- * Supports two flows:
402
- * - PKCE flow (new): Backend returns `insforge_code` param, exchanged for tokens
403
- * - Legacy flow: Backend returns tokens directly in URL (backward compatible)
369
+ * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
404
370
  */
405
- async detectAuthCallback() {
371
+ detectAuthCallback() {
406
372
  if (typeof window === "undefined") return;
407
373
  try {
408
374
  const params = new URLSearchParams(window.location.search);
409
- const error = params.get("error");
410
- if (error) {
411
- const url = new URL(window.location.href);
412
- url.searchParams.delete("error");
413
- window.history.replaceState({}, document.title, url.toString());
414
- console.debug("OAuth callback error:", error);
415
- return;
416
- }
417
- const code = params.get("insforge_code");
418
- if (code) {
419
- const url = new URL(window.location.href);
420
- url.searchParams.delete("insforge_code");
421
- window.history.replaceState({}, document.title, url.toString());
422
- const { error: exchangeError } = await this.exchangeOAuthCode(code);
423
- if (exchangeError) {
424
- console.debug("OAuth code exchange failed:", exchangeError.message);
425
- }
426
- return;
427
- }
428
375
  const accessToken = params.get("access_token");
429
376
  const userId = params.get("user_id");
430
377
  const email = params.get("email");
@@ -442,6 +389,8 @@ var Auth = class {
442
389
  email,
443
390
  profile: { name: name || "" },
444
391
  metadata: null,
392
+ // These fields are not provided by backend OAuth callback
393
+ // They'll be populated when calling getCurrentUser()
445
394
  emailVerified: false,
446
395
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
447
396
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -455,6 +404,9 @@ var Auth = class {
455
404
  url.searchParams.delete("email");
456
405
  url.searchParams.delete("name");
457
406
  url.searchParams.delete("csrf_token");
407
+ if (params.has("error")) {
408
+ url.searchParams.delete("error");
409
+ }
458
410
  window.history.replaceState({}, document.title, url.toString());
459
411
  }
460
412
  } catch (error) {
@@ -535,20 +487,11 @@ var Auth = class {
535
487
  }
536
488
  /**
537
489
  * Sign in with OAuth provider
538
- * Uses PKCE (Proof Key for Code Exchange) for enhanced security
539
490
  */
540
491
  async signInWithOAuth(options) {
541
492
  try {
542
493
  const { provider, redirectTo, skipBrowserRedirect } = options;
543
- const codeVerifier = generateCodeVerifier();
544
- const codeChallenge = await generateCodeChallenge(codeVerifier);
545
- storePkceVerifier(codeVerifier);
546
- const params = {
547
- code_challenge: codeChallenge
548
- };
549
- if (redirectTo) {
550
- params.redirect_uri = redirectTo;
551
- }
494
+ const params = redirectTo ? { redirect_uri: redirectTo } : void 0;
552
495
  const endpoint = `/api/auth/oauth/${provider}`;
553
496
  const response = await this.http.get(endpoint, { params });
554
497
  if (typeof window !== "undefined" && !skipBrowserRedirect) {
@@ -558,9 +501,7 @@ var Auth = class {
558
501
  return {
559
502
  data: {
560
503
  url: response.authUrl,
561
- provider,
562
- codeVerifier
563
- // Return verifier for manual flow (skipBrowserRedirect)
504
+ provider
564
505
  },
565
506
  error: null
566
507
  };
@@ -578,85 +519,6 @@ var Auth = class {
578
519
  };
579
520
  }
580
521
  }
581
- /**
582
- * Exchange OAuth authorization code for tokens (PKCE flow)
583
- *
584
- * After OAuth callback redirects with an `insforge_code` parameter, call this method
585
- * to exchange it for access tokens. The code verifier is automatically
586
- * retrieved from sessionStorage if available.
587
- *
588
- * Note: This is called automatically by the SDK on initialization. You typically
589
- * don't need to call this directly unless using `skipBrowserRedirect: true`.
590
- *
591
- * @param code - The authorization code from OAuth callback URL
592
- * @param codeVerifier - Optional code verifier (auto-retrieved from sessionStorage if not provided)
593
- * @returns Session data with access token and user info
594
- *
595
- * @example
596
- * ```ts
597
- * // Automatic verifier retrieval (recommended for browser)
598
- * const params = new URLSearchParams(window.location.search);
599
- * const code = params.get('insforge_code');
600
- * if (code) {
601
- * const { data, error } = await insforge.auth.exchangeOAuthCode(code);
602
- * }
603
- *
604
- * // Manual verifier (for custom flows)
605
- * const { data, error } = await insforge.auth.exchangeOAuthCode(code, codeVerifier);
606
- * ```
607
- */
608
- async exchangeOAuthCode(code, codeVerifier) {
609
- try {
610
- const verifier = codeVerifier ?? retrievePkceVerifier();
611
- if (!verifier) {
612
- return {
613
- data: null,
614
- error: new InsForgeError(
615
- "PKCE code verifier not found. Ensure signInWithOAuth was called in the same browser session.",
616
- 400,
617
- "PKCE_VERIFIER_MISSING"
618
- )
619
- };
620
- }
621
- const request = {
622
- code,
623
- code_verifier: verifier
624
- };
625
- const response = await this.http.post("/api/auth/oauth/exchange", request, { credentials: "include" });
626
- if (!isHostedAuthEnvironment()) {
627
- const session = {
628
- accessToken: response.accessToken,
629
- user: response.user
630
- };
631
- if (response.csrfToken) {
632
- this.tokenManager.setMemoryMode();
633
- setCsrfToken(response.csrfToken);
634
- }
635
- this.tokenManager.saveSession(session);
636
- this.http.setAuthToken(response.accessToken);
637
- }
638
- return {
639
- data: {
640
- accessToken: response.accessToken,
641
- user: response.user,
642
- redirectTo: response.redirectTo
643
- },
644
- error: null
645
- };
646
- } catch (error) {
647
- if (error instanceof InsForgeError) {
648
- return { data: null, error };
649
- }
650
- return {
651
- data: null,
652
- error: new InsForgeError(
653
- "An unexpected error occurred during OAuth code exchange",
654
- 500,
655
- "UNEXPECTED_ERROR"
656
- )
657
- };
658
- }
659
- }
660
522
  /**
661
523
  * Sign out the current user
662
524
  */
@@ -745,10 +607,8 @@ var Auth = class {
745
607
  /**
746
608
  * Get the current session (only session data, no API call)
747
609
  * Returns the stored JWT token and basic user info from local storage
748
- * Automatically waits for any pending OAuth callback to complete first
749
610
  */
750
611
  async getCurrentSession() {
751
- await this.authCallbackHandled;
752
612
  if (isHostedAuthEnvironment()) {
753
613
  return { data: { session: null }, error: null };
754
614
  }
@@ -757,9 +617,17 @@ var Auth = class {
757
617
  if (session) {
758
618
  this.http.setAuthToken(session.accessToken);
759
619
  if (!session.user) {
760
- const authResponse = await this.http.get("/api/auth/sessions/current", { credentials: "include" });
761
- session.user = authResponse.user;
762
- this.tokenManager.setUser(session.user);
620
+ try {
621
+ const authResponse = await this.http.get(
622
+ "/api/auth/sessions/current",
623
+ { credentials: "include" }
624
+ );
625
+ if (authResponse.user) {
626
+ session.user = authResponse.user;
627
+ this.tokenManager.setUser(authResponse.user);
628
+ }
629
+ } catch {
630
+ }
763
631
  }
764
632
  return { data: { session }, error: null };
765
633
  }
@@ -1441,16 +1309,46 @@ var ChatCompletions = class {
1441
1309
  * });
1442
1310
  * console.log(completion.choices[0].message.content);
1443
1311
  *
1444
- * // With images
1312
+ * // With images (OpenAI-compatible format)
1445
1313
  * const response = await client.ai.chat.completions.create({
1446
1314
  * model: 'gpt-4-vision',
1447
1315
  * messages: [{
1448
1316
  * role: 'user',
1449
- * content: 'What is in this image?',
1450
- * images: [{ url: 'https://example.com/image.jpg' }]
1317
+ * content: [
1318
+ * { type: 'text', text: 'What is in this image?' },
1319
+ * { type: 'image_url', image_url: { url: 'https://example.com/image.jpg' } }
1320
+ * ]
1451
1321
  * }]
1452
1322
  * });
1453
1323
  *
1324
+ * // With PDF files
1325
+ * const pdfResponse = await client.ai.chat.completions.create({
1326
+ * model: 'anthropic/claude-3.5-sonnet',
1327
+ * messages: [{
1328
+ * role: 'user',
1329
+ * content: [
1330
+ * { type: 'text', text: 'Summarize this document' },
1331
+ * { type: 'file', file: { filename: 'doc.pdf', file_data: 'https://example.com/doc.pdf' } }
1332
+ * ]
1333
+ * }],
1334
+ * fileParser: { enabled: true, pdf: { engine: 'mistral-ocr' } }
1335
+ * });
1336
+ *
1337
+ * // With web search
1338
+ * const searchResponse = await client.ai.chat.completions.create({
1339
+ * model: 'openai/gpt-4',
1340
+ * messages: [{ role: 'user', content: 'What are the latest news about AI?' }],
1341
+ * webSearch: { enabled: true, maxResults: 5 }
1342
+ * });
1343
+ * // Access citations from response.choices[0].message.annotations
1344
+ *
1345
+ * // With thinking/reasoning mode (Anthropic models)
1346
+ * const thinkingResponse = await client.ai.chat.completions.create({
1347
+ * model: 'anthropic/claude-3.5-sonnet',
1348
+ * messages: [{ role: 'user', content: 'Solve this complex math problem...' }],
1349
+ * thinking: true
1350
+ * });
1351
+ *
1454
1352
  * // Streaming - returns async iterable
1455
1353
  * const stream = await client.ai.chat.completions.create({
1456
1354
  * model: 'gpt-4',
@@ -1472,7 +1370,11 @@ var ChatCompletions = class {
1472
1370
  temperature: params.temperature,
1473
1371
  maxTokens: params.maxTokens,
1474
1372
  topP: params.topP,
1475
- stream: params.stream
1373
+ stream: params.stream,
1374
+ // New plugin options
1375
+ webSearch: params.webSearch,
1376
+ fileParser: params.fileParser,
1377
+ thinking: params.thinking
1476
1378
  };
1477
1379
  if (params.stream) {
1478
1380
  const headers = this.http.getHeaders();
@@ -1506,7 +1408,9 @@ var ChatCompletions = class {
1506
1408
  index: 0,
1507
1409
  message: {
1508
1410
  role: "assistant",
1509
- content
1411
+ content,
1412
+ // Include annotations if present (from web search or file parsing)
1413
+ ...response.annotations && { annotations: response.annotations }
1510
1414
  },
1511
1415
  finish_reason: "stop"
1512
1416
  }