Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into add-low-concurrency…
Browse files Browse the repository at this point in the history
…-warning-to-worker
  • Loading branch information
netroy committed Nov 19, 2024
2 parents 6b7481f + 17ef2c6 commit 8cfc9bc
Show file tree
Hide file tree
Showing 161 changed files with 3,835 additions and 1,090 deletions.
4 changes: 4 additions & 0 deletions cypress/composables/ndv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export function getOutputPanelTable() {
return getOutputPanelDataContainer().get('table');
}

export function getRunDataInfoCallout() {
return cy.getByTestId('run-data-callout');
}

export function getOutputPanelItemsCount() {
return getOutputPanel().getByTestId('ndv-items-count');
}
Expand Down
100 changes: 100 additions & 0 deletions cypress/e2e/30-langchain.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import {
clickCreateNewCredential,
clickExecuteNode,
clickGetBackToCanvas,
getRunDataInfoCallout,
getOutputPanelTable,
toggleParameterCheckboxInputByName,
} from '../composables/ndv';
import {
Expand Down Expand Up @@ -418,4 +420,102 @@ describe('Langchain Integration', () => {
assertInputOutputText('Berlin', 'not.exist');
assertInputOutputText('Kyiv', 'not.exist');
});

it('should show tool info notice if no existing tools were used during execution', () => {
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true);
addNodeToCanvas(AGENT_NODE_NAME, true);

addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
AGENT_NODE_NAME,
true,
);

clickCreateNewCredential();
setCredentialValues({
apiKey: 'sk_test_123',
});
clickGetBackToCanvas();

addToolNodeToParent(AI_TOOL_CALCULATOR_NODE_NAME, AGENT_NODE_NAME);
clickGetBackToCanvas();
openNode(AGENT_NODE_NAME);

const inputMessage = 'Hello!';
const outputMessage = 'Hi there! How can I assist you today?';

clickExecuteNode();

runMockWorkflowExecution({
trigger: () => sendManualChatMessage(inputMessage),
runData: [
createMockNodeExecutionData(AGENT_NODE_NAME, {
jsonData: {
main: { output: outputMessage },
},
metadata: {
subRun: [{ node: AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, runIndex: 0 }],
},
}),
],
lastNodeExecuted: AGENT_NODE_NAME,
});
closeManualChatModal();
openNode(AGENT_NODE_NAME);

getRunDataInfoCallout().should('exist');
});

it('should not show tool info notice if tools were used during execution', () => {
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true);
addNodeToCanvas(AGENT_NODE_NAME, true, true);
getRunDataInfoCallout().should('not.exist');
clickGetBackToCanvas();

addLanguageModelNodeToParent(
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
AGENT_NODE_NAME,
true,
);

clickCreateNewCredential();
setCredentialValues({
apiKey: 'sk_test_123',
});
clickGetBackToCanvas();

addToolNodeToParent(AI_TOOL_CALCULATOR_NODE_NAME, AGENT_NODE_NAME);
clickGetBackToCanvas();
openNode(AGENT_NODE_NAME);

getRunDataInfoCallout().should('not.exist');

const inputMessage = 'Hello!';
const outputMessage = 'Hi there! How can I assist you today?';

clickExecuteNode();

runMockWorkflowExecution({
trigger: () => sendManualChatMessage(inputMessage),
runData: [
createMockNodeExecutionData(AGENT_NODE_NAME, {
jsonData: {
main: { output: outputMessage },
},
metadata: {
subRun: [{ node: AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, runIndex: 0 }],
},
}),
createMockNodeExecutionData(AI_TOOL_CALCULATOR_NODE_NAME, {}),
],
lastNodeExecuted: AGENT_NODE_NAME,
});

closeManualChatModal();
openNode(AGENT_NODE_NAME);
// This waits to ensure the output panel is rendered
getOutputPanelTable();

getRunDataInfoCallout().should('not.exist');
});
});
6 changes: 3 additions & 3 deletions cypress/e2e/34-template-credentials-setup.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,18 @@ describe('Template credentials setup', () => {
it('can be opened from template collection page', () => {
visitTemplateCollectionPage(testData.ecommerceStarterPack);
templateCredentialsSetupPage.enableTemplateCredentialSetupFeatureFlag();
clickUseWorkflowButtonByTitle('Promote new Shopify products on Twitter and Telegram');
clickUseWorkflowButtonByTitle('Promote new Shopify products');

templateCredentialsSetupPage.getters
.title("Set up 'Promote new Shopify products on Twitter and Telegram' template")
.title("Set up 'Promote new Shopify products' template")
.should('be.visible');
});

it('has all the elements on page', () => {
templateCredentialsSetupPage.visitTemplateCredentialSetupPage(testTemplate.id);

templateCredentialsSetupPage.getters
.title("Set up 'Promote new Shopify products on Twitter and Telegram' template")
.title("Set up 'Promote new Shopify products' template")
.should('be.visible');

templateCredentialsSetupPage.getters
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/42-nps-survey.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { WorkflowPage } from '../pages/workflow';

const workflowPage = new WorkflowPage();

const NOW = 1717771477012;
const NOW = Date.now();
const ONE_DAY = 24 * 60 * 60 * 1000;
const THREE_DAYS = ONE_DAY * 3;
const SEVEN_DAYS = ONE_DAY * 7;
Expand Down
2 changes: 2 additions & 0 deletions cypress/e2e/45-ai-assistant.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,8 @@ describe('General help', () => {
}).as('chatRequest');

aiAssistant.getters.askAssistantFloatingButton().click();
wf.getters.zoomToFitButton().click();

aiAssistant.actions.sendMessage('What is wrong with this workflow?');
cy.wait('@chatRequest');

Expand Down
1,556 changes: 1,555 additions & 1 deletion cypress/fixtures/Ecommerce_starter_pack_template_collection.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion cypress/fixtures/Test_Template_1.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"workflow": {
"id": 1205,
"name": "Promote new Shopify products on Twitter and Telegram",
"name": "Promote new Shopify products",
"views": 478,
"recentViews": 9880,
"totalViews": 478,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,7 @@
},
{
"id": 1205,
"name": "Promote New Shopify Products on Social Media (Twitter and Telegram)",
"name": "Promote New Shopify Products",
"totalViews": 219,
"recentViews": 0,
"user": {
Expand Down
8 changes: 8 additions & 0 deletions packages/@n8n/api-types/src/push/execution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ type ExecutionStarted = {
};
};

type ExecutionWaiting = {
type: 'executionWaiting';
data: {
executionId: string;
};
};

type ExecutionFinished = {
type: 'executionFinished';
data: {
Expand Down Expand Up @@ -45,6 +52,7 @@ type NodeExecuteAfter = {

export type ExecutionPushMessage =
| ExecutionStarted
| ExecutionWaiting
| ExecutionFinished
| ExecutionRecovered
| NodeExecuteBefore
Expand Down
30 changes: 30 additions & 0 deletions packages/@n8n/config/src/configs/diagnostics.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Config, Env, Nested } from '../decorators';

@Config
class PostHogConfig {
/** API key for PostHog. */
@Env('N8N_DIAGNOSTICS_POSTHOG_API_KEY')
apiKey: string = 'phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo';

/** API host for PostHog. */
@Env('N8N_DIAGNOSTICS_POSTHOG_API_HOST')
apiHost: string = 'https://ph.n8n.io';
}

@Config
export class DiagnosticsConfig {
/** Whether diagnostics are enabled. */
@Env('N8N_DIAGNOSTICS_ENABLED')
enabled: boolean = false;

/** Diagnostics config for frontend. */
@Env('N8N_DIAGNOSTICS_CONFIG_FRONTEND')
frontendConfig: string = '1zPn9bgWPzlQc0p8Gj1uiK6DOTn;https://telemetry.n8n.io';

/** Diagnostics config for backend. */
@Env('N8N_DIAGNOSTICS_CONFIG_BACKEND')
backendConfig: string = '1zPn7YoGC3ZXE9zLeTKLuQCB4F6;https://telemetry.n8n.io';

@Nested
posthogConfig: PostHogConfig;
}
8 changes: 8 additions & 0 deletions packages/@n8n/config/src/configs/runners.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,12 @@ export class TaskRunnersConfig {
/** Should the output of deduplication be asserted for correctness */
@Env('N8N_RUNNERS_ASSERT_DEDUPLICATION_OUTPUT')
assertDeduplicationOutput: boolean = false;

/** How long (in seconds) a task is allowed to take for completion, else the task will be aborted and the runner restarted. Must be greater than 0. */
@Env('N8N_RUNNERS_TASK_TIMEOUT')
taskTimeout: number = 60;

/** How often (in seconds) the runner must send a heartbeat to the broker, else the task will be aborted and the runner restarted. Must be greater than 0. */
@Env('N8N_RUNNERS_HEARTBEAT_INTERVAL')
heartbeatInterval: number = 30;
}
4 changes: 4 additions & 0 deletions packages/@n8n/config/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CacheConfig } from './configs/cache.config';
import { CredentialsConfig } from './configs/credentials.config';
import { DatabaseConfig } from './configs/database.config';
import { DiagnosticsConfig } from './configs/diagnostics.config';
import { EndpointsConfig } from './configs/endpoints.config';
import { EventBusConfig } from './configs/event-bus.config';
import { ExternalSecretsConfig } from './configs/external-secrets.config';
Expand Down Expand Up @@ -117,4 +118,7 @@ export class GlobalConfig {

@Nested
pruning: PruningConfig;

@Nested
diagnostics: DiagnosticsConfig;
}
11 changes: 11 additions & 0 deletions packages/@n8n/config/test/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ describe('GlobalConfig', () => {
maxOldSpaceSize: '',
maxConcurrency: 5,
assertDeduplicationOutput: false,
taskTimeout: 60,
heartbeatInterval: 30,
},
sentry: {
backendDsn: '',
Expand Down Expand Up @@ -280,6 +282,15 @@ describe('GlobalConfig', () => {
hardDeleteInterval: 15,
softDeleteInterval: 60,
},
diagnostics: {
enabled: false,
frontendConfig: '1zPn9bgWPzlQc0p8Gj1uiK6DOTn;https://telemetry.n8n.io',
backendConfig: '1zPn7YoGC3ZXE9zLeTKLuQCB4F6;https://telemetry.n8n.io',
posthogConfig: {
apiKey: 'phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo',
apiHost: 'https://ph.n8n.io',
},
},
};

it('should use all default values when no env variables are defined', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ export class AnthropicApi implements ICredentialType {
test: ICredentialTestRequest = {
request: {
baseURL: 'https://api.anthropic.com',
url: '/v1/complete',
url: '/v1/messages',
method: 'POST',
headers: {
'anthropic-version': '2023-06-01',
},
body: {
model: 'claude-2',
prompt: '\n\nHuman: Hello, world!\n\nAssistant:',
max_tokens_to_sample: 256,
model: 'claude-3-haiku-20240307',
messages: [{ role: 'user', content: 'Hey' }],
max_tokens: 1,
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ export class AzureOpenAiApi implements ICredentialType {
required: true,
default: '2023-07-01-preview',
},
{
displayName: 'Endpoint',
name: 'endpoint',
type: 'string',
default: undefined,
placeholder: 'https://westeurope.api.cognitive.microsoft.com',
},
];

authenticate: IAuthenticateGeneric = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,36 @@ export class EmbeddingsAzureOpenAi implements INodeType {
'Maximum amount of time a request is allowed to take in seconds. Set to -1 for no timeout.',
type: 'number',
},
{
displayName: 'Dimensions',
name: 'dimensions',
default: undefined,
description:
'The number of dimensions the resulting output embeddings should have. Only supported in text-embedding-3 and later models.',
type: 'options',
options: [
{
name: '256',
value: 256,
},
{
name: '512',
value: 512,
},
{
name: '1024',
value: 1024,
},
{
name: '1536',
value: 1536,
},
{
name: '3072',
value: 3072,
},
],
},
],
},
],
Expand All @@ -98,13 +128,15 @@ export class EmbeddingsAzureOpenAi implements INodeType {
apiKey: string;
resourceName: string;
apiVersion: string;
endpoint?: string;
}>('azureOpenAiApi');
const modelName = this.getNodeParameter('model', itemIndex) as string;

const options = this.getNodeParameter('options', itemIndex, {}) as {
batchSize?: number;
stripNewLines?: boolean;
timeout?: number;
dimensions?: number | undefined;
};

if (options.timeout === -1) {
Expand All @@ -113,9 +145,15 @@ export class EmbeddingsAzureOpenAi implements INodeType {

const embeddings = new OpenAIEmbeddings({
azureOpenAIApiDeploymentName: modelName,
azureOpenAIApiInstanceName: credentials.resourceName,
// instance name only needed to set base url
azureOpenAIApiInstanceName: !credentials.endpoint ? credentials.resourceName : undefined,
azureOpenAIApiKey: credentials.apiKey,
azureOpenAIApiVersion: credentials.apiVersion,
// azureOpenAIEndpoint and configuration.baseURL are both ignored here
// only setting azureOpenAIBasePath worked
azureOpenAIBasePath: credentials.endpoint
? `${credentials.endpoint}/openai/deployments`
: undefined,
...options,
});

Expand Down
Loading

0 comments on commit 8cfc9bc

Please sign in to comment.