n8n-nodes-berget-mk 0.3.0 → 0.4.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.
package/README.md CHANGED
@@ -1,13 +1,14 @@
1
1
  # n8n-nodes-berget-mk
2
2
 
3
- n8n community node for [Berget AI](https://berget.ai), packaged as a single installable module. Maintained by Micke Kring.
3
+ n8n community nodes for [Berget AI](https://berget.ai), packaged as a single installable module. Maintained by Micke Kring.
4
4
 
5
- Two nodes, two purposes:
5
+ Three nodes:
6
6
 
7
- - **Berget AI** — a multi-resource action node with five resources: **Chat**, **Embeddings**, **OCR**, **Rerank**, **Speech to Text**. Use this for one-shot calls.
8
- - **Berget AI Chat Model** — a sub-node that plugs into n8n's built-in **AI Agent**, **Basic LLM Chain**, and any other LangChain-based node. Use this to drive an agent with Berget AI as the underlying LLM. Exposes `reasoning_effort` and the full standard LLM parameter set.
7
+ - **Berget AI** — multi-resource action node for one-shot calls: **Chat** (completions, classification), **OCR** (document text extraction), **Rerank** (document reranking), and **Speech to Text** (Swedish-tuned KB-Whisper). Can also be exposed as a tool to an AI Agent.
8
+ - **Berget AI Chat Model** — sub-node that plugs into n8n's built-in **AI Agent**, **Basic LLM Chain**, and other LangChain-based nodes. Exposes `reasoning_effort` and the full standard LLM parameter set.
9
+ - **Berget AI Embeddings Model** — sub-node that plugs into n8n's **Vector Store** nodes (Supabase, Qdrant, Pinecone, PGVector, etc.) and **Question and Answer Chain**.
9
10
 
10
- > ⚠️ **Experimental — actively developed.** This package is pre-1.0 and the shape of nodes may change between minor releases. Pin a specific version in production workflows until `1.0.0`. See [CHANGELOG.md](CHANGELOG.md) for breaking changes.
11
+ > ⚠️ **Experimental — actively developed.** This package is pre-1.0 and may break between minor releases. Pin a specific version in production workflows until `1.0.0`. See [CHANGELOG.md](CHANGELOG.md) for breaking changes.
11
12
 
12
13
  ## Install
13
14
 
@@ -19,19 +20,31 @@ n8n-nodes-berget-mk
19
20
 
20
21
  Then add a **Berget AI API** credential with your API key from [berget.ai](https://berget.ai).
21
22
 
22
- ## Using the Berget AI action node
23
+ ## Typical workflows
23
24
 
24
- 1. Drop **Berget AI** onto the canvas.
25
- 2. Select a **Resource** (Chat, Embeddings, OCR, Rerank, or Speech to Text).
26
- 3. Fill in the resource-specific fields (model, input, options).
27
- 4. Execute.
25
+ ### One-shot chat / classification
28
26
 
29
- ## Using Berget with n8n's AI Agent
27
+ 1. Drop **Berget AI** onto the canvas, pick Resource = **Chat**, select a model, add a user message. Execute.
30
28
 
31
- 1. Add n8n's built-in **AI Agent** node.
32
- 2. Add a **Berget AI Chat Model** node and connect it to the Agent's **Chat Model** socket.
33
- 3. Pick a Berget AI chat model and optionally configure `reasoning_effort` for reasoning-capable models (GPT-OSS, DeepSeek R1).
34
- 4. Add Memory and Tool sub-nodes as usual they work with Berget as the underlying LLM.
29
+ ### Agent with tools and memory
30
+
31
+ 1. Add n8n's built-in **AI Agent**.
32
+ 2. Add **Berget AI Chat Model** and connect it to the Agent's Chat Model socket.
33
+ 3. Add Memory and Tool sub-nodes as needed — they work with Berget as the underlying LLM.
34
+
35
+ ### RAG / vector search
36
+
37
+ 1. Add a Vector Store node (Supabase, Qdrant, etc.) or a Question and Answer Chain.
38
+ 2. Add **Berget AI Embeddings Model** and connect it to the Embedding socket.
39
+ 3. Index documents or query as usual.
40
+
41
+ ### Document extraction
42
+
43
+ 1. Drop **Berget AI** onto the canvas, pick Resource = **OCR**, provide a document URL or base64 data, and pick your output format (Markdown or JSON).
44
+
45
+ ### Swedish speech transcription
46
+
47
+ 1. Drop **Berget AI** onto the canvas, pick Resource = **Speech to Text**, pick a model (defaults to `KB-Whisper-Large`), and point at an audio file.
35
48
 
36
49
  ## Changelog
37
50
 
@@ -4,7 +4,6 @@ export declare class BergetAi implements INodeType {
4
4
  methods: {
5
5
  loadOptions: {
6
6
  getChatModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
7
- getEmbeddingsModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
8
7
  getRerankModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
9
8
  getSpeechModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
10
9
  };
@@ -4,7 +4,6 @@ exports.BergetAi = void 0;
4
4
  const n8n_workflow_1 = require("n8n-workflow");
5
5
  const n8n_workflow_2 = require("n8n-workflow");
6
6
  const chat_1 = require("./chat");
7
- const embeddings_1 = require("./embeddings");
8
7
  const ocr_1 = require("./ocr");
9
8
  const rerank_1 = require("./rerank");
10
9
  const speech_1 = require("./speech");
@@ -18,14 +17,15 @@ class BergetAi {
18
17
  group: ['transform'],
19
18
  version: 1,
20
19
  subtitle: '={{$parameter["resource"]}}',
21
- description: 'Use Berget AI for chat completions, embeddings, document OCR, speech-to-text, and document reranking',
20
+ description: 'Use Berget AI for chat completions, document OCR, speech-to-text, and document reranking',
22
21
  defaults: { name: 'Berget AI' },
22
+ usableAsTool: true,
23
23
  codex: {
24
+ alias: ['Berget', 'Berget AI', 'Swedish AI', 'LLM', 'KB-Whisper'],
24
25
  categories: ['AI'],
25
26
  subcategories: {
26
- AI: ['Miscellaneous'],
27
+ AI: ['Agents', 'Miscellaneous', 'Root Nodes'],
27
28
  },
28
- alias: ['Berget', 'Berget AI', 'Swedish AI', 'LLM'],
29
29
  },
30
30
  credentials: [
31
31
  {
@@ -48,11 +48,6 @@ class BergetAi {
48
48
  value: 'chat',
49
49
  description: 'Create a chat completion',
50
50
  },
51
- {
52
- name: 'Embeddings',
53
- value: 'embeddings',
54
- description: 'Generate vector embeddings from text',
55
- },
56
51
  {
57
52
  name: 'OCR',
58
53
  value: 'ocr',
@@ -71,7 +66,6 @@ class BergetAi {
71
66
  ],
72
67
  },
73
68
  ...chat_1.chatProperties,
74
- ...embeddings_1.embeddingsProperties,
75
69
  ...ocr_1.ocrProperties,
76
70
  ...rerank_1.rerankProperties,
77
71
  ...speech_1.speechProperties,
@@ -82,9 +76,6 @@ class BergetAi {
82
76
  async getChatModels() {
83
77
  return (0, shared_1.loadModelOptions)(this, (m) => m.model_type === 'text' || m.model_type === 'ocr');
84
78
  },
85
- async getEmbeddingsModels() {
86
- return (0, shared_1.loadModelOptions)(this, (m) => m.model_type === 'embedding');
87
- },
88
79
  async getRerankModels() {
89
80
  return (0, shared_1.loadModelOptions)(this, (m) => m.model_type === 'rerank');
90
81
  },
@@ -105,9 +96,6 @@ class BergetAi {
105
96
  case 'chat':
106
97
  result = await (0, chat_1.executeChat)(this, i);
107
98
  break;
108
- case 'embeddings':
109
- result = await (0, embeddings_1.executeEmbeddings)(this, i);
110
- break;
111
99
  case 'ocr':
112
100
  result = await (0, ocr_1.executeOcr)(this, i);
113
101
  break;
@@ -0,0 +1,10 @@
1
+ import { type ILoadOptionsFunctions, type INodePropertyOptions, type INodeType, type INodeTypeDescription, type ISupplyDataFunctions, type SupplyData } from 'n8n-workflow';
2
+ export declare class BergetAiEmbeddingsModel implements INodeType {
3
+ description: INodeTypeDescription;
4
+ methods: {
5
+ loadOptions: {
6
+ getEmbeddingsModels(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
7
+ };
8
+ };
9
+ supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData>;
10
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BergetAiEmbeddingsModel = void 0;
7
+ const openai_1 = require("@langchain/openai");
8
+ const axios_1 = __importDefault(require("axios"));
9
+ const n8n_workflow_1 = require("n8n-workflow");
10
+ const BERGET_API_BASE_URL = 'https://api.berget.ai/v1';
11
+ class BergetAiEmbeddingsModel {
12
+ constructor() {
13
+ this.description = {
14
+ displayName: 'Berget AI Embeddings Model',
15
+ name: 'bergetAiEmbeddingsModel',
16
+ icon: 'file:bergetai.svg',
17
+ group: ['transform'],
18
+ version: 1,
19
+ description: 'Use a Berget AI embedding model with Vector Store, Question and Answer Chain, or other LangChain nodes',
20
+ defaults: { name: 'Berget AI Embeddings Model' },
21
+ codex: {
22
+ categories: ['AI'],
23
+ subcategories: {
24
+ AI: ['Embeddings'],
25
+ },
26
+ },
27
+ credentials: [{ name: 'bergetAiApi', required: true }],
28
+ inputs: [],
29
+ outputs: [n8n_workflow_1.NodeConnectionTypes.AiEmbedding],
30
+ outputNames: ['Embeddings'],
31
+ properties: [
32
+ {
33
+ displayName: 'This node must be connected to a Vector Store or QA Chain, not executed on its own.',
34
+ name: 'notice',
35
+ type: 'notice',
36
+ default: '',
37
+ },
38
+ {
39
+ displayName: 'Model',
40
+ name: 'model',
41
+ type: 'options',
42
+ typeOptions: { loadOptionsMethod: 'getEmbeddingsModels' },
43
+ default: '',
44
+ required: true,
45
+ description: 'The Berget AI embedding model to use. Fetched live from the Berget API.',
46
+ },
47
+ {
48
+ displayName: 'Options',
49
+ name: 'options',
50
+ type: 'collection',
51
+ placeholder: 'Add Option',
52
+ default: {},
53
+ options: [
54
+ {
55
+ displayName: 'Batch Size',
56
+ name: 'batchSize',
57
+ type: 'number',
58
+ typeOptions: { minValue: 1 },
59
+ default: 512,
60
+ description: 'Number of documents to embed per API request',
61
+ },
62
+ {
63
+ displayName: 'Strip New Lines',
64
+ name: 'stripNewLines',
65
+ type: 'boolean',
66
+ default: true,
67
+ description: 'Whether to strip newlines from input text before embedding',
68
+ },
69
+ {
70
+ displayName: 'Timeout (Ms)',
71
+ name: 'timeout',
72
+ type: 'number',
73
+ typeOptions: { minValue: 1 },
74
+ default: 60000,
75
+ description: 'Maximum time in milliseconds to wait for the embeddings API',
76
+ },
77
+ ],
78
+ },
79
+ ],
80
+ };
81
+ this.methods = {
82
+ loadOptions: {
83
+ async getEmbeddingsModels() {
84
+ var _a, _b;
85
+ const credentials = await this.getCredentials('bergetAiApi');
86
+ const response = await axios_1.default.get(`${BERGET_API_BASE_URL}/models`, {
87
+ headers: {
88
+ Authorization: `Bearer ${credentials.apiKey}`,
89
+ 'Content-Type': 'application/json',
90
+ },
91
+ });
92
+ const models = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : [];
93
+ return models
94
+ .filter((m) => m.model_type === 'embedding')
95
+ .map((m) => ({
96
+ name: m.id,
97
+ value: m.id,
98
+ }))
99
+ .sort((a, b) => a.name.localeCompare(b.name));
100
+ },
101
+ },
102
+ };
103
+ }
104
+ async supplyData(itemIndex) {
105
+ var _a, _b, _c;
106
+ const credentials = await this.getCredentials('bergetAiApi');
107
+ const modelName = this.getNodeParameter('model', itemIndex);
108
+ const options = this.getNodeParameter('options', itemIndex, {});
109
+ const embeddings = new openai_1.OpenAIEmbeddings({
110
+ apiKey: credentials.apiKey,
111
+ model: modelName,
112
+ configuration: {
113
+ baseURL: BERGET_API_BASE_URL,
114
+ },
115
+ batchSize: (_a = options.batchSize) !== null && _a !== void 0 ? _a : 512,
116
+ stripNewLines: (_b = options.stripNewLines) !== null && _b !== void 0 ? _b : true,
117
+ timeout: (_c = options.timeout) !== null && _c !== void 0 ? _c : 60000,
118
+ });
119
+ return { response: embeddings };
120
+ }
121
+ }
122
+ exports.BergetAiEmbeddingsModel = BergetAiEmbeddingsModel;
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 463 419">
2
+ <path fill="#10b981" d="M208.739 17L255.261 17L446 403L398 403L313.5 255L261.5 176L233.163 96.1677L237.815 98.6522H226.185L230.837 96.1677L113 331L64.5 403L18 403L208.739 17Z"/>
3
+ </svg>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "n8n-nodes-berget-mk",
3
- "version": "0.3.0",
4
- "description": "n8n community node for Berget AI. One multi-resource action node (chat, embeddings, OCR, speech-to-text, rerank) plus a Chat Model sub-node that plugs into n8n's built-in AI Agent.",
3
+ "version": "0.4.0",
4
+ "description": "n8n community node for Berget AI. Multi-resource action node (chat, OCR, rerank, speech-to-text) plus Chat Model and Embeddings Model sub-nodes that plug into n8n's built-in AI Agent and Vector Store nodes.",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
7
7
  "n8n",
@@ -62,7 +62,8 @@
62
62
  ],
63
63
  "nodes": [
64
64
  "dist/nodes/BergetAi/BergetAi.node.js",
65
- "dist/nodes/BergetAiChatModel/BergetAiChatModel.node.js"
65
+ "dist/nodes/BergetAiChatModel/BergetAiChatModel.node.js",
66
+ "dist/nodes/BergetAiEmbeddingsModel/BergetAiEmbeddingsModel.node.js"
66
67
  ]
67
68
  }
68
69
  }
@@ -1,3 +0,0 @@
1
- import type { IDataObject, IExecuteFunctions, INodeProperties } from 'n8n-workflow';
2
- export declare const embeddingsProperties: INodeProperties[];
3
- export declare function executeEmbeddings(context: IExecuteFunctions, itemIndex: number): Promise<IDataObject>;
@@ -1,71 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.embeddingsProperties = void 0;
4
- exports.executeEmbeddings = executeEmbeddings;
5
- const n8n_workflow_1 = require("n8n-workflow");
6
- const shared_1 = require("./shared");
7
- const showForEmbeddings = {
8
- displayOptions: {
9
- show: {
10
- resource: ['embeddings'],
11
- },
12
- },
13
- };
14
- exports.embeddingsProperties = [
15
- {
16
- displayName: 'Model',
17
- name: 'embeddingsModel',
18
- type: 'options',
19
- typeOptions: { loadOptionsMethod: 'getEmbeddingsModels' },
20
- default: '',
21
- required: true,
22
- description: 'The Berget AI embedding model to use',
23
- ...showForEmbeddings,
24
- },
25
- {
26
- displayName: 'Input Text',
27
- name: 'embeddingsInput',
28
- type: 'string',
29
- typeOptions: { rows: 4 },
30
- default: '',
31
- required: true,
32
- description: 'Text to convert into an embedding vector',
33
- ...showForEmbeddings,
34
- },
35
- {
36
- displayName: 'Options',
37
- name: 'embeddingsOptions',
38
- type: 'collection',
39
- placeholder: 'Add Option',
40
- default: {},
41
- options: [
42
- {
43
- displayName: 'Encoding Format',
44
- name: 'encoding_format',
45
- type: 'options',
46
- options: [
47
- { name: 'Float', value: 'float' },
48
- { name: 'Base64', value: 'base64' },
49
- ],
50
- default: 'float',
51
- description: 'Format of the returned embedding data',
52
- },
53
- ],
54
- ...showForEmbeddings,
55
- },
56
- ];
57
- async function executeEmbeddings(context, itemIndex) {
58
- var _a, _b;
59
- const credentials = await context.getCredentials('bergetAiApi');
60
- const model = context.getNodeParameter('embeddingsModel', itemIndex);
61
- const input = context.getNodeParameter('embeddingsInput', itemIndex);
62
- const options = context.getNodeParameter('embeddingsOptions', itemIndex, {});
63
- const { status, data } = await (0, shared_1.bergetRequest)(credentials.apiKey, 'POST', '/embeddings', { model, input, ...options });
64
- if (status !== 200) {
65
- const message = (_b = (_a = data === null || data === void 0 ? void 0 : data.error) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : `HTTP ${status}`;
66
- throw new n8n_workflow_1.NodeOperationError(context.getNode(), `Berget AI embeddings error: ${message}`, {
67
- itemIndex,
68
- });
69
- }
70
- return data;
71
- }