n8n-nodes-vercel-ai-sdk-universal-temp 0.1.1 → 0.1.3

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 (36) hide show
  1. package/README.md +23 -1
  2. package/dist/credentials/DeepSeekApi.credentials.js +12 -3
  3. package/dist/credentials/DeepSeekApi.credentials.js.map +1 -1
  4. package/dist/credentials/GoogleGenerativeAIApi.credentials.js +12 -3
  5. package/dist/credentials/GoogleGenerativeAIApi.credentials.js.map +1 -1
  6. package/dist/credentials/GroqApi.credentials.js +12 -3
  7. package/dist/credentials/GroqApi.credentials.js.map +1 -1
  8. package/dist/credentials/OpenAiApi.credentials.d.ts +9 -0
  9. package/dist/credentials/OpenAiApi.credentials.js +46 -0
  10. package/dist/credentials/OpenAiApi.credentials.js.map +1 -0
  11. package/dist/credentials/OpenRouterApi.credentials.js +11 -2
  12. package/dist/credentials/OpenRouterApi.credentials.js.map +1 -1
  13. package/dist/nodes/UniversalAI/UniversalAI.node.js +64 -138
  14. package/dist/nodes/UniversalAI/UniversalAI.node.js.map +1 -1
  15. package/dist/nodes/UniversalAI/model-lists.d.ts +20 -0
  16. package/dist/nodes/UniversalAI/model-lists.js +172 -0
  17. package/dist/nodes/UniversalAI/model-lists.js.map +1 -0
  18. package/dist/nodes/UniversalAIEmbedding/UniversalEmbedding.node.d.ts +10 -0
  19. package/dist/nodes/UniversalAIEmbedding/UniversalEmbedding.node.js +332 -0
  20. package/dist/nodes/UniversalAIEmbedding/UniversalEmbedding.node.js.map +1 -0
  21. package/dist/nodes/UniversalAIImageGen/UniversalImageGen.node.d.ts +10 -0
  22. package/dist/nodes/UniversalAIImageGen/UniversalImageGen.node.js +359 -0
  23. package/dist/nodes/UniversalAIImageGen/UniversalImageGen.node.js.map +1 -0
  24. package/dist/nodes/UniversalImageGen/UniversalImageGen.node.js +3 -3
  25. package/dist/nodes/UniversalImageGen/UniversalImageGen.node.js.map +1 -1
  26. package/dist/nodes/UniversalSpeechGen/UniversalSpeechGen.node.d.ts +10 -0
  27. package/dist/nodes/UniversalSpeechGen/UniversalSpeechGen.node.js +269 -0
  28. package/dist/nodes/UniversalSpeechGen/UniversalSpeechGen.node.js.map +1 -0
  29. package/dist/nodes/UniversalSpeechGen/icons/UniversalSpeechGen.svg +4 -0
  30. package/dist/nodes/UniversalTranscription/UniversalTranscription.node.d.ts +5 -0
  31. package/dist/nodes/UniversalTranscription/UniversalTranscription.node.js +216 -0
  32. package/dist/nodes/UniversalTranscription/UniversalTranscription.node.js.map +1 -0
  33. package/dist/nodes/UniversalTranscription/icons/UniversalTranscription.svg +6 -0
  34. package/dist/package.json +8 -4
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +8 -4
package/README.md CHANGED
@@ -11,6 +11,8 @@ Follow the [n8n community node installation guide](https://docs.n8n.io/integrati
11
11
  - **Universal AI** (`nodes/UniversalAI/`)
12
12
  - **Universal Embedding** (`nodes/UniversalEmbedding/`)
13
13
  - **Universal Image Generation** (`nodes/UniversalImageGen/`)
14
+ - **Universal Speech Generation** (`nodes/UniversalSpeechGen/`)
15
+ - **Universal Transcription** (`nodes/UniversalTranscription/`)
14
16
 
15
17
  ## Universal AI Node
16
18
 
@@ -49,13 +51,33 @@ Create images via multiple providers while sharing one configuration surface:
49
51
  - **OpenAI**: Image size, quality, style.
50
52
  - **Outputs**: Base64 image data, MIME type, downloadable binary, warnings.
51
53
 
54
+ ## Universal Speech Generation Node
55
+
56
+ Generate speech audio from text:
57
+
58
+ - **Providers**: Google Generative AI, OpenAI.
59
+ - **Controls**: Text input, voice selection, output format, speed, language.
60
+ - **Google Voices**: Default voice.
61
+ - **OpenAI Voices**: Alloy, Echo, Fable, Onyx, Nova, Shimmer.
62
+ - **Outputs**: Base64 audio data, MIME type, downloadable binary, warnings.
63
+
64
+ ## Universal Transcription Node
65
+
66
+ Convert audio files to text transcripts:
67
+
68
+ - **Providers**: OpenAI (Whisper).
69
+ - **Inputs**: Binary audio data or URL to audio file.
70
+ - **Features**: Language detection/auto-detection, timestamped segments.
71
+ - **Models**: Whisper Large v3.
72
+ - **Outputs**: Full transcript, language, duration, optional segments, warnings.
73
+
52
74
  ## Credentials
53
75
 
54
76
  - **Google Generative AI**: API key from [Google AI Studio](https://makersuite.google.com/app/apikey).
55
77
  - **DeepSeek**: API key from [DeepSeek](https://platform.deepseek.com/).
56
78
  - **Groq**: API key from [Groq Console](https://console.groq.com/).
57
79
  - **OpenRouter**: API key from [OpenRouter](https://openrouter.ai/).
58
- - **OpenAI** (for embeddings/images through OpenRouter-ready models): API key from [OpenAI](https://platform.openai.com/).
80
+ - **OpenAI**: API key from [OpenAI](https://platform.openai.com/) (for embeddings and image generation).
59
81
 
60
82
  Provide keys directly in node parameters or configure reusable n8n credentials.
61
83
 
@@ -13,7 +13,16 @@ class DeepSeekApi {
13
13
  type: 'string',
14
14
  typeOptions: { password: true },
15
15
  default: '',
16
- required: true,
16
+ required: false,
17
+ description: 'Your DeepSeek API key',
18
+ },
19
+ {
20
+ displayName: 'Base URL',
21
+ name: 'baseUrl',
22
+ type: 'string',
23
+ default: 'https://api.deepseek.com',
24
+ required: false,
25
+ description: 'Custom base URL for DeepSeek API',
17
26
  },
18
27
  ];
19
28
  this.authenticate = {
@@ -26,8 +35,8 @@ class DeepSeekApi {
26
35
  };
27
36
  this.test = {
28
37
  request: {
29
- baseURL: 'https://api.deepseek.com',
30
- url: '/v1/user/balance',
38
+ baseURL: '={{$credentials.baseUrl || "https://api.deepseek.com"}}',
39
+ url: '/models',
31
40
  method: 'GET',
32
41
  },
33
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DeepSeekApi.credentials.js","sourceRoot":"","sources":["../../credentials/DeepSeekApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,WAAW;IAAxB;QACI,SAAI,GAAG,aAAa,CAAC;QACrB,gBAAW,GAAG,cAAc,CAAC;QAC7B,qBAAgB,GAAG,oCAAoC,CAAC;QACxD,eAAU,GAAsB;YAC5B;gBACI,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;aACjB;SACJ,CAAC;QAEF,iBAAY,GAAyB;YACjC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACR,OAAO,EAAE;oBACL,aAAa,EAAE,iCAAiC;iBACnD;aACJ;SACJ,CAAC;QAEF,SAAI,GAA2B;YAC3B,OAAO,EAAE;gBACL,OAAO,EAAE,0BAA0B;gBACnC,GAAG,EAAE,kBAAkB;gBACvB,MAAM,EAAE,KAAK;aAChB;SACJ,CAAC;IACN,CAAC;CAAA;AA/BD,kCA+BC"}
1
+ {"version":3,"file":"DeepSeekApi.credentials.js","sourceRoot":"","sources":["../../credentials/DeepSeekApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,WAAW;IAAxB;QACI,SAAI,GAAG,aAAa,CAAC;QACrB,gBAAW,GAAG,cAAc,CAAC;QAC7B,qBAAgB,GAAG,oCAAoC,CAAC;QACxD,eAAU,GAAsB;YAC5B;gBACI,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,uBAAuB;aACvC;YACD;gBACI,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,0BAA0B;gBACnC,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,kCAAkC;aAClD;SACJ,CAAC;QAEF,iBAAY,GAAyB;YACjC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACR,OAAO,EAAE;oBACL,aAAa,EAAE,iCAAiC;iBACnD;aACJ;SACJ,CAAC;QAEF,SAAI,GAA2B;YAC3B,OAAO,EAAE;gBACL,OAAO,EAAE,yDAAyD;gBAClE,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE,KAAK;aAChB;SACJ,CAAC;IACN,CAAC;CAAA;AAxCD,kCAwCC"}
@@ -13,7 +13,16 @@ class GoogleGenerativeAIApi {
13
13
  type: 'string',
14
14
  typeOptions: { password: true },
15
15
  default: '',
16
- required: true,
16
+ required: false,
17
+ description: 'Your Google Generative AI API key',
18
+ },
19
+ {
20
+ displayName: 'Base URL',
21
+ name: 'baseUrl',
22
+ type: 'string',
23
+ default: 'https://generativelanguage.googleapis.com/v1beta',
24
+ required: false,
25
+ description: 'Custom base URL for Google Generative AI API',
17
26
  },
18
27
  ];
19
28
  this.authenticate = {
@@ -26,8 +35,8 @@ class GoogleGenerativeAIApi {
26
35
  };
27
36
  this.test = {
28
37
  request: {
29
- baseURL: 'https://generativelanguage.googleapis.com',
30
- url: '/v1/models',
38
+ baseURL: '={{$credentials.baseUrl || "https://generativelanguage.googleapis.com/v1beta"}}',
39
+ url: '/models',
31
40
  method: 'GET',
32
41
  },
33
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"GoogleGenerativeAIApi.credentials.js","sourceRoot":"","sources":["../../credentials/GoogleGenerativeAIApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,qBAAqB;IAAlC;QACC,SAAI,GAAG,uBAAuB,CAAC;QAC/B,gBAAW,GAAG,0BAA0B,CAAC;QACzC,qBAAgB,GAAG,4BAA4B,CAAC;QAChD,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;aACd;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,gBAAgB,EAAE,0BAA0B;iBAC5C;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,2CAA2C;gBACpD,GAAG,EAAE,YAAY;gBACjB,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AA/BD,sDA+BC"}
1
+ {"version":3,"file":"GoogleGenerativeAIApi.credentials.js","sourceRoot":"","sources":["../../credentials/GoogleGenerativeAIApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,qBAAqB;IAAlC;QACC,SAAI,GAAG,uBAAuB,CAAC;QAC/B,gBAAW,GAAG,0BAA0B,CAAC;QACzC,qBAAgB,GAAG,4BAA4B,CAAC;QAChD,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,mCAAmC;aAChD;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,kDAAkD;gBAC3D,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,8CAA8C;aAC3D;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,gBAAgB,EAAE,0BAA0B;iBAC5C;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,iFAAiF;gBAC1F,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AAxCD,sDAwCC"}
@@ -13,7 +13,16 @@ class GroqApi {
13
13
  type: 'string',
14
14
  typeOptions: { password: true },
15
15
  default: '',
16
- required: true,
16
+ required: false,
17
+ description: 'Your Groq API key',
18
+ },
19
+ {
20
+ displayName: 'Base URL',
21
+ name: 'baseUrl',
22
+ type: 'string',
23
+ default: 'https://api.groq.com/openai/v1',
24
+ required: false,
25
+ description: 'Custom base URL for Groq API',
17
26
  },
18
27
  ];
19
28
  this.authenticate = {
@@ -26,8 +35,8 @@ class GroqApi {
26
35
  };
27
36
  this.test = {
28
37
  request: {
29
- baseURL: 'https://api.groq.com',
30
- url: '/openai/v1/models',
38
+ baseURL: '={{$credentials.baseUrl || "https://api.groq.com/openai/v1"}}',
39
+ url: '/models',
31
40
  method: 'GET',
32
41
  },
33
42
  };
@@ -1 +1 @@
1
- {"version":3,"file":"GroqApi.credentials.js","sourceRoot":"","sources":["../../credentials/GroqApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,OAAO;IAApB;QACI,SAAI,GAAG,SAAS,CAAC;QACjB,gBAAW,GAAG,UAAU,CAAC;QACzB,qBAAgB,GAAG,sCAAsC,CAAC;QAC1D,eAAU,GAAsB;YAC5B;gBACI,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;aACjB;SACJ,CAAC;QAEF,iBAAY,GAAyB;YACjC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACR,OAAO,EAAE;oBACL,aAAa,EAAE,iCAAiC;iBACnD;aACJ;SACJ,CAAC;QAEF,SAAI,GAA2B;YAC3B,OAAO,EAAE;gBACL,OAAO,EAAE,sBAAsB;gBAC/B,GAAG,EAAE,mBAAmB;gBACxB,MAAM,EAAE,KAAK;aAChB;SACJ,CAAC;IACN,CAAC;CAAA;AA/BD,0BA+BC"}
1
+ {"version":3,"file":"GroqApi.credentials.js","sourceRoot":"","sources":["../../credentials/GroqApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,OAAO;IAApB;QACI,SAAI,GAAG,SAAS,CAAC;QACjB,gBAAW,GAAG,UAAU,CAAC;QACzB,qBAAgB,GAAG,sCAAsC,CAAC;QAC1D,eAAU,GAAsB;YAC5B;gBACI,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,mBAAmB;aACnC;YACD;gBACI,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,gCAAgC;gBACzC,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,8BAA8B;aAC9C;SACJ,CAAC;QAEF,iBAAY,GAAyB;YACjC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACR,OAAO,EAAE;oBACL,aAAa,EAAE,iCAAiC;iBACnD;aACJ;SACJ,CAAC;QAEF,SAAI,GAA2B;YAC3B,OAAO,EAAE;gBACL,OAAO,EAAE,+DAA+D;gBACxE,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE,KAAK;aAChB;SACJ,CAAC;IACN,CAAC;CAAA;AAxCD,0BAwCC"}
@@ -0,0 +1,9 @@
1
+ import type { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class OpenAiApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ authenticate: IAuthenticateGeneric;
8
+ test: ICredentialTestRequest;
9
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenAiApi = void 0;
4
+ class OpenAiApi {
5
+ constructor() {
6
+ this.name = 'openAiApi';
7
+ this.displayName = 'OpenAI API';
8
+ this.documentationUrl = 'https://platform.openai.com/docs/api-reference';
9
+ this.properties = [
10
+ {
11
+ displayName: 'API Key',
12
+ name: 'apiKey',
13
+ type: 'string',
14
+ typeOptions: { password: true },
15
+ default: '',
16
+ required: false,
17
+ description: 'Your OpenAI API key',
18
+ },
19
+ {
20
+ displayName: 'Base URL',
21
+ name: 'baseUrl',
22
+ type: 'string',
23
+ default: 'https://api.openai.com/v1',
24
+ required: false,
25
+ description: 'Custom base URL for OpenAI API',
26
+ },
27
+ ];
28
+ this.authenticate = {
29
+ type: 'generic',
30
+ properties: {
31
+ headers: {
32
+ Authorization: '=Bearer {{$credentials.apiKey}}',
33
+ },
34
+ },
35
+ };
36
+ this.test = {
37
+ request: {
38
+ baseURL: '={{$credentials.baseUrl || "https://api.openai.com/v1"}}',
39
+ url: '/models',
40
+ method: 'GET',
41
+ },
42
+ };
43
+ }
44
+ }
45
+ exports.OpenAiApi = OpenAiApi;
46
+ //# sourceMappingURL=OpenAiApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenAiApi.credentials.js","sourceRoot":"","sources":["../../credentials/OpenAiApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,SAAS;IAAtB;QACC,SAAI,GAAG,WAAW,CAAC;QACnB,gBAAW,GAAG,YAAY,CAAC;QAC3B,qBAAgB,GAAG,gDAAgD,CAAC;QACpE,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,qBAAqB;aAClC;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,2BAA2B;gBACpC,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,gCAAgC;aAC7C;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,iCAAiC;iBAChD;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,0DAA0D;gBACnE,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AAxCD,8BAwCC"}
@@ -13,7 +13,16 @@ class OpenRouterApi {
13
13
  type: 'string',
14
14
  typeOptions: { password: true },
15
15
  default: '',
16
- required: true,
16
+ required: false,
17
+ description: 'Your OpenRouter API key',
18
+ },
19
+ {
20
+ displayName: 'Base URL',
21
+ name: 'baseUrl',
22
+ type: 'string',
23
+ default: 'https://openrouter.ai/api/v1',
24
+ required: false,
25
+ description: 'Custom base URL for OpenRouter API',
17
26
  },
18
27
  ];
19
28
  this.authenticate = {
@@ -26,7 +35,7 @@ class OpenRouterApi {
26
35
  };
27
36
  this.test = {
28
37
  request: {
29
- baseURL: 'https://openrouter.ai/api/v1',
38
+ baseURL: '={{$credentials.baseUrl || "https://openrouter.ai/api/v1"}}',
30
39
  url: '/models',
31
40
  method: 'GET',
32
41
  },
@@ -1 +1 @@
1
- {"version":3,"file":"OpenRouterApi.credentials.js","sourceRoot":"","sources":["../../credentials/OpenRouterApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,aAAa;IAA1B;QACC,SAAI,GAAG,eAAe,CAAC;QACvB,gBAAW,GAAG,gBAAgB,CAAC;QAC/B,qBAAgB,GAAG,4BAA4B,CAAC;QAChD,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;aACd;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,iCAAiC;iBAChD;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,8BAA8B;gBACvC,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AA/BD,sCA+BC"}
1
+ {"version":3,"file":"OpenRouterApi.credentials.js","sourceRoot":"","sources":["../../credentials/OpenRouterApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,aAAa;IAA1B;QACC,SAAI,GAAG,eAAe,CAAC;QACvB,gBAAW,GAAG,gBAAgB,CAAC;QAC/B,qBAAgB,GAAG,4BAA4B,CAAC;QAChD,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,yBAAyB;aACtC;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,8BAA8B;gBACvC,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,oCAAoC;aACjD;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,iCAAiC;iBAChD;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,6DAA6D;gBACtE,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE,KAAK;aACb;SACD,CAAC;IACH,CAAC;CAAA;AAxCD,sCAwCC"}
@@ -8,10 +8,11 @@ const n8n_workflow_1 = require("n8n-workflow");
8
8
  const { createGoogleGenerativeAI } = require('@ai-sdk/google');
9
9
  const { createDeepSeek } = require('@ai-sdk/deepseek');
10
10
  const { createGroq } = require('@ai-sdk/groq');
11
- const { createOpenRouter } = require('@ai-sdk/openrouter');
11
+ const { createOpenRouter } = require('@openrouter/ai-sdk-provider');
12
12
  const ai_1 = require("ai");
13
13
  const zod_1 = require("zod");
14
14
  const ajv_1 = __importDefault(require("ajv"));
15
+ const model_lists_1 = require("./model-lists");
15
16
  async function buildInput(exec, itemIndex) {
16
17
  const inputType = exec.getNodeParameter('inputType', itemIndex);
17
18
  if (inputType === 'prompt') {
@@ -114,22 +115,25 @@ async function buildInput(exec, itemIndex) {
114
115
  }
115
116
  }
116
117
  function formatTextResult(result, includeRequestBody, provider) {
117
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
118
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
118
119
  let text = result.text;
119
120
  let reasoning = result.reasoning;
120
121
  if (provider === 'groq' && text.includes('<think>')) {
121
122
  const thinkMatch = text.match(/<think>(.*?)<\/think>/s);
122
123
  if (thinkMatch) {
123
- reasoning = thinkMatch[1].trim();
124
+ reasoning = [{ text: thinkMatch[1].trim() }];
124
125
  text = text.replace(/<think>.*?<\/think>\s*/s, '').trim();
125
126
  }
126
127
  }
127
128
  const out = {
128
129
  text,
129
130
  reasoning,
131
+ reasoningText: result.reasoningText,
130
132
  toolCalls: result.toolCalls || [],
131
133
  toolResults: result.toolResults || [],
132
134
  finishReason: result.finishReason,
135
+ sources: result.sources || [],
136
+ files: result.files || [],
133
137
  usage: {
134
138
  promptTokens: (_a = result.usage) === null || _a === void 0 ? void 0 : _a.promptTokens,
135
139
  completionTokens: (_b = result.usage) === null || _b === void 0 ? void 0 : _b.completionTokens,
@@ -146,19 +150,29 @@ function formatTextResult(result, includeRequestBody, provider) {
146
150
  promptCacheMissTokens: (_l = (_k = result.experimental_providerMetadata) === null || _k === void 0 ? void 0 : _k.groq) === null || _l === void 0 ? void 0 : _l.promptCacheMissTokens,
147
151
  },
148
152
  }),
153
+ ...(provider === 'google' && {
154
+ cacheMetrics: {
155
+ cachedContentTokenCount: (_p = (_o = (_m = result.experimental_providerMetadata) === null || _m === void 0 ? void 0 : _m.google) === null || _o === void 0 ? void 0 : _o.usageMetadata) === null || _p === void 0 ? void 0 : _p.cachedContentTokenCount,
156
+ thoughtsTokenCount: (_s = (_r = (_q = result.experimental_providerMetadata) === null || _q === void 0 ? void 0 : _q.google) === null || _r === void 0 ? void 0 : _r.usageMetadata) === null || _s === void 0 ? void 0 : _s.thoughtsTokenCount,
157
+ },
158
+ }),
149
159
  },
150
160
  response: {
151
- id: (_m = result.response) === null || _m === void 0 ? void 0 : _m.id,
152
- modelId: (_o = result.response) === null || _o === void 0 ? void 0 : _o.modelId,
153
- timestamp: (_p = result.response) === null || _p === void 0 ? void 0 : _p.timestamp,
154
- headers: (_q = result.response) === null || _q === void 0 ? void 0 : _q.headers,
161
+ id: (_t = result.response) === null || _t === void 0 ? void 0 : _t.id,
162
+ modelId: (_u = result.response) === null || _u === void 0 ? void 0 : _u.modelId,
163
+ timestamp: (_v = result.response) === null || _v === void 0 ? void 0 : _v.timestamp,
164
+ headers: (_w = result.response) === null || _w === void 0 ? void 0 : _w.headers,
155
165
  },
156
166
  steps: result.steps || [],
157
167
  warnings: result.warnings || [],
158
168
  experimental_providerMetadata: result.experimental_providerMetadata,
169
+ ...(provider === 'google' && {
170
+ groundingMetadata: (_y = (_x = result.experimental_providerMetadata) === null || _x === void 0 ? void 0 : _x.google) === null || _y === void 0 ? void 0 : _y.groundingMetadata,
171
+ safetyRatings: (_0 = (_z = result.experimental_providerMetadata) === null || _z === void 0 ? void 0 : _z.google) === null || _0 === void 0 ? void 0 : _0.safetyRatings,
172
+ }),
159
173
  };
160
174
  if (includeRequestBody) {
161
- out.request = { body: (_r = result.request) === null || _r === void 0 ? void 0 : _r.body };
175
+ out.request = { body: (_1 = result.request) === null || _1 === void 0 ? void 0 : _1.body };
162
176
  }
163
177
  return out;
164
178
  }
@@ -201,7 +215,12 @@ class UniversalAI {
201
215
  },
202
216
  inputs: [{ type: "main" }],
203
217
  outputs: [{ type: "main" }],
204
- credentials: [],
218
+ credentials: [
219
+ { name: "googleGenerativeAIApi", required: false, displayOptions: { show: { provider: ["google"] } } },
220
+ { name: "deepSeekApi", required: false, displayOptions: { show: { provider: ["deepseek"] } } },
221
+ { name: "groqApi", required: false, displayOptions: { show: { provider: ["groq"] } } },
222
+ { name: "openRouterApi", required: false, displayOptions: { show: { provider: ["openrouter"] } } },
223
+ ],
205
224
  properties: [
206
225
  {
207
226
  displayName: 'Provider',
@@ -230,28 +249,6 @@ class UniversalAI {
230
249
  default: 'google',
231
250
  description: 'Choose which AI provider to use',
232
251
  },
233
- {
234
- displayName: 'API Key',
235
- name: 'apiKey',
236
- type: 'string',
237
- typeOptions: { password: true },
238
- default: '',
239
- required: false,
240
- description: 'API key for the selected provider. Leave empty to use credentials.',
241
- displayOptions: {
242
- show: {
243
- provider: ['google', 'deepseek', 'groq', 'openrouter'],
244
- },
245
- },
246
- },
247
- {
248
- displayName: 'Base URL',
249
- name: 'baseURL',
250
- type: 'string',
251
- default: `={{ $parameter.provider === 'google' ? 'https://generativelanguage.googleapis.com/v1beta' : $parameter.provider === 'deepseek' ? 'https://api.deepseek.com' : $parameter.provider === 'groq' ? 'https://api.groq.com' : $parameter.provider === 'openrouter' ? 'https://openrouter.ai/api/v1' : '' }}`,
252
- required: false,
253
- description: 'Base URL for the provider API. Defaults are set automatically based on the selected provider.',
254
- },
255
252
  {
256
253
  displayName: 'Operation',
257
254
  name: 'operation',
@@ -881,33 +878,7 @@ class UniversalAI {
881
878
  try {
882
879
  switch (provider) {
883
880
  case 'google': {
884
- const credentials = await this.getCredentials('googleGenerativeAIApi');
885
- const response = await this.helpers.request({
886
- method: 'GET',
887
- url: 'https://generativelanguage.googleapis.com/v1beta/models',
888
- headers: {
889
- 'x-goog-api-key': credentials.apiKey,
890
- },
891
- json: true,
892
- });
893
- const returnData = [];
894
- if (response.models) {
895
- for (const model of response.models) {
896
- if (model.name.includes('gemini')) {
897
- const modelId = model.name.split('/').pop();
898
- const displayName = model.displayName || modelId;
899
- const version = modelId.includes('latest')
900
- ? '(Latest)'
901
- : `(${model.version || 'v1'})`;
902
- returnData.push({
903
- name: `${displayName} ${version}`,
904
- value: modelId,
905
- description: model.description || '',
906
- });
907
- }
908
- }
909
- }
910
- return returnData.sort((a, b) => a.name.localeCompare(b.name));
881
+ return model_lists_1.GOOGLE_GEMINI_MODELS;
911
882
  }
912
883
  case 'deepseek': {
913
884
  return [
@@ -953,52 +924,7 @@ class UniversalAI {
953
924
  ];
954
925
  }
955
926
  case 'openrouter': {
956
- try {
957
- const credentials = await this.getCredentials('openRouterApi');
958
- const response = await this.helpers.request({
959
- method: 'GET',
960
- url: 'https://openrouter.ai/api/v1/models',
961
- headers: {
962
- Authorization: `Bearer ${credentials.apiKey}`,
963
- },
964
- json: true,
965
- });
966
- const returnData = [];
967
- if (response.data) {
968
- for (const model of response.data) {
969
- returnData.push({
970
- name: model.name || model.id,
971
- value: model.id,
972
- description: model.description || '',
973
- });
974
- }
975
- }
976
- return returnData.sort((a, b) => a.name.localeCompare(b.name));
977
- }
978
- catch (error) {
979
- return [
980
- {
981
- name: 'GPT-4o',
982
- value: 'openai/gpt-4o',
983
- description: 'OpenAI GPT-4o via OpenRouter',
984
- },
985
- {
986
- name: 'GPT-4o Mini',
987
- value: 'openai/gpt-4o-mini',
988
- description: 'OpenAI GPT-4o Mini via OpenRouter',
989
- },
990
- {
991
- name: 'Claude 3.5 Sonnet',
992
- value: 'anthropic/claude-3.5-sonnet',
993
- description: 'Anthropic Claude 3.5 Sonnet via OpenRouter',
994
- },
995
- {
996
- name: 'Gemini 1.5 Pro',
997
- value: 'google/gemini-pro-1.5',
998
- description: 'Google Gemini 1.5 Pro via OpenRouter',
999
- },
1000
- ];
1001
- }
927
+ return model_lists_1.OPENROUTER_MODELS;
1002
928
  }
1003
929
  default:
1004
930
  return [];
@@ -1060,56 +986,50 @@ class UniversalAI {
1060
986
  const items = this.getInputData();
1061
987
  const returnData = [];
1062
988
  const provider = this.getNodeParameter('provider', 0);
1063
- const apiKey = this.getNodeParameter('apiKey', 0, '');
1064
- const baseURL = this.getNodeParameter('baseURL', 0, '');
1065
989
  let credentials = null;
1066
- if (!apiKey) {
1067
- switch (provider) {
1068
- case 'google':
1069
- credentials = await this.getCredentials('googleGenerativeAIApi');
1070
- break;
1071
- case 'deepseek':
1072
- credentials = await this.getCredentials('deepSeekApi');
1073
- break;
1074
- case 'groq':
1075
- credentials = await this.getCredentials('groqApi');
1076
- break;
1077
- case 'openrouter':
1078
- credentials = await this.getCredentials('openRouterApi');
1079
- break;
1080
- }
1081
- if (!(credentials === null || credentials === void 0 ? void 0 : credentials.apiKey)) {
1082
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No API key provided in credentials');
1083
- }
990
+ switch (provider) {
991
+ case 'google':
992
+ credentials = await this.getCredentials('googleGenerativeAIApi');
993
+ break;
994
+ case 'deepseek':
995
+ credentials = await this.getCredentials('deepSeekApi');
996
+ break;
997
+ case 'groq':
998
+ credentials = await this.getCredentials('groqApi');
999
+ break;
1000
+ case 'openrouter':
1001
+ credentials = await this.getCredentials('openRouterApi');
1002
+ break;
1003
+ }
1004
+ if (!(credentials === null || credentials === void 0 ? void 0 : credentials.apiKey)) {
1005
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No API key provided in credentials');
1084
1006
  }
1085
- const actualApiKey = apiKey || credentials.apiKey;
1007
+ const actualApiKey = credentials.apiKey;
1008
+ const actualBaseURL = credentials.baseUrl;
1086
1009
  let aiProvider;
1087
1010
  switch (provider) {
1088
1011
  case 'google':
1089
1012
  aiProvider = createGoogleGenerativeAI({
1090
1013
  apiKey: actualApiKey,
1091
- baseURL: baseURL || 'https://generativelanguage.googleapis.com/v1beta',
1092
- headers: {
1093
- 'x-goog-api-key': actualApiKey,
1094
- },
1014
+ ...(actualBaseURL && { baseURL: actualBaseURL }),
1095
1015
  });
1096
1016
  break;
1097
1017
  case 'deepseek':
1098
1018
  aiProvider = createDeepSeek({
1099
1019
  apiKey: actualApiKey,
1100
- baseURL: baseURL || 'https://api.deepseek.com',
1020
+ ...(actualBaseURL && { baseURL: actualBaseURL }),
1101
1021
  });
1102
1022
  break;
1103
1023
  case 'groq':
1104
1024
  aiProvider = createGroq({
1105
1025
  apiKey: actualApiKey,
1106
- baseURL: baseURL || 'https://api.groq.com',
1026
+ ...(actualBaseURL && { baseURL: actualBaseURL }),
1107
1027
  });
1108
1028
  break;
1109
1029
  case 'openrouter':
1110
1030
  aiProvider = createOpenRouter({
1111
1031
  apiKey: actualApiKey,
1112
- baseURL: baseURL || 'https://openrouter.ai/api/v1',
1032
+ ...(actualBaseURL && { baseURL: actualBaseURL }),
1113
1033
  });
1114
1034
  break;
1115
1035
  }
@@ -1241,18 +1161,24 @@ class UniversalAI {
1241
1161
  if (!ajv.validateSchema(parsedSchema)) {
1242
1162
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON Schema: ${ajv.errorsText(ajv.errors)}`);
1243
1163
  }
1244
- const result = await (0, ai_1.generateObject)({
1164
+ const generateObjectParams = {
1245
1165
  model: aiProvider(model, modelSettings),
1246
1166
  schema: (0, ai_1.jsonSchema)(parsedSchema),
1247
1167
  schemaName,
1248
1168
  schemaDescription,
1249
- prompt: input.prompt,
1250
- system: input.system,
1251
- messages: input.messages,
1252
- maxTokens: options.maxTokens,
1253
1169
  temperature: options.temperature,
1254
1170
  ...(stopSequences && (provider === 'google' || provider === 'openrouter') && { stopSequences }),
1255
- });
1171
+ };
1172
+ if (input.messages && input.messages.length > 0) {
1173
+ generateObjectParams.messages = input.messages;
1174
+ }
1175
+ else if (input.prompt) {
1176
+ generateObjectParams.prompt = input.prompt;
1177
+ }
1178
+ if (input.system) {
1179
+ generateObjectParams.system = input.system;
1180
+ }
1181
+ const result = await (0, ai_1.generateObject)(generateObjectParams);
1256
1182
  const formatted = formatObjectResult(result, options.includeRequestBody);
1257
1183
  returnData.push({ json: formatted });
1258
1184
  }