chore: update n8n to 2.8.3 (#603)

* chore: update n8n to 2.8.3 and bump version to 2.35.3

- Updated n8n from 2.6.3 to 2.8.3
- Updated n8n-core from 2.6.1 to 2.8.1
- Updated n8n-workflow from 2.6.0 to 2.8.0
- Updated @n8n/n8n-nodes-langchain from 2.6.2 to 2.8.1
- Fixed node loader to bypass restricted package.json exports in
  @n8n/n8n-nodes-langchain >=2.9.0 (resolves via absolute paths)
- Fixed community doc generator for cloud LLMs: added API key env var
  support, switched to max_completion_tokens, auto-omit temperature
- Rebuilt node database with 1,236 nodes (673 n8n-nodes-base,
  133 @n8n/n8n-nodes-langchain, 430 community)
- Refreshed community nodes (361 verified + 69 npm) with 424 AI summaries
- Updated README badge with new n8n version and node counts
- Updated CHANGELOG with dependency changes

Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update documentation-generator tests for max_completion_tokens

- Updated test assertions from max_tokens to max_completion_tokens
- Updated testConnection token limit expectation from 10 to 200
- Added temperature to test config to match new configurable behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Romuald Członkowski
2026-02-20 02:15:15 +01:00
committed by GitHub
parent 6f695be482
commit 77048347b3
14 changed files with 9321 additions and 5329 deletions

View File

@@ -57,12 +57,14 @@ export interface DocumentationGeneratorConfig {
timeout?: number;
/** Max tokens for response (default: 2000) */
maxTokens?: number;
/** Temperature for generation (default: 0.3, set to undefined to omit) */
temperature?: number;
}
/**
* Default configuration
*/
const DEFAULT_CONFIG: Required<Omit<DocumentationGeneratorConfig, 'baseUrl'>> = {
const DEFAULT_CONFIG: Required<Omit<DocumentationGeneratorConfig, 'baseUrl' | 'temperature'>> = {
model: 'qwen3-4b-thinking-2507',
apiKey: 'not-needed',
timeout: 60000,
@@ -78,6 +80,7 @@ export class DocumentationGenerator {
private model: string;
private maxTokens: number;
private timeout: number;
private temperature?: number;
constructor(config: DocumentationGeneratorConfig) {
const fullConfig = { ...DEFAULT_CONFIG, ...config };
@@ -90,6 +93,7 @@ export class DocumentationGenerator {
this.model = fullConfig.model;
this.maxTokens = fullConfig.maxTokens;
this.timeout = fullConfig.timeout;
this.temperature = fullConfig.temperature;
}
/**
@@ -101,8 +105,8 @@ export class DocumentationGenerator {
const completion = await this.client.chat.completions.create({
model: this.model,
max_tokens: this.maxTokens,
temperature: 0.3, // Lower temperature for more consistent output
max_completion_tokens: this.maxTokens,
...(this.temperature !== undefined ? { temperature: this.temperature } : {}),
messages: [
{
role: 'system',
@@ -321,7 +325,7 @@ Guidelines:
try {
const completion = await this.client.chat.completions.create({
model: this.model,
max_tokens: 10,
max_completion_tokens: 200,
messages: [
{
role: 'user',
@@ -353,10 +357,15 @@ export function createDocumentationGenerator(): DocumentationGenerator {
const baseUrl = process.env.N8N_MCP_LLM_BASE_URL || 'http://localhost:1234/v1';
const model = process.env.N8N_MCP_LLM_MODEL || 'qwen3-4b-thinking-2507';
const timeout = parseInt(process.env.N8N_MCP_LLM_TIMEOUT || '60000', 10);
const apiKey = process.env.N8N_MCP_LLM_API_KEY || process.env.OPENAI_API_KEY;
// Only set temperature for local LLM servers; cloud APIs like OpenAI may not support custom values
const isLocalServer = !baseUrl.includes('openai.com') && !baseUrl.includes('anthropic.com');
return new DocumentationGenerator({
baseUrl,
model,
timeout,
...(apiKey ? { apiKey } : {}),
...(isLocalServer ? { temperature: 0.3 } : {}),
});
}

View File

@@ -31,24 +31,44 @@ export class N8nNodeLoader {
return results;
}
/**
* Resolve the absolute directory of an installed package.
* Uses require.resolve on package.json (always exported) and strips the filename.
*/
private resolvePackageDir(packagePath: string): string {
const pkgJsonPath = require.resolve(`${packagePath}/package.json`);
return path.dirname(pkgJsonPath);
}
/**
* Load a node module by absolute file path, bypassing package.json "exports".
* Some packages (e.g. @n8n/n8n-nodes-langchain >=2.9) restrict exports but
* still list node files in the n8n.nodes array — we need direct filesystem access.
*/
private loadNodeModule(absolutePath: string): any {
return require(absolutePath);
}
private async loadPackageNodes(packageName: string, packagePath: string, packageJson: any): Promise<LoadedNode[]> {
const n8nConfig = packageJson.n8n || {};
const nodes: LoadedNode[] = [];
const packageDir = this.resolvePackageDir(packagePath);
// Check if nodes is an array or object
const nodesList = n8nConfig.nodes || [];
if (Array.isArray(nodesList)) {
// Handle array format (n8n-nodes-base uses this)
for (const nodePath of nodesList) {
try {
const fullPath = require.resolve(`${packagePath}/${nodePath}`);
const nodeModule = require(fullPath);
// Resolve absolute path directly to bypass package exports restrictions
const fullPath = path.join(packageDir, nodePath);
const nodeModule = this.loadNodeModule(fullPath);
// Extract node name from path (e.g., "dist/nodes/Slack/Slack.node.js" -> "Slack")
const nodeNameMatch = nodePath.match(/\/([^\/]+)\.node\.(js|ts)$/);
const nodeName = nodeNameMatch ? nodeNameMatch[1] : path.basename(nodePath, '.node.js');
// Handle default export and various export patterns
const NodeClass = nodeModule.default || nodeModule[nodeName] || Object.values(nodeModule)[0];
if (NodeClass) {
@@ -65,9 +85,9 @@ export class N8nNodeLoader {
// Handle object format (for other packages)
for (const [nodeName, nodePath] of Object.entries(nodesList)) {
try {
const fullPath = require.resolve(`${packagePath}/${nodePath as string}`);
const nodeModule = require(fullPath);
const fullPath = path.join(packageDir, nodePath as string);
const nodeModule = this.loadNodeModule(fullPath);
// Handle default export and various export patterns
const NodeClass = nodeModule.default || nodeModule[nodeName] || Object.values(nodeModule)[0];
if (NodeClass) {
@@ -81,7 +101,7 @@ export class N8nNodeLoader {
}
}
}
return nodes;
}
}

View File

@@ -11,6 +11,7 @@
* Environment variables:
* N8N_MCP_LLM_BASE_URL - LLM server URL (default: http://localhost:1234/v1)
* N8N_MCP_LLM_MODEL - LLM model name (default: qwen3-4b-thinking-2507)
* N8N_MCP_LLM_API_KEY - LLM API key (falls back to OPENAI_API_KEY; default: 'not-needed')
* N8N_MCP_LLM_TIMEOUT - Request timeout in ms (default: 60000)
* N8N_MCP_DB_PATH - Database path (default: ./data/nodes.db)
*/
@@ -81,6 +82,7 @@ Options:
Environment Variables:
N8N_MCP_LLM_BASE_URL LLM server URL (default: http://localhost:1234/v1)
N8N_MCP_LLM_MODEL LLM model name (default: qwen3-4b-thinking-2507)
N8N_MCP_LLM_API_KEY LLM API key (falls back to OPENAI_API_KEY; default: 'not-needed')
N8N_MCP_LLM_TIMEOUT Request timeout in ms (default: 60000)
N8N_MCP_DB_PATH Database path (default: ./data/nodes.db)